See site in english Voir le site en francais
Website skin:
home  download  forum  link  contact

Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length

Author Topic: [C++] Animations  (Read 11291 times)

0 Members and 1 Guest are viewing this topic.

Offline picto

  • Legend
  • ******
  • Posts: 5014
  • Country: France fr
  • Karma: 25
  • Criiii Crii Crii
24 August 2007, 15:20:13
Petite question bête :sick:
Une seule fonction pour définir TOUTES les anims d'un vessel
ou une fonction par anim ?

C'est celle qu'on retrouve aussi en constructeur.



Message modifié ( 25-08-2007 02:27 )

Pic

Offline picto

  • Legend
  • ******
  • Posts: 5014
  • Country: France fr
  • Karma: 25
  • Criiii Crii Crii
Reply #1 - 24 August 2007, 15:47:20
Oups désolé ... suffit de regarder ... les exemples. :sick:

C'est parce que je galère sur un truc ... un peu ...
Je cherche à automatiser les Fonctions d'animation ( à terme, qu'il n'y en ai que deux
rotation et translation pour n'importe quel anime du vessel, même si j'en déclare 50 ...
M'énerve de faire du boulot répétitif de copié collé en changeant juste les noms :)
Puis plus tard les registres des groupes aussi tant qu'à faire ... c'est pas joli comme ça !

J'y suis presque, donc je cherche dans toutes les directions d'ou peut provenir l'erreur ...
Tiens, je poste tout ... peut être que l'erreur de logique va sauter aux yeux de quelqu'un :)

// déclarations d'anims dans DefineAnimations ():
Code: [Select]


( .... )
  static UINT PorteProbeFive_Groups[1] = {GRP_ANIM_PorteProbe05};
static MGROUP_ROTATE PorteProbe_05 (0, PorteProbeFive_Groups, 1, _V(6.189, 1.446, 26.748 ), _V(0,0,1), (float)(85.5*RAD));
    Portes[DOOR_PROBE_5].anim_Porte = CreateAnimation (0.0);
AddAnimationComponent (Portes[DOOR_PROBE_5].anim_Porte, 0, 1, &PorteProbe_05);
( .... )
// Fonction de test de l'état des animations pour toutes les portes qui ont le même type de fonctionnement.
Code: [Select]
void Irridium::RevertdAnimationPortes (int QuellePorte)
{
Portes[QuellePorte].dPorte_status = ((Portes[QuellePorte].dPorte_status == Portes[QuellePorte].dPorte_CLOSED ||
Portes[QuellePorte].dPorte_status == Portes[QuellePorte].dPorte_CLOSING ) ?
Portes[QuellePorte].dPorte_OPENING : Portes[QuellePorte].dPorte_CLOSING );
}
// En RunTime
Code: [Select]
for (int porte = DOOR_PROBE_1; porte < FIN_PORTES; porte++)
if (Portes[porte].dPorte_status >= Portes[porte].dPorte_CLOSING)
{
double da = oapiGetSimStep() * Portes[porte].dPorte_SPEED;
if (Portes[porte].dPorte_status == Portes[porte].dPorte_CLOSING)
{ // retractation
if (Portes[porte].dAnimPorte_proc > 0.0)
Portes[porte].dAnimPorte_proc = max (0.0, Portes[porte].dAnimPorte_proc-da);
else Portes[porte].dPorte_status = Portes[porte].dPorte_CLOSED;
}
else
{ // déploiement
if (Portes[porte].dAnimPorte_proc < 1.0)
Portes[porte].dAnimPorte_proc = min (1.0, Portes[porte].dAnimPorte_proc+da);
else Portes[porte].dPorte_status = Portes[porte].dPorte_OPEN;
}
SetAnimation (Portes[porte].anim_Porte, Portes[porte].dAnimPorte_proc);
}
Et on déclenche comme ça ... par exemple
Code: [Select]
case OAPI_KEY_NUMPAD3:
{
RevertdAnimationPortes(DOOR_PROBE_3);      
}
return 1;

Mais j'ai un petit problème de logique quelque part car quand je déclenche par

