0

我正在为 iPhone6S 实施一个应用程序,该应用程序可以帮助残疾人通过使用虚拟教练进行训练来恢复他们的四肢控制。

这个虚拟教练执行简单的动作,例如抬起和放下手臂、抬起和放下腿,然后将它们组合成各种节奏模式。

由于目标平台的原因,我无法使用强大的 ARKit,因此我不得不单独依赖 SceneeKit。

我的代码目前能够加载一个 dae,并对骨架应用多个操作。但是,我在理解 SCNAction.rotateTo 和 SCNAction.rotateBy 的行为时遇到了问题


let DegreesPerRadians = Float(Double.pi/180)

func convertToRadians(angle:Float) -> Float {
    return angle * DegreesPerRadians
}

func convertToRadians(angle:CGFloat) -> CGFloat {
    return CGFloat(CGFloat(angle) * CGFloat(DegreesPerRadians))
}

    var x45  = SCNAction.rotateBy( x: convertToRadians(angle: 45), y: 0, z: 0,  duration: 0.2)
    var x45r = SCNAction.rotateBy( x: convertToRadians(angle: -45), y: 0, z: 0, duration: 0.2)

  func FOL()->SCNAction! {
        let human            = getHuman()
        let bodyOfHuman      = human?.childNode(withName: "Body", recursively: true)
        let bodyRealSkeleton = bodyOfHuman?.skinner?.skeleton
        let leftLegBone         = bodyRealSkeleton?.childNode(withName: "mixamorig_LeftLeg", recursively: true)
        let leftLegKick = SCNAction.customAction(duration: 0.1) { [self]
            (node, elapsedTime) in leftLegBone?.runAction(x45)
        }
        return leftLegKick
    }
    
    func FOLrev()->SCNAction! {
        let human            = getHuman()
        let bodyOfHuman      = human?.childNode(withName: "Body", recursively: true)
        let bodyRealSkeleton = bodyOfHuman?.skinner?.skeleton
        let leftLegBone         = bodyRealSkeleton?.childNode(withName: "mixamorig_LeftLeg", recursively: true)
        let leftLegKick = SCNAction.customAction(duration: 0.1) { [self]
            (node, elapsedTime) in leftLegBone?.runAction(x45r)
        }
        return leftLegKick
    }

var actionSequence=[FOL(),FOLrev()]

然后调用上面的代码

 _scene?.rootNode.runAction(SCNAction.sequence(actionSequence))

它导致模型正确弯曲左腿并拉直它。

然而,当使用“rotateTo”代替时,它会进入相反的方向并且不会“回来”。

截图-rotateTo

我查看了所有 DevCon SceneKit 材料和示例代码,但找不到任何解释或指导。

我的真正目标是添加更复杂的动作,例如拍手,当在这些模式上尝试相同的方法(需要 3-4 次旋转)时,结果就不太可预测了。

4

1 回答 1

0

这个问题的答案是,在使用rotateTo时,为了“返回”,应该使用特定角度的起始位置。

在具体的例子中,使用rotateTo的意思是使用下面的代码

var x45  = SCNAction.rotateTo( x: convertToRadians(angle: 45), y: 0, z: 0,  duration: 0.2)
var x45r = SCNAction.rotateTo( x: 0, y: 0, z: 0, duration: 0.2)
于 2020-12-01T11:31:26.337 回答