La cocotte : étape 3

Répondre
Partager Rechercher
Pour les courageux qui ont franchi les deux premières étapes voici la troisième .

Pour cette troisième étape on va ajouter les primitives c1 et c2 :

img10.png

Les numéros de liaison



On va encore compléter le code pour les numéros de liaison :


listPRIM_NAMES=["a1","a2","b1","b2","c1","c2"];
list l_link = [0,0,0,0,0,0];


On va aussi créer deux variables pour manipuler les index :


id_c1=llList2Integer(l_link,llListFindList(PRIM_NAMES,["c1"]));
id_c2=llList2Integer(l_link,llListFindList(PRIM_NAMES,["c2"]));


Rotation et position de départ

Pour ces deux primitive on va avoir besoin de deux informations, position et rotation :


// Initialisations c1
l=getPrimParams(id_c1);
r_c1=llList2Rot(l,0);
v_c1=llList2Vector(l,1);


// Initialisations c2
l=getPrimParams(id_c2);
r_c2=llList2Rot(l,0);
v_c2=llList2Vector(l,1);




Jusque là rien de nouveau !


Le centre de c1 est nommé v_center_c1 tout comme on avait nommé v_center_b1 le centre de b1.


Le mouvement



Pour le mouvement de c1 ça va un peu se compliquer…


L'axe autour duquel doit tourner c1 est nommé sur la figure ci-dessus axis_c1. On voit que pour déterminer cet axe on a besoin de deux renseignements :



  1. la position v_end_b1,
  2. la position du point v_0


Pour le point v_0 c'est plus simple et on l'a déjà rencontré parce qu'il ne bouge pas :


vector v_o = <diagonal, 0, 0>;


Mais pour v_end_b1 il nous faut connaître la position de v_center_b1 mais ça on l'a déjà calculé pour b1 :


vector v_center_b1=v_b1*rot_a1;


Il faut ensuite ajouter le vecteur jusqu'à v_end_b1. On se rend compte que le vecteur pour aller de v_center_b1 à v_end_b1 est exactement le même que v_b1 :


img11.PNG



Donc pour calculer la position de v_end_b1 on a :


vector v_end_b1=v_center_b1+v_b1*rot_a1*rot_b1;


On ajoute à v_center_b1 le vecteur v_b1 orienté par la rotation de a1 et celle de b1.


On calcule maintenant facilement l'axe :


vector axis_c1=v_end_b1-v_o;


Pour la rotation on va utiliser encore la fonction llAxisAngle2Rot que je ne vous présente plus :

rotation rot_c1=llAxisAngle2Rot(llVecNorm(axis_c1),fCos(0,160.5,step)*DEG_TO_RAD);

On prévoit une rotation totale de 160,5 degrés pour que les deux primitives coïncident exactement en bout de mouvement.


Pour la primitive c2 c'est exactement le même raisonnement mais en symétrique.


Au final on applique tout ça :


llSetLinkPrimitiveParamsFast(id_a1,[
PRIM_ROT_LOCAL,r_a1*rot_a1,
PRIM_LINK_TARGET,id_a2,PRIM_ROT_LOCAL,r_a2*rot_a2,
PRIM_LINK_TARGET,id_b1,PRIM_POS_LOCAL,v_center_b1,PRIM_ROT_LOCAL,r_b1*rot_a1*rot_b1,
PRIM_LINK_TARGET,id_b2,PRIM_POS_LOCAL,v_center_b2,PRIM_ROT_LOCAL,r_b2*rot_a2*rot_b2,
PRIM_LINK_TARGET,id_c1,PRIM_POS_LOCAL,v_center_c1,PRIM_ROT_LOCAL,r_c1*rot_a1*rot_b1*rot_c1,
PRIM_LINK_TARGET,id_c2,PRIM_POS_LOCAL,v_center_c2,PRIM_ROT_LOCAL,r_c2*rot_a2*rot_b2*rot_c2
]);

Remarquez comment est appliquée la rotation pour c1 :


  1. on commence par sa rotation de départ : r_c1,
  2. on applique ensuite la rotation de a1 : rot_a1,
  3. on applique la rotation de b1 : rot_b1,
  4. pour finir on applique la rotation autour de l'axe : rot_c1,


Pour c2 c'est pareil mais en miroir.


On doit obtenir ces trois mouvements conjugués :


img12.png


Le code

Voilà le code complet pour cette troisième étape :


/////////////////////////////////////////////////////////////////
// //
// Etape 3 //
// //
/////////////////////////////////////////////////////////////////

// Version
string VERSION = "1.0";

// Time
float TIME = 5;
float TEMPS_BASE = .04;

// Primitives
list PRIM_NAMES = ["a1","a2","b1","b2","c1","c2"];

// Dimensions
float SIDE = 2.0;


// -----------------------------------------------
// Variables
// -----------------------------------------------

// Dimensions
float diagonal;

// Link numbers
list l_link = [0,0,0,0,0,0];

// Indexes
integer id_a1;
integer id_a2;
integer id_b1;
integer id_b2;
integer id_c1;
integer id_c2;

// Rotations
rotation r_a1;
rotation r_a2;
rotation r_b1;
rotation r_b2;
rotation r_c1;
rotation r_c2;

// Positions
vector v_b1;
vector v_b2;
vector v_c1;
vector v_c2;

// Utilities
float f_step;

// -----------------------------------------------
// Initialisations
// -----------------------------------------------
initialisations() {
// Links detection
linkedPrimsDetection();

// Time
f_step = 1.0 / (TIME / TEMPS_BASE);

// Indexes
id_a1 = llList2Integer(l_link, llListFindList(PRIM_NAMES, ["a1"]));
id_a2 = llList2Integer(l_link, llListFindList(PRIM_NAMES, ["a2"]));
id_b1 = llList2Integer(l_link, llListFindList(PRIM_NAMES, ["b1"]));
id_b2 = llList2Integer(l_link, llListFindList(PRIM_NAMES, ["b2"]));
id_c1 = llList2Integer(l_link, llListFindList(PRIM_NAMES, ["c1"]));
id_c2 = llList2Integer(l_link, llListFindList(PRIM_NAMES, ["c2"]));

// Dimensions
diagonal = SIDE * llCos(PI_BY_TWO / 2.0);

// Initialisations a1
r_a1 = llList2Rot(getPrimParams(id_a1), 0);

// Initialisations a2
r_a2 = llList2Rot(getPrimParams(id_a2), 0);

// Initialisations b1
list l = getPrimParams(id_b1);
r_b1 = llList2Rot(l, 0);
v_b1 = llList2Vector(l, 1);

// Initialisations b2
l = getPrimParams(id_b2);
r_b2 = llList2Rot(l, 0);
v_b2 = llList2Vector(l, 1);

// Initialisations c1
l = getPrimParams(id_c1);
r_c1 = llList2Rot(l, 0);
v_c1 = llList2Vector(l, 1);

// Initialisations c2
l = getPrimParams(id_c2);
r_c2 = llList2Rot(l, 0);
v_c2 = llList2Vector(l, 1);
}

// -----------------------------------------------
// Get prim params
// -----------------------------------------------
list getPrimParams(integer id) {
return llGetLinkPrimitiveParams(id, [PRIM_ROT_LOCAL, PRIM_POS_LOCAL]);
}

// -----------------------------------------------
// Linked primitives detection
// -----------------------------------------------
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);
}
}

// -----------------------------------------------
// Interpolation
// -----------------------------------------------
float fCos(float x, float y, float t) {
float F = (1 - llCos(t * PI)) / 2;
return x * (1 - F) + y * F;
}

// -----------------------------------------------
// Movement
// -----------------------------------------------
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>);

// Calculus b1
vector v_center_b1 = v_b1 * rot_a1;
vector v_o = <diagonal, 0, 0>;
vector axis_b1 = v_center_b1 - v_o;
rotation rot_b1 = llAxisAngle2Rot(llVecNorm(axis_b1), fCos(0, -140, step) * DEG_TO_RAD);

