|
Comme suite à la discussion qui a eu lieu ici voici la première étape de la réalisation de la cocotte.
Pour mémoire j'ai déjà développé la réalisation de mouvements dans SL avec deux guides (Rotations pour les nuls et Guide des machines) qu'on peut trouver ici. La première étape est de posséder la maîtrise de la version papier. Donc apprendre déjà, si ce n'est déjà fait, à en réaliser une, s'amuser avec, la plier et déplier dans tous les sens, en un mot apprivoiser la cocotte (enfin en 3 mots). L'étape suivante est de modéliser les faces nécessaires. Voilà ce que ça donne pour la cocotte : Vérifiez sur votre exemplaire papier ! On se retrouve donc avec 14 facettes. En transposant en SL ça nous fera donc 14 primitives. D'autre part pour des questions de système de référence on va ajouter au milieu une primitive qui restera bien orientée par rapport au repère de base. Donc en tout on aura 15 primitives. On pourrait gagner 2 primitives si on admet que les pattes ne seront jamais pliées mais on est pas à deux primitives près… Pour s'y retrouver il faut aussi nommer les primitives. J'ai fait un truc simple : Comme les primitives sont parfaitement symétriques j'ai numéroté celles qui se font face avec juste une indexation pour les différencier. J'ai ajouté une petit boule au centre pour figurer la primitive mère et aussi la représentation du système de coordonnées en haut à droite. La réalisation du build dans SL ne présente pas de difficulté majeure. On part de prismes aplatis. Il faut juste être précis dans le positionnement des primitives (se rappeler que la diagonale d'un carré de côté 1 est égale à racine de 2). D'autre part il vaut mieux colorer les primitives pour les distinguer ! Pour les dimensions je suis parti sur une base de prismes de 2 mètres de côté pour les deux centrales. Du coup la surface totale est de 4m x 4m. Mais on va s'arranger pour que le code fonctionne quelles que soient les dimensions. L'orienttaion de chaque primitive n'a pas d'importance puisqu'on tiendra compte de la rotation de départ pour chacune. Pour ne pas se perdre il vaut mieux commencer modestement avec juste deux primitives à bouger, les plus simples : a1 et a2, ça permettra de s'échauffer… On va donc se débarrasser de tout le reste et conserver que la primitive racine et les deux ailes : Dans votre build assurez-vous d'avoir bien comme racine la primitive centrale. En limitant les éléments à bouger on se simplifie la vie et on avance prudemment. En plus comme les primitives sont des moitiés de carrés leur centre se retrouve fusionné avec le centre de l'objet, ce qui va aussi simplifier les calculs. Les numéros de liaison La première chose va être de connaître le numéro de liaison de ces deux primitives. Comme on les a nommées ça ne va pas être bien difficile et on va pouvoir commencer à coder. On va mettre les noms des primitives dans une liste : list PRIM_NAMES = ["a1","a2"]; Pour le moment la liste est courte mais elle se remplira peu à peu. On va aussi prévoir une liste pour recueillir les numéros de liaison correspondants : list l_link = [0,0]; Pour le moment c'est à zéro, on va actualiser les valeurs avec cette petite fonction : linkedPrimsDetection(){ integer i; integer n = llGetNumberOfPrims(); for(i = 2; i <= n; ++i){ string name = llList2String(llGetLinkPrimitiveParams(i, [PRIM_NAME]), 0); integer id = llListFindList(PRIM_NAMES, [name]); if(~id) l_link = llListReplaceList(l_link, [i], id, id); } } On passe enrevue toutes les primitives de l'objet et lorsqu'on rencontre un nom de la liste PRIM_NAMES on met son numéro de liaison dans la case correspondante de la liste l_link. Pour simplifier l'accès à ces valeur on va créer deux variables : id_a1 = llList2Integer(l_link, llListFindList(PRIM_NAMES, ["a1"])); id_a2 = llList2Integer(l_link, llListFindList(PRIM_NAMES, ["a2"])); Dans la première on aura le numéro de liaison de a1 et dans la deuxième celui de a2. Rotation de départ On a aussi besoin de connaître la rotation de chacune des deux primitives (pour la position on a vu que c'est le centre de l'objet). En effet on a été obligés de les faire tourner pour les positionner du coup leurs axes locaux ne sont plus alignés avec les axes de l'objet. On va créer une petite fonction pour ça : list getPrimParams(integer id){ return llGetLinkPrimitiveParams(id, [PRIM_ROT_LOCAL, PRIM_POS_LOCAL]); } Cette fonction renvoie une liste contenant la rotation et la position locales. Pour le moment on n'a besoin que de la rotation mais la position sera nécessaire pour la suite. On peut alors initialiser les variables pour les deux primitives : r_a1 = llList2Rot(getPrimParams(id_a1), 0); r_a2 = llList2Rot(getPrimParams(id_a2), 0); On a la rotation de départ de a1 dans la première variable et celle de a2 dans la seconde. Mouvement et Interpolation Comme on va effectuer des mouvements on va avoir besoin d'une routine de calcul de valeurs intermédiaires, on parle dans ce cas d'interpolation : float fCos(float x, float y, float t){ float F = (1 - llCos(t * PI)) / 2; return x * (1 - F) + y * F; } Cette fonction qui est issue de la librairie de SL renvoie une valeur numérique entre x et y en fonction de la valeur de t qui doit être entre 0 et 1. Par exemple :
D'autre part j'ai choisi une interpolation sinusoïdale pour avoir un mouvement plus naturel (ça démarre lentement, ça accélère puis ça ralentit à la fin). On va avoir besoin aussi de régler la vitesse du mouvement : float TIME=5; float TEMPS_BASE=.04; float f_step; La première constante va régler la durée totale en seconde. Le seconde variable va régler la durée de chaque étape du mouvement en seconde aussi. La variable step nous indiquera la fraction de durée sur la base de l'unité pour la durée totale (utile pour l »interpolation) : f_step=1.0/(TIME/TEMPS_BASE); Le mouvement Venons-en maintenant au mouvement avec cette fonction : movement(){ float step; while((step+=f_step)<=1.0){ // Calculus a1 and a2 rotation rot_a1=llEuler2Rot(<fCos(0,-80,step)*DEG_TO_RAD,0,0>); rotation rot_a2=llEuler2Rot(<fCos(0,80,step)*DEG_TO_RAD,0,0>); // Movement llSetLinkPrimitiveParamsFast(id_a1,[PRIM_ROT_LOCAL,r_a1*rot_a1]); llSetLinkPrimitiveParamsFast(id_a2, [PRIM_ROT_LOCAL, r_a2 * rot_a2]); llSleep(TEMPS_BASE); } } On a une boucle avec while dans laquelle on fait évoluer la valeur de la variable step entre 0 et 1,0. On va appliquer à chaque primitive une rotation de 80 degrés pour laisser un peu d'air. Le calcul pour a1 est ici : rotation rot_a1=llEuler2Rot(<fCos(0,-80,step)*DEG_TO_RAD,0,0>); On applique la rotation uniquement sur l'axe X en allant progressivement de 0 à -80 degrés. La fonction llEuler2Rot est destinée à transformer la représentation de la rotation sous forme de vecteur (compréhensible) en sa version sous forme de quaternion (moins compréhensible pour nous mais indispensable pour la machine). Pour mémoire on a des vecteurs avec les trois coordonnées ainsi : <x, y, z>. On peut ainsi préciser une position ou une rotation dans l'espace en 3 dimensions. Pour a2 on a le même code mais avec l'angle inversé. On applique la rotation avec la fonction llSetLinkPrimitiveParamsFast qui présente l'avantage d'être sans délai après exécution : llSetLinkPrimitiveParamsFast(id_a1,[PRIM_ROT_LOCAL,r_a1*rot_a1]); Regardez au niveau de la rotation. On ajoute à la rotation de base de la primitive (r_a1) la rotation calculée (rot_a1). Pour ajouter deux rotations on utilise le signe de la multiplication (c'est comme ça faut s'y faire). En gros on dit :
Pour finir on attend le temps nécessaire avant de passer au micro-mouvement suivant : llSleep(TEMPS_BASE); La suite juste après... Dernière modification par bestmomo ; 07/06/2016 à 13h27. |
07/06/2016, 13h17 |
Aller à la page... |
La cocotte : étape 1
Suivre Répondre |
|
Partager | Rechercher |
|
|
07/06/2016, 13h22 |
|
Alpha & Oméga
|
|
07/06/2016, 13h23 |
|
Alpha & Oméga
|
N'empêche ton guide devrait faire partie des fixes dans la section TECHNIQUE !!!
ça serait bien mérité !!! |
07/06/2016, 13h37 |
|
|
Respect...
|
07/06/2016, 14h08 |
|
|
Et c'est parti !
Merci, Bestmomo pour ce petit tuto que, je pense, nous allons être nombreux à suivre. |
07/06/2016, 14h10 |
|
Alpha & Oméga
|
Moi Bestmomo, ce mec, il m'épate
|
07/06/2016, 15h09 |
|
|
Étape 1 faite !
J'attaque la 2... |
07/06/2016, 17h49 |
|
Alpha & Oméga
|
Et beh alors je croyais que c'était trop dur voir impossible hein msieur anpton qui est devenu accroc aussi du coup 😂
|
07/06/2016, 21h22 |
|
Alpha & Oméga
|
|
11/06/2016, 14h38 |
|
Alpha & Oméga
|
Ah cool je regarderai ce soir merci.
|
11/06/2016, 17h34 |
|
|
Peut-être qu'un jour je créerai un outil simple pour créer des origamis, au moins tout le monde pourrait débrider son imagination .
|
21/06/2016, 22h14 |
|
Alpha & Oméga
|
|
21/06/2016, 22h15 |
|
Alpha & Oméga
|
Mon pauvre . Mais tu sais que tu n'es pas obligé d'en faire autant ? Tu en as déjà fait beaucoup .
|
26/06/2016, 11h07 |
|
|
|
26/06/2016, 17h24 |
|
Alpha & Oméga
|
|
26/06/2016, 17h48 |
|
|
|
26/06/2016, 18h10 |
|
|
|
26/06/2016, 18h35 |
|
Suivre Répondre |
Fil d'ariane
Connectés sur ce fil1 connecté (0 membre et 1 invité)
Afficher la liste détaillée des connectés
|