Recherche

Recherche personnalisée

dimanche 29 mars 2009

Tutorial 9 Balançoire

J'ai découvert lsl il y a 3 mois lorsqu'une amie m'a demandée de l'aider à écrire un script dans Second life. Le but était d'animer une balançoire. Je pensais la tâche aisée étant donnée mon expérience en programmation. Mais c'était sans compter sur les particularités de lsl et de Second Life. J'ai galéré pendant deux jours pour trouver les éléments nécessaires et j'ai fulminé contre l'hégémonie de la langue anglaise au niveau de la documentation. Il en est sorti un script fonctionnel mais pas vraiment esthétique. Avec le recul je me rends compte de ses imperfections. Récemment dans le forum de jeuxonline (je ne peux que vous conseiller ce forum en français avec des personnes très compétentes et vraiment serviables) j'ai proposé ce script suite à une question. Voici le lien :



http://forums.jeuxonline.info/showthread.php?t=803732



On m'a très justement fait remarquer que mon script ne fonctionne plus lorsque la balançoire subit une rotation. Il était donc temps que je reprenne ce script pour le rendre à la fois plus élégant et plus efficace. Voici le code qu'il en est sorti :



//
// Balancoire Version 1.0
// par bestmomo
//

// Periode du mouvement en secondes
float Periode;
// Amplitude du demi mouvement en degres
float Amplitude;
// Amplitude sur l'axe X
float AmplitudeX;
// Amplitude sur l'axe Y
float AmplitudeY;
// Pas de changement
float Pas;
// Rotation de depart
rotation Rotdepart;
// Gestion du temps
float Temps;

initialisations()
{
Periode = 4.0; // 4 secondes
Pas = 0.2; // 0,2 secondes
// Rotation de depart
Rotdepart = llGetRot();
// Rotation de depart Euler
vector RotdepartEuler = llRot2Euler(Rotdepart);
// Amplitude du mouvement en radians
Amplitude = 40.0 * DEG_TO_RAD;
// Amplitude sur l'axe X
AmplitudeX = Amplitude * llCos(RotdepartEuler.z);
// Amplitude sur l'axe Y
AmplitudeY = Amplitude * llSin(RotdepartEuler.z);
}

default
{
touch_start(integer total_number)
{
// Mise en marche
state marche;
}
}

state marche
{
state_entry()
{
initialisations();
// Demarrage du timer
llSetTimerEvent(Pas);
}

touch_start(integer total_number)
{
// Retour position initiale
llSetRot(Rotdepart);
// Reset du script
llResetScript();
}

timer()
{
// Incrementation du temps
Temps += Pas;
// Calcul des angles
float AngleX = AmplitudeX * llSin((TWO_PI / Periode) * Temps);
float AngleY = AmplitudeY * llSin((TWO_PI / Periode) * Temps);
// Calcul de la rotation
rotation Rot = Rotdepart * llEuler2Rot( );
// Application de la rotation
llSetRot(Rot);
}

}



Au niveau de la construction le script doit se trouver dans le root, au niveau de l'axe. Le prim correspondant doit être centré et ne doit pas subir de rotation sur les axes X et Y. Le plus simple est de prévoir un box que vous redimensionnez, quitte à le rendre transparent ensuite pour conserver uniquement les cordes. C'est ce que j'ai fait sur mon exemple que vous pouvez voir sur la photo. Cette fois la balançoire peut être déplacée sans souci à condition évidemment de la conserver horizontale ! Ce qui paraît très naturel pour une balançoire.

Le mouvement d'une balançoire est pendulaire, autrement dit c'est une fonction sinusoïdale. J'ai vu sur SL des balancelles avec un mouvement très fluide mais désespérément linéaire. Il est facile de réaliser ce type d'animation avec la fonction llTargetOmega :



http://www.lslwiki.net/lslwiki/wakka.php?wakka=llTargetOmega



Mais le soucis de réalisme doit nous éloigner de cette solution qu'il faut réserver à des mouvements linéaires du genre manège. LSL possède une librairie mathématique relativement complète :



http://www.lslwiki.net/lslwiki/wakka.php?wakka=math



On y trouve en particulier les fonctions trigonométriques qui vont nous servir pour la balançoire : llCos pour trouver le cosinus et llSin pour le sinus. Voyons un peu le code...

Il y a un certain nombre de variables globales. La Periode représente le rythme du balancement, c'est le temps mis pour accomplir un mouvement de balancement complet. L'Amplitude représente la dimension du balancement (en fait la moitié de celui-ci) en degrés. Ensuite viennent deux amplitudes : AmplitudeX et AmplitudeY. Ces deux valeurs sont nécessaires pour gérer les rotations de la balançoire lors de ses différents positionnements. Il s'agit de la projection de l'amplitude du mouvement par rapport aux axes X et Y. Le Pas de changement représente l'incrémentation temporelle, autrement dit à quel rythme nous allons calculer la nouvelle position. La rotation initiale est stockée dans la variable Rotdepart. La dernière variable Temps est consacrée à gérer le temps de fonctionnement, elle est intimement liée au Pas.

La méthode initialisations sert à initialiser toutes ces variables. Pour la Periode et le Pas vous pouvez essayer différentes valeurs pour voir les effets. Pour trouver la rotation de départ on utilise la fonction llGetRot que nous avons déjà vu pour le script de la porte. Vous savez qu'on obtient un quaternion, pour nous simplifier la vie nous transformons cette valeur en Euler avec la fonction llRot2Euler. J'ai pris une demie Amplitude de 40° que je transforme en radians grâce à la constante DEG_TO_RAD. Ensuite nous déterminons les composantes de l'amplitude sur les axes X et Y avec les fonctions cosinus et sinus.

L' organisation générale du script est très simple avec deux états : le classique default qui contient seulement l'événement touch_start dans l'attente qu'un avatar touche la balançoire, ce qui a pour effet de basculer dans l'état marche. Dans cet état l'événement state_entry lance l'initialisation et le timer avec le Pas.

Au niveau de l'événement timer nous trouvons l'animation proprement dite. On commence par incrémenter le Temps de la valeur du Pas. Ensuite nous calculons le nouvel angle par rapport aux axes X et Y. L'amplitude est simplement multipliée par une fonction sinusoïdale du temps. Les non matheux peuvent sauter ces lignes ! Ensuite on calcule la rotation et on l'applique avec la fonction llSetRot que vous connaissez déjà.

Si la balançoire est touchée lorsqu'elle est en fonctionnement c'est l'événement touch_start de l'état marche qui est déclenché. Il suffit alors de ramener la balançoire à sa rotation initiale et à faire un reset du script.

5 commentaires:

  1. Je suis vraiment fière de vous découvrir, votre blog est vraiment super ! J’aime bien son interface, et j’ai trop adoré le contenu aussi. Surtout continuez ainsi !

    voyance par mail gratuite

    RépondreSupprimer
  2. Merci beaucoup pour ce site et toutes les informations qu’il regorge. Je le trouve très intéressant et je le conseille à tous !
    Bonne continuation à vous. Amicalement

    voyance par mail


    RépondreSupprimer
  3. Je viens de découvrir votre blog aujourd’hui et je pense que je vais passer plusieurs jours dessus.
    voyance serieuse rapide

    RépondreSupprimer
  4. Bonjour, j’ai eu le plaisir de me rentre sur ce blog, l’ambiance, la qualité des installations, le sentiment de liberté de bien être vous gagne des vôtre arrivé…
    voyance gratuite email

    RépondreSupprimer
  5. Félicitation à tous ceux qui veillent pour le bon déroulement de ce magnifique blog !!

    Voyance en ligne discount

    RépondreSupprimer