SceneKit Child node position not changed during Parent node rotation

江枫思渺然 提交于 2019-12-12 03:49:41

问题


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

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

If anyone have an idea? Thanks


回答1:


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.

If you want to access the world transform for a given node, use the worldTransform property.



来源:https://stackoverflow.com/questions/38521491/scenekit-child-node-position-not-changed-during-parent-node-rotation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!