簡體   English   中英

父節點旋轉期間SceneKit子節點位置未更改

[英]SceneKit Child node position not changed during Parent node rotation

我正在嘗試在SceneKit中重新編碼相機管理。 為此,我使用UIPanGestureRecognizer使攝像機圍繞對象旋轉(在這種情況下,圍繞場景中心旋轉)。

接下來,我得到不同的比率或長度來確定要在連接攝像機的虛球的軸(X,Y,Z)(代碼中的cameraOrbit)上增加的角度。

我的問題是我使用相機的位置來確定要在球體上添加的角度。 但是位置是不變的。 當我更改球體旋轉時,子節點攝像機的位置永遠不會更新。 然后角度永遠不會改變。

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

如果有人有主意? 謝謝

當更新父節點的變換(位置,旋轉,比例)時,子節點的變換在局部坐標(相對於父坐標)中保持不變,僅在世界坐標中發生變化。

如果要訪問給定節點的世界變換,請使用worldTransform屬性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM