[Discussion] Sur la nouvelle fonction llSetKeyframedMotion

Répondre
Partager Rechercher
Bon, BestMomo doit être complètement déprimé car il va falloir, encore une fois, le pauvre, mettre à jour ses tutos sur les déplacements de prims. Il n'y a que cela qui puisse expliquer le silence du forum sur cette nouvelle fonction complètement bluffante, introduite pourtant depuis plusieurs mois (en tout cas sur Aditi mais ça marche désormais sur Agni).
En gros, vous pouvez obtenir la belle fluidité des mouvements physiques (rien à voir avec les mouvements pour moi assez laborieux de llSetLinkPrimitiveParamsFast) , sans en avoir les inconvénients (collisions). Il semble qu'on puisse travailler aussi bien en données géographiques qu'en données relatives à l'emplacement de l'objet.

J'ai été complètement bluffé par ce petit script, à insérer dans un prim cubique aplati (mettons une plateforme de 3m sur 3). Avec les viewers supportant les meshes, il faut aussi préalablement cocher dans la rubrique "features" de l'objet, la nouvelle case "shape convex" ou bien, si on utilise un viewer 1. et dérivés, insérer une petite ligne de code supplémentaire:

Code PHP:

default
{
    
state_entry()
    {
        
//llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_PHYSICS_SHAPE_TYPE, PRIM_PHYSICS_SHAPE_CONVEX]); //ligne à ajouter si on travaille en viewer 1 et qu'on n'a pas la nouvelle case à cocher dans "features"
        
llSetKeyframedMotion([<0,0,0>, 3, <0,5,0>, 3, <5,0,0>, 3, <0,-5,0>, 3, <-5,0,0>,3], [KFM_DATAKFM_TRANSLATIONKFM_MODEKFM_LOOP]); //cela va déplacer l'objet selon un carré de 5 mètres (sur des durées de 3 secondes), en boucle.
    
}

C'est magique, car l'avatar peut se mettre debout sur la plateforme et être déplacé, sans s'asseoir, comme lorsqu'on monte, par exemple, dans un bus dans la vraie vie.

Pour les feignasses qui n'ont pas envie de tester in world, voilà ce que ça donne en vidéo (la deuxième partie de la vidéo pour la plateforme, auparavant on a, toujours obtenu avec cette fonction, un "carrousel" (avec beaucoup de guillemets)):



Bref, on nous promet de faire avec ça des carrousels, manèges, montagnes russes, un maximum de choses géniaaaaaales avec un minimum de lignes.


Mais, il y a un HIC, enfin, je me suis dit: c'est l'arnaque.
Car j'ai lié à ce cube une petite voiture ridicule freebie avec un minimum de prims (comme elle était initialement physique, style 25 prims) et j'obtiens le message d'erreur suivant: " Error, failed to play animation. Does your linkset exceed the complexity limit for keyframing?"

Mon "linkset", question "complexity", c'est du simple de chez simple, du genre quelques cubes basiques ressemblant vaguement de loin à une voiture, style freebie de 2003, avec des roues presque carrées (pas de sculpties ou de prims flexibles ou torturés et tout et tout). De plus, cela explose la capacité en prims de la homestead où j'ai fait l'essai de plus de 800 prims ("845 prims will be deleted") alors qu'il restait environ 300 prims de disponibles).

Je crie à l'arnaque, on nous roule dans la farine, alors qu'on nous promettait, carrément, le Luna-Park!!!

Dernière modification par Poisson.Soluble ; 04/01/2012 à 20h46.
.

Dernière modification par Compte #361860 ; 04/01/2012 à 23h30.
moi ca marche

Dernière modification par Compte #361860 ; 04/01/2012 à 23h57.
Merci Poisson, je ne connaissais pas
On peut faire de vrais escalators, à voir ici

On peut faire des trucs drôles aussi; vous créez une plateforme de taille par exemple 3x3x1, vous changez les features en convex hull puis vous mettez ce script dedans.
Code:
default
{
    touch_start(integer total_number)
    {
        llSetKeyframedMotion([ZERO_VECTOR, 0.1, <0,0,5>, 0.1], [KFM_DATA, KFM_TRANSLATION, KFM_MODE, KFM_FORWARD]);
        state up;
    }
}

