SceneKit 子节点位置在父节点旋转期间未更改 [英] SceneKit Child node position not changed during Parent node rotation
问题描述
我正在尝试重新编码 SceneKit 中的相机管理.为此,我使用 UIPanGestureRecognizer 使相机围绕对象(在本例中围绕场景中心)旋转.
I'm trying to recode the camera management in SceneKit. For that, I use UIPanGestureRecognizer for the rotation of camera around an object (In this case around the centre of scene).
接下来,我得到不同的比率或长度来确定在连接相机的假想球体的轴(X、Y、Z)上添加的角度(代码中的cameraOrbit).
Next I get the different ratio or length to determinate the angle to add at axes (X, Y, Z) of imaginary sphere where camera is attached (cameraOrbit in code).
我的问题是我使用相机的位置来确定添加到球体的角度.但位置是不变的.当我改变球体旋转时,子节点相机的位置永远不会更新.那么角度永远不会改变.
My problem is that I use the position of camera to determinate the angle to add at sphere. But the position is constant. When I change the sphere rotation, the position of child node camera are never updated. Then angle never change.
import SceneKit
import UIKit
class SceneManager
{
private let scene: SCNScene
private let view: SCNView
private let camera: SCNNode
private let cameraOrbit: SCNNode
private let cameraRadius: Float
init(view: SCNView, assetFolder: String, sceneName: String, cameraName: String, backgroundColor: UIColor) {
self.view = view
self.scene = SCNScene(named: (assetFolder + "/" + sceneName))!
if (self.scene.rootNode.childNodeWithName(cameraName, recursively: true) == nil) {
print("Fatal error: Cannot find camera in scene with name :\"", cameraName, "\"")
exit(1)
}
self.camera = self.scene.rootNode.childNodeWithName(cameraName, recursively: true)! // Retrieve cameraNode created in scene file
self.cameraOrbit = SCNNode()
self.cameraOrbit.addChildNode(self.camera)
self.cameraRadius = sqrt(pow((self.camera.position.x), 2) + pow(self.camera.position.y, 2)) // CameraOrbit radius for rotation camera in panHandler
self.scene.rootNode.addChildNode(self.cameraOrbit)
let panGesture = UIPanGestureRecognizer(target: self, action: #selector(panHandler(_:)))
panGesture.maximumNumberOfTouches = 1
self.view.addGestureRecognizer(panGesture)
self.view.backgroundColor = backgroundColor
self.view.pointOfView = self.camera
self.view.scene = self.scene
}
@objc private func panHandler(sender: UIPanGestureRecognizer) {
let alpha = cos(self.camera.position.z / self.cameraRadius) // Get angle of camera
// --
print(self.camera.position) // <-------- (X, Y, Z) The axes position are always the same
// --
var ratioX = 1 - ((CGFloat)(alpha) / (CGFloat)(M_PI)) // Get the radio with angle for apply to Z and X axes rotation
var ratioZ = ((CGFloat)(alpha) / (CGFloat)(M_PI))
// Change direction of rotation depending camera's position in trigonometric circle
if (self.camera.position.z > 0 && self.camera.position.x < 0) {
ratioZ *= -1
} else if (self.camera.position.z < 0 && self.camera.position.x < 0) {
ratioX *= -1
ratioZ *= -1
} else if (self.camera.position.z > 0 && self.camera.position.x > 0) {
ratioX *= -1
}
// Set the angle rotation to add at imaginary sphere (cameraOrbit)
let xAngleToAdd = (sender.velocityInView(sender.view!).y / 10000) * ratioX
let yAngleToAdd = (sender.velocityInView(sender.view!).x / 10000) * (-1)
let zAngleToAdd = (sender.velocityInView(sender.view!).y / 10000) * ratioZ
let rotation = SCNAction.rotateByX(xAngleToAdd, y: yAngleToAdd, z: zAngleToAdd, duration: 0.5)
self.cameraOrbit.runAction(rotation)
}
}
如果有人有想法?谢谢
推荐答案
当你更新父节点的变换(位置、旋转、缩放)时,子节点的变换在局部坐标(相对于父节点)保持不变,它只有世界坐标的变化.
When you update the parent node's transform (position, rotation, scale), the child nodes' transform remains unchanged in local coordinates (relative to the parent), it only changes in world coordinates.
如果要访问给定节点的世界变换,请使用 worldTransform 属性.
If you want to access the world transform for a given node, use the worldTransform property.
这篇关于SceneKit 子节点位置在父节点旋转期间未更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!