1、SCNNode简介
SCNNode是场景图的结构元素,表示3D坐标空间中的位置和变换,您可以将模型,灯光,相机或其他可显示内容附加到该元素。也可以对其做动画。
2、相关API简介
- 初始化方法
//懒加载 + (instancetype)node; //geometry附加到节点的几何体 + (SCNNode *)nodeWithGeometry:(nullable SCNGeometry *)geometry;
- 管理Node节点的变换
//Node的变换 @property(nonatomic) simd_float4x4 simdTransform API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0)); //Node的位置动画 @property(nonatomic) simd_float3 simdPosition API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0)); //Node的旋转动画 @property(nonatomic) simd_float4 simdRotation API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0)); //Node的方向动画(四元素),表示通过一个旋转角度达到和欧拉角一样的状态 @property(nonatomic) simd_quatf simdOrientation API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0)); //Node的方向动画(欧拉角),表示为俯仰(X轴旋转),偏航(Y轴旋转),和滚动角弧度(Z轴旋转)的顺序 @property(nonatomic) simd_float3 simdEulerAngles API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0)); //Node的缩放动画 @property(nonatomic) simd_float3 simdScale API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0)); //Node的位置、旋转和缩放的枢轴点。 @property(nonatomic) simd_float4x4 simdPivot API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0));
- 管理Node节点的内容
//Node的名字 @property(nonatomic, copy, nullable) NSString *name; //添加的灯光 @property(nonatomic, retain, nullable) SCNLight *light; //添加的相机 @property(nonatomic, retain, nullable) SCNCamera *camera; //添加的几何体 @property(nonatomic, retain, nullable) SCNGeometry *geometry; //添加的骨骼 @property(nonatomic, retain, nullable) SCNSkinner *skinner API_AVAILABLE(macos(10.9)); //形态结构贴图 @property(nonatomic, retain, nullable) SCNMorpher *morpher API_AVAILABLE(macos(10.9));
/*! 定义接收器属于什么逻辑“类别”。 默认为1) 1.从给定光的影响中排除节点(参见SCNLight.categoryBitMask) 2.从渲染过程中包含/排除节点(参见SCNTechnique.h) 3.3.指定在命中测试时要使用的节点(请参阅SCNHitTestOptionCategoryBitMask) */ @property(nonatomic) NSUInteger categoryBitMask API_AVAILABLE(macos(10.10));
- 给Node添加约束
//添加Node的约束数组 具体参考SCNConstraint.h类 @property(copy, nullable) NSArray<SCNConstraint *> *constraints API_AVAILABLE(macos(10.9));
- 访问描述Node
//描述节:返回包含当前事务开始时所有属性的节点的副本,并应用任何活动动画 @property(nonatomic, readonly) SCNNode *presentationNode; //控件的节点是否是最新的动作和动画,或者暂停节点和其子节点动画 @property(nonatomic, getter=isPaused) BOOL paused API_AVAILABLE(macos(10.10));
- 修改节点可见度
//是否隐藏 @property(nonatomic, getter=isHidden) BOOL hidden; //设置透明度0-1 @property(nonatomic) CGFloat opacity; //渲染顺序 默认值为0,值越大越最后呈现 @property(nonatomic) NSInteger renderingOrder; //确定节点是否在阴影贴图中呈现 Defaults to YES. @property(nonatomic) BOOL castsShadow API_AVAILABLE(macos(10.10)); //在计算光探针时,不捕获活动节点,固定节点不被探针照亮。可移动节点不被运动模糊。 @property(nonatomic) SCNMovabilityHint movabilityHint API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0)); //enum SCNMovabilityHint typedef NS_ENUM(NSInteger, SCNMovabilityHint) { SCNMovabilityHintFixed, //固定 SCNMovabilityHintMovable, //可移动 } API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0));
- 管理Node节点的层次结构
//读取父节点 @property(nonatomic, readonly, nullable) SCNNode *parentNode; //获取所有子节点 @property(nonatomic, readonly) NSArray<SCNNode *> *childNodes; //添加子节点 - (void)addChildNode:(SCNNode *)child; //添加子节点到数组指定位置 - (void)insertChildNode:(SCNNode *)child atIndex:(NSUInteger)index; //移除子节点 - (void)removeFromParentNode; //新节点newChild替换旧节点oldChild - (void)replaceChildNode:(SCNNode *)oldChild with:(SCNNode *)newChild;
- 搜索节点的层次结构
//name:节点名称,recursively:是否递归方式查询 //获取指定的节点树中的第一个节点 - (nullable SCNNode *)childNodeWithName:(NSString *)name recursively:(BOOL)recursively; //通过谓词predicate对子节点进行测试,返回测试通过的所有子节点 - (NSArray<SCNNode *> *)childNodesPassingTest:(NS_NOESCAPE BOOL (^)(SCNNode *child, BOOL *stop))predicate; //列举所有子节点 - (void)enumerateChildNodesUsingBlock:(NS_NOESCAPE void (^)(SCNNode *child, BOOL *stop))block API_AVAILABLE(macos(10.10)); //列举自身节点和所有子节点 - (void)enumerateHierarchyUsingBlock:(NS_NOESCAPE void (^)(SCNNode *node, BOOL *stop))block API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0));
- 自定义节点渲染
//应用于接收器及其子节点的渲染的Core Image过滤器数组。 动画 //默认为nil。 应该通过在过滤器附加到的每个节点上调用setValue:forKeyPath:来修改过滤器属性。 如果在将过滤器附加到节点之后直接修改过滤器的输入,则行为是未定义的 @property(nonatomic, copy, nullable) NSArray<CIFilter *> *filters API_AVAILABLE(macos(10.9)) __WATCHOS_PROHIBITED; /* 指定接收器的渲染器委托对象 设置渲染器委托可防止SceneKit渲染器绘制节点,并允许您使用自定义OpenGL代码 自定义渲染的首选方法是调整节点几何的不同材质的材质属性。 SCNMaterial符合SCNShadable协议,并允许使用GLSL进行更高级的渲染。 您通常使用具有没有几何节点,并且仅用作空间中位置的渲染代理。 例如将粒子系统附加到该节点,并用自定义的OpenGL代码渲染它。 */ @property(nonatomic, assign, nullable) id <SCNNodeRendererDelegate> rendererDelegate;
@protocol SCNNodeRendererDelegate <NSObject> @optional /** 当一个节点被渲染时调用。 @param node 要渲染的节点 @param renderer 渲染到的场景渲染器 @param arguments 字典,其值是包装在NSValue对象中的SCNMatrix4矩阵 */ - (void)renderNode:(SCNNode *)node renderer:(SCNRenderer *)renderer arguments:(NSDictionary<NSString *, id> *)arguments; @end
- 添加节点的物理属性
//节点的物理体的描述 @property(nonatomic, retain, nullable) SCNPhysicsBody *physicsBody API_AVAILABLE(macos(10.10)); //节点的物理场的描述 @property(nonatomic, retain, nullable) SCNPhysicsField *physicsField API_AVAILABLE(macos(10.10));
- 复制节点
/*! 返回接收器的副本。 返回的实例是自动释放的。 复制是递归的:每个子节点也将被克隆。 对于非递归复制,请改用复制。 复制的节点将与原始实例共享其附加对象(光,几何,摄像机,...) 如果您想要独立于原始对象更改副本的材质,则必须单独复制节点的几何。*/ - (instancetype)clone; /* (平面克隆) 返回包含连接节点层次结构中包含的所有几何的几何的节点的克隆。 */ - (instancetype)flattenedClone API_AVAILABLE(macos(10.9));
- 节点的命中测试
/** 返回接收器子树中与指定段相交的每个节点的SCNHitTestResult数组 @param pointA 段相对于接收器的第一点 @param pointB 段相对于接收器的第二点 @param options 可选参数(有关可用选项,请参阅SCNSceneRenderer.h中的“命中测试选项”一节) @return 有关屏幕空间命中测试方法,请参阅SCNSceneRenderer.h */ - (NSArray<SCNHitTestResult *> *)hitTestWithSegmentFromPoint:(SCNVector3)pointA toPoint:(SCNVector3)pointB options:(nullable NSDictionary<NSString *, id> *)options API_AVAILABLE(macos(10.9));
- 执行节点相对操作
//改变节点的方向,使其局部前向矢量指向指定位置。 - (void)simdLookAt:(vector_float3)worldTarget API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0)); //改变节点的方向,使指定的前向矢量指向指定位置。 - (void)simdLookAt:(vector_float3)worldTarget up:(vector_float3)worldUp localFront:(simd_float3)localFront API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0)); //改变节点相对于其当前位置的位置。 - (void)simdLocalTranslateBy:(simd_float3)translation API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0)); //改变节点相对于其当前方向的方向。 - (void)simdLocalRotateBy:(simd_quatf)rotation API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0)); //通过围绕场景空间中指定点的旋转,来改变节点相对于其当前变换的位置和方向。 - (void)simdRotateBy:(simd_quatf)worldRotation aroundTarget:(simd_float3)worldTarget API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0));
- 节点相对变换的计算
//表示所有节点在SceneKit中的上、右、前方向 @property(class, readonly, nonatomic) simd_float3 simdLocalUp API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0)); @property(class, readonly, nonatomic) simd_float3 simdLocalRight API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0)); @property(class, readonly, nonatomic) simd_float3 simdLocalFront API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0)); //在世界空间中表示相对于节点的上(+Y)、右(+X)、前(-Z)方向向量 @property(readonly, nonatomic) simd_float3 simdWorldUp API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0)); @property(readonly, nonatomic) simd_float3 simdWorldRight API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0)); @property(readonly, nonatomic) simd_float3 simdWorldFront API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0));
- 管理世界空间中的变换
//接收器在世界空间的位置(相对于场景的根节点) @property(nonatomic) simd_float3 simdWorldPosition API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0)); //接收器在世界空间的方向(相对于场景的根节点)可动画 @property(nonatomic) simd_quatf simdWorldOrientation API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0)); //接收器在世界空间的变换(相对于场景的根节点)可动 @property(nonatomic) simd_float4x4 simdWorldTransform API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0));
- 坐标空间之间的转换
//将位置从节点的局部坐标空间转换为另一节点的位置。 - (simd_float3)simdConvertPosition:(simd_float3)position toNode:(nullable SCNNode *)node API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0)); //将位置从另一节点转换为节点的局部坐标空间。 - (simd_float3)simdConvertPosition:(simd_float3)position fromNode:(nullable SCNNode *)node API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0)); //将方向向量从节点的局部坐标空间转换为另一节点的方向向量。 - (simd_float3)simdConvertVector:(simd_float3)vector toNode:(nullable SCNNode *)node API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0)); //将方向向量转换为节点的局部坐标空间与另一节点的方向坐标空间。 - (simd_float3)simdConvertVector:(simd_float3)vector fromNode:(nullable SCNNode *)node API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0)); //将一个变换从节点的局部坐标空间转换为另一个节点的变换 - (simd_float4x4)simdConvertTransform:(simd_float4x4)transform toNode:(nullable SCNNode *)node API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0)); //将转换转换为节点的局部坐标空间,从另一节点转换为节点的局部坐标空间。 - (simd_float4x4)simdConvertTransform:(simd_float4x4)transform fromNode:(nullable SCNNode *)node API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0));
- 处理UI的焦点
//节点的焦点行为。Defaults to SCNNodeFocusBehaviorNone. @property(nonatomic) SCNNodeFocusBehavior focusBehavior API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0)); // @enum SCNNodeFocusBehavior typedef NS_ENUM(NSInteger, SCNNodeFocusBehavior) { SCNNodeFocusBehaviorNone = 0, // 节点是不可聚焦的 SCNNodeFocusBehaviorOccluding, // 节点是不可聚焦的,并且防止其视觉上模糊的节点变得可聚焦。 SCNNodeFocusBehaviorFocusable // 节点是可聚焦的,并且防止其视觉上模糊的节点变得可聚焦。 } API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0));
- 管理节点的变换(SceneKit 类型)
//变换是下面定义的位置,旋转和刻度的组合。 因此,当设置变换时,接收器的位置,旋转和缩放比例将更改为匹配新的变换 @property(nonatomic) SCNMatrix4 transform; //确定接收器在世界空间中的转换(相对于场景的根节点)。可动画。 @property(nonatomic, readonly) SCNMatrix4 worldTransform; - (void)setWorldTransform:(SCNMatrix4)worldTransform API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0)); //确定接收器的位置.动画) @property(nonatomic) SCNVector3 position; //确定接收器在世界空间中的位置(相对于场景的根节点)。 @property(nonatomic) SCNVector3 worldPosition API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0)); //确定接收器的旋转 可动画 @property(nonatomic) SCNVector4 rotation; //确定接收器的方向(四元数) 可动画 @property(nonatomic) SCNQuaternion orientation API_AVAILABLE(macos(10.10)); //确定接收器在世界空间中的方向(相对于场景的根节点)。 @property(nonatomic) SCNQuaternion worldOrientation API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0)); //欧拉角 @property(nonatomic) SCNVector3 eulerAngles API_AVAILABLE(macos(10.10)); //缩放 @property(nonatomic) SCNVector3 scale; //中心轴 @property(nonatomic) SCNMatrix4 pivot;
- 执行节点相对操作(SceneKit类型)
//改变节点的方向,使其局部前向矢量指向指定位置。 - (void)lookAt:(SCNVector3)worldTarget API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0)); //改变节点的方向,使指定的前向矢量指向指定位置。 - (void)lookAt:(SCNVector3)worldTarget up:(SCNVector3)worldUp localFront:(SCNVector3)localFront API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0)); //相对于其当前方向改变节点的方向。 - (void)localTranslateBy:(SCNVector3)translation API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0)); //相对于其当前位置改变节点的位置。 - (void)localRotateBy:(SCNQuaternion)rotation API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0)); // 通过围绕场景空间中指定点的旋转来改变节点相对于其当前变换的位置和方向。 - (void)rotateBy:(SCNQuaternion)worldRotation aroundTarget:(SCNVector3)worldTarget API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0));
- 计算节点相对变换(SceneKit 类型)
/*! @property 获取上方向 @abstract The local unit Y axis (0, 0, 1). */ @property(class, readonly, nonatomic) SCNVector3 localUp API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0)); /*! @property 获取右方向 @abstract The local unit X axis (0, 1, 0). */ @property(class, readonly, nonatomic) SCNVector3 localRight API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0)); /*! @property 获取前方向 @abstract The local unit -Z axis (0, 0, -1). */ @property(class, readonly, nonatomic) SCNVector3 localFront API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0)); /*! @property 获取世界空间上方向 @abstract The local unit Y axis (0, 0, 1) in world space. */ @property(readonly, nonatomic) SCNVector3 worldUp API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0)); /*! @property 获取世界空间右方向 @abstract The local unit X axis (0, 1, 0) in world space. */ @property(readonly, nonatomic) SCNVector3 worldRight API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0)); /*! @property 获取世界空间前方向 @abstract The local unit -Z axis (0, 0, -1) in world space. */ @property(readonly, nonatomic) SCNVector3 worldFront API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0));
- 坐标空间之间的转换(SceneKit 类型)
//将位置从节点的局部坐标空间转换为另一节点的位置。 - (SCNVector3)convertPosition:(SCNVector3)position toNode:(nullable SCNNode *)node API_AVAILABLE(macos(10.9)); //将位置从另一节点转换为节点的局部坐标空间。 - (SCNVector3)convertPosition:(SCNVector3)position fromNode:(nullable SCNNode *)node API_AVAILABLE(macos(10.9)); //将方向向量从节点的局部坐标空间转换为另一节点的方向向量。 - (SCNVector3)convertVector:(SCNVector3)vector toNode:(nullable SCNNode *)node API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0)); //将方向向量转换为节点的局部坐标空间与另一节点的方向坐标空间 - (SCNVector3)convertVector:(SCNVector3)vector fromNode:(nullable SCNNode *)node API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0)); //将一个变换从节点的局部坐标空间转换为另一个节点的变换。 - (SCNMatrix4)convertTransform:(SCNMatrix4)transform toNode:(nullable SCNNode *)node API_AVAILABLE(macos(10.9)); //将转换转换为节点的局部坐标空间,从另一节点转换为节点的局部坐标空间。 - (SCNMatrix4)convertTransform:(SCNMatrix4)transform fromNode:(nullable SCNNode *)node API_AVAILABLE(macos(10.9));
- 枚举
FOUNDATION_EXTERN NSString *const SCNModelTransform;//模型转换 FOUNDATION_EXTERN NSString *const SCNViewTransform;//视图转换 FOUNDATION_EXTERN NSString *const SCNProjectionTransform;//投影转换 FOUNDATION_EXTERN NSString *const SCNNormalTransform;//正常转换 FOUNDATION_EXTERN NSString *const SCNModelViewTransform;//正常模型视图转换 FOUNDATION_EXTERN NSString *const SCNModelViewProjectionTransform;//模型视图投影转换