3d SceneKit,沿摄影机方向投影节点

3d SceneKit,沿摄影机方向投影节点,3d,camera,scenekit,quaternions,hittest,3d,Camera,Scenekit,Quaternions,Hittest,在SceneKit中,我看到一个连接了相机的节点有一个欧拉角(弧度角的变换器3)和方向(ScnQueterNion) 我的cameraNode位于0,0,0,可以随时更改其方向 我需要用从点开始的分段进行HitTest。。。拓扑点 起点总是已知的 但是我需要根据摄像机的方向投射一个位于摄像机直线上的远点 我的大脑还没有正确地捕捉到四元数,而且基于欧拉格朗日,我也没有取得任何进展。使用一些线性代数 func findNextPoint(p0: SCNVector3, direction: SCNV

在SceneKit中,我看到一个连接了相机的节点有一个欧拉角(弧度角的变换器3)和方向(ScnQueterNion)

我的cameraNode位于0,0,0,可以随时更改其方向

我需要用从点开始的分段进行HitTest。。。拓扑点

起点总是已知的

但是我需要根据摄像机的方向投射一个位于摄像机直线上的远点


我的大脑还没有正确地捕捉到四元数,而且基于欧拉格朗日,我也没有取得任何进展。

使用一些线性代数

func findNextPoint(p0: SCNVector3, direction: SCNVector3) -> SCNVector3{

    var x = Float()
    var y = Float()
    var z = Float()
    let t = 100 as Float

    x = p0.x + t * direction.x
    y = p0.y + t * direction.y
    z = p0.z + t * direction.z

    let result = SCNVector3Make(x, y, z)
    return result

}
这将使用p0作为起点,然后在给定方向上找到所需的下一个点。t是向量的长度,或者是你想从p0开始移动的距离

要找到相机指向的方向,必须获得其旋转并乘以旋转矩阵

func calculateCameraDirection(cameraNode: SCNNode) -> GLKVector3 {

    let x = -cameraNode.rotation.x
    let y = -cameraNode.rotation.y
    let z = -cameraNode.rotation.z
    let w = cameraNode.rotation.w

    let cameraRotationMatrix = GLKMatrix3Make(cos(w) + pow(x, 2) * (1 - cos(w)),
        x * y * (1 - cos(w)) - z * sin(w),
        x * z * (1 - cos(w)) + y*sin(w),

        y*x*(1-cos(w)) + z*sin(w),
        cos(w) + pow(y, 2) * (1 - cos(w)),
        y*z*(1-cos(w)) - x*sin(w),

        z*x*(1 - cos(w)) - y*sin(w),
        z*y*(1 - cos(w)) + x*sin(w),
        cos(w) + pow(z, 2) * ( 1 - cos(w)))

    let cameraDirection = GLKMatrix3MultiplyVector3(cameraRotationMatrix, GLKVector3Make(0.0, 0.0, -1.0))

    return cameraDirection

}
然后,您只需要使用两个坐标执行hitTest。在本例中,我使用了rayTestWithSegmentFromPoint:ToPoint,但是您可以在那里使用任何其他类型的测试,例如hitTestWithSegmentFromPoint:ToPoint:

func raycastTest(cameraDirection: GLKVector3) -> SCNVector3{

    let nextPoint = findNextPoint(cameraNode.position, direction: SCNVector3Make(cameraDirection.x, cameraDirection.y, cameraDirection.z))
    let hitTest = sceneView.scene!.physicsWorld.rayTestWithSegmentFromPoint(cameraNode.position, toPoint: nextPoint, options: nil)

    if hitTest.count > 0 {
        return (hitTest.first?.worldCoordinates)!
    }else{
        return nextPoint
    }
}

非常感谢@KeyChainDude,我找到了另一种方法,将farNode作为摄影机节点的子节点,因此所有旋转都会影响它,然后转换其坐标。但我会换成这个。