Code: [Select]
case OAPI_KEY_NUMPAD6:
{
RevertdAnimationPortes(DOOR_PROBE_6);      
}
return 1;
qui est censée déclencher la porte 6 ...
C'est aussi la porte 1 qui est actionnée !! :badsmile:
Et en fait, quoi que je fasse, c'est toujours la porte 1 qui est déclenchée !



Message modifié ( 24-08-2007 17:01 )

Pic

Offline picto

  • Legend
  • ******
  • Posts: 5014
  • Country: France fr
  • Karma: 25
  • Criiii Crii Crii
Reply #2 - 24 August 2007, 16:25:25
:rant:
C'est quoi ce truc !
Les TAGS cpp inventent des caractères là ou il n'y en a pas !
Dans runtime, il faut lire sur la première ligne ...

for (int porte = DOOR_PROBE_1; porte < FIN_PORTES; porte++)

Pas moyen de virer le ;  

Il n'existe pas d'ailleurs si on fait citer le message ;..
Je précise quand même car j'ai cru un moment que c'est ce qui déclenchait
les animes toujours sur le même groupe :)

Par contre, ça fonctionne avec le TAG code.
Dan, si tu lis ça ... les TAGs cpp ajoutent systématiquement un ; derrière > ou <
La preuve : copié collé de ça en dessous > < < <<<< >>>>>

Code: [Select]
> < < <<<< >>>>>


Message modifié ( 24-08-2007 16:37 )

Pic

Offline yoann

  • Legend
  • ******
  • Posts: 1914
  • Country: France fr
  • Karma: 9
Reply #3 - 24 August 2007, 16:54:23
j'aime bien les monolgues (3 post a la suite...) :lol:
pourles tags , c'est vous que ca regarde, ya que vous sur tous le forum qui doit utilisé les tag [cpp ]


__________________________________
    Luke, je suis ton pere            kchuuu  pchiiiii

Offline picto

  • Legend
  • ******
  • Posts: 5014
  • Country: France fr
  • Karma: 25
  • Criiii Crii Crii
Reply #4 - 24 August 2007, 16:58:25
C'est passionnant hein ? :)
Mais tu l'as gâché  ... :sad:
Maintenant c'est plus un monologue :sad:


Pic

Offline picto

  • Legend
  • ******
  • Posts: 5014
  • Country: France fr
  • Karma: 25
  • Criiii Crii Crii
Reply #5 - 24 August 2007, 17:48:03
Bon, ben je continue mon monologue !!!

J'ai trouvé !!!
Ca marche nickel !!!  :hot:
Une seule fonction !!!
6 portes 6 boutons 6 consumebufferedkeys !
6 animes !!! Et je peux en faire 500, ça me prendra juste le temps de repérer la charnière !!!

C'était une bête erreur d'initialisation !
Celle là :
for (int QuellePorte = DOOR_PROBE_1; QuellePorte < FIN_PORTES; QuellePorte++)
Portes[QuellePorte].anim_Porte = 0;
Donc, ça déclenchait tout le temps l'anim 0 :siffle:



Message modifié ( 24-08-2007 18:00 )

Pic

Offline DanSteph

  • Administrator
  • Legend
  • *****
  • Posts: 15410
  • Karma: 266
  • Hein, quoi !?
    • FsPassengers
Reply #6 - 24 August 2007, 18:43:57
Quote
picto a écrit:
Dan, si tu lis ça ...

Quelqu'un m'appelle ?

Ah non c'est juste picto qui fait des monologues :badsmile:

Pour le tag ouais... faudrais que je regarde a l'occase...

Dan


Offline picto

  • Legend
  • ******
  • Posts: 5014
  • Country: France fr
  • Karma: 25
  • Criiii Crii Crii
Reply #7 - 25 August 2007, 02:34:44
Je suis un peu surpris ...
Dans la doc sur les anims je lis ça :

