1 /*****************************************************************************
2 *
3 * Copyright (C) 2003 C�dric Br�gardis <cedric.bregardis@free.fr>
4 *
5 * This file is part of BRIQUOLO
6 *
7 * BRIQUOLO is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * BRIQUOLO is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with BRIQUOLO; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 *****************************************************************************/
22 #include "../I18n.h"
23 #include "MOGL_EnsembleObjet.h"
24 #include "MOGL_Armature.h"
25 #include "MOGL_Peau.h"
26 //#include
27 #include <stdio.h>
28
29 //#include <mmsystem.h>
30
MOGL_EnsembleObjet()31 MOGL_EnsembleObjet::MOGL_EnsembleObjet()
32 {
33 }
34
Charger(char * p_NomFichier,const MOGL_GestionnaireTexture p_GM)35 bool MOGL_EnsembleObjet::Charger(char * p_NomFichier, const MOGL_GestionnaireTexture p_GM)
36 {
37 char chaine[200];
38 int i,j;
39 char temp[50];
40 float x,y,z,u,v,xn,yn,zn;
41 int index_point=0;
42 bool debut=true;
43 bool PremiereFace=true;
44 bool Noeud=false;
45 MOGL_Struct_Point Pt[3];
46 MOGL_Texture * Texture=NULL;
47 MOGL_Noeud * ObjetCourant;
48 string NomCourant;
49 unsigned int NiveauCourant=0;
50
51 vector <MOGL_Noeud *> TabObjet;
52 _Noeud=new MOGL_Noeud;
53 TabObjet.push_back(_Noeud);
54
55 ifstream Fichier(p_NomFichier);
56
57 if (Fichier.fail())
58 {
59 return false;
60 }
61
62 do
63 {
64 Fichier.getline(chaine,200);
65
66 if (!strncmp(chaine,"Objet",5))
67 {
68 // C'est un objet avec des faces
69
70
71 if (!debut)
72 {
73 if (!Noeud)
74 {
75 ((MOGL_Objet *)ObjetCourant)->AjouterTriangle(Pt[0],Pt[1],Pt[2],Texture);
76 }
77 index_point=0;
78 _MapObjet[NomCourant]=ObjetCourant;
79 if (TabObjet.size()<=NiveauCourant)
80 {
81 TabObjet.push_back(ObjetCourant);
82 }
83 {
84 TabObjet[NiveauCourant]=ObjetCourant;
85 }
86 TabObjet[NiveauCourant-1]->AjouterElement(ObjetCourant);
87 }
88 else
89 {
90 debut=false;
91 }
92 ObjetCourant=new MOGL_Objet;
93 PremiereFace=true;
94
95 // Quelle est le nom ?
96
97 i=0;
98 while(chaine[i]!='"') i++;
99 i++;
100 j=i;
101 while(chaine[j]!='"') j++;
102 strncpy(temp,chaine+i,j-i);
103 temp[j-i]=0;
104 NomCourant=string(temp);
105 Noeud=false;
106 }
107 if (!strncmp(chaine,"Noeud",5))
108 {
109 // C'est un simple noeud sans faces
110
111
112 if (!debut)
113 {
114 if (!Noeud)
115 {
116 ((MOGL_Objet *)ObjetCourant)->AjouterTriangle(Pt[0],Pt[1],Pt[2],Texture);
117 }
118 index_point=0;
119 _MapObjet[NomCourant]=ObjetCourant;
120 if (TabObjet.size()<=NiveauCourant)
121 {
122 TabObjet.push_back(ObjetCourant);
123 }
124 {
125 TabObjet[NiveauCourant]=ObjetCourant;
126 }
127 TabObjet[NiveauCourant-1]->AjouterElement(ObjetCourant);
128
129 }
130 else
131 {
132 debut=false;
133 }
134 ObjetCourant=new MOGL_Noeud;
135 PremiereFace=true;
136
137 // Quelle est le nom ?
138
139 i=0;
140 while(chaine[i]!='"') i++;
141 i++;
142 j=i;
143 while(chaine[j]!='"') j++;
144 strncpy(temp,chaine+i,j-i);
145 temp[j-i]=0;
146 NomCourant=string(temp);
147 Noeud=true;
148 }
149
150 if (!strncmp(chaine,"Niveau",6))
151 {
152 i=0;
153 while(chaine[i]!=':') i++;
154 i++;
155 sscanf(chaine+i,"%i",&NiveauCourant);
156 }
157
158
159 if (!strncmp(chaine,"FACE",4))
160 {
161 if (!PremiereFace)
162 {
163 ((MOGL_Objet *)ObjetCourant)->AjouterTriangle(Pt[0],Pt[1],Pt[2],Texture);
164 }
165 else
166 {
167 PremiereFace=false;
168 }
169 index_point=0;
170 }
171 if (!strncmp(chaine,"Material",8))
172 {
173 // Quelle est la texture ?
174 i=0;
175 while(chaine[i]!='"') i++;
176 i++;
177 j=i;
178 while(chaine[j]!='"') j++;
179 strncpy(temp,chaine+i,j-i);
180 temp[j-i]=0;
181 Texture=p_GM.GetTexture(temp);
182
183 }
184
185 if (!strncmp(chaine,"Vertex",6))
186 { // Lecture des coordonn�es d'un point
187
188 i=0;
189
190 while(chaine[i]!='X') i++;
191 i+=2;
192 sscanf(chaine+i,"%f",&x);
193
194 while(chaine[i]!='Y') i++;
195 i+=2;
196 sscanf(chaine+i,"%f",&y);
197
198 while(chaine[i]!='Z') i++;
199 i+=2;
200 sscanf(chaine+i,"%f",&z);
201
202 while(chaine[i]!='U') i++;
203 i+=2;
204 sscanf(chaine+i,"%f",&u);
205
206 while(chaine[i]!='V') i++;
207 i+=2;
208 sscanf(chaine+i,"%f",&v);
209
210 while(chaine[i]!='x') i++;
211 i+=2;
212 sscanf(chaine+i,"%f",&xn);
213
214 while(chaine[i]!='y') i++;
215 i+=2;
216 sscanf(chaine+i,"%f",&yn);
217
218 while(chaine[i]!='z') i++;
219 i+=2;
220 sscanf(chaine+i,"%f",&zn);
221
222 Pt[index_point].xp=x;
223 Pt[index_point].yp=y;
224 Pt[index_point].zp=z;
225
226 Pt[index_point].xn=xn;
227 Pt[index_point].yn=yn;
228 Pt[index_point].zn=zn;
229
230 Pt[index_point].xt=u;
231 Pt[index_point].yt=v;
232
233 index_point++;
234 }
235 } while(!Fichier.eof());
236 if (!Noeud)
237 {
238 ((MOGL_Objet *)ObjetCourant)->AjouterTriangle(Pt[0],Pt[1],Pt[2],Texture);
239 }
240 _MapObjet[NomCourant]=ObjetCourant;
241 TabObjet[NiveauCourant-1]->AjouterElement(ObjetCourant);
242
243 return true;
244 }
245
ChargerArmaturePeau(char * p_NomFichier,const MOGL_GestionnaireTexture p_GM)246 bool MOGL_EnsembleObjet::ChargerArmaturePeau(char * p_NomFichier, const MOGL_GestionnaireTexture p_GM)
247 {
248 typedef enum{ARMATURE, NOEUD, PEAU} Enum_TypeObjet;
249 Enum_TypeObjet type_objet=NOEUD;
250 char chaine[200];
251 int i,j;
252 char temp[50];
253 float x,y,z,u,v,xn,yn,zn;
254 unsigned int indicePoint;
255 unsigned int numPoint=0;
256 int index_point=0;
257 bool debut=true;
258 bool PremiereFace=true;
259 unsigned int PtNum[3];
260
261 MOGL_Texture * Texture=NULL;
262 MOGL_Noeud * ObjetCourant;
263 MOGL_TrianglePeau Triangle;
264 string NomCourant,NomRef;
265 unsigned int NiveauCourant=0;
266 MOGL_Struct_Vecteur Rotation = {0,0,0};
267 MOGL_Struct_Vecteur Translation = {0,0,0};
268
269 vector <MOGL_Noeud *> TabObjet;
270
271 bool peauRencontre=false;
272
273
274 // Ici le _Noeud de base est un MOGL_Peau
275 _Noeud=new MOGL_Peau;
276
277 TabObjet.push_back(_Noeud);
278
279
280 ifstream Fichier(p_NomFichier);
281
282 if (Fichier.fail())
283 {
284 return false;
285 }
286
287 do
288 {
289 Fichier.getline(chaine,200);
290
291 if (!strncmp(chaine,"Objet",5))
292 {
293 if (!debut)
294 {
295 if (type_objet==PEAU && !PremiereFace)
296 {
297 static_cast<MOGL_Peau *>(ObjetCourant)->AjouterTriangle(Triangle);
298 }
299
300 index_point=0;
301 _MapObjet[NomCourant]=ObjetCourant;
302 if (type_objet==ARMATURE)
303 {
304 MOGL_MatriceTransformation Mat=MOGL_MatriceTransformation::FabriqueRotation(Rotation.x, Rotation.y, Rotation.z);
305 Mat.AjouterTranslation(Translation.x, Translation.y, Translation.z);
306 ((MOGL_Armature *)ObjetCourant)->SetMatriceInitialisation(Mat);
307 ((MOGL_Armature *)ObjetCourant)->ReinitialiserPosition();
308 static_cast<MOGL_Peau*>(_Noeud)->DefinirInvMatriceBase(static_cast<MOGL_Armature*>(ObjetCourant));
309 }
310 if (type_objet!=PEAU)
311 {
312 if (TabObjet.size()<=NiveauCourant)
313 {
314 TabObjet.push_back(ObjetCourant);
315 }
316 {
317 TabObjet[NiveauCourant]=ObjetCourant;
318 }
319 TabObjet[NiveauCourant-1]->AjouterElement(ObjetCourant);
320 }
321 }
322 else
323 {
324 debut=false;
325 }
326 //PremiereFace=true;
327
328 // Quelle est le nom ?
329
330 i=5;
331 while(chaine[i]!='"') i++;
332 i++;
333 j=i;
334 while(chaine[j]!='"') j++;
335 strncpy(temp,chaine+i,j-i);
336 temp[j-i]=0;
337 NomCourant=string(temp);
338 numPoint=0;
339 }
340 if (!strncmp(chaine,"Niveau",6))
341 {
342 i=6;
343 while(chaine[i]!=':') i++;
344 i++;
345 sscanf(chaine+i,"%i",&NiveauCourant);
346 }
347
348 if (!strncmp(chaine,"Bone",4))
349 {
350 ObjetCourant=new MOGL_Armature();
351 type_objet=ARMATURE;
352 }
353
354 if (!strncmp(chaine,"Skin",4))
355 {
356 if (!peauRencontre)
357 {
358 ObjetCourant=_Noeud;
359 type_objet=PEAU;
360 PremiereFace=true;
361 peauRencontre=true;
362 }
363 else
364 {
365 cerr<<"The file contains two skin objects, which is impossinble!"<<endl;
366 return false;
367 }
368 }
369
370 if (!strncmp(chaine,"Noeud",5))
371 {
372 ObjetCourant=new MOGL_Noeud();
373 type_objet=NOEUD;
374 }
375
376 if (!strncmp(chaine,"Rotation",8))
377 {
378 // Lecture de la rotation
379 i=8;
380
381 while(chaine[i]!='X') i++;
382 i+=2;
383 sscanf(chaine+i,"%f",&x);
384
385 while(chaine[i]!='Y') i++;
386 i+=2;
387 sscanf(chaine+i,"%f",&y);
388
389 while(chaine[i]!='Z') i++;
390 i+=2;
391 sscanf(chaine+i,"%f",&z);
392
393 Rotation.x=x;
394 Rotation.y=y;
395 Rotation.z=z;
396 }
397 if (!strncmp(chaine,"Translation",11))
398 {
399 // Lecture de la translation
400 i=11;
401
402 while(chaine[i]!='X') i++;
403 i+=2;
404 sscanf(chaine+i,"%f",&x);
405
406 while(chaine[i]!='Y') i++;
407 i+=2;
408 sscanf(chaine+i,"%f",&y);
409
410 while(chaine[i]!='Z') i++;
411 i+=2;
412 sscanf(chaine+i,"%f",&z);
413
414 Translation.x=x;
415 Translation.y=y;
416 Translation.z=z;
417 }
418
419 if (!strncmp(chaine,"POINT",5))
420 {
421 // Lecture des coordonn�es d'un point
422 // pour un objet normal
423 i=5;
424
425 while(chaine[i]!='X') i++;
426 i+=2;
427 sscanf(chaine+i,"%f",&x);
428
429 while(chaine[i]!='Y') i++;
430 i+=2;
431 sscanf(chaine+i,"%f",&y);
432
433 while(chaine[i]!='Z') i++;
434 i+=2;
435 sscanf(chaine+i,"%f",&z);
436
437 while(chaine[i]!='x') i++;
438 i+=2;
439 sscanf(chaine+i,"%f",&xn);
440
441 while(chaine[i]!='y') i++;
442 i+=2;
443 sscanf(chaine+i,"%f",&yn);
444
445 while(chaine[i]!='z') i++;
446 i+=2;
447 sscanf(chaine+i,"%f",&zn);
448
449 switch (type_objet)
450 {
451 case ARMATURE :
452 {
453 static_cast<MOGL_Armature*>(ObjetCourant)->AjouterPoint(numPoint,x,y,z,xn,yn,zn);
454 numPoint++;
455 break;
456 }
457 case PEAU :
458 {
459 static_cast<MOGL_Peau*>(ObjetCourant)->AjouterPoint(numPoint,x,y,z,xn,yn,zn);
460 numPoint++;
461 break;
462 }
463 case NOEUD :
464 {
465 cerr<<"A node can't contain points!"<<endl;
466 }
467 }
468 }
469
470 if (!strncmp(chaine,"FACE",4))
471 {
472 if (!PremiereFace)
473 {
474 static_cast<MOGL_Peau *>(ObjetCourant)->AjouterTriangle(Triangle);
475 }
476 else
477 {
478 PremiereFace=false;
479 }
480 index_point=0;
481 Triangle.Reinitialiser();
482 }
483
484 if (!strncmp(chaine,"Material",8))
485 {
486 // Quelle est la texture ?
487 i=8;
488 while(chaine[i]!='"') i++;
489 i++;
490 j=i;
491 while(chaine[j]!='"') j++;
492 strncpy(temp,chaine+i,j-i);
493 temp[j-i]=0;
494 Texture=p_GM.GetTexture(temp);
495 if (Texture==NULL)
496 {
497 cerr<<"Texture not found"<<endl;
498 }
499 Triangle.SetTexture(Texture);
500 }
501
502 if (!strncmp(chaine,"Vertex",6))
503 {
504 // Lecture des coordonn�es d'un point
505 i=6;
506
507 while(chaine[i]!='P') i++;
508 i++;
509 int indice_ref;
510
511 if (chaine[i]=='E')
512 {
513 // C'est une r�f�rence externe
514 i+=2;
515 sscanf(chaine+i,"%i",&indice_ref);
516
517 while(chaine[i]!='"') i++;
518 i++;
519 j=i;
520 while(chaine[j]!='"') j++;
521 strncpy(temp,chaine+i,j-i);
522 temp[j-i]=0;
523
524 Triangle.SetPoint(index_point, (MOGL_Armature *)_MapObjet[temp], indice_ref-1);
525 }
526 else
527 {
528 // C'est une r�f�rence interne
529 i+=2;
530 sscanf(chaine+i,"%i",&indice_ref);
531
532 Triangle.SetPoint(index_point, indice_ref-1);
533 }
534
535 i+=2;
536 sscanf(chaine+i,"%i",&indicePoint);
537
538 while(chaine[i]!='U') i++;
539 i+=2;
540 sscanf(chaine+i,"%f",&u);
541
542 while(chaine[i]!='V') i++;
543 i+=2;
544 sscanf(chaine+i,"%f",&v);
545
546 PtNum[index_point]=indicePoint-1;
547
548 MOGL_Struct_PointTexture PtText;
549 PtText.xt=u;
550 PtText.yt=v;
551 Triangle.SetPointTexture(index_point, PtText);
552
553 index_point++;
554 }
555
556 } while(!Fichier.eof());
557
558 if (!peauRencontre)
559 {
560 cerr<<"The file doesn't contain a skin! That's impossible!"<<endl;
561 return false;
562 }
563
564 if (type_objet==PEAU && !PremiereFace)
565 {
566 static_cast<MOGL_Peau *>(ObjetCourant)->AjouterTriangle(Triangle);
567 }
568
569 if (type_objet==ARMATURE)
570 {
571 MOGL_MatriceTransformation Mat=MOGL_MatriceTransformation::FabriqueRotation(Rotation.x, Rotation.y, Rotation.z);
572 Mat.AjouterTranslation(Translation.x, Translation.y, Translation.z);
573 ((MOGL_Armature *)ObjetCourant)->SetMatriceInitialisation(Mat);
574 ((MOGL_Armature *)ObjetCourant)->ReinitialiserPosition();
575 static_cast<MOGL_Peau*>(_Noeud)->DefinirInvMatriceBase(static_cast<MOGL_Armature*>(ObjetCourant));
576
577 }
578 if (type_objet!=PEAU)
579 {
580 _MapObjet[NomCourant]=ObjetCourant;
581 TabObjet[NiveauCourant-1]->AjouterElement(ObjetCourant);
582 }
583
584
585 return true;
586 }
587
588
ChargerAnimation(char * p_NomFichier,char * p_NomAnimation)589 bool MOGL_EnsembleObjet::ChargerAnimation(char * p_NomFichier, char * p_NomAnimation)
590 {
591 char chaine[200];
592 int i,j;
593 char temp[50];
594 //float x,y,z,u,v,xn,yn,zn;
595 float t,x,y,z;
596 int index_point=0;
597 bool debut=true;
598 MOGL_Noeud * NoeudCourant;
599 MOGL_Animation * AnimationCourant=NULL;
600 MOGL_GroupeAnimation * GroupeAnimation=new MOGL_GroupeAnimation;
601 string NomCourant;
602
603
604 ifstream Fichier(p_NomFichier);
605
606 if (Fichier.fail())
607 {
608 return false;
609 }
610
611 do
612 {
613 Fichier.getline(chaine,200);
614
615 if (!strncmp(chaine,"Nom",3))
616 {
617 // Quelle est le nom ?
618
619 if (!debut)
620 {
621 GroupeAnimation->AjouterAnimation(AnimationCourant);
622 }
623 else
624 {
625 debut=false;
626 }
627
628 //PremiereFace=true;
629 i=0;
630 while(chaine[i]!='"') i++;
631 i++;
632 j=i;
633 while(chaine[j]!='"') j++;
634 strncpy(temp,chaine+i,j-i);
635 temp[j-i]=0;
636 NomCourant=string(temp);
637 NoeudCourant=_MapObjet[NomCourant];
638 AnimationCourant=new MOGL_Animation(NoeudCourant);
639 }
640
641
642
643 if (!strncmp(chaine,"Rotation",8))
644 {
645 // Lecture de la rotation
646 i=8;
647
648 while(chaine[i]!='T') i++;
649 i+=2;
650 sscanf(chaine+i,"%f",&t);
651
652 while(chaine[i]!='X') i++;
653 i+=2;
654 sscanf(chaine+i,"%f",&x);
655
656 while(chaine[i]!='Y') i++;
657 i+=2;
658 sscanf(chaine+i,"%f",&y);
659
660 while(chaine[i]!='Z') i++;
661 i+=2;
662 sscanf(chaine+i,"%f",&z);
663
664 index_point++;
665
666 MOGL_Struct_Vecteur vect;
667 vect.x=x;
668 vect.y=y;
669 vect.z=z;
670
671 AnimationCourant->AjouterClefRotation(t,vect);
672 }
673 if (!strncmp(chaine,"Translation",11))
674 {
675 // Lecture de la translation
676 i=11;
677
678 while(chaine[i]!='T') i++;
679 i+=2;
680 sscanf(chaine+i,"%f",&t);
681
682 while(chaine[i]!='X') i++;
683 i+=2;
684 sscanf(chaine+i,"%f",&x);
685
686 while(chaine[i]!='Y') i++;
687 i+=2;
688 sscanf(chaine+i,"%f",&y);
689
690 while(chaine[i]!='Z') i++;
691 i+=2;
692 sscanf(chaine+i,"%f",&z);
693
694 index_point++;
695
696 MOGL_Struct_Vecteur vect;
697 vect.x=x;
698 vect.y=y;
699 vect.z=z;
700
701 AnimationCourant->AjouterClefTranslation(t,vect);
702 }
703 } while(!Fichier.eof());
704 GroupeAnimation->AjouterAnimation(AnimationCourant);
705
706 _MapGroupeAnimation[p_NomAnimation]=GroupeAnimation;
707
708 return true;
709 }
710
711
DebuterAnimation(char * p_NomAnim)712 void MOGL_EnsembleObjet::DebuterAnimation(char * p_NomAnim)
713 {
714 MOGL_ItMap_GroupeAnimation itGAnim=_MapGroupeAnimation.find(p_NomAnim);
715 if (itGAnim!=_MapGroupeAnimation.end())
716 {
717 _ListeAnimCourante.insert(p_NomAnim);
718 itGAnim->second->SetUniteTemps(0.5);
719 itGAnim->second->Initialiser();
720 }
721
722 }
723
Animer()724 void MOGL_EnsembleObjet::Animer()
725 {
726 for(MOGL_ItSet_String it=_ListeAnimCourante.begin(); it!=_ListeAnimCourante.end(); it++)
727 {
728 MOGL_ItMap_GroupeAnimation itGAnim=_MapGroupeAnimation.find(*it);
729 if (itGAnim!=_MapGroupeAnimation.end())
730 {
731 if (!itGAnim->second->SetTemps())
732 {
733 itGAnim->second->Initialiser();
734 }
735 }
736 }
737 }
738
GetNoeudPrincipal()739 MOGL_Noeud * MOGL_EnsembleObjet::GetNoeudPrincipal()
740 {
741 return _Noeud;
742 }
743
GetNoeud(char * p_Nom)744 MOGL_Noeud * MOGL_EnsembleObjet::GetNoeud(char * p_Nom)
745 {
746 MOGL_ItMap_Noeud it;
747 it=_MapObjet.find(p_Nom);
748 if (it!=_MapObjet.end())
749 return it->second;
750 else
751 return NULL;
752 }
753