Rotation/fr

From Second Life Wiki
Jump to navigation Jump to search


***** PAGE EN COURS DE TRADUCTION PAR SAMIA *****

Rotations

Le type LSL rotation est utilisé pour représenter une orientation en 3D (nous nous efforçons d'écrire le nom des types en gras). Une orientation, ou angle en 3D, est représentée par un objet mathématique appelé un quaternion. Considérons les quaternions comme un ensemble de 4 nombres, dont trois représentent la direction à laquelle l'objet fait face et la quatrième son pivotage vers la droite ou vers la gauche autour de cette direction. Le principal intérêt d'utiliser les quaternions est qu'ils ne sont pas sujets à la perte de degré de liberté (gimbal lock). Pour le fonctionnement interne complexe des mathématiques des quaternions, voir quaternion. Pour une liste de fonctions ou d'évènements liés aux rotations, voir Rotation Synopsis. Il y a aussi des informations sur la façon de faire tourner des textures sur la page textures.

Autres représentations

Une autre façon de représenter une rotation est d'utiliser 3 nombres, <X, Y, Z>, qui représentent de combien (en radians) l'objet tourne autour de trois axes. C'est par exemple utilisé dans la fenêtre de modification et est généralement facilement visualisé par les gens. Notez que ces trois nombres sont de type vector et non de type rotation, bien que cela puisse représenter la même information. On appelle cela les rotations d'Euler.

Une troisième façon de faire est d'utiliser trois vecteurs, qui vont indiquer vers où sont orientés l'avant, le dessus et le coté gauche. En réalité, il n'y a besoin que de deux de ces vecteurs, le troisième découlant des deux premiers.

Il y a de bonne raisons de préférer la version à quatre nombres, la rotation, bien qu'elle soit plus compliquée à s'approprier pour des débutants. Il existe des fonctions qui permettent de convertir facilement d'une représentation à une autre.

La règle de la main droite

Dans LSL, toutes les rotations sont effectuées suivant la règle de la main droite. Avec votre main droite, pointez l'index vers la direction de l'axe X positif, le majeur à angle droit de l'index pointera alors en direction de l'axe Y positif, et le pouce, à angle droit des deux autres, pointera vers l'axe Z positif. Lorsque vous modifiez un objet, les trois flèches de couleur pointent vers le coté positif de chacun des axes (X rouge, Y vert, Z bleu).

Règle de la main droite

Gardez votre main en position, c'est utile pour autre chose : trouver de quel côté est l'axe positif. Fermez le poing et sortez le pouce en direction du coté positif de l'axe qui vous intéresse. Vos autres doigts sont repliés dans le sens des axes positifs. Les rotations autour des axes X, Y et Z sont géréralement appelées roulis, tangage et lacet, en particulier lorsqu'il est question de véhicules.

Roulis, tangage et lacet

Dans le monde ou localement

Il est important de différencier les rotations relatives au monde et la rotation relatives à l'objet lui-même. Dans la fenetre de modifications, vous pouvez passer de l'une à l'autre. Dans un script, il faut convertir l'une en l'autre pour obtenir le comportement souhaité.

Pour scripter la rotation d'un prim non lié, utiliser :

rotation myRot = llGetRot(); // charge la rotation par rapport au monde dans myRot

Rotations combinées

Pour combiner des rotations, on utilise les opérateurs multiplier et diviser. Ne pas utiliser les opérateurs addition ou soustraction, qui ne donneront pas le résultat attendu. L'opération multiplier s'applique à la rotation dans la direction positive, l'opération diviser effectue une rotation négative. Il est également possible d'obtenir une rotation négative directement, en utilisant le signe - : X.s = -X.s.

A l'inverse d'autres entrées comme float, l'ordre dans lequel les opérations sont effectuées est important. non-commutative. La raison en est simple : l'ordre dans lequel on effectue des rotations est importante en RL. Par exemple, si vous avez une flèche avec quatre plumes, qui commence à la rotation <0, 0, 0> avec sa queue comme origine, elle sera alignée sur l'axe X avec sa pointe dans la direction X positive, ses plumes seront alignées sur les axes Z et Y, et les axes de la fleche seront alignés sur les axes dans le monde. Nous allons la faire tourner de 45 degrés autour de l'axe X et de 30 degrés autour de l'axe Y, mais en changeant l'ordre.

D'abord, après une rotation de 45° autour de l'axe X, la flèche sera toujours alignée le long de l'axe X, et l'aura pas bougé, elle aura simplement pivoté autour de son axe, donc les plumes seront à 45° des axes. Ensuite, la faire tourner de 30° autour de l'axe Y la fera pointer de 30° vers le bas (par rapport à l'axe X - souvenez vous que la règle de la main droite fait qu'une rotation positive va vers le bas) La flèche finit par être pointée de 30° vers le bas, sur le même plan vertical qu'au départ, mais en ayant pivoté sur elle même, ce qui fait que les plumes ne sont plus alignées vers le haut et le bas.

Si on effectue les modifications dans l'autre ordre, en commençant par une rotation de 30° sur l'axe Y, la flèche va pencher vers le bas par rapport au plan XY. Notez qu'elle n'est plus alignée par rapport à son axe X : Donc, son axe X et celui du monde ne sont plus alignés l'un par rapport à l' autre. Une rotation de 45° autour de l'axe X la fera pivoter autour de sa queue, la pointe tournera de 45° vers le haut et la droite en suivant un cône de 30° dont l'axe est aligné avec l'axe positif dans le monde.

Le résultat est clairement différent de celui de la premiere rotation, alors que seul l'ordre dans lequel les rotations ont été effectuées a changé.

Pour effectuer une rotation constante, vous devez définir une valeur rotation, ce qui se fait en créant un vector avec comme composants les angles X, Y, Z en radians (cela s'appelle un angle d'Euler), puis en le convertissant en rotation avec la fonction llEuler2Rot. Vous pouvez aussi créer directement une rotation native : la partie réelle est le cosinus de la motié de l'angle de rotation, et la partie vectorielle l'axe normalisé de rotation multiplié par le sinus de la moitié de l'angle de rotation. Pour passer d'une rotation à un angle d'Euler, vector utilise llRot2Euler.

NOTE: les angles dans LSL sont en radians, pas en degrés, mais vous pouvez facilement les convertir avec les constantes prédéfinies RAD_TO_DEG et DEG_TO_RAD. Pour une rotation de 30 degrés autour de l'axe X par exemple :

rotation rot30X = llEuler2Rot(<30, 0,0> * DEG_TO_RAD); // convertit les degrés en radians, puis convertit ce vector en une rotation, rot30x
vector vec30X = llRot2Euler(rot30X ); // retransforme la rotation en un vector (avec les valeurs en radians)

Rotations Locales ou Globales

Les rotations Locales sont effectuées autour des axes de l'objet lui-même, dans les directions avant/arriere, droite/gauche et bas/haut, quelque soit l'orientation de l'objet dans le monde qui l'entoure. Les rotations Globales sont effectuées autour des axes du monde, Nord/Sud, Est/Ouest, plus haut/Plus bas. Vous pouvez visualiser la différence en faisant tourner un prim, puis en le modifiant, et en changeant les réglages d'axes entre local et global : regardez comment les flèches de couleur changent.

Dans LSL, la différence entre une rotation locale ou globale réside dans l'ordre dans selon lequel les rotations seront traitées dans le state.

Ce script effectue une rotation locale en plaçant une constate rotation de 30° à gauche de la rotation de l'objet. C'est identique à la première opération effectuée dans l'exemple précédent, cela fait pivoter la flèche autour de son axe long.

rotation localRot = rot30X * myRot; // effectue une rotation locale en multipliant une constante de rotation par une rotation dans le monde.

Pour effectuer une rotation globale, utiliser les mêmes valeurs rotation, mais dans l'ordre opposé. Cela correspond à la seconde rotation du deuxième exemple, avec la flèche qui qui pivote vers le haut et la droite autour de l'axe X du monde.

rotation globalRot = myRot * rot30X; // effectue une rotation globale en multipliant une rotation dans le monde par une constante de rotation.

Another way to think about combining rotations

You may want to think about this local vs global difference by considering that rotations are done in evaluation order, that is left to right except for parenthesized expressions.

In the localRot case, what happened was that starting from <0, 0, 0>, the rot30X was done first, rotating the prim around the world X axis, but since when it's unrotated, the local and global axes are identical it has the effect of doing the rotation around the object's local X axis. Then the second rotation myRot was done which rotated the prim to its original rotation, but now with the additional X axis rotation baked in. What this looks like is that the prim rotated in place around its own X axis, a local rotation.

In the globalRot case, again starting from <0, 0, 0>, first the object is rotated to its original rotation, but the object's axes and the world's axes are no longer aligned! So, now the second rotation rot30x does exactly what it did in the local case, rotates the object 30 degrees around the world X axis, but the effect is to rotate the object through a cone around the world X axis since the object's X axis and the world's X axis aren't the same this time. What this looks like is that the prim pivoted 30 degrees around the world X axis, hence a global rotation.

Division of rotations has the effect of doing the rotation in the opposite direction, multiplying by a 330 degree rotation is the same as dividing by a 30 degree rotation.

Using Rotations

You can access the individual components of a rotation R by R.x, R.y, R.z, & R.s (not R.w). The scalar part R.s is the cosine of half the angle of rotation. The vector part (R.x,R.y,R.z) is the product of the normalized axis of rotation and the sine of half the angle of rotation. You can generate an inverse rotation by negating the x,y,z members (or by making the s value negative). As an aside, you can also use a rotation just as a repository of float values, each rotation stores four of them and a list consisting of rotation is more efficient than a list consisting of floats, but there is overhead in unpacking them.

rotation rot30X = llEuler2Rot(<30, 0,0> * DEG_TO_RAD ); // Create a rotation constant
rotation rotCopy = rot30X; // Just copy it into rotCopy, it copies all 4 float components
float X = rotCopy.x; // Get out the individual components of the rotation
float Y = rotCopy.y;
float Z = rotCopy.z;
float S = rotCopy.s;
rotation anotherCopy = <X, Y, Z, S>; // Make another rotation out of the components


There is a built in constant for a zero rotation ZERO_ROTATION which you can use directly or, if you need to invert a rotation R, divide ZERO_ROTATION by R. As a reminder from above, this works by first rotating to the zero position, then because it is a divide, rotating in the opposite sense to the original rotation, thereby doing the inverse rotation.

rotation rot330X = <-rot30X.x, -rot30X.y, -rot30X.z, rot30X.s>; // invert a rotation - NOTE the s component isn't negated
rotation another330X = ZERO_ROTATION / rot30X; // invert a rotation by division, same result as rot330X
rotation yetanother330X = <rot30X.x, rot30X.y, rot30X.z, -rot30X.s>; // not literally the same but works the same.

Single or Root Prims vs Linked Prims vs Attachments

The reason for talking about single or linked prim rotations is that for things like doors on vehicles, the desired motion is to move the door relative to the vehicle, no matter what the rotation of the overall vehicle is. While possible to do this with global rotations, it would quickly grow tedious. There are generally three coordinate systems a prim can be in: all alone, part of a linkset, or part of an attachment. When a prim is alone, i.e., not part of a linkset, it acts like a root prim; when it is part of an attachment, it acts differently and is a bit broken.

Getting and setting rotations of prims
Function Ground (rez'ed) Prims Attached Prims
Root Children Root Children
llGetRot
llGPP:PRIM_ROTATION
llGetObjectDetails
global rotation of prim global rotation of prim global rotation of avatar global rotation of avatar * global rotation of prim (Not Useful)
llGetLocalRot
llGPP:PRIM_ROT_LOCAL
global rotation of prim rotation of prim relative to root prim rotation of attachment relative to attach point rotation of prim relative to root prim
llGetRootRotation global rotation of prim global rotation of root prim global rotation of avatar global rotation of avatar
llSetRot*
llSPP:PRIM_ROTATION*
set global rotation complicated, see llSetRot set rotation relative to attach point set rotation to root attachment rotation * new_rot.
llSetLocalRot*
llSPP:PRIM_ROT_LOCAL*
set global rotation set rotation of prim relative to root prim set rotation relative to attach point set rotation of prim relative to root prim
llTargetOmega
ll[GS]PP:PRIM_OMEGA
spin linkset around prim's location spin prim around its location spin linkset around attach point spin prim around its location
Physical objects which are not children in a linkset will not respond to setting rotations.
†  For non-Physical objects llTargetOmega is executed on the client side, providing a simple low lag method to do smooth continuous rotation.

Rotation de Vecteurs

Dans LSL, faire pivoter un vector est très utile quand vous voulez faire bouger un objet suivant un arc de cercle, mais que le centre de la rotation n'est pas le centre de l'objet.

Ca peut sembler très compliqué, mais c'est beaucoup plus simple qu'il n'y paraît. Rappelez vous de la partie ci dessus sur la rotation de dart, et remplacez la flèche par un vector dont l'origine est la queue de la flèche, et dont les composants X, Y, and Z indiquent la position de la pointe de la flèche. Faire tourner la flèche autour de sa queue fait bouger sa pointe suivant un arc dont le centre est la queue de la flèche. De la même façon, faire tourner un vector qui représente un décalage par rapport au centre du prim le fait pivoter suivant le meme arc. L'objet pivote autour d'une position qui est décalée par rapport au centre du prim par le vector.

rotation rot30X = llEuler2Rot(<30, 0,0> * DEG_TO_RAD ); // crée une constante de rotation, 30 degrés autour de l'axe X
vector offset = <0, 1, 0>; // décale d'un mètre dans la direction Y positive
vector rotatedOffset = offset * rot30X; // fait tourner le vecteur décalé pour obtenir le mouvement donné par la rotation
vector newPos = llGetPos() + rotatedOffset; // fait bouger le prim en fonction du vecteur décalé et tourné

Nota Bene: Ceci est un mouvement, donc prenez garde aux problèmes qui se posent lorsqu'un objet est bougé hors du monde, sous le sol, de plus de 10 mètres, etc...

Constantes

ZERO_ROTATION

ZERO_ROTATION = <0.0, 0.0, 0.0, 1.0>;
Une constante de rotation correspondant à un angle d'Euler de <0.0, 0.0, 0.0>.

DEG_TO_RAD

DEG_TO_RAD = 0.01745329238f;
Une constante float qui donne l'angle en radians quand on la multiplie par l'angle en degrés. A float constant that when multiplied by an angle in degrees gives the angle in radians.

RAD_TO_DEG

RAD_TO_DEG = 57.29578f;
Une constante float qui donne l'angle en degrés quand on la multiplie par l'angle en radians.