Code: [Select]
_V(0,-1.0,6.5), _V(1,0,0), (float)(2*PI));
anim_gear = CreateAnimation (0.0);
parent = AddAnimationComponent (anim_gear, 0, 1, &gear);
anim_wheel = CreateAnimation (0.0);
AddAnimationComponent (anim_wheel, 0, 1, wheel, parent);
}
The gear and wheel rotations are defined by the MGROUP_ROTATE variables “gear” and
“wheel”. Note that in this case [b]“wheel” is not defined static, since reference point and axis will
be modified by the parent. Therefore, “wheel” must be defined as a data member of the
MyVessel class. Since “wheel” is allocated dynamically[/b], don’t forget to de-allocate it with
MyVessel::~MyVessel()
{
...
delete wheel;
...
}

Et je m'aperçois que beaucoup de programmes exemples utilisent malgré tout des statics pour les pointeurs.
J'ai fait une anim de panneau solaire avec des statics pour les composants enfant et me suis rendu compte de
l'erreur quand j'ai voulu faire les delete.

'Panneaux20' : identificateur non déclaré
 'delete' : impossible de détruire des objets qui ne sont pas des pointeurs ... :siffle:
Et blablabla.


Normal, ce sont des variables locales dans le cas de statics déclarées dans DefineAnimation();

Maintenant, la question qui tue :badsmile:
Etant donné que ça fonctionne avec des statics, est ce important de passer par des variables de classe
et de faire les delete sur les pointeurs dans le destructeur ? Et si oui pourquoi ?
Je crois comprendre à la lumière de ces mots que c'est une histoire de mémoire occupée " dynamically "
Mais quels sont les risques ?



Message modifié ( 25-08-2007 02:39 )

Pic

Offline DanSteph

  • Administrator
  • Legend
  • *****
  • Posts: 15410
  • Karma: 266
  • Hein, quoi !?
    • FsPassengers
Reply #8 - 25 August 2007, 03:09:38
je m'y colle... bouge pas

Dan


Offline picto

  • Legend
  • ******
  • Posts: 5014
  • Country: France fr
  • Karma: 25
  • Criiii Crii Crii
Reply #9 - 25 August 2007, 03:33:50
Encore mieux :doubt:
Dans certains exemples, les composantes ne sont même pas définies comme ça ...

static UINT wheel_groups[2] = {10,11};
wheel = new MGROUP_ROTATE (0, wheel_groups, 2,_V(0,-1.0,6.5), _V(1,0,0), (float)(2*PI));

Et pourtant les anims ont l'air de fonctionner



Message modifié ( 25-08-2007 03:46 )

Pic

Offline DanSteph

  • Administrator
  • Legend
  • *****
  • Posts: 15410
  • Karma: 266
  • Hein, quoi !?
    • FsPassengers
Reply #10 - 25 August 2007, 03:45:35
operateur new et delete....

new alloue de la mémoire et te retourne un pointeur sur cette mémoire, delete "désalloue" cette mémoire.
Si le prog alloue toujours en oubliant de désallouer il y aura de moins en moins de mémoire dispo jusqu'au crash
systeme ou des effets pire.

Prend un anti-virus qui tourne h24, tout les 5mn il fait tourner une routine, charge des db en mémoire avec new pour
comparer et oublie de delete... au bout de 5 heures ca peut devenir très critique. L'alzheimer de masse pour l'ordi.
Comme a court de mémoire il commence a swaper sur le disque et utilise de giga octets dieu sait quel effet ca peut avoir)

Comme un prog tourne dans un "espace mémoire virtuel" en principe toute la mémoire allouée est retournée
comme "libre" quand le programme ce termine , mais ca dépend en fait du type de mémoire allouée.

Dans le cas qui nous occupe , orbiter et les anims, en général tu a 10-20 anims qui consument quelques ko,
comme les vaisseaux ne sont pas généré a la pelle c'est pas très critique dans ce cas. Au pire meme après des
heures il n'y a que 100 ou 200ko de perdu qui sont libérés quand Orbiter ce termine *si on oublie de les delete*.

Maid ca peut devenir TRES critique pour un prog qui alloue des new/delete a la pelle, genre chaque fois que le user
fais une action ou tout les nn scondes. C'est pour cette raison que je les évite comme la peste.