state up
{
    touch_start(integer total_number)
    {
        llSetKeyframedMotion([ZERO_VECTOR, 0.1, <0,0,-5>, 0.45], [KFM_DATA, KFM_TRANSLATION, KFM_MODE, KFM_FORWARD]);
        state default;
    }
}
Vous vous mettez debout sur la plateforme et vous cliquez dessus. Faut cliquer une 2e fois pour faire revenir la plateforme à son point de départ.
__________________

Dernière modification par L'âme immortelle ; 05/01/2012 à 00h09.
Citation :
Publié par Elenia B.
Bon j'essaye avec le V3: ça ne marche pas. La plateforme se déplace bien, mais je ne peux pas rester dessus: elle glisse sous moi sans m'emporter.
Ca m'a fait ça la 1ere fois aussi, il faut que la plateforme soit plus épaisse et/ou plus grande.
Citation :
Publié par litza
quelqu un a un script de l escalator ? ca a l air lourd en prim mais j adore le principe ^^
J'ai pris un peu le temps de m'amuser avec cette fonction. Pour l'escalator on peut économiser des prims en négligeant le retour des marches en dessous qui sont normalement masquées. On gagne comme ça pratiquement la moitié des prims.

Pour tester l'escalator il faut commencer par créer une marche de profondeur 50cm (la valeur est paramétrable dans le script) sur l'axe X, appeler cette marche "1" et mettre ce script :

Code PHP:

integer i_nbr_m   6;     // Nombre de marches de l'escalator
float   f_time    1.0;   // Temps de base de déplacement d'une marche à l'autre en secondes
float   f_l       .5;    // Profondeur d'une marche en mètres
integer i_channel = -236510;

integer i_listen;
string  s_nbr;

default
{
    
state_entry() {
        
i_listen llListen(i_channel""NULL_KEY"");
        
s_nbr llGetObjectName();
        
llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_PHYSICS_SHAPE_TYPEPRIM_PHYSICS_SHAPE_CONVEX]);
    }

    
listen(integer channelstring namekey idstring message) {
        if(
message == s_nbr) {
            
float f = (float)i_nbr_m;
            
llSetKeyframedMotion([
                <
f_l 2.00.0>, f_time 2.0,
                <
f_l f.0f_l f>, f_time f,
                <
f_l 2.00.0>, f_time 2.0,
                <
.0.0, -f_l * (1.0)>, f_time 3.0,
                <-
f_l * (4.0), .0.0>, f_time 3.0,
                <
.0.0f_l>, f_time 3.0
                    
], [KFM_DATAKFM_TRANSLATIONKFM_MODEKFM_LOOP]);
            
llListenRemove(i_listen);
        }
    }

Il faut dupliquer cette marche 11 fois pour obtenir ainsi 12 marches. Il faut les appeler "2", puis "3" jusqu'à "12".

Rassembler les 12 marches au même endroit, même position. On ne doit plus voir qu'une marche.

Ensuite créer un autre objet avec ce script :

Code PHP:

integer i_channel = -236510;
integer i_nbr_m   6;     // Nombre de marches de l'escalator
float   f_time    1.0;   // Temps de base de déplacement d'une marche à l'autre en secondes

integer i_nbr;

