在场景套件中围绕锚点旋转



目标:我的场景中有一个SCNCylinder对象。我希望能够拖动圆柱体的一端并向任何方向旋转圆柱体,同时将另一端保持在相同的位置。

目前,我调用localRotate(by: SCNQuaternion)首先旋转节点,然后计算移动圆柱体所需的位置偏移,以便另一端可以返回到其原始位置。

我怎样才能一步到位地实现目标,而不是我现在正在做的事情?

pivot属性就是您要查找的。或者,由于现代 SceneKit 通常工作得更好/使 Swift 更好/在使用 SIMD 类型时更容易与 ARKit 互操作,因此simdPivot属性。

请注意文档中的这一部分:

更改透视转换会以许多有用的方式更改这些行为。您可以:

  • 相对于节点的位置偏移节点的内容。例如,通过将透视设置为平移变换,您可以相对于球体在地板上的位置而不是相对于其中心来定位包含球体几何图形的节点。
  • 移动节点的旋转轴。例如,使用平移变换可以使节点围绕远点旋转,而不是围绕其中心旋转,而使用旋转变换可以使旋转轴倾斜。

同样,对于圆柱体,您可以使其枢轴成为变换矩阵,将原点的高度平移一半,从而在一端而不是中心为其提供一个"锚点"(用于位置和旋转更改(。像这样的东西(未经测试(:

let cylinder = SCNCylinder(radius: /*...*/, height: /*...*/)
let cylinderNode = SCNNode(geometry: cylinder)
cylinderNode.simdPivot = float4x4(translation: cylinder.height / 2)
extension float4x4 {
    init(translation vector: float3) {
        self.init(float4(1, 0, 0, 0),
                  float4(0, 1, 0, 0),
                  float4(0, 0, 1, 0),
                  float4(vector.x, vector.y, vector.z, 1))
    }
}

更一般地说,每当您使用基于场景图/转换层次结构的图形框架时,任何时候您发现自己根据一个转换(旋转、平移等(进行数学运算以影响另一个转换时,检查可以为您完成数学运算的 API 总是好的——因为做这种数学就是转换层次结构的全部内容。

如果没有一个相当特定于您需要的 API,请记住层次结构本身有利于进行依赖转换。例如,如果您希望一个节点遵循围绕另一个节点的圆形轨道,则无需使用正弦和余弦设置其位置......只需将其设置为另一个节点的子节点,然后旋转该节点即可。

在这种情况下,透视是一种便利,等效于使用节点层次结构。您也可以创建一个中间节点并在其中移动圆柱体(如下所示(:

let cylinder = SCNCylinder(radius: /*...*/, height: /*...*/)
let cylinderNode = SCNNode(geometry: cylinder)
let offsetNode = SCNNode()
offsetNode.addChildNode(cylinderNode)
cylinderNode.simdPosition.y = cylinder.height / 2
offsetNode.position = /*...*/ // set world-space position of end of cylinder
offsetNode.eulerAngles.x = /*...*/ // rotate cylinder around its end

相关内容

  • 没有找到相关文章

最新更新