感谢小伙伴的到来~~~
(一)前言
上章对ARKit进行了一个简单介绍
一、ARKit初探索
没有看过的小伙伴可以点击了解一下。
本章我会来带大家了解一下SCNGeometry使用顶点信息创建几何体
(二) SCNGeometry
1、介绍
在SceneKit中,附加到SCNNode对象的几何形状形成场景的可见元素,并且SCNMaterial连接到几何的对象决定其外观。
2、创建方法
描述 | 了解更多 |
---|---|
从使用外部3D创作工具创建的场景文件加载 | SCNScene、SCNSceneSource |
使用和自定义SceneKit的内置原始形状 | SCNPlane、SCNBox、SCNSphere、SCNPyramid、SCNCone、SCNCylinder、SCNCapsule、SCNTube和SCNTorus |
从2D文本或Bézier曲线创建3D几何 | SCNText、SCNShape |
从顶点数据创建自定义几何 | SCNGeometrySource、 SCNGeometryElement、init(sources:elements:)或是管理形状数据 |
本章主要是用 init(sources:elements:)的方法来创建自定义几何体
3、SCNGeometry init(sources:elements:)
本章我主要使用顶点来创建几何体。法线和纹理映射坐标将在下章介绍
参数说明
sources 描述几何及其属性中的顶点的SCNGeometrySource对象数组。
elements 描述如何连接几何的顶点的SCNGeometryElement对象数组。
几何的可见内容来自几何源的组合,其中包含描述其顶点的数据、几何元素、描述顶点如何连接以形成曲面的数据。
每个SCNGeometrySource对象描述由源的属性识别的几何中的所有顶点的属性(顶点位置,表面法线矢量,颜色或纹理映射坐标)semantic。要创建自定义几何,您必须提供至少一个源,用于vertex。通常,您还提供用于照明和阴影的法线和纹理坐标的来源。
顶点,正常和颜色语义的来源必须是唯一的 - 如果sources数组中的多个对象具有相同的语义,则SceneKit仅使用第一个。几何可能有多个texcoord来源-sources阵列中的纹理坐标源的顺序决定了在附加材料时用于属性的值mappingChannel。
每个SCNGeometryElement对象描述几何源的顶点如何组合成多边形以创建几何体的形状。创建自定义几何需要至少一个元素。如果数组包含多个elements对象,则它们的顺序决定了几何图形材料的排列方式有关详细信息,请参阅materials。
4、使用顶点坐标创建线、面和几何体
(1)线
let indices: [UInt8] = [0, 1]//需要特别注意 [UInt8]可以使用UInt8、UInt16、UInt32,不能使用UInt64,否则什么几何图像都绘制不出来,具体原因还在查看
我这里索引都不会很大所以使用的UInt8,请注意变量最大取值范围
//使用SCNVector3创建顶点索引
let geometrySources = SCNGeometrySource(vertices: [
SCNVector3(x: 0.1, y: 0.0, z: -0.1),
SCNVector3(x: 0.1, y: 0.1, z: -0.1),
])
//indices:一组索引值,每个索引值都标识几何源中的一个顶点(连接顶点的顺序)
//primitiveType:渲染几何元素时连接顶点的绘图方式(SCNGeometryPrimitiveType)
/*
SCNGeometryPrimitiveType:
case triangles
几何元素的数据是一系列三角形,每个三角形由三个新的顶点描述。
case triangleStrip
几何元素的数据是一系列三角形,每个三角形由一个新顶点和前三角形的两个顶点描述。
case line
几何元素的数据是一系列线段,每个线段由两个新顶点描述。
case point
几何元素的数据是一系列未连接的点。
*/
let indices: [UInt8] = [0, 1]
let geometryElement = SCNGeometryElement(indices: indices, primitiveType: .line)
//根据顶点和索引数据 创建几何形状
let geometry = SCNGeometry(sources: [geometrySources], elements: [geometryElement])
(2)绘制平面
在介绍代码之间我们先了解一下关于图形的一些基本知识
在3D空间中绘制的大部分内容都包含大量三角形,他是具有表面的最小形状。三点形成一个表面,我们可以用四点形成一个矩形实际上只是两个三角形。
每个表面都有前面和后面,"前面以逆时针方向指定"。SCNMaterial渲染器默认只渲染前面(isDoubleSided属性默认NO),这是一个常见的优化,因为后面很多时候是被几何体中的其他表面遮蔽。
①绘制三角形
注意:顶点个数n至少要大于3,否则不能绘制任何三角形。
let geometrySources = SCNGeometrySource(vertices: [
SCNVector3(x: 0.1, y: 0.0, z: -0.1),
SCNVector3(x: 0.1, y: 0.1, z: -0.1),
SCNVector3(x: -0.1, y: 0.0, z: -0.1),
])
let indices: [UInt8] = [0, 1, 2]
let geometryElement = SCNGeometryElement(indices: indices, primitiveType: .triangles)
let geometry = SCNGeometry(sources: [geometrySources], elements: [geometryElement])
运行代码会看到一个面向我们的三角形,而从三角形的背面看是透明的
②绘制长方形
我们将使用三角形两种不同的顶点索引方式来分别拼合一个长方形
case triangles 几何元素的数据是一系列三角形,每个三角形由三个新的顶点描述。
case triangleStrip
几何元素的数据是一系列三角形,每个三角形由一个新顶点和前三角形的两个顶点描述。
A、triangles
以每三个顶点绘制一个三角形。如果顶点的个数n不是3的倍数,那么最后的1个或者2个顶点会被忽略。
let geometrySources = SCNGeometrySource(vertices: [
SCNVector3(x: 0.1, y: 0.0, z: -0.1),
SCNVector3(x: 0.1, y: 0.1, z: -0.1),
SCNVector3(x: -0.1, y: 0.0, z: -0.1),
SCNVector3(x: -0.1, y: 0.1, z: -0.1),
])
//正面向前,逆时针索引每个三角形,三个一组
//0->1->2 2->1->3
let indices: [UInt8] = [0, 1, 2,
2, 1, 3]
let geometryElement = SCNGeometryElement(indices: indices, primitiveType: .triangles)
let geometry = SCNGeometry(sources: [geometrySources], elements: [geometryElement])
A、triangleStrip
构建当前三角形的顶点的连接顺序依赖于要和前面已经出现过的2个顶点组成三角形
一般用在"三角带"上,三角带是一个三角形列表,其中每个三角形都与前一个三角形共享一边。下图显示了一个三角带
下图中,注意到,顶点顺序在顺时针和逆时针间不断变换。
let geometrySources = SCNGeometrySource(vertices: [
SCNVector3(x: 0.1, y: 0.0, z: -0.1),
SCNVector3(x: 0.1, y: 0.1, z: -0.1),
SCNVector3(x: -0.1, y: 0.0, z: -0.1),
SCNVector3(x: -0.1, y: 0.1, z: -0.1),
SCNVector3(x: -0.1, y: 0.0, z: 0.0),
SCNVector3(x: -0.1, y: 0.1, z: 0.0),
])
//0->1->2(逆) 1->2->3(顺) 2->3->4(逆) 3->4->5(顺)
let indices: [UInt8] = [0, 1, 2, 3, 4, 5]
let geometryElement = SCNGeometryElement(indices: indices, primitiveType: .triangleStrip)
let geometry = SCNGeometry(sources: [geometrySources], elements: [geometryElement])
)
(3) 绘制几何体
绘制立方体其实就是两个三角形拼接成一个方形面,六个正方形面拼接成闭合的立方体。需要注意的是立方体每个面的正反面。
代码已经上传其中已经打好注释在这里不做过多解释了: github
(三)创建SCN文件 拖拽模型
最后简单的给大家截图看一下创建SCN文件拖装一些模型,然后用SCNScene(named:)加载模型文件
本章内容就到这里感谢小伙伴们的到来~
下章我将给大家介绍SCNGeometry曲面的绘制、法线以及纹理映射坐标的内容。我会尽量加快更新速度~~~
代码已经上传github