Dans ton cas il te faut n'utiliser que la nouvelle methode d'orbiter pour les anims, cad un "handle" dans
la classe genre:

Code: [Select]
// DANS LA CLASSE:
MGROUP_ROTATE *nosewheeltourne;

Avec un operateurr new genre:

Code: [Select]
static UINT NosewheelGrpTourne[1] = {GRP_ANIMnosewheels};
nosewheeltourne = new MGROUP_ROTATE (MshIndex,NosewheelGrpTourne,1,_V(0,-2.316,8.474),_V(1,0,0),
(float)(2*PI));

Tu note que NosewheelGrpTourne est statique, on s'en fout c'est juste la définition des groupes.

Of course le handle nosewheeltourne  ayant alloué de la mémoire avec new il faut le delete a la fin
avec

Code: [Select]
delete(nosewheeltourne);


Note sur delete:

Ce rappeler le mantra indélébile: tout pointeur invalide doit etre NULL

La methode correct pour une bonne prog c'est :

Code: [Select]
    if(nosewheeltourne!=NULL)  // assure que le pointeur est valide
     {
           delete(nosewheeltourne);  // si oui, le desalloue
           nosewheeltourne=NULL;    // et le met a NULL (donc invalide pour nos tests)
     }

Ca assure:

1-qu'on essaie pas de delete un handle invalide (delete(NULL)=CTD)
2-qu'on remet bien a NULL un handle invalide.


Pour ca tu peut mettre dans un header "super visible" ceci:

Code: [Select]
#define SafeDelete(a) { if (a) {delete a; a = NULL; }} //safely delete a pointer, and set it to NULL. ...

En faisant:

Code: [Select]
SafeDelete(nosewheeltourne);
Tu satisfait les deux conditions.

Voila

A++

Dan



Message modifié ( 25-08-2007 03:59 )


Offline picto

  • Legend
  • ******
  • Posts: 5014
  • Country: France fr
  • Karma: 25
  • Criiii Crii Crii
Reply #11 - 25 August 2007, 03:59:24
// DANS LA CLASSE:
MGROUP_ROTATE *nosewheeltourne;

Pfff .... J'en ai au moins cinquante à faire comme ça ....


Oki, je comprend mieux pourquoi j'arrivais pas à compiler avec ma structure.
AnimationPointeurs.Panneaux02  = new MGROUP_ROTATE
Je recevais cette insulte de MSVC :)
Les types pointés n'ont aucun rapport entre eux 
Toi même que je lui répondais ... mais il voulait quand même pas compiler !

Il y a quand même un truc qui me surprend.
Tu me dis : " A éviter comme la peste "
Et : " Fais quand même !"
C'est bizarre ...

Et cette écriture,
#define SafeDelete(a) { if (a) {delete a; a = NULL; }}  
c'est très étrange ... c'est quoi ? Un define ... une fonction ? Un truc entre les deux ?



Message modifié ( 25-08-2007 04:09 )

Pic

Offline DanSteph

  • Administrator
  • Legend
  • *****
  • Posts: 15410
  • Karma: 266
  • Hein, quoi !?
    • FsPassengers
Reply #12 - 25 August 2007, 04:15:23
Quote
picto a écrit:
Il y a quand même un truc qui me surprend.
Tu me dis : " A éviter comme la peste "
Et : " Fais quand même !"
C'est bizarre ...

Les anims tu en à cinq ou dix, c'est très spécifique, même si tu merde totalement au pire tu perd l'equivalent d'un
gros jpg jusqu'a que Orbiter ce termine.

Si tu commence a aimer les new/delete au point de les utiliser partout comme certains l'aiment bien, il arrivera un jour
ou tu oubliera sur une routine dynamique de faire tes delete... C'est pourquoi je ne les utilise qu'en dernier recours.

Et cette écriture,
Code: [Select]
#define SafeDelete(a) { if (a) {delete a; a = NULL; }}  

