SceneKit - 使SCNNode水平旋转但不旋转多次?

时间:2018-03-23 20:07:26

标签: ios swift3 scenekit augmented-reality arkit

好的,有一个奇怪的时间基于操纵杆旋转SCNNode,只需旋转到操纵杆定义的角度。我模仿Apple的Fox WWDC演示,所以我得到了操纵杆的角度并将其转换为CGFloat -

我只是试图在水平轴上旋转我的节点(而不是仅在y方向上旋转x)以便它

当操纵杆向下并且

时,

面向摄像机的视角 当操纵杆向上时

面向前方

我的工作达到了一定程度,但并非一直如此。不知道为什么 - 问题是我需要我的节点(它的一个立方体)面对左边说操纵杆是否向下 - 现在这可能会也可能不会发生,这取决于立方体在获得多少次旋转时向后朝(向下)角度。

例如,如果我在节点的背面有一个点,如果操纵杆指向下方并且立方体旋转指向用户,我需要该点始终面向用户/相机。

到目前为止,我从float2中获取操纵杆(全部来自Apple)的角度 - 看看cameraDirection:

func padOverlayVirtualStickInteractionDidStart(_ padNode: PadOverlay) {
        //control char
        if padNode == overlay!.controlOverlay!.leftPad {
            characterDirection = float2(Float(padNode.stickPosition.x), -Float(padNode.stickPosition.y))
        }

        //control world
        if padNode == overlay!.controlOverlay!.rightPad {
            cameraDirection = float2(Float(padNode.stickPosition.x), -Float(padNode.stickPosition.y))
        }
    }

    func padOverlayVirtualStickInteractionDidChange(_ padNode: PadOverlay) {
        //control char
        if padNode == overlay!.controlOverlay!.leftPad {
            characterDirection = float2(Float(padNode.stickPosition.x), -Float(padNode.stickPosition.y))
        }

        //control world
        if padNode == overlay!.controlOverlay!.rightPad {
            cameraDirection = float2( -Float(padNode.stickPosition.x), Float(padNode.stickPosition.y))
        }
    }

再次转换:

var worldDirection = float2()
public var cameraDirection: vector_float2 {
        get {
            return self.worldDirection
        }
        set {
            var direction = newValue
            let l = simd_length(direction)
            if l > 1.0 {
                direction *= 1 / l
            }
            self.worldDirection = direction
        }
    }

然后:

func updateWorldRot() //called in update
    {
        if(overallWorldNode != nil)
        {
            let newDir = worldDirection(withPointOfView: sceneRenderer?.pointOfView)
            if !newDir.allZero() {

               worldDirectionAngle = CGFloat(atan2f(newDir.x, newDir.z))
            }
                //print("NODE: ", platformsSpawned[currentLevel]?.first?.node.rotation)
                //print("ANGLE: ", worldDirectionAngle)
        }
    }
 func worldDirection(withPointOfView pointOfView: SCNNode?) -> float3 {
        let controllerDir = self.cameraDirection
        if controllerDir.allZero() {
            return float3.zero
        }

        var directionWorld = float3.zero
        if let pov = pointOfView {
            let p1 = pov.presentation.simdConvertPosition(float3(controllerDir.x, 0.0, controllerDir.y), to: nil)
            let p0 = pov.presentation.simdConvertPosition(float3.zero, to: nil)
            directionWorld = p1 - p0
            directionWorld.y = 0
            if simd_any(directionWorld != float3.zero) {
                let minControllerSpeedFactor = Float(0.2)
                let maxControllerSpeedFactor = Float(1.0)
                let speed = simd_length(controllerDir) * (maxControllerSpeedFactor - minControllerSpeedFactor) + minControllerSpeedFactor
                directionWorld = speed * simd_normalize(directionWorld)
            }
        }
        return directionWorld
    }

然后我申请到节点:

 public var worldDirectionAngle: CGFloat = 0.0 {
        didSet {
            overallWorldNode.runAction(
                SCNAction.rotateTo(x: 0.0, y: worldDirectionAngle, z: 0.0, duration: 0.2, usesShortestUnitArc:true))
        }
    }

如何停止多次旋转?

0 个答案:

没有答案