Author Topic: une astuce simple pour afficher les normales sans geometry shader?  (Read 14357 times)

0 Members and 1 Guest are viewing this topic.

Re : une astuce simple pour afficher les normales sans geometry shader?
« Reply #75 on: 21 February 2013 à 00:12:13 »
et donc je mets axis à [1,0,0], [0,1,0],[0,0,1], [1,1,1] ou [1,1,0 ] ... etc c'est bien ça?? selon le nombre d'axe où je veux la rotation de mon angle

si c'est ça ok,...

maintenant, si je décompose cette instruction en 3 consécutives (1 par axe) et que je les multiplie entre elles j'aurais le même résultat ?


Offline h0bby1

  • Base
    • View Profile
et donc je mets axis à [1,0,0], [0,1,0],[0,0,1], [1,1,1] ou [1,1,0 ] ... etc c'est bien ça?? selon le nombre d'axe où je veux la rotation de mon angle

si c'est ça ok,...

maintenant, si je décompose cette instruction en 3 consécutives (1 par axe) et que je les multiplie entre elles j'aurais le même résultat ?

l'axe que tu donne pour initialiser le quaternion la c'est directement l'axe de rotation ' options._axes' et l'angle c'est v

pour avoir les 3 angles qui correspondent c'est compliqué, mais normalement dans la lib tu doit avoir la fonction, en general il faut coller le quaternion dans une matrice et extraire les 3 angles, qui appliqués successivement autour de leur axe  respectif ([1,0,0], [0,1,0],[0,0,1]) dans le bon ordre vont donner la meme rotation que l'angle v autour de l'axe x/y/z representée par le quaternion mais la transformation est pas triviale

dans le code que flure a posté ou ca initialise le quaternion avec les 3 axes [1,0,0], [0,1,0],[0,0,1] ca doit etre pour specifier l'ordre dans le quel il effectue les rotations dans le cas ou tu lui donne 3 angles en entrée et qu'il doit calculer la rotation equivalente a ces trois rotations appliquée successivement autour des axes dans l'ordre specifié

une rotation autour d'un axe XYZ equivault a trois rotations autour des axes [1,0,0], [0,1,0],[0,0,1] appliquées successivement dans un certain ordre, le quaternions permet de convertir entre les 2
« Last Edit: 21 February 2013 à 00:42:56 by h0bby1 »

Re : une astuce simple pour afficher les normales sans geometry shader?
« Reply #77 on: 21 February 2013 à 00:43:01 »
bon, j'ai
Code: [Select]
quat.setAxisAngle(entity._private.quaternionXYZ,options._axes,degToRad(v));
si axes possède au moins 2 axes (x [1,1,0] , ça fait n'importe quoi. quand je dis n'importe quoi c'est que bizarrement le satellite s'éloigne pendant qu'il tourne et revient à la bonne distance. et j'ai regardé le code, il n'y a aucun lien entre la translation et mon quaternion, a part au moment de construire la matrice MODEL de l'objet. on dirait que ça fait un scale...

quoi q'il en soit, ça sonne faux... la biblio est bonne, elle est utilisé dans plein de moteur javascript

pour la 2ème partie je vais reformuler différemment,

- imaginons, que je souhaite faire tourner mon objet de 45deg sur X, 80deg sur Y et 30deg sur Z (parce que au final, si ils faisaient tout les 3 le même angle ce serait un cas particulier) la j'écris quoi? (je viens de voir ta modif, donc ça correspond au code de flure c'est ça ?)
« Last Edit: 21 February 2013 à 00:46:23 by dark poulpo »

Offline h0bby1

  • Base
    • View Profile
