SceneKit平面旋转

时间:2017-12-22 23:09:51

标签: ios scenekit

当我在SceneKit中创建平面时,默认情况下平面的法向量是正z轴。我想通过使用不同的法向量来重新定向平面。但是,我不知道如何将平面旋转到正确的位置,即使我知道新的法向量应该是什么。想法?

2 个答案:

答案 0 :(得分:0)

以下是基于输入SCNVector3'轴创建旋转矩阵的示例。 (这将是你的目标正常)。

        SCNVector3 tangent0 = [self crossVector: axis: SCNVector3Make(1, 0, 0)];
        if ([self dotVector:tangent0 : tangent0] < 0.001) {
            tangent0 = [self crossVector: axis: SCNVector3Make(0, 1, 0)];
        }
        tangent0 = [self normalizeVector:tangent0];
        SCNVector3 tangent1 = [self normalizeVector: [self crossVector:axis: tangent0]];

        GLKVector4 tangent0GLK = GLKVector4Make(tangent0.x, tangent0.y, tangent0.z, 0);
        GLKVector4 tangent1GLK = GLKVector4Make(tangent1.x, tangent1.y, tangent1.z, 0);
        GLKVector4 axisGLK = GLKVector4Make(axis.x, axis.y, axis.z, 0);

        rotMat = GLKMatrix4MakeWithColumns(tangent0GLK, tangent1GLK, axisGLK, GLKVector4Make(0, 0, 0, 1));

然后可以使用乘法将其应用于平面节点的transform属性:

_node.transform = SCNMatrix4Mult(transmat, SCNMatrix4FromGLKMatrix4( rotMat)) );

以上内容来自我正在进行的项目,尚未单独进行测试。不包括cross,dot和normalizeVector。

答案 1 :(得分:0)

您的帖子的THX Xartex。我在Swift中将其重新编码。刚开始使用Swift,所以整个过程可能会效率更高,但它可以::

仅出现一个问题,飞机的位置也移动了,这是不应该的,所以我在变换动作之后再次设置了原来的位置。

  func SCNVector3CrossProduct(left: SCNVector3, right: SCNVector3) -> SCNVector3 {
        return SCNVector3Make(left.y * right.z - left.z * right.y, left.z * right.x - left.x * right.z, left.x * right.y - left.y * right.x)
    }

    func SCNVector3DotProduct(left: SCNVector3, right: SCNVector3) -> float_t {
        return (left.x * right.x + left.y * right.y + left.z * right.z)
    }

    func SCNVektor3Normalize(vector: SCNVector3) -> SCNVector3 {
        let scale = 1.0 / sqrt(vector.x*vector.x + vector.y*vector.y + vector.z*vector.z)

        return SCNVector3Make(vector.x * scale, vector.y * scale, vector.z*scale)
    }
    let plane2Node = SCNNode(geometry: planeGeometry)
    let plane2Position = SCNVector3(x:0.0, y:0, z:-0.5)
    plane2Node.position = plane2Position


    let normalVector = SCNVector3Make(0.5, 0, 0)
    let transVector1 = SCNVector3Make(1,0,0)
    let transVector2 = SCNVector3Make(0,1,0)
    var tangent0 = SCNVector3CrossProduct(left: normalVector, right: transVector1)
    let dotprod = SCNVector3DotProduct(left: tangent0, right: tangent0)
    if dotprod < 0.001 {
        tangent0 = SCNVector3CrossProduct(left: normalVector, right: transVector2)
    }
    tangent0 = SCNVektor3Normalize(vector: tangent0)

    let helpVector1 = SCNVector3CrossProduct(left: normalVector, right: tangent0)
    let tangent1 = SCNVektor3Normalize(vector: helpVector1)

    let tangent0GLK = GLKVector4Make(tangent0.x, tangent0.y, tangent0.z, 0)
    let tangent1GLK = GLKVector4Make(tangent1.x, tangent1.y, tangent1.z, 0)
    let normalGLK = GLKVector4Make(normalVector.x, normalVector.y, normalVector.z, 0);

    let rotMat = GLKMatrix4MakeWithColumns(tangent0GLK, tangent1GLK, normalGLK, GLKVector4Make(0, 0, 0, 1))
    // transforms the "normal position" of the plane
    let transMat = SCNMatrix4MakeTranslation(plane2Node.position.x, plane2Node.position.y, plane2Node.position.z);

    plane2Node.transform = SCNMatrix4Mult(transMat, SCNMatrix4FromGLKMatrix4( rotMat))

    // position must be set again!
    plane2Node.position = plane2Position

    scene.rootNode.addChildNode(plane2Node)