C'est une macro...
quand tu aura compris ce que le C++ fait avec ton ecriture (la transformer en code assembleur)
et le distinguer de ce qui sera executé réellement ce jour la tu aura fini... well :)
la partie 1A de ton apprentissage du C++

En bref quand tu ecris:

Code: [Select]
SafeDelete(nosewheeltourne)
C'est transformé *a la compilation* en code ASM (peudo):


Code: [Select]
if(a!=NULL)  // assure que le pointeur est valide
     {
           delete(a);  // si oui, le desalloue
           a=NULL;    // et le met a NULL (donc invalide pour nos tests)
     }

Et c'est *ca* qui sera executé.

pour la petite histoire en asm ca donne ca:

Code: [Select]
0A9B62A5  mov         eax,dword ptr [ebp-10h]
0A9B62A8  cmp         dword ptr [eax+1EAEF8h],0           // compare le pointeur avec zéro (NULL)
0A9B62AF  je          0A9B62DC                            // si égal n'execute pas, saute a l'adresse apres le delete
0A9B62B1  mov         eax,dword ptr [ebp-10h]
0A9B62B4  mov         ecx,dword ptr [eax+1EAEF8h]
0A9B62BA  mov         dword ptr [ebp-0F7Ch],ecx
0A9B62C0  mov         edx,dword ptr [ebp-0F7Ch]
0A9B62C6  push        edx  
0A9B62C7  call        operator delete (0A978613h)       // sinon appelle le delete
0A9B62CC  add         esp,4
0A9B62CF  mov         eax,dword ptr [ebp-10h]
0A9B62D2  mov         dword ptr [eax+1EAEF8h],0      // et mets le pointeur a zéro
0A9B62DC  push        48h

A++

Dan



Message modifié ( 25-08-2007 04:22 )


Offline picto

  • Legend
  • ******
  • Posts: 5014
  • Country: France fr
  • Karma: 25
  • Criiii Crii Crii
Reply #13 - 25 August 2007, 11:45:01
La manip est intéressante quand même, en tout cas nouvelle pour moi ...
Une classe " externe " qui pointe directement sur une variable de ma classe.
L'intérêt n'est pas encore bien clair pour le moment :badsmile: mais ça viendra peut être !
Le plus important étant quand même de ne pas faire sans arrêt du boulot de singe
mais de bien comprendre ce qui se passe quand on fait quelque chose...

Ceci dit, je ne comprend pas encore bien l'intérêt de la manip pour les anims.
Une static n'est visible que là ou elle est déclarée et retiens sa valeur entre deux
 appels à la fonction. ... tout ce qu'il faut pour que les animes se passent bien et
puissent être opérées à chaque call de la fonction.

A moins que Martin se soit amusé à faire cette "mise en mémoire" d'une variable
de notre classe dans sa class ROTATE  ... :wonder:



Message modifié ( 25-08-2007 11:47 )

Pic

Offline DanSteph

  • Administrator
  • Legend
  • *****
  • Posts: 15410
  • Karma: 266
  • Hein, quoi !?
    • FsPassengers
Reply #14 - 25 August 2007, 12:49:57
Si je comprend bien ce que martin a fait:

