ios 使用SCNIKConstraint时,如何根据目标位置更改设置SCNNode的方向变换?

yqyhoc1h  于 2023-06-07  发布在  iOS
关注(0)|答案(1)|浏览(178)

我正在使用SceneKit创建一个人体骨骼3D动画。下面是解释我的节点关系的图表:

我将Spine节点设置为它上面所有节点的根节点。我正在创建一个手臂运动的动画,使用的数据是从设备的摄像头捕捉到的。现在,我将Neck设置为根链节点,以创建SCNIKConstraint来移动hand节点的位置。我的代码看起来很像这样:

// The nodes to create an arm
var spineNode: SCNNode!
var neckNode: SCNNode!
var shoulderNode: SCNNode!
var elbowNode: SCNNode!
var handNode: SCNNode!

// Setting the initial positions
spineNode.position = setSpinePosition()
neckNode.position = setNeckPosition()
// and so on for the other nodes...

// Setting the constraint to the hand node
let handIkConstraint: SCNIKConstraint = .inverseKinematicsConstraint(chainRootNode: neckNode)
handNode.constraints = [handIkConstraint]

对于位置更改,由于我使用的是从视频中的运动捕捉中检索到的数据,因此我根据如下新数据设置位置:

func changeFrame(data: HumanKeypointData) {
    spineNode.position = getNewPosition(data.spinePosition)
    handIkConstraint.targetPosition = data.handPosition
}

它工作得很好,手节点按预期移动,它的父节点也是如此。但肩关节没有按预期移动。它基于手的移动/位置变化而旋转,但它保持在其位置。它看起来像这样(黑色框是肩部节点,正如您可以看到的那样,它固定在其位置,而它基于手节点/蓝色框旋转):

但是我想实现这样的东西(肩膀节点/黑盒子基于使用SCNIKConstraint的手节点的目标位置变化而移动):

现在,为了移动肩部节点,我只是在新数据上设置位置,就像我对脊柱节点所做的那样。但是,为了防止数据不准确,我希望使其基于IK约束目标位置自动移动。我想知道是否有任何方法可以实现这一点?如果您需要更多信息,请让我知道,谢谢。

kzmpq1sx

kzmpq1sx1#

backbone 及其IK系统

我认为最好的解决方案是使用SCNSkinner。使用***skinner***对象,可以对角色的骨骼进行反变换初始化,在绑定的皮肤中不仅实现父子依赖,还可以实现***骨骼权重***这样的重要参数。
请参阅Rigging a Model for Motion Capture文章,了解有关角色操纵的更多信息。

必要的IK工具,SceneKit中缺少

然而,上述所有内容在SceneKit中都是非常费力的过程。最有效的方法是在Autodesk Maya中使用IK/FK设置角色动画,然后使用.dae.usdz的***烘焙动画***导出该角色。Maya应用程序具有完整的动画工具库和可设置动画的属性,用于微调反向运动学,包括IK solvers(单链、旋转平面、样条线、人体IK、多链等)、效应器固定、IK/FK切换和混合、极向量约束、MEL和Python脚本。所有这些功能在SceneKit中都是不可用的。

相关问题