如何在旋转后沿特定轴拖动SCNNode



我目前正在Swift ARKit项目中工作。

我正试图弄清楚如何在特定的轴上拖动节点对象,即使经过一些旋转。例如,我想在旋转后沿着Y轴移动节点,但它的轴方向保持不变,所以即使我改变Y位置,它仍然沿着世界Y移动。SCNNode.localup是静态的,并返回SCNVector3(0,1,0(,据我所见,节点的局部向上没有函数。如果我没记错的话,在Unity中旋转后,增加局部轴拖动就足够了。

旋转前的节点对象

在应用一些旋转来拖动对象之前,您所需要做的就是增加或减少特定的轴。

旋转后的节点对象

旋转后,绿色Y轴也旋转,但当我增加或减少局部Y值时,对象仍沿世界Y移动。

抱歉我英语不好。谢谢你的帮助。

出于好奇,您目前是如何应用轮换的?

在不需要深入研究四元数数学的情况下,实现这一点的一个简单方法是将有问题的节点封装在父节点中,并分别应用这些变换。可以将旋转应用于父节点,然后将沿轴的拖动运动应用于子节点。

如果在该操作之外引入此层会有问题,则可以将添加/旋转/平移/移除作为单个原子操作,在应用所有变换后使用node.convertPosition(_:to:)在局部坐标和世界坐标之间进行交换。

let parent = SCNNode()
rootNode.addChildNode(parent)
parent.simdPosition = node.simdPosition
node.simdPosition = .zero
parent.simdRotation = /../
node.simdPosition = simd_float3(0, localYAxisShift, 0) 
node.simdPosition = rootNode.convertPosition(node.simdPosition, from: parent)
rootNode.addChildNode(node)
rootNode.removeChildNode(parent)

我没有测试上面的代码,但一般的方法应该可以工作。一般来说,直接在节点本身上进行所描述的复合运动有点复杂,而在使用上述方法时,SceneKit将为您完成所有这些操作。


编辑

这里有一个版本,它只是直接进行矩阵变换,而不是依赖于内置的调节。

let currentTransform = node.transform
let yShift = SCNMatrix4MakeTranslation(0, localYAxisShift, 0)
node.transform = SCNMatrix4Mult(yShift, currentTransform)

这将沿着"局部"y轴移动对象。请注意,矩阵乘法是不可交换的,即SCNMatrix4Mult调用中参数的顺序很重要(请尝试反转它们来说明(。

最新更新