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