SceneKit开发教程03|SceneKit开发教程03 | 使用SCNNode && SCNReferenceNode定义场景结构

上一篇介绍了场景(SCNScene)和视图(SCNView)相关的内容,本节介绍 和节点相关的内容。
0. 写在前面 在SceneKit场景中,把节点的层次树结构称为场景图,场景中的节点可以分为两类:
  • 一个根节点,它为场景的世界定义了一个坐标空间
  • 其它节点,其它节点一起构成场景中的可见内容
SceneKit在视图中显示场景,处理场景图并执行动画,然后通过GPU逐帧渲染出来。
在使用SceneKit之前,您应该熟悉基本的图形概念,例如坐标系和立体几何。 SceneKit使用右手坐标系,其中(默认情况下)视图的方向沿着负z轴,如下所示:
SceneKit开发教程03|SceneKit开发教程03 | 使用SCNNode && SCNReferenceNode定义场景结构
文章图片
SceneKit坐标系.png 其实SceneKit构建的3D空间可以和UIKit构建的3D空间对比理解,画了一张草图可以对比理解:
SceneKit开发教程03|SceneKit开发教程03 | 使用SCNNode && SCNReferenceNode定义场景结构
文章图片
image.png 2. SCNNode 场景图的结构元素,表示3D坐标空间中的位置变换,可以将几何体,灯光,相机或其他可显示内容附加到节点上。
注意:SCNNoad对象本身没有可见内容,它只代表相对于它的父节点的坐标空间变换(位置、方向和尺寸)。为了构建场景的时候,使用节点的层次结构来创建其结构,然后向节点添加灯、相机和几何体以创建可视内容。
2.1 创建一个节点
SCNNode提供了两个init方法来创建节点对象:
  • init(geometry: SCNGeometry?),创建附加了指定几何的节点对象
  • init(mdlObject: MDLObject),从指定的 Model I/O 对象创建节点对象
2.1 节点的变换(transform)
和节点变换相关的属性很重要,它们直接影响了节点的位置、大小以及动画。
节点的转换对于开发者来说很重要,主要原因有两点:
  • 转换描述了节点相对于父节点的位置、旋转以及尺寸信息,只有掌握了转换,才能把节点放在正确的位置
  • 这部分内容和动画相关,要使你的场景动起来,这部分是基础
要掌握这部分内容,就要弄清楚“两个矩阵”和“五个向量”。
2.1.1 两个矩阵 simdPivot
pivot的意思是枢轴、中心点。所以这个矩阵我称之为枢轴矩阵,在SCNNode中,API定义如下:
  • var simdPivot: simd_float4x4
节点的“枢轴”表示节点坐标空间之间的转换,它还会被simdPosition、simdRotation和simdScale属性使用。
枢轴矩阵的默认值是4x4的单位矩阵,表示 :
  1. 节点的位置在其坐标系的原点位置,
  2. 节点的旋转轴是穿过其中心点的轴,
  3. 节点的缩放也是相当对其中心点的。
simdTransform
变换矩阵,表示当前节点相对于父节点的变换,默认值是4x4的单位矩阵。它由节点的simdRotation、simdPosition、和 simdScale 属性组成。
  • var simdTransform: simd_float4x4
当改变节点的simdTransform属性,节点的simdRotation、simdOrientation、simdEulerAngles、simdPosition 和 simdScale 属性会随着自动变化。反之亦然。
2.1.2 五个向量
  • var simdPosition: simd_float3,节点的位置,一个三维向量,描述节点相对于父节点的位置,默认是个零向量,表示当前节点添加在父节点坐标系的原点位置
  • var simdRotation: simd_float4,节点的旋转,一个四维向量,前三维描述旋转轴的方向,第四维描述旋转的角度,默认是零向量,表示没有旋转
  • var simdScale: simd_float3,节点的大小,一个三维向量,表示几何体在每一维上大小缩放系数
  • var simdEulerAngles: simd_float3,节点的欧拉角,一个三维向量,用每一维分别表示 pitch、yaw 和 roll。其中,pitch 表示 节点围绕 X 轴的旋转角度; yaw 表示 节点围绕 Y 轴的旋转角度;roll 表示 节点围绕 Z 轴旋转的角度。我在网上找了一张图片来辅助理解。