default
{
    
touch_start(integer total_number) {
        
i_nbr i_nbr_m 6;
        
llSetTimerEvent(f_time);
    }

    
timer() {
        
llSay(i_channel, (string)i_nbr--);
        if(!
i_nbrllSetTimerEvent(.0);
    }

Il suffit de cliquer sur l'objet pour déclencher l'escalator. J'ai joint une petite vidéo du résultat.

Dans le script on peut régler le nombre de marches et la vitesse de défilement. ce n'est qu'une maquette, on pourrait ajouter la fonction de pause facilement, etc...

Citation :
Publié par L'âme immortelle
Ca m'a fait ça la 1ere fois aussi, il faut que la plateforme soit plus épaisse et/ou plus grande.
Oui merci l'ame; j'essayais avec une épaisseur de 0.1. Avec 0.25 pas de problème.
Il y a plusieurs petites précisions à rajouter .

1) Eviter de changer d état dans l'évènement touch_start mais plutot dans l évenement touch_end .
Dans l’évènement touch_start , cela peut inhiber certains clicks de souris.
Or comme tu fais des mouvements relatifs , cela peut te conduire à monter ou descendre 2 fois de suite

2) Avec cette fonction il faut raisonner en Frames ( au niveaux sim ), même si les paramètres sont exprimées en secondes .
Dans ton exemple , si je prend le cas de la descente :
on a 0.45 en temps de déplacement , ce qui fait 0.45 * 45 ( cadence du nombre de frames par secondes de la sim ) = 20.25 .
Le déplacement en fait se faira en 20 frames .
Tu perds donc 0.25 frame , ce qui équivaut à 0.25 / 45 * 5( metres de déplacements = 0.027 mètres à chaque descente .
Il faudrait calculer aussi à chaque montée .

Le plus facile est d arrondir les temps de déplacements à un temps multiple d un certain nombre de frames

Code PHP:

float ceilFrame(float time)
{
    return 
llCeil45.0 time ) /45.0;

Pour ton ascenseur , cela fait peut le faire décaler au fur et à mesure du nombre de fois qu'il s anime .


3) Comme les objets physiques , l objet peut être grabé . Mais cela n est valable que pendant le temps de l exécution de la fonction .
Or , si ton utilisateur fait un touch en relâchant le bouton un peu tardivement , cela va altérer la position de la prim .
C est d autant plus facile à graber que la prim est petite ( question de masse )
Donc pour être plus certaine , il peut être référable , en tout cas plus user_friendly d empêcher le grab .


4) C est peut être préférable d attendre la fin de déplacement de la prim pour pouvoir redonner la main à l utilisateur et lui permette de retoucher la prim .
On peut tester si l objet se déplace avec llGetVel et llGetOmega

5) Cela peut être vu comme une fonctionnalité , mais normalement , un ascenseur dans le réel a une accélération quasi constante et est de l ordre de 1 m/s-²
Ta montée est très rapide et accélère très rapidement . Les objets ou avatars qui sont dessus vont se sentir projetés dans l air ( cela dépend de leurs masses )
Enfin , la prim doit ajuster ses paramètres de friction et de restitution pour avoir un meilleur rendu des collisions des prims qui sont dessus.
C est le même problème qu avec les fonctions physiques.

6) Enfin pas pour l ascenceur mais pour le carousel , pour des rotations trop lentes , l animation peut se "geler"
un autre grand classique la rotation par rapport à un axe qui n est pas le centre de rotation de la prim ( par exemple la rotation de portes )
version setkeyframe

Code PHP:


// variables a parametrer
float angle=PI_BY_TWO;
float time_opening 3.15;
float time_closing 5.25;
// fin variables a parametrer

integer open=FALSE;
turnfloat angfloat time)
{

    list 
FrameList;
    
// actuellement le temps minimum par key de l animation est de 0.1 secondes 
    // mais le temps d une key doit etre multiple de durée de frames théorique du simulateur pour que les déplacements soient plus précis
    // donc on pose le temps d une key a 5.0/ 45.0 ( 45 etant le nombre de FPS théorique de la sim )  = 1/9 > 0.1 s
    
integer maxsteps=(integer)(time 9);
    
float newtime maxsteps 9.0;
    
integer i ;
    
vector v1;
    
rotation deltaRot llAxisAngle2Rot(llRot2Up(llGetRot()), ang/(float)maxsteps);

    for  ( 
0maxsteps i++)
    {
        
v1 0.5 llGetScale() * llEuler2Rot(< 0,0,ang/(float)maxsteps>) * llGetRot();
        
        
FrameList += [ 
            
v1 deltaRot v1 
            
llEuler2Rot(< 0,0,ang/(float)maxsteps>),
            
newtime/(float)maxsteps
        
];
    }
    
llSetTimerEvent(newtime);   
    
llSetKeyframedMotion(  FrameList, []);
    if ( 
TRUE 
        
state turning;
 
}

default
{
    
state_entry()
    {
        
// on  rend posssible l utilisation de llsetkeyframe en changeant sa physics_shape
        
llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_PHYSICS_SHAPE_TYPEPRIM_PHYSICS_SHAPE_CONVEX]); // make client mesh-aware
        // on desactive la possibilite de deplacer l objet par toucher
        
llSetStatus(STATUS_BLOCK_GRABTRUE);
    }

    
