1

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?

Répondre

0

Votre hypothèse est fausse:

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 il suffit de tourner le noeud par ladite différence.

Si vous l'avez fait correctement, vos nœuds doivent être orientés dans la même direction que la caméra. Ceci est assez différent de réellement face à la caméra.

Ce dont vous avez besoin est de trouver la transformation qui fait face à la position de l'appareil photo dans l'espace monde. Vous pourriez bénéficier de quelques recherches rapides dans gluLookAt().

+0

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

Questions connexes