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