二、SCNGeometry代码创建几何体

感谢小伙伴的到来~~~

(一)前言

上章对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),这是一个常见的优化,因为后面很多时候是被几何体中的其他表面遮蔽。

①绘制三角形
二、SCNGeometry代码创建几何体_第1张图片
逆时针索引顶点
注意:顶点个数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个顶点组成三角形
一般用在"三角带"上,三角带是一个三角形列表,其中每个三角形都与前一个三角形共享一边。下图显示了一个三角带

下图中,注意到,顶点顺序在顺时针和逆时针间不断变换。

二、SCNGeometry代码创建几何体_第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])
二、SCNGeometry代码创建几何体_第3张图片
结构图
二、SCNGeometry代码创建几何体_第4张图片
效果图

)

(3) 绘制几何体

绘制立方体其实就是两个三角形拼接成一个方形面,六个正方形面拼接成闭合的立方体。需要注意的是立方体每个面的正反面。

代码已经上传其中已经打好注释在这里不做过多解释了: github

二、SCNGeometry代码创建几何体_第5张图片
曲线

二、SCNGeometry代码创建几何体_第6张图片
曲面

(三)创建SCN文件 拖拽模型

最后简单的给大家截图看一下创建SCN文件拖装一些模型,然后用SCNScene(named:)加载模型文件


二、SCNGeometry代码创建几何体_第7张图片
添加
二、SCNGeometry代码创建几何体_第8张图片
添加模型

本章内容就到这里感谢小伙伴们的到来~
下章我将给大家介绍SCNGeometry曲面的绘制、法线以及纹理映射坐标的内容。我会尽量加快更新速度~~~
代码已经上传github

你可能感兴趣的:(二、SCNGeometry代码创建几何体)