bon, j'ai
Code: [Select]
quat.setAxisAngle(entity._private.quaternionXYZ,options._axes,degToRad(v));
si axes possède au moins 2 axes (x [1,1,0] , ça fait n'importe quoi. quand je dis n'importe quoi c'est que bizarrement le satellite s'éloigne pendant qu'il tourne et revient à la bonne distance. et j'ai regardé le code, il n'y à aucun lien entre la translation et mon quaternion, a part au moment de construire la matrice MODEL de l'objet, on dirait que ça fait un scale...

quoi q'il en soit, ça sonne faux... la biblio est bonne, elle est utilisé dans plein de moteur javascript

pur la 2ème partie je vais reformuler différemment,

- imaginons, que je souhaite faire tourner mon objet de 45deg sur X, 80deg sur Y et 30deg sur Z (parce que au final, si ils faisaient tout les 3 le même angle ce serait un cas particulier) la j'écris quoi? (je viens de voir ta modif, donc ca correspond au code de flure c'est ça ?)

http://www.blancmange.info/notes/maths/vectors/mops/

Quote
Rotation about a principal axis

Rotation about a principal axis in 3D is really a rotation in a plane formed by two other axes. It's not hard to see that the matrices below are copies of the 2D rotation matrix padded out with extra ones and zeros.

Matrix       Description

      
1   0        0   
0   cosθ        ⁻sinθ
0   sinθ       cosθ
      
Rotation by θ about x
      
cosθ     0   ⁻sinθ   
0     1   0
sinθ     0   cosθ
      
Rotation by θ about y
      
cosθ        ⁻sinθ        0   
sinθ            cosθ   0
0             0            1
      
Rotation by θ about z


By multiplying all three of these matrices, with appropriate values of θ for each, it's possible to come up with a matrix that can be used to transform a set of vertices to any new orientation, given those three euler angles.

Describing orientation with euler angles is useful for jointed objects such as gun turrets, cameras on dollies and other gimbled bits of machinery. Most such machinery have pitch upon yaw or roll upon pitch upon yaw.


Rotation about an arbitrary axis through the origin

This is best done with quaternion rotation, whatever quaternions are, exactly. Although the maths looks daunting, it's not really all that computationally expensive.

Let A be a unit vector that lies in the axis of rotation.
Let θ be the rotation angle.
This rotation can be described as a quaternion, Q where
Qx =  Ax*sin(θ/2),   
Qy =  Ay*sin(θ/2),     
Qz =  Az*sin(θ/2),     
Qw =  cos(θ/2) 

This rotation quaternion can be converted into an equivalent matrix, T.

pour avoir la rotation comme ca

" 45deg sur X, 80deg sur Y et 30deg sur Z"

 pour utiliser un quaternion la ca depend comment le quaternion il calcul la rotation, logiquement tu doit avoir une fonction qui prend en entrée les 3 angles, mais si la transformation doit correspondre avec celle qui est faite par un modeleur a partir de ces 3 angles, il faut configuer le quaternion pour qu'il les fasse dans le meme ordre que le modeleur

normalement la lib elle doit avoir la fonction pour calculer le quaternion en fonction des 3 angles,  du genre quat_from_angle, qui fera ces 3 rotations en une seule, mais c'est vrai que dans la lib JS la je ne l'ai pas vue cette fonction, mais le calcul normalement il existe, mais la je sais pas comment tu peux faire avec cette lib pour avoir le quaternion a partir de 3 angles, mais j'ai vu que il a une fonction rotateZ





{quat} quat.rotateX(out, a, rad)

Rotates a quaternion by the given angle around the X axis

Parameters:
{quat} out
quat receiving operation result
{quat} a
quat to rotate
{number} rad
angle (in radians) to rotate
Returns:
{quat} out
{quat} quat.rotateY(out, a, rad)

Rotates a quaternion by the given angle around the X axis

Parameters:
{quat} out
quat receiving operation result
{quat} a
quat to rotate
{number} rad
angle (in radians) to rotate
Returns:
{quat} out
{quat} quat.rotateZ(out, a, rad)

Rotates a quaternion by the given angle around the X axis

Parameters:
{quat} out
quat receiving operation result
{quat} a
quat to rotate
{number} rad
angle (in radians) to rotate
Returns:
{quat} out