Ancienne methode: static donc un seul group "anim" pour tout les mesh, quand il y avait plusieurs vessel necessité
de "transformer" (rotate etc) le groupe plusieurs fois par image meme quand le mesh n'avait pas bougé.
(eg: un vaisseau a la porte ouverte, l'autre fermée)

Nouvelle methode: a *chaque instance* d'un nouveau vessel une zone mémoire spécifique est allouée et le group
anim mis dedans. Comme chaque copie de vessel a son group propre pas besoin de transformer les mesh si il n'y a
pas de changement dans l'anim.

J'ai pas vu le code de martin mais ca semblerais logique.

Dan


Offline DanSteph

  • Administrator
  • Legend
  • *****
  • Posts: 15410
  • Karma: 266
  • Hein, quoi !?
    • FsPassengers
Reply #15 - 25 August 2007, 13:12:00
En passant très important:

Oublie pas de tester une scenario avec DEUX irridium voir plus; anim, panel, plein de raisons d'avoir des bug hideux si
on à merdé un peu dans la classe. Genre une array qui c'est glissée subrepticement dehors par exemple.

T'a fait comment finalement pour les "animation automatique" on peut voir ? :badsmile:

Dan


Offline picto

  • Legend
  • ******
  • Posts: 5014
  • Country: France fr
  • Karma: 25
  • Criiii Crii Crii
Reply #16 - 25 August 2007, 13:46:39
Merci pour le conseil, pour le nombre de vessels ..
Mais franchement, faudrait être cinglé pour en mettre plusieurs dans un scenar.
C'est pas un DGIV non plus ...
Mais bon, gouverner c'est prévoir ;) ....

Animes auto
Ben comme ça ... :doubt:
Une seule fonction pour déclencher et faire le revert et une seule boucle en runtime pour toutes les animes de même
type. Y'a qu'un truc dommage, c'est qu'elle ne prend pas en compte le STOPPED de la classe Animstate. Mais je
rajouterais plus tard.
C'est déjà pas mal ... par exemple, pour 10 animes ... 320 lignes de moins dans le code.
Et SURTOUT aucuns risques de plantages dans les variables ! ( stuveux j'peux te montrer comment faire  avec des
tableaux et des structures .... :lol:  )
Déclaration des groupes et composantes dans DefineAnimations();  et un mot dans le enum et j'ai plus à m'en
occuper, l'est pas  belle la vie ? :)

Par contre, j'ai pas encore fait la déclaration auto des groupes. :sad:
Pour l'instant, je les met toutes au point ... avec délais et tout le bastringue. C'est assez chouette à faire.
Puis après un chtiot for next comme dans le register panel avec une liste d'appel à une fonction de register.
Je coince juste un peu sur comment définir ce qui est enfant ou parent.
Parce que ce n'est pas un état figé ... Ce que je veux dire, c'est que selon l'anim, certains
groupes peuvent changer de statut en fonction de ce qu'on veut faire.

A ce sujet,
Y'a un truc que j'aimerais bien apprendre à faire, c'est de jouer sur les noms.
Je ne sais pas comment expliquer vraiment ce que je veux dire mais ça serait très utile.
Prenons le mot Panneau au hasard ...
Il y a sûrement moyen de créer 20 noms Panneau01 ... à Panneau20  ... à partir du premier mot
concaténation ?


Code: [Select]
void Irridium::RevertdAnimationPortes (int QuellePorte)
{
Portes[QuellePorte].dPorte_status = ((Portes[QuellePorte].dPorte_status == Portes
[QuellePorte].dPorte_CLOSED ||
Portes[QuellePorte].dPorte_status == Portes[QuellePorte].dPorte_CLOSING ) ?
Portes[QuellePorte].dPorte_OPENING : Portes[QuellePorte].dPorte_CLOSING );
}

// En RunTime

Code: [Select]
for (int porte = DOOR_PROBE_1; porte < FIN_PORTES; porte++)
if (Portes[porte].dPorte_status >= Portes[porte].dPorte_CLOSING)
{
double da = oapiGetSimStep() * Portes[porte].dPorte_SPEED;
if (Portes[porte].dPorte_status == Portes[porte].dPorte_CLOSING)
{ // retractation
if (Portes[porte].dAnimPorte_proc > 0.0)
Portes[porte].dAnimPorte_proc = max (0.0, Portes
[porte].dAnimPorte_proc-da);
else Portes[porte].dPorte_status = Portes[porte].dPorte_CLOSED;
}
else
{ // déploiement
if (Portes[porte].dAnimPorte_proc < 1.0)
Portes[porte].dAnimPorte_proc = min (1.0, Portes
[porte].dAnimPorte_proc+da);
else Portes[porte].dPorte_status = Portes[porte].dPorte_OPEN;
}
SetAnimation (Portes[porte].anim_Porte, Portes[porte].dAnimPorte_proc);
}


Pic

Offline DanSteph

  • Administrator
  • Legend
  • *****
  • Posts: 15410
  • Karma: 266
  • Hein, quoi !?
    • FsPassengers
Reply #17 - 25 August 2007, 14:12:44
Si c'est une chaine de caractere "Salut voici une chaine de caractere" facile.

Si c'est une variable ou un nom "define"  ou enum impossible, c'est des symbole, le nom c'est juste pour l'humain
l'ordi s'en fout en fait a la compilation il transforme ca en adresse. Comme c'est fait à la compilation impossible
de changer ca dynamiquement.

pour chaine de caractere, "sprintf":

Code: [Select]
char ChaineResultante[20]={0};

for(I=0;I<20;I++)
{
     sprintf(ChaineResultante,"Panneau%i",I);
}


Juste un tout petit truc d'optimisation:

Code: [Select]
double da = oapiGetSimStep() * Portes[porte].dPorte_SPEED;
avec 20 anim tu appelle 20 fois la fonction oapiGetSimStep alors qu'elle te retourne la même valeur.
C'est quelques cycle de perdu seulement mais dix par ici, dix par la... "hop, passez l'album photo !"

Comme SimStep est une variable qui est souvent utilisée un peu partout ca vaux le coup de la mettre
en "Data." et de la chopper au début de PostStep et remplacer tout les oapiGetSimStep

Code: [Select]
double da = Data.dSimStep* Portes[porte].dPorte_SPEED;
A++

Dan



Message modifié ( 25-08-2007 14:13 )


Offline picto

  • Legend
  • ******
  • Posts: 5014
  • Country: France fr
  • Karma: 25
  • Criiii Crii Crii
Reply #18 - 25 August 2007, 14:42:19
Quote
"define" ou enum impossible

C'est à ça que je pensais. :sad:
Tellement feignant que je me disais y'a sûrement moyen de
faire écrire les listes d'enums à notre place par l'ordi ...

Y'a rien à faire, sur un ordi, quand je fais deux fois de suite la même opération, je me dit, :"C'est forcément débile ...."
Visiblement, pas à chaque fois donc  ... je vais oublier la déclaration auto ... pour le moment.
Le jeu n'en vaut pas la chandelle. Pour faire un vaisseau avec 500 portes peut être mais pas pour 10 ...

Merci pour la combine d'optimisation.
Ce ne sont pas des trucs qui me saute aux yeux directement.
A se fourrer dans le crâne



Message modifié ( 25-08-2007 14:43 )

Pic

Offline DanSteph

  • Administrator
  • Legend
  • *****
  • Posts: 15410
  • Karma: 266
  • Hein, quoi !?
    • FsPassengers
Reply #19 - 25 August 2007, 18:26:22
Ya bien un moment ou faut ecrire du code quand meme :badsmile:

Sinon tu fais un utilitaire qui CREE du code, j'ai deja fait un truc dans le style... Ca copie
direct le resultat dans le presse papier... reste à faire CTL+V, si les touches sont pas trop
dure on doit y arriver :badsmile:

Dan


Offline picto

  • Legend
  • ******
  • Posts: 5014
  • Country: France fr
  • Karma: 25
  • Criiii Crii Crii
Reply #20 - 25 August 2007, 19:56:49
Quote
un utilitaire qui CREE du code

C'était du code pour quoi faire ?
" Ben !!!  pour écrire du code "
Le fin du fin :)


