Как работает SCNIKConstraint?

У меня есть следующий код (его можно запустить, заменив стандартный код ViewController в базовом проекте Game для macOS):

    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.

1 ответ

Вы добавили сферу как дочерний элемент boxNode. Если вы переместите boxNode, все дочерние элементы также будут перемещены, и ограничение не будет иметь никакого эффекта.

Другие вопросы по тегам