Как работает 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, все дочерние элементы также будут перемещены, и ограничение не будет иметь никакого эффекта.