SCNIKConstraint如何运作?

时间:2018-06-15 07:26:15

标签: swift xcode animation scenekit inverse-kinematics

我有以下代码(这可以通过替换macOS的游戏基础项目中的标准ViewController代码来运行):

    let scene = SCNScene()
    let cameraNode = SCNNode()
    cameraNode.camera = SCNCamera()
    scene.rootNode.addChildNode(cameraNode)
    cameraNode.position = SCNVector3(x: 0, y: 0, z: 15)
    let lightNode = SCNNode()
    lightNode.light = SCNLight()
    lightNode.light!.type = .omni
    lightNode.position = SCNVector3(x: 0, y: 10, z: 10)
    scene.rootNode.addChildNode(lightNode)
    let ambientLightNode = SCNNode()
    ambientLightNode.light = SCNLight()
    ambientLightNode.light!.type = .ambient
    ambientLightNode.light!.color = NSColor.darkGray
    scene.rootNode.addChildNode(ambientLightNode)

    /* RELEVANT CODE BEGINS */

    let boxGeo = SCNBox(width: 1, height: 1, length: 1, chamferRadius: 0)
    let boxMaterial = SCNMaterial()
    boxMaterial.diffuse.contents = NSColor.gray
    boxGeo.firstMaterial = boxMaterial
    let boxNode = SCNNode(geometry: boxGeo)
    scene.rootNode.addChildNode(boxNode)
    boxNode.name = "box0"

    let sphereGeo = SCNSphere(radius: 0.5)
    let sphereMaterial = SCNMaterial()
    sphereMaterial.diffuse.contents = NSColor.green
    sphereGeo.firstMaterial = sphereMaterial
    let sphereNode = SCNNode(geometry: sphereGeo)
    boxNode.addChildNode(sphereNode)
    sphereNode.name = "sphere0"

    sphereNode.constraints = [SCNConstraint]()

    let distance = SCNDistanceConstraint(target: boxNode)
    distance.minimumDistance = 2.0
    distance.maximumDistance = 5.0
    sphereNode.constraints?.append(distance)

    let ik = SCNIKConstraint.inverseKinematicsConstraint(chainRootNode: boxNode)
    sphereNode.constraints?.append(ik)

    let anim = CABasicAnimation(keyPath: "targetPosition.y")
    anim.fromValue = -2.0
    anim.toValue = 2.0
    anim.duration = 1
    anim.autoreverses = true
    anim.repeatCount = .infinity
    ik.addAnimation(anim, forKey: nil)

    /* RELEVANT CODE ENDS */

    let scnView = self.view as! SCNView
    scnView.scene = scene
    scnView.allowsCameraControl = true
    scnView.showsStatistics = true
    scnView.backgroundColor = NSColor.black

根据我从文档中收集的内容,动画(是的,场景工具包视图动画设置被设置为在IB中播放和循环)应该尽可能地将球体移动到点2.0和-2.0上通过旋转立方体的y轴。然而,球体只是保持静止。我还尝试通过直接操纵它们的位置矢量而不是通过距离约束来设置球体和立方体的初始位置,但动画再没有做任何事情。

此外,我尝试将距离约束与具有lookAt约束的框结合使用,使其旋转以不断查看球体 - 这些导致框和球体的渲染完全变形。

我觉得好像我在这里的文档中遗漏了一些东西,比如另一个约束或某种变换矩阵来设置某种初始值。但是我遇到了一些限制,动画和骨架的其他问题,这让我开始相信SceneKit存在一个bug或一些未记录的方面。

1 个答案:

答案 0 :(得分:0)

您已将sphereNode添加为boxNode的子级。如果移动boxNode,则还会移动所有子项,并且约束无效。