我需要让节点层次结构中的节点面向摄像机,或者换句话说,是一个广告牌。 对于每个节点,我将其世界矩阵和世界旋转存储为四元数。 根据我所知的四元数,我想要的操作是获取相机四元数和节点的旋转四元数之间的差异,并简单地通过所述差异旋转节点。
我的相机存储为欧拉角,因此我首先创建X轴旋转,然后是Z轴旋转(我没有Y轴旋转),并将它们相乘,构建相机四元数。
从那里只是一些数学来获得差异,最后从中创建一个旋转矩阵,并将节点的世界矩阵与它相乘。
然而,这最终会导致节点像疯子一样旋转,绝不会面对镜头。
以下是相关的JavaScript代码:
// If there is a parent, multiply both world matrix and rotation by it
// localMatrix here is the current local matrix of the node
// rotation here is the local rotation quaternion
if (node.parent) {
math.Mat4.multMat(node.parent.worldMatrix, localMatrix, node.worldMatrix);
math.Quaternion.concat(node.parent.worldRotation, rotation, node.worldRotation);
} else {
node.worldMatrix = localMatrix;
node.worldRotation = rotation.copy();
}
// And here the mess begins
if (node.billboarded) {
var cameraX = [];
var cameraZ = [];
var camera = [];
// transform.rotation is my camera's rotation stored as 3 euler angles,
// but I am not using the Y-axis for now
math.Quaternion.setFromAxisAngle([1, 0, 0], transform.rotation[0], cameraX);
math.Quaternion.setFromAxisAngle([0, 0, 1], transform.rotation[2], cameraZ);
math.Quaternion.concat(cameraX, cameraZ, camera);
// The current rotation on the node
var initial = node.worldRotation.copy();
// Need to reverse it, since the difference is camera * -initial
math.Quaternion.conjugate(initial, initial);
var difference = [];
math.Quaternion.concat(camera, initial, difference);
var rotationMatrix = [];
math.Quaternion.toRotationMatrix4(difference, rotationMatrix);
var finalMatrix = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
// pivot is the node's position, need to keep the rotation in local space
math.Mat4.translate(finalMatrix, pivot[0], pivot[1], pivot[2]);
math.Mat4.multMat(finalMatrix, rotationMatrix, finalMatrix);
math.Mat4.translate(finalMatrix, -pivot[0], -pivot[1], -pivot[2]);
// And finally actually rotate the node
math.Mat4.multMat(node.worldMatrix, finalMatrix, node.worldMatrix);
}
我正在犯一些明显的错误吗?
答案 0 :(得分:0)
你的假设是错误的:
我想要的操作是获取相机之间的差异 四元数和节点的旋转四元数,并简单地旋转 所述差异的节点。
如果您正确执行此操作,则应导致节点面向相机所朝向的方向。这与实际面对相机完全不同。
您需要的是在世界空间中找到面向相机位置的变换。您可能会对gluLookAt()的一些快速研究中受益。