touch_end(integer total_number)
    {
        
turnangletime_opening);
    }
}

state turning
{
    
timer()
    {
        
state waitingTouch;
    }
}
state waitingTouch
{
    
touch_end(integer t)
    {
        
angle = - angle;
        
turnangletime_closing);
    }   

Merci à nos brillants scripteurs de nous proposer, déjà, des exemples de scripts possibles.
Cependant, par rapport à mon message initial, je ne trouve pas d'information: pourquoi est-il impossible de l'utiliser avec un linkset somme toute simple et constitué de prims peu nombreux, avec le message d'erreur: "Error, failed to play animation. Does your linkset exceed the complexity limit for keyframing?" Impossible de trouver de la documentation par rapport à ces limites.

Est-ce à dire qu'on est restreint à animer de simples cubes? Ou bien à ne travailler qu'avec des meshes?
Il y a une limite de facon analogue aux linkset des prims physiques

"This function requires the linkset to use the Prim Equivalency system. However, it keyframed objects will not receive the dynamics penalty and can have a physics PE of up to 64"

Tu peux avoir un PE de 64

Source
http://wiki.secondlife.com/wiki/LlSetKeyframedMotion

Je ne sais pas si tu l as atteinte
Ce qui est normal puisque le poids des objets n est pas le même et qu il peut dépendre de plusieurs facteurs comme la taille de l objet , sa complexité , etc ...

https://sites.google.com/site/tradew...g/mesh-physics


exemples :
simple et unique cube :
0.1 télécharger
0.4 proriétés physiques
0.5 serveur
simple et unique tore :
1.4 télécharger
1.8 proriétés physiques
0.5 serveur
8 tores liées de 1 m toutes en convex_hull :
12.9 télécharger
14.7 proriétés physiques
4 serveur
8 tores liées de 21 m toutes en convex_hull :
190.6 télécharger
69.6 proriétés physiques
4 serveur
8 tores liées de 21 m la root en convex hull , les autres a none :
190.6 télécharger
4.9 proriétés physiques
4 serveur


Dans l outil d édition , clique sur le lien "more info" / "plus infos" pour savoir le poids

Ceci dit , llSetKeyframedMotion ne marche que sur la prim root .
Donc du coup , il t est inutile de mettre toutes les prims de ton linkset en convex_hull . seulement la prim root suffit .
Pour les autres prims tu mets l attribut de forme physique à "none"/ "aucun" ; dans ce cas tu peux atteindre tes 255 prims
Mais dans ce cas là , seules les collisions avec la prim root auront un impact sur les autres objets physiques et/ou avatar , pas les autres prims de ta linkset qui se comporteront comme des prims phantoms.

De plus ( à vérifier, je n ai pas testé ) ta prim root peut etre une mesh complexe ; la prim root est retranchée du décompte pour llSetKeyframedMotion

Dernière modification par redpurple ; 07/01/2012 à 20h54.
Un script pour enregistrer le parcours d'un objet mobile. Cela peut servir pour faire un ascenseur, une montgolfière, un travelling pour ceux qui font des machinima, etc. Bien évidemment, il n'est pas de moi, je l'ai trouvé ici, mais je vous le communique car il sera sans doute utile à certains.
Il peut constituer une alternative "setkeyframedmotion" au mobile physique qu'avait publié le regretté Sébastien sur ce forum ou à celui, très élaboré, de BestMomo en "fast", qui d'ailleurs facilite l'installation du parcours.

Il faut mettre ce script dans un cube (préalablement réglé en CONVEX_HULL). On peut copier/coller dans une notecard le mode d'emploi qui suit ce script. Cette notecard apparaîtra lorsqu'on appuiera HELP dans le menu.

Code PHP:

vector initPOS;
rotation initROT;
list 
positions=[];
list 
rotations=[];
list 
motionPath;
integer iframe=0;