donc peut etre un truc du genre ca :
 
quat.rotateX(entity._private.quaternion,entity._private.quaternion, angleX);
quat.rotateY(entity._private.quaternion,entity._private.quaternion, angleY);
quat.rotateZ(entity._private.quaternion,entity._private.quaternion, angleZ);

a faire dans le bon ordre avec les bons angles sur les bon axes si les angles viennent d'un modeleur
« Last Edit: 21 February 2013 à 01:12:28 by h0bby1 »

Re : une astuce simple pour afficher les normales sans geometry shader?
« Reply #79 on: 21 February 2013 à 01:16:50 »
ok, je te remercie.

à but lucratif j'ai effectué des testes, il s'avère que :

Code: [Select]
var v = (90 * gametime) / 1000.0;

var quaternionX = quat.create();
var quaternionY = quat.create();
var quaternionZ = quat.create();

quat.setAxisAngle(quaternionX,[1,0,0],degToRad(v * options._axes[0]));
quat.setAxisAngle(quaternionY,[0,1,0],degToRad(v * options._axes[1]));
quat.setAxisAngle(quaternionZ,[0,0,1],degToRad(v * options._axes[2]));

var tmp = quat.create();
quat.multiply(tmp,quaternionX,quaternionY);
quat.multiply(entity._private.quaternion,tmp,quaternionZ);

var tmp2 = quat.create();
quat.rotateX(tmp2,tmp2, degToRad(v * options._axes[0]));
quat.rotateY(tmp2,tmp2, degToRad(v * options._axes[1]));
quat.rotateZ(tmp2,tmp2, degToRad(v * options._axes[2]));

var tmp3 = quat.create();
quat.setAxisAngle(tmp3,options._axes,degToRad(v));

tmp2 est identique à entity._private.quaternion
tmp3 est différent des 2 précédents.


Offline h0bby1

  • Base
    • View Profile
Re : une astuce simple pour afficher les normales sans geometry shader?
« Reply #80 on: 21 February 2013 à 01:23:00 »
c'est normal que tmp3 soit different, mais normalement t'as aucun besoin de multiplier l'angle par les composantes de l'axe

normalement ca

        quat.setAxisAngle(quaternionX,[1,0,0],degToRad(v));
   quat.setAxisAngle(quaternionY,[0,1,0],degToRad(v));
   quat.setAxisAngle(quaternionZ,[0,0,1],degToRad(v));
   
   var tmp = quat.create();
   quat.multiply(tmp,quaternionX,quaternionY);
   quat.multiply(entity._private.quaternion,tmp,quaternionZ);

ca doit etre pareil que

 var tmp2 = quat.create();

quat.rotateX(tmp2,tmp2, degToRad(v ));
quat.rotateY(tmp2,tmp2, degToRad(v ));
quat.rotateZ(tmp2,tmp2, degToRad(v ));

en gros c'est 3 rotations successive de v sur les 3 axes [1,0,0],[0,1,0],[0,0,1]

 quat.setAxisAngle(quaternion,[1,0,0],degToRad(v)); ==  quat.rotateX(quaternion,quaternion, degToRad(v ));
 quat.setAxisAngle(quaternion,[0,1,0],degToRad(v)); ==  quat.rotateY(quaternion,quaternion, degToRad(v ));
 quat.setAxisAngle(quaternion,[0,0,1],degToRad(v)); ==  quat.rotateZ(quaternion,quaternion, degToRad(v ));


mais normalement la bonne fonction pour calculer la rotation d'angle v autour de l'axe options._axes c'est

quat.setAxisAngle(tmp3,options._axes,degToRad(v));

qui est normalement la meme chose que ca :

quat.fromValues(options._axes[0]*sin(degToRad(v)/2),
                           options._axes[1]*sin(degToRad(v)/2),
                           options._axes[2]*sin(degToRad(v)/2),
                           cos(degToRad(v)/2) );



