je dois faire un nœud dans une hiérarchie de noeud face à la caméra, ou en d'autres termes, être un panneau d'affichage. Pour chaque nœud, je stocke sa matrice du monde et la rotation du monde en quaternion. par ce que je connais escouades, l'opération que je veux est d'obtenir la différence entre la caméra quaternion et la rotation quaternion d'un nœud et faites pivoter simplement le noeud par ladite différence. Comme ma caméra est stockée sous forme d'angles euler, je construis le quaternion en créant d'abord la rotation de l'axe X, puis la rotation de l'axe Z (je n'ai pas de rotation de l'axe Y) et en les multipliant.Obtenir un nœud dans une hiérarchie de noeud pour faire face à la caméra (panneau d'affichage)
De là, il est juste un peu de mathématiques pour obtenir la différence et enfin créer une matrice de rotation de celui-ci, et en multipliant la matrice du monde du nœud avec elle.
Ceci, cependant, finit résultant dans les noeuds tournant comme des hommes de main fous, et en aucune façon face à la caméra.
Voici le code JavaScript concerné:
// 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);
}
est-il une erreur évidente que je fais?
Je ne peux pas croire que je en quelque sorte négligé cela. A propos de Look-à matrices, je ne peux pas les utiliser ici, car les nœuds sont affectés par le reste de la hiérarchie des noeuds, je ne peux pas simplement remplacer leur transformation avec un look à la matrice, et sinon ils ne vais pas travailler, parce que ils fonctionnent sur la base du fait que vous avez une orientation alignée sur l'axe fixe. – user2503048