menu(){
    
llDialog(llGetOwner(),"Choose",["HELP","ADDFRAME","DELFRAME","RESTART","SCRIPT","PLAY","|<<",">>|","STOP","<",">" ],-1);
}
vector lastPOS()
{
  
vector pos=initPOS;
  
integer i;
  for(
i=0;i<iframe;i++) pos+=llList2Vector(positions,iframe-1);
  return 
pos;
}
rotation lastROT()
{
    
rotation rot=initROT;
  
integer i;
  for(
i=0;i<iframe;i++) rot*=llList2Rot(rotations,iframe-1);
  return 
rot;

}
goFrame()
{
    
integer l=llGetListLength(positions);
    
llSay(0,"You are at frame #"+(string)iframe);
    if(
iframe==0)
    {
        
warpPosRot(initPOS,initROT);
        return;
    }
    
warpPosRot(llList2Vector(positions,iframe-1), llList2Rot(rotations,iframe-1));
}
addFrame(vector posrotation rot)
{
    
iframe++;
    
// removing frame at pos iframe
    
if(iframe>llGetListLength(positions)){
        
positions+=[pos];
        
rotations+=[rot];
        return;
    }
    
positions=llListReplaceList(positions,[pos],iframe-1,iframe-1);
    
rotations=llListReplaceList(rotations,[rot],iframe-1,iframe-1);
    
}
removeFrame()
{
    
iframe--;
    
integer l=llGetListLength(positions);
    if(
iframe>=l)
    {
        
        if(
l<=1){ positions=[]; rotations=[]; return;}
        
        
// remove last position
        
positions=llDeleteSubList(positions,-1,-1);
        
rotations=llDeleteSubList(rotations,-1,-1);        
        return;
    }
    
// removing intermediate frame
    
positions=llDeleteSubList(positions,iframe,iframe);
    
}
warpPosRot(vector posrotation rot)
{
    
llSay(0,"warping to "+(string)pos);
    
// loop to move the prim at initial destination
    
while(llVecDist(llGetPos(),pos)>0.01)
        
llSetLinkPrimitiveParamsFast(1, [ PRIM_POSITIONposPRIM_ROTATIONrot ]);

}
getMotionPath()
{
    
motionPath=[];
    
integer ivector lastp=initPOSrotation lastr=initROT;
    for(
i=0;i<llGetListLength(positions);i++)
    {
        
vector curp=llList2Vector(positions,i);
        
rotation curr=llList2Rot(rotations,i);
        
vector diffp=curp-lastp;
        
rotation diffr=curr/lastr;
        
float distllVecMag(diffp);
        
// try to force length in seconds proportional to actual meters
        
if (dist<1dist=1;
        
motionPath+=[ diffpdiffrdist*0.1 ];
        
lastp=curp;
        
lastr=curr;
    }    
}

default
{
    
changed(integer change)
    {
        if(
change CHANGED_OWNERllResetScript();
    }
    
state_entry()
    {
        
// setting shape
        
llSetLinkPrimitiveParamsFast(1, [ PRIM_TYPEPRIM_TYPE_BOX0, <0.01.00.0>, 0.898000ZERO_VECTOR, <0.2500000.2500000.0>, ZERO_VECTORPRIM_SIZE, <0.5000000.5000000.500000>, PRIM_ROTATION, <-0.49999, -0.50001, -0.500010.49999>, PRIM_COLOR0, <1.01.01.0>, 1.0PRIM_COLOR1, <0.01.00.0>, 1.0PRIM_COLOR2, <0.00.5019611.0>, 1.0PRIM_COLOR3, <0.01.00.0>, 1.0PRIM_COLOR4, <1.01.01.0>, 1.0PRIM_COLOR5, <0.7294120.00.121569>, 1.0PRIM_COLOR6, <1.01.01.0>, 1.0PRIM_TEXTUREALL_SIDES"5748decc-f629-461c-9a36-a35a221fe21f", <1.01.00.0>, ZERO_VECTOR0.0PRIM_FLEXIBLEFALSE,0,0.000000,0.000000,0.000000,0.000000,ZERO_VECTOR]);
        
// set sit
        
llSitTarget(<0.5,0,-.5>,llEuler2Rot(DEG_TO_RAD*<0,90,180>));
        
// dialog
        
llListen(-1,"",llGetOwner(),"");
        
// save first position
        
initPOS=llGetPos();
        
initROT=llGetRot();
        
menu();
    }


    
touch_start(integer total_number)
    {
        
menu();
    }
    
listen(integer channel,string namekey idstring str)
    {
        if(
str=="RESTART")
        {
            
llSay(0,"Resetting script");
            
llResetScript();
            return;
        }
        if(
str=="ADDFRAME")
        {
            
llSay(0,"Marking waypoint");
            
addFrame(llGetPos(),llGetRot());
                
                    }
        
// remove last if only one just RESET
        
if(str=="DELFRAME")
        {
           
removeFrame();
           
        }
        if(
str=="PLAY")
        {
            
llSay(0,"Starting motion...");
            
warpPosRot(initPOS,initROT);
            
llSleep(.5);
            
getMotionPath();

            
llSetKeyframedMotionmotionPath, [ KFM_MODEKFM_FORWARD ]);
            
motionPath=[]; 
                
        }
        if(
str=="STOP")
        {
            
llSay(0,"Stopping motion...");
            
llSetKeyframedMotion([],[]);
        }
        if(
str=="SCRIPT")
        {
            
getMotionPath();
            
llSay(0,"default { state_entry() { while(llVecDist(llGetPos(),"+(string)initPOS+")>0.01)llSetLinkPrimitiveParamsFast(0, [ PRIM_POSITION, "+(string)initPOS+", PRIM_ROTATION, "+(string)initROT+"]); llSetKeyframedMotion([ ");
            
            
string s=llList2CSV(motionPath);
            while(
llStringLength(s)>255)
            {
                
string first=llGetSubString(s,0,255);
                
llSay(0,first);
                
s=llGetSubString(s,256,-1);
            }
            
llSay(0,s);
            
            
llSay(0,"],[KFM_MODE,KFM_FORWARD]);}}");       
        }
        if(
str=="|<<")
        {
                
iframe=0;
                
goFrame();
        }
        if(
str==">>|")
        {
                
iframe=llGetListLength(positions);
                
goFrame();
        }
        if(
str==">")
        {
                
iframe++;
                
integer l=llGetListLength(positions);
                if(
iframe>l)iframe=l
                
goFrame();
        }
        if(
str=="<")
        {
                
iframe--; if(iframe<0iframe=0;
                
goFrame();
        }
        if(
str=="HELP")
        
llGiveInventory(llGetOwner(),llGetInventoryName(INVENTORY_NOTECARD,0));
        
menu();      
    }



Mode d'emploi:

1. Bien penser à relancer préalablement le script ("reset scripts in selection" dans "outils")
2. Toucher RESTART dans le menu, pour définir le point de départ du parcours.
3. Bouger l'objet (déplacer/pivoter) jusqu'à sa 2e position. Enregistrer la deuxième position en cliquant "ADDFRAME" dans le menu.
4. Répéter 3., pour toutes les positions (frames) du parcours.
5. On peut visualiser l'animation: |<< et >>| pour aller au début ou à la fin de l'animation, < ou > pour parcourir les frames.
6. Si une frame ne vous convient pas, appuyer DELFRAME et repositionnez l'objet à la bonne place avant d'appuyer ADDFRAME de nouveau pour remplacer la frame annulée.
7. Pour tester l'animation, appuyer sur PLAY.
8. Pour générer le script avec ce parcours, cliquer sur SCRIPT.
9. Copier/Coller le script généré dans le chat local. Supprimer les passages du type indications de l'heure ou "Machin Truc est connecté" et enregistrer comme nouveau script.
10. Insérer ce script dans un nouvel objet
en CONVEX_HULL et le tour est joué!

PS: J'avais oublié de remercier redpurple pour toutes les informations ci-dessus. J'en profite pour le faire.

Dernière modification par Poisson.Soluble ; 15/01/2012 à 22h16.
C'est possible de modifier l'angle de rotation du script de porte precedent ?

Code PHP:

// variables a parametrer 
float angle=PI_BY_TWO
float time_opening 3.15
float time_closing 5.25
// fin variables a parametrer 

integer open=FALSE
turnfloat angfloat time


    list 
FrameList
    
// actuellement le temps minimum par key de l animation est de 0.1 secondes  
    // mais le temps d une key doit etre multiple de durée de frames théorique du simulateur pour que les déplacements soient plus précis 
    // donc on pose le temps d une key a 5.0/ 45.0 ( 45 etant le nombre de FPS théorique de la sim )  = 1/9 > 0.1 s 
    
integer maxsteps=(integer)(time 9); 
    
float newtime maxsteps 9.0
    
integer i 
    
vector v1
    
rotation deltaRot llAxisAngle2Rot(llRot2Up(llGetRot()), ang/(float)maxsteps); 

    for  ( 
0maxsteps i++) 
    { 
        
v1 0.5 llGetScale() * llEuler2Rot(< 0,0,ang/(float)maxsteps>) * llGetRot(); 
         
        
FrameList += [  
            
v1 deltaRot v1 ,  
            
llEuler2Rot(< 0,0,ang/(float)maxsteps>), 
            
newtime/(float)maxsteps 
        
]; 
    } 
    
llSetTimerEvent(newtime);    
    
llSetKeyframedMotion(  FrameList, []); 
    if ( 
TRUE )  
        
state turning
  


default 

    
state_entry() 
    { 
        
// on  rend posssible l utilisation de llsetkeyframe en changeant sa physics_shape 
        
llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_PHYSICS_SHAPE_TYPEPRIM_PHYSICS_SHAPE_CONVEX]); // make client mesh-aware 
        // on desactive la possibilite de deplacer l objet par toucher 
        
llSetStatus(STATUS_BLOCK_GRABTRUE); 
    } 

    
touch_end(integer total_number
    { 
        
turnangletime_opening); 
    } 


state turning 

    
timer() 
    { 
        
state waitingTouch
    } 

state waitingTouch 

    
touch_end(integer t
    { 
        
angle = - angle
        
turnangletime_closing); 
    }    

Par exemple au lieu de 90°, 45° ...

c est le paramètre float angle en 1ère ligne que tu dois changer .
Il s exprime en radians pas en degrés .
PI_BY_TWO vaut l angle pi/2 = 90 degres.
Tu peux utiliser la constante DEG_TO_RAD pour convertir de degrés en radians
et RAD_TO_DEG pour convertir de radians en degrès .

exemple en le modifiant lors du reset ou de la sauvegarde du script

Code PHP:

// le debut du script inchange 
// ....
//

    
state_entry()  
    {  
       
// l angle de rotation sera de 45 degres
        
angle DEG_TO_RAD 45.0 
        
        
// on  rend posssible l utilisation de llsetkeyframe en changeant sa physics_shape  
        
llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_PHYSICS_SHAPE_TYPEPRIM_PHYSICS_SHAPE_CONVEX]); // make client mesh-aware  
        // on desactive la possibilite de deplacer l objet par toucher  
        