si tu doit calculer 3 rotations differentes autour des 3 axes X,Y,Z , il te faut 3 valeurs comme v separées pour faire les rotations respectives du bon angle autour de chaque axe

et donc avoir

var v1 += (90 * gametime) / 1000.0;
var v2 += (90 * gametime) / 2000.0;
var v3 += (90 * gametime) / 4000.0;

quat.rotateX(tmp2,tmp2, degToRad(v1 ));
quat.rotateY(tmp2,tmp2, degToRad(v2 ));
quat.rotateZ(tmp2,tmp2, degToRad(v3 ));

v1 est l'angle pour la rotation autour de l'axe X,  v2 est l'angle pour la rotation autour de l'axe Y, v3 est l'angle pour la rotation autour de l'axe Z ,mais les modeleurs n'utilisent pas toujours angles[0] pour l'axe X, angles[1] pour l'axe Y et angles[2] pour l'axe Z, ni meme cet ordre de rotation

donc tu peux aussi bien avoir

quat.rotateY(tmp2,tmp2, degToRad(v3 ));
quat.rotateZ(tmp2,tmp2, degToRad(v1 ));
quat.rotateX(tmp2,tmp2, degToRad(v2 ));

qui ne sont pas equivalents, d'ou l'interet normalement d'utiliser un quaternion au lieu de 3 angles
« Last Edit: 21 February 2013 à 01:52:08 by h0bby1 »

var v1 += (90 * gametime) / 1000.0;
var v2 += (90 * gametime) / 2000.0;
var v3 += (90 * gametime) / 4000.0;

quat.rotateX(tmp2,tmp2, degToRad(v1 ));
quat.rotateY(tmp2,tmp2, degToRad(v2 ));
quat.rotateZ(tmp2,tmp2, degToRad(v3 ));

c'est le code que j'avais d'origine ça... et justement ça ne marchait pas... du moment que j'avais une rotation sur 2 axes
(ce code qui ajoutait l'angle relatif à l'angle absolue avant de tout passer aux quaternions...)

il a fallut que je fasse comme on a dit juste au dessus (call de quaternion relatif) et de multiplier par le quaternion final (absolue) pour obtenir le nouveau quaternion absolue pour que cela marche avec 2 axes de rotations
 bon je me couche
« Last Edit: 21 February 2013 à 02:01:02 by dark poulpo »

Offline h0bby1

  • Base
    • View Profile
c'est le code que j'avais d'origine ça... et justement ça ne marchait pas... du moment que j'avais une rotation sur 2 axes
(ce code qui ajoutait l'angle relatif à l'angle absolue avant de tout passer aux quaternions...)

il a fallut que je fasse comme on a dit juste au dessus (call de quaternion relatif) et de multiplier par le quaternion final (absolue) pour obtenir le nouveau quaternion absolue pour que cela marche avec 2 axes de rotations
 bon je me couche
a l'origine t'avais des multiplications de l'angle par les valeurs de l'axe ce qui ne doit pas etre le cas, a aucun moment tu doit avoir v * options._axis[0], et normalement ta pas besoin de mutliplier 3 quaternions pour faire une rotation d'un angle autour d'un axe, c'est bizarre

mais bon si ca marche tant mieux hin lol bonne nuit :D



mais ca c'est
quat.rotateX(quat,quat, degToRad(v* options._axis[0] ));
quat.rotateY(quat,quat, degToRad(v* options._axis[1] ));
quat.rotateZ(quat,quat, degToRad(v* options._axis[2] ));
 
est entierement different de ca

setAngleAxis(quat,options._axis, degToRad(v));

=)
« Last Edit: 21 February 2013 à 02:41:24 by h0bby1 »

Re : une astuce simple pour afficher les normales sans geometry shader?
« Reply #83 on: 21 February 2013 à 10:56:24 »
bon en tout cas merci à vous tous pour votre aide!