2016-07-22 119 views
0

我试图在SceneKit中重新编码相机管理。为此,我使用UIPanGestureRecognizer围绕一个物体(在这种情况下围绕场景的中心)旋转相机。SceneKit父节点旋转期间子节点位置未更改

接着我得到的不同的比或长度,以确定的角度在其中相机安装假想球体(cameraOrbit在代码)的轴(X,Y,Z)添加。

我的问题是,我用相机的位置来确定的角度在球添加。但是这个位置是不变的。当我改变球体旋转时,子节点相机的位置永远不会更新。那么角度永不改变。

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) 
    } 
} 

如果有人有想法?由于

+0

我注意到你提及“cameranode”从'self.rootNode.childNodeWithName'。然后调用'self.camearOrbit.addChildNode(self.cameranode)'。在将cameranode添加到cameraOrbit之前,你没有叫'self.cameranode.removeFromParentNode'吗? –

+0

我会尽力处理父母/子女的财产并回复你。感谢 – Ynamy

回答

1

当您更新父节点的变换(位置,旋转,缩放),子节点改造遗体在当地坐标(相对于父)不变,只在世界的变化坐标。

如果您要访问的世界转变为一个给定的节点上,使用worldTransform属性。

+0

是的,我知道,但是当我用“self.camera.position”获取位置时,我获得了世界位置?球体的中心是0,0,0。我如何才能获得世界的地位呢? – Ynamy