llSetStatus(STATUS_BLOCK_GRABTRUE);  
    }  
// le reste du script inchange*
// ....
// 
Si tu as beaucoup de portes a faire , il serait peut etre plus pratique de modifier le script pour qu il lise l angle par exemple dans la description de l objet ou dans une notecard .

Dernière modification par redpurple ; 23/09/2012 à 15h20.
Citation :
Publié par Poisson.Soluble
Un script pour enregistrer le parcours d'un objet mobile. Cela peut servir pour faire un ascenseur, une montgolfière, un travelling pour ceux qui font des machinima, etc.
Bonjour,

J'avais reproduit ce script llSetKeyFramedMotion il y a plusieurs mois, script permettant d'enregistrer les positions successives d'un objet pour créer un parcours. Je l'avais testé à l'époque et il fonctionnait.
Quelqu'un du forum vient de me signaler par "message privé" qu'il ne marchait pas et de fait, ça ne marche plus avec moi non plus: non seulement l'objet ne bouge plus, lorsqu'on appuie PLAY mais le menu n'apparaît plus non plus, comme si cela bousillait toute l'exécution du script.
Lorsqu'on publie le script simplifié (de pur mouvement) via le menu (bouton "SCRIPT") et qu'on utilise alors celui-ci, on obtient une erreur: "Object: Delta times must be >0.1s". Je suppose que le problème vient de là (des restrictions ultérieures semblent avoir été apportées à la fonction llSetKeyFramedMotion ).