Pic

Offline picto

  • Legend
  • ******
  • Posts: 5014
  • Country: France fr
  • Karma: 25
  • Criiii Crii Crii
Reply #21 - 05 September 2007, 23:51:13
Petite question pour les pros de l'animation.
Est il possible de récupérer des composants d'une animation pour une autre animation.
C'est pas simple à expliquer mais ce que je veux faire est simple.

J'ai une antenne stockée dans une trappe avec parent enfant ...
Ca fonctionne.

Mais je ne peux que stocker ou déployer cette antenne.

Si ensuite je veux la faire tourner sur elle même mais que cette part là soit une
animation à part entière
, c'est à dire pas une ènième composante de la première
animation ( en jouant sur les délais )

Je me retrouve face à deux problèmes ... les positions deviennent aléatoires puisque
le mesh était stocké et que je veux animer à partir de la situation déstockée.

J'ai tenté de simplement récupérer les composantes de la première animation
pour faire un deuxième create animation, mais Orbiter n'aime pas trop.
J'en suis donc à recréer une animation à part entière en mettant les axes virtuellement
à la position finale du déploiement de la première animation.

Je sais pas si je suis clair sur ce coup là :badsmile:
A force d'approximations, je parviens petit à petit à la mettre au point mais ce n'est pas
aussi parfait qu'à partir des positions initiales du mesh avec les parents enfants ...