// Calculus b2
vector v_center_b2 = v_b2 * rot_a2;
vector axis_b2 = v_center_b2 - v_o;
rotation rot_b2 = llAxisAngle2Rot(llVecNorm(axis_b2), fCos(0, 140, step) * DEG_TO_RAD);

// Calculus c1
vector v_end_b1 = v_center_b1 + v_b1 * rot_a1 * rot_b1;
vector axis_c1 = v_end_b1 - v_o;
rotation rot_c1 = llAxisAngle2Rot(llVecNorm(axis_c1), fCos(0, 160.5, step) * DEG_TO_RAD);
vector v_center_c1 = v_o + (<diagonal / 2.0, diagonal / 2.0, 0>) * rot_a1 * rot_b1 * rot_c1;

// Calculus c2
vector v_end_b2 = v_center_b2 + v_b2 * rot_a2 * rot_b2;
vector axis_c2 = v_end_b2 - v_o;
rotation rot_c2 = llAxisAngle2Rot(llVecNorm(axis_c2), fCos(0, -160.5, step) * DEG_TO_RAD);
vector v_center_c2 = v_o + (<diagonal / 2.0, - diagonal / 2.0, 0>) * rot_a2 * rot_b2 * rot_c2;

// Movement
llSetLinkPrimitiveParamsFast(id_a1, [
PRIM_ROT_LOCAL, r_a1 * rot_a1,
PRIM_LINK_TARGET, id_a2, PRIM_ROT_LOCAL, r_a2 * rot_a2,
PRIM_LINK_TARGET, id_b1, PRIM_POS_LOCAL, v_center_b1, PRIM_ROT_LOCAL, r_b1 * rot_a1 * rot_b1,
PRIM_LINK_TARGET, id_b2, PRIM_POS_LOCAL, v_center_b2, PRIM_ROT_LOCAL, r_b2 * rot_a2 * rot_b2,
PRIM_LINK_TARGET, id_c1, PRIM_POS_LOCAL, v_center_c1, PRIM_ROT_LOCAL, r_c1 * rot_a1 * rot_b1 * rot_c1,
PRIM_LINK_TARGET, id_c2, PRIM_POS_LOCAL, v_center_c2, PRIM_ROT_LOCAL, r_c2 * rot_a2 * rot_b2 * rot_c2
]);


llSleep(TEMPS_BASE);
}
}

// -----------------------------------------------
// Base state
// -----------------------------------------------
default
{
state_entry() {
llWhisper(0, "Cocotte version " + VERSION);
initialisations();
}

touch_start(integer total_number)
{
movement();
state reset;
}
}

// -----------------------------------------------
// Reset state
// -----------------------------------------------
state reset
{
touch_start(integer total_number)
{
llSetLinkPrimitiveParamsFast(id_a1, [
PRIM_ROT_LOCAL, r_a1,
PRIM_LINK_TARGET, id_a2, PRIM_ROT_LOCAL, r_a2,
PRIM_LINK_TARGET, id_b1, PRIM_POS_LOCAL, v_b1, PRIM_ROT_LOCAL, r_b1,
PRIM_LINK_TARGET, id_b2, PRIM_POS_LOCAL, v_b2, PRIM_ROT_LOCAL, r_b2,
PRIM_LINK_TARGET, id_c1, PRIM_POS_LOCAL, v_c1, PRIM_ROT_LOCAL, r_c1,
PRIM_LINK_TARGET, id_c2, PRIM_POS_LOCAL, v_c2, PRIM_ROT_LOCAL, r_c2
]);
state default;
}
}

Dernière modification par bestmomo ; 07/06/2016 à 18h36.
euhhh. je tire mon chapeau et je vote pour dire que Bestmomo est bien le meilleur scripteur SL .

chapeau BAS, je me retire dans le respect le plus total

Grace l'a Imaginé, Bestmomo le fait ! la j'admire aussi le coté "defi technique" avec un language LSL pas tres adapté.
__________________
Paris 1900
http://www.paris1900.net

Dernière modification par Netpat ; 07/06/2016 à 21h54.
Répondre

Connectés sur ce fil

 
1 connecté (0 membre et 1 invité) Afficher la liste détaillée des connectés