Bref, si quelqu'un avait une idée (sans perdre pour autant tout son dimanche là-dessus): cela pourrait aider la personne qui m'a contacté... D'autant plus que c'est un script d'intérêt général si je puis dire, pouvant rendre pas mal de services.

PS: j'en profite pour soulever un autre problème. A l'époque, je m'étais rendu compte que le clic droit ("edit") de l'owner sur un objet animé en llSetKeyFramedMotion arrêtait l'objet. Comme la liste calcule les points du parcours en valeurs relatives, cette immobilisation temporaire créait ensuite un décalage sur tout le reste du parcours. Ne serait-il pas préférable que la liste soit plutôt exprimée en coordonnées géographiques pour éviter ce problème? Enfin... c'est ce qu'elle fait déjà, puisque le script enregistre d'abord la première position en coordonnées géographiques... Bref, je ne sais pas s'il y a une solution pour éviter cela.
Le message d erreur "Delta times must be >0.1s" a tojours éxisté .
Il signifie que dans ta liste passée à LLSKFM, tu renseignes des valeurs pour le temps inférieures à 0.1 secondes .

Or pour qu il puisse faire son interpolation entre 2 frames ,llSKFM doit avoir plusieurs frames . Ce qui justifie donc le minimum à 0.1 secondes ( à mon avis , LL pourrait le réduire à 4 frames , soit 0.088888 ms )
C est possible que le message d erreur s affiche en fait pour inférieur à 5 frames soit < 0.11111111 ms.
Il me semble de mémoire que y avait un truc comme cela