La question, certains ici ont ils déjà tenté ce genre d'expérience et quelle est la meilleure méthode ?
Ou y a t'il de récupérer de façon stable les composantes de la première animation.
Je précise quand même que les deux animations seront liées ... Dans le sens ou je bloquerais la possibilité de
déclencher la seconde si la première n'a pas été éxécutée ... Donc pas de risques de récupérer des trucs qui
n'existent pas.



Message modifié ( 05-09-2007 23:53 )

Pic

Offline DanSteph

  • Administrator
  • Legend
  • *****
  • Posts: 15410
  • Karma: 266
  • Hein, quoi !?
    • FsPassengers
Reply #22 - 06 September 2007, 01:35:43
wow désolé rien compris...

pourquoi le parent/enfant ne marche pas dans ce cas la ?

Dan


Offline picto

  • Legend
  • ******
  • Posts: 5014
  • Country: France fr
  • Karma: 25
  • Criiii Crii Crii
Reply #23 - 06 September 2007, 02:04:26
Je me doutais que ce serait pas clair ....
Avec du code ça va être plus simple ... j'élague pour que ça fasse pas trois pages ...

Bla bla ... je définis les composantes ...
Puis je crée une Anime de ce type ...

// ANIME ANTENNE
Portes[DOORS_ANTENNE].anim_Porte = CreateAnimation (0.0);
parentAntenne00 =
AddAnimationComponent (Portes[DOORS_ANTENNE].anim_Porte, 0.14,    1, BrasAntenne01);
parentAntenne01 =
AddAnimationComponent (Portes[DOORS_ANTENNE].anim_Porte, 0.14,    1, BrasAntenne02, parentAntenne00);
AddAnimationComponent (Portes[DOORS_ANTENNE].anim_Porte, 0.6,1, Parabole, parentAntenne01);


Cette anime fonctionne parfaitement ...
C'est elle qui fait sortir une antenne de sa boite ... Elle est composée de trois éléments mobiles les uns par rapport
aux autres d'ou l'utilisation de parents enfants. Les coordonnées pour les axes de rotation sont donc pris à partir de
la position rentrée.

PUIS, je décide de créer une seconde animation ou je veux ne faire tourner QUE Parabole...
MAIS Pas dans la même anime ...

//ROTATE PARABOLE
    Portes[ROTATION_ANTENNE].anim_Porte = CreateAnimation (0.0);


Mais le groupe concerné est un objet de l'anime précédente aussi ...
Ses coordonnées précises dans l'espace 3D sont inconnues car elles ont été crées à partir de l'animation précédente
à partir de la parabole dockée .... Oki ? :)
J'essaye donc ça ...
AddAnimationComponent (Portes[DOORS_ANTENNE].anim_Porte, 0.6,1, Parabole, parentAntenne01);
Mais Orbiter n'aime pas :badsmile:
Non seulement la seconde anime ne fonctionne pas mais ça donne des résultats étranges pour la première animation.


Pic

Offline picto

  • Legend
  • ******
  • Posts: 5014
  • Country: France fr
  • Karma: 25
  • Criiii Crii Crii
Reply #24 - 06 September 2007, 02:20:38
Avec des petites images ce sera beaucoup plus clair ...

Première anime



Maintenant, je veux faire une seconde anime qui ne ferait que faire tourner la parabole autour du bras ...
ET plus complexe plus tard ... mais c'est pour simplifier le problo ...
Une fois dans la position finale du gif ...



Message modifié ( 06-09-2007 02:24 )

Pic