SceneKit开发教程03|SceneKit开发教程03 | 使用SCNNode && SCNReferenceNode定义场景结构
文章图片
image.png 要注意理解simdRotationsimdEularAngles 的联系和区别。
  • var simdOrientation: simd_quatf,节点的方向,用一个四元组来,表示节点的方向。
simd 什么意思](https://stackoverflow.com/questions/44756858/what-does-the-simd-prefix-mean-in-scenekit)。
这一小节弄清楚了节点在场景中的位置,下一节介绍节点的内容,也就是场景中的可视部分。
2.2 节点的内容
这一小节介绍,节点包含的内容。
  • var name: String?,顾名思义,节点的名称。给节点起一个可读性较好的名称,方便管理节点,尤其是在读写场景文件的时候。
  • var light: SCNLight?,添加到节点上的灯光,一个节点上只能添加一个灯光。
  • var camera: SCNCamera?,添加到节点上的相机,只有给显示场景的视图的pointOfView属性,设置一个包含相机的节点,视图才能显示场景。这句话读起来比较拗口,举个之前举过的例子来辅助理解,下图是一个拍摄电影的画面:
SceneKit开发教程03|SceneKit开发教程03 | 使用SCNNode && SCNReferenceNode定义场景结构
文章图片
image.png SceneKit中的场景可以和我们在电影院看到的电影场景对应起来,SceneKit中相机可以和拍摄电影的摄像机对应起来。
我们在电影院看到的电影画面,本质上是从相机角度看到的场景,所以说如果没有相机或者相机坏了,接下来发生的场景我们就看不到了!
在SceneKit中也是一样,场景中如果没有包含相机的节点,我们也不到东西。如果我们想多角度的观看场景,那就必须在场景中添加多个包含相机的节点。关于更多相机的信息,在SCNCamera章节详细讲解。
  • var geometry: SCNGeometry?,添加到节点上的几何体,一个节点上只能添加一个几何体,要同时控制多个几何体,可以创建一个不包含几何体的节点,给刚创建的节点添加子节点,然后将几何体添加到这些节点上。改变节点的几何属性,可以达到移动、旋转或者缩放附着在上面几何体的目的。
  • var morpher: SCNMorpher?,morpher中文翻译成变形器,这个属性主要用作在多个几何图形之间进行插值,在后面SCNMorpher详细讲解这个属性。
  • var skinner: SCNSkinner?,这个属性和节点内容的骨骼动画相关。
  • var categoryBitMask: Int,给节点添加分类,每个节点可以有多个分类。
2.3 给节点添加约束
  • var constraints: [SCNConstraint]?
2.4 处理节点动画
  • var presentation: SCNNode
  • var isPaused: Bool
3. SCNReferenceNode SCNReferenceNode是用来从场景文件中加载node。
接下来分析一下这个类,加深对它的理解!
reference ,引用的意思,这个词在oc中很常见,一个实例的引用,表示指向该实例的指针。
那么,reference node 到底是什么意思?我们先给SCNReferenceNode下一个定义:
SCNReferenceNode 是 SCNNode的一个子类,用来表示从外部场景文件中加载的node。
SCNReferenceNode 有两个重要的方法:
  • init?(url: URL)方法,使用改方法来实例化SCNReferenceNode,传入的参数是场景文件的地址,注意,新生成的SCNReferenceNode对象是没有“附着”任何内容的,是个空白的node
  • load()方法,只有运行该方法之后,才会将场景文件中的内容,加载到我们上一步实例化的node中
结合上面两个方法可以看出,我新实例化的SCNReferenceNode是没有内容的,它只是一个引用,指向外部场景文件的某些内容,只有当我们运行load()方法之后,这些"外部场景文件中的内容"才会加载进来!!!!
所以,我们前面给出的,对SCNReferenceNode的定义不是很准确,我们需要重新描述一下:
SCNReferenceNode 是 SCNNode的一个子类,SCNReferenceNode实例在调用load()方法之前,它只是一个空的占位符,在调用load()方法之后,它用来呈现“外部的场景文件中的内容”
【SceneKit开发教程03|SceneKit开发教程03 | 使用SCNNode && SCNReferenceNode定义场景结构】在 SceneKit | 加载 3D模型(obj/scn/dae)到你的AR项目中 中,给出的有从文件加载SCNReferenceNode的示例,有需要可以移步!

    推荐阅读