Tes données en entrée de LLSKFM sont très probablement différentes dans ton cas de test d aujourd hui que dans ton cas de test voilà quelques mois

Concernant le clique droit :
dans ton cas , il faudrait que tu rajoutes
llSetStatus(STATUS_BLOCK_GRAB, TRUE);
pour éviter que le mouvement soit altéré par l utilisateur .
Les personnes n ayant pas le droit de déplacement sur l objet , ne peuvent déjà pas le faire .
Dans ces 2 cas , l objet sera peut être stoppé par l utilisateur pendant l édition mais reprendra sa course après

Il ne faut pas forcément le faire pour tous les objets . Des fois cela peut etre pratique par exemple pour un mouvement cyclique de donner la possibilité de positionner son objet ou bon lui semble .

Dernière modification par redpurple ; 25/11/2012 à 11h41.
Citation :
Publié par redpurple
Concernant le clique droit :
dans ton cas , il faudrait que tu rajoutes
llSetStatus(STATUS_BLOCK_GRAB, TRUE);
pour éviter que le mouvement soit altéré par l utilisateur .
Dans ce cas , il sera peut etre stoppé par l utilisateur pendant l edition mais reprendra sa course après

Il ne faut pas forcément le faire pour tous les objets . Des fois cela peut etre pratique par exemple pour un mouvement cyclique de donner la possibilité de positionner son objet ou bon lui semble .
Merci pour cette solution.

Citation :
Publié par redpurple
Tes données en entrée de LLSKFM sont très probablement différentes dans ton cas de test d aujourd hui que dans ton cas de test voilà quelques mois
Le problème se pose non seulement pour moi mais aussi pour cette personne qui m'a contacté en MP (qui devait penser que j'étais bon en script). Mon essai du script ce matin n'était pourtant pas compliqué: un simple cube et deux ou trois positions enregistrées (avec "ADDFRAME"). Ca ne marche pas, alors que je me souviens que tout était ok lorsque j'avais testé la 1ere fois le script... Je n'ai plus trop utilisé le script ensuite, j'ai oublié.
Je ne retrouve pas l'objet avec lequel j'avais fait le test dans l'inventaire (il doit s'appeler "object") et je ne sais pas si j'avais apporté des modifications au script initial pour que ça fonctionne (du genre lignes pour arrondir les valeurs des rotations). Bref, incapable d'expliquer d'où vient la "panne".
Visiblement, la personne qui m'a contacté avait besoin de ce script, j'aurais bien voulu la dépanner. Elle s'exprimera peut-être ici...

Dernière modification par Poisson.Soluble ; 25/11/2012 à 11h56.
Répondre

Connectés sur ce fil

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