Merge branch '138-toggle-free-look-with-hotkey' into main/gingo-test
[ryzomcore.git] / ryzom / client / src / scene_parser.cpp
blob484c00129da9847aef048d467ca4d54c78462540
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include "stdpch.h"
22 /////////////
23 // INCLUDE //
24 /////////////
25 // Misc.
26 #include "nel/misc/path.h"
27 #include "nel/misc/debug.h"
28 #include "nel/misc/matrix.h"
29 // 3D Interface.
30 #include "nel/3d/u_driver.h"
31 #include "nel/3d/u_scene.h"
32 #include "nel/3d/u_play_list.h"
33 #include "nel/3d/u_track.h"
34 #include "nel/3d/u_camera.h"
35 // Client.
36 #include "scene_parser.h"
37 #include "entities.h"
38 #include "entity_cl.h"
39 #include "animated_scene_object.h"
40 #include "ig_client.h"
41 #include "user_controls.h"
42 #include "time_client.h"
43 // Game Share
44 #include "game_share/entity.h"
47 ///////////
48 // USING //
49 ///////////
50 using namespace NLMISC;
51 using namespace NL3D;
52 using namespace std;
55 ////////////
56 // EXTERN //
57 ////////////
58 extern UDriver *Driver;
59 extern UScene *Scene;
60 extern UScene *SceneRoot;
63 /////////////
64 // METHODS //
65 /////////////
66 const uint CSceneParser::MAX_LINE_SIZE = 500;
67 const char *CSceneParser::delimiter = " \t";
69 //-----------------------------------------------
70 // CSceneParser :
71 // Constructor.
72 //-----------------------------------------------
73 CSceneParser::CSceneParser()
75 _FrameRate = 30.0;
76 _Line = 0;
77 _AnimationSet = 0;
78 _TimeStart = -1;
79 _AnimationSet = 0;
80 _Apply = false;
81 _Day = true;
83 _ItScene = _Scene.end();
84 _SceneStart = -1.f;
85 }// CSceneParser //
88 //-----------------------------------------------
89 // load :
90 // Load the file with the scene.
91 //-----------------------------------------------
92 void CSceneParser::load(const string &filename)
94 // Look for the file -> nlwarning and return if sceneFile is empty.
95 string sceneFile = CPath::lookup(filename, false);
96 if(sceneFile.empty())
98 nlwarning("CSceneParser::load : Can't find file \"%s\".", filename.c_str());
99 return;
102 // Open the file.
103 ifstream file(sceneFile.c_str(), ios::in);
104 if(file.is_open())
106 // Load the capture speed.
107 ifstream speedFile("capture_speed.txt", ios::in);
108 if(speedFile.is_open())
110 char tmpBuff[MAX_LINE_SIZE];
112 // Set the default fram rate (30fps).
113 _FrameRate = 30.0;
115 // Init Lines.
116 _Line = 0;
118 // While the end of the file is not reached -> parse the script.
119 while(!speedFile.eof())
121 // Get next valid line.
122 getNextValidLine(speedFile, tmpBuff);
124 char *ptr = strtok(tmpBuff, delimiter);
125 if(ptr != NULL)
126 NLMISC::fromString(ptr, _FrameRate);
129 // Close the speed file.
130 speedFile.close();
132 else
133 nlwarning("CSceneParser::load : 'capture_speed.txt' can't be open, default frame rate is %f.", _FrameRate);
135 // Init Lines.
136 _Line = 0;
138 // Parse the File.
139 parse(file);
141 // Initialize Actors Position and rotation .
142 initActors();
144 // Close the File.
145 file.close();
147 else
149 nlwarning("CSceneParser::load : File \"%s\" can't be open.", sceneFile.c_str());
150 return;
152 }// load //
155 //-----------------------------------------------
156 // parse :
157 // Parse the file.
158 //-----------------------------------------------
159 void CSceneParser::parse(ifstream &file)
161 char tmpBuff[MAX_LINE_SIZE];
163 // While the end of the file is not reached -> parse the script.
164 while(!file.eof())
166 // Get next valid line.
167 getNextValidLine(file, tmpBuff);
169 char *ptr = strtok(tmpBuff, delimiter);
170 if(ptr != NULL)
172 // Time (Day/Night)
173 if(strcmp(ptr, "Time:") == 0)
174 parseTime();
176 // Filename of the File with all IG to load for the scene.
177 else if(strcmp(ptr, "IG:") == 0)
178 parseIG(file, tmpBuff);
180 // Ig for the init.
181 else if(strcmp(ptr, "IG_Init:") == 0)
182 parseIGInit();
184 // Particle.
185 else if(strcmp(ptr, "Particle:") == 0)
186 parseParticle(file, tmpBuff);
188 // Actor.
189 else if(strcmp(ptr, "Actor:") == 0)
190 parseActor(file, tmpBuff);
192 // Camera.
193 else if(strcmp(ptr, "Camera:") == 0)
194 parseCamAnims(file, tmpBuff);
196 // Action.
197 else if(strcmp(ptr, "Sequence:") == 0)
198 parseSequence(file, tmpBuff);
200 // Bad Keyword
201 else
202 nlwarning("Unknown keyword '%s' at line %d.", ptr, _Line);
205 }// parse //
208 //-----------------------------------------------
209 // getNextValidLine :
210 // Skip empty lines and comment lines.
211 //-----------------------------------------------
212 void CSceneParser::getNextValidLine(ifstream &file, char *buff)
214 while(!file.eof())
216 // Get the line.
217 file.getline(buff, MAX_LINE_SIZE);
219 // Increase line nnumber.
220 _Line++;
222 // Skip comments.
223 if(buff[0] != 0)
225 // First char is not the beginning of a comment.
226 if(buff[0] != '/')
227 break;
228 // Second char is not the end of a coment.
229 else if(buff[1] != '/')
230 break;
233 }// getNextValidLine //
236 //-----------------------------------------------
237 // parseTime :
238 // Day or Night.
239 //-----------------------------------------------
240 void CSceneParser::parseTime()
242 char *ptr = strtok(NULL, delimiter);
243 if(ptr != NULL)
245 if(atoi(ptr))
246 _Day = true;
247 else
248 _Day = false;
250 }// parseTime //
252 //-----------------------------------------------
253 // parseIG :
254 // Parse the list of IG to load for the scene
255 //-----------------------------------------------
256 void CSceneParser::parseIG(ifstream &file, char *buff)
258 while(!file.eof())
260 // Get next valid line.
261 getNextValidLine(file, buff);
263 char *ptr = strtok(buff, delimiter);
264 if(ptr != NULL)
266 // End of the actor definition.
267 if(strcmp(ptr, "End_IG") == 0)
268 break;
269 // IG Name.
270 else
271 _IG.push_back(ptr);
274 }// parseIG //
276 //-----------------------------------------------
277 // parseIGInit :
278 // Get the name of the IG to initialize entities.
279 //-----------------------------------------------
280 void CSceneParser::parseIGInit()
282 char *ptr = strtok(NULL, delimiter);
283 if(ptr != NULL)
284 _IG_Init = ptr;
285 }// parseIGInit //
288 ///////////////
289 // PARTICLES //
290 //-----------------------------------------------
291 // parseParticle :
292 // Parse Particle.
293 //-----------------------------------------------
294 void CSceneParser::parseParticle(ifstream &file, char *buff)
296 // Reset the current particle.
297 _CurrentParticle.reset();
299 while(!file.eof())
301 // Get next valid line.
302 getNextValidLine(file, buff);
304 char *ptr = strtok(buff, delimiter);
305 if(ptr != NULL)
307 // End of the actor definition.
308 if(strcmp(ptr, "End_Particle") == 0)
309 break;
311 // Particle's Id
312 else if(strcmp(ptr, "Id:") == 0)
313 parseParticleId();
315 // Particle's IG
316 else if(strcmp(ptr, "IG:") == 0)
317 parseParticleIG();
319 // Particle's Cluster
320 else if(strcmp(ptr, "Cluster:") == 0)
321 parseParticleCluster();
323 // Actor father of the particle is there is one.
324 else if(strcmp(ptr, "Actor:") == 0)
325 parseParticleActor();
327 // Particle's Anims
328 else if(strcmp(ptr, "Anims:") == 0)
329 parseParticleAnims(file, buff);
331 // Bad Keyword
332 else
333 nlwarning("Unknown keyword '%s' at line %d.", ptr, _Line);
337 // If the current particle Id is Valid -> create the particle.
338 if(_CurrentParticle.Id >= 0)
340 map<uint, CParticle>::iterator it = _Particles.find((uint)_CurrentParticle.Id);
341 // Id already exists.
342 if(it != _Particles.end())
343 nlwarning("Particle before line %d has the ID %d that already exists -> Particle Not Created.", _Line, _CurrentParticle.Id);
344 // Insert the new Particle.
345 else
346 _Particles.insert(make_pair((uint)_CurrentParticle.Id, _CurrentParticle));
348 else
349 nlwarning("Particle before line %d has no ID or a Bad one -> Particle Not Created.", _Line);
350 }// parseParticle //
352 //-----------------------------------------------
353 // parseParticleId :
354 // Parse Particle's Id.
355 //-----------------------------------------------
356 void CSceneParser::parseParticleId()
358 char *ptr = strtok(NULL, delimiter);
359 if(ptr != NULL)
360 _CurrentParticle.Id = atoi(ptr);
361 }// parseParticleId //
363 //-----------------------------------------------
364 // parseParticleIG :
365 // Parse Particle's IG.
366 //-----------------------------------------------
367 void CSceneParser::parseParticleIG()
369 char *ptr = strtok(NULL, delimiter);
370 if(ptr != NULL)
371 _CurrentParticle.IG = ptr;
372 }// parseParticleIG //
374 //-----------------------------------------------
375 // parseParticleCluster :
376 // Parse Particle's Cluster.
377 //-----------------------------------------------
378 void CSceneParser::parseParticleCluster()
380 char *ptr = strtok(NULL, delimiter);
381 if(ptr != NULL)
382 _CurrentParticle.Cluster = ptr;
383 }// parseParticleCluster //
385 //-----------------------------------------------
386 // parseParticleActor :
387 // Parse Particle's Actor.
388 //-----------------------------------------------
389 void CSceneParser::parseParticleActor()
391 char *ptr = strtok(NULL, delimiter);
392 if(ptr != NULL)
393 _CurrentParticle.Actor = atoi(ptr);
394 }// parseParticleActor //
396 //-----------------------------------------------
397 // parseParticleAnims :
398 // Parse Particle's anims.
399 //-----------------------------------------------
400 void CSceneParser::parseParticleAnims(ifstream &file, char *buff)
402 while(!file.eof())
404 // Get next valid line.
405 getNextValidLine(file, buff);
407 char *ptr = strtok(buff, delimiter);
408 if(ptr != NULL)
410 // End of the actor definition.
411 if(strcmp(ptr, "End_Anims") == 0)
412 break;
413 // Meshes Name.
414 else
415 _CurrentParticle.Anims.push_back(ptr);
418 }// parseParticleAnims //
421 ////////////
422 // ACTORS //
423 //-----------------------------------------------
424 // parseActor :
425 // Parse an actor.
426 //-----------------------------------------------
427 void CSceneParser::parseActor(ifstream &file, char *buff)
429 // Reset the current actor.
430 _CurrentActor.reset();
432 while(!file.eof())
434 // Get next valid line.
435 getNextValidLine(file, buff);
437 char *ptr = strtok(buff, delimiter);
438 if(ptr != NULL)
440 // End of the actor definition.
441 if(strcmp(ptr, "End_Actor") == 0)
442 break;
444 // Actor's Id
445 else if(strcmp(ptr, "Id:") == 0)
446 parseId();
448 // Actor's Name
449 else if(strcmp(ptr, "Name:") == 0)
450 parseName();
452 // Is the Actor a flyer.
453 else if(strcmp(ptr, "Fly:") == 0)
454 parseFly();
456 // Actor father of the particle is there is one.
457 else if(strcmp(ptr, "Actor:") == 0)
458 parseActorActor();
460 // Actor's Skeleton
461 else if(strcmp(ptr, "Skel:") == 0)
462 parseSkel();
464 // Actor's Meshes
465 else if(strcmp(ptr, "Meshes:") == 0)
466 parseMeshes(file, buff);
468 // Actor's Anims
469 else if(strcmp(ptr, "Anims:") == 0)
470 parseAnims(file, buff);
472 // Bad Keyword
473 else
474 nlwarning("Unknown keyword '%s' at line %d.", ptr, _Line);
478 // If the current actor Id is Valid -> create the actor.
479 if(_CurrentActor.Id >= 0)
481 map<uint, CActor>::iterator it = _Actors.find((uint)_CurrentActor.Id);
482 // Id already exists.
483 if(it != _Actors.end())
484 nlwarning("Actor before line %d has the ID %d that already exists -> Actor Not Created.", _Line, _CurrentActor.Id);
485 // Insert the new actor.
486 else
487 _Actors.insert(make_pair((uint)_CurrentActor.Id, _CurrentActor));
489 else
490 nlwarning("Actor before line %d has no ID or a Bad one -> Actor Not Created.", _Line);
491 }// parseActor //
493 //-----------------------------------------------
494 // parseId :
495 // Parse the current actor Id.
496 //-----------------------------------------------
497 void CSceneParser::parseId()
499 char *ptr = strtok(NULL, delimiter);
500 if(ptr != NULL)
501 _CurrentActor.Id = atoi(ptr);
502 }// parseId //
504 //-----------------------------------------------
505 // parseName :
506 // Parse the current actor Name.
507 //-----------------------------------------------
508 void CSceneParser::parseName()
510 char *ptr = strtok(NULL, delimiter);
511 if(ptr != NULL)
512 _CurrentActor.Name = ptr;
513 }// parseName //
515 //-----------------------------------------------
516 // parseFly :
517 // Is the Actor a flyer.
518 //-----------------------------------------------
519 void CSceneParser::parseFly()
521 char *ptr = strtok(NULL, delimiter);
522 if(ptr != NULL)
524 if(atoi(ptr))
525 _CurrentActor.Fly = true;
526 else
527 _CurrentActor.Fly = false;
529 }// parseFly //
531 //-----------------------------------------------
532 // parseActorActor :
533 // Parse Actor's Actor.
534 //-----------------------------------------------
535 void CSceneParser::parseActorActor()
537 char *ptr = strtok(NULL, delimiter);
538 if(ptr != NULL)
540 _CurrentActor.Actor = atoi(ptr);
541 nlwarning("Actor: %d Follow : %d", _CurrentActor.Id, _CurrentActor.Actor);
543 }// parseActorActor //
545 //-----------------------------------------------
546 // parseSkel :
547 // Parse the current actor Skeleton Name.
548 //-----------------------------------------------
549 void CSceneParser::parseSkel()
551 char *ptr = strtok(NULL, delimiter);
552 if(ptr != NULL)
553 _CurrentActor.Skeleton = ptr;
554 }// parseSkel //
556 //-----------------------------------------------
557 // parseMeshes :
558 // Parse meshes used for the current actor.
559 //-----------------------------------------------
560 void CSceneParser::parseMeshes(ifstream &file, char *buff)
562 while(!file.eof())
564 // Get next valid line.
565 getNextValidLine(file, buff);
567 char *ptr = strtok(buff, delimiter);
568 if(ptr != NULL)
570 // End of the actor definition.
571 if(strcmp(ptr, "End_Meshes") == 0)
572 break;
573 // Meshes Name.
574 else
575 _CurrentActor.Meshes.push_back(ptr);
578 }// parseMeshes //
580 //-----------------------------------------------
581 // parseAnims :
582 // Parse anims used for the current actor.
583 //-----------------------------------------------
584 void CSceneParser::parseAnims(ifstream &file, char *buff)
586 while(!file.eof())
588 // Get next valid line.
589 getNextValidLine(file, buff);
591 char *ptr = strtok(buff, delimiter);
592 if(ptr != NULL)
594 // End of the actor definition.
595 if(strcmp(ptr, "End_Anims") == 0)
596 break;
597 // Meshes Name.
598 else
599 _CurrentActor.Anims.push_back(ptr);
602 }// parseAnims //
605 ////////////
606 // CAMERA //
607 //-----------------------------------------------
608 // parseCamAnims :
609 // Parse all anims used for the camera in all sequence.
610 //-----------------------------------------------
611 void CSceneParser::parseCamAnims(ifstream &file, char *buff)
613 while(!file.eof())
615 // Get next valid line.
616 getNextValidLine(file, buff);
618 char *ptr = strtok(buff, delimiter);
619 if(ptr != NULL)
621 // End of Anims for the camera.
622 if(strcmp(ptr, "End_Camera") == 0)
623 break;
624 // Meshes Name.
625 else
626 _CamAnims.push_back(ptr);
629 }// parseCamAnims //
632 ///////////////
633 // SEQUENCES //
634 //-----------------------------------------------
635 // parseSequence :
636 // Parse a sequence.
637 //-----------------------------------------------
638 void CSceneParser::parseSequence(ifstream &file, char *buff)
640 // Reset the current sequence.
641 _CurrentSequence.reset();
643 while(!file.eof())
645 // Get next valid line.
646 getNextValidLine(file, buff);
648 char *ptr = strtok(buff, delimiter);
649 if(ptr != NULL)
651 // End of the actor definition.
652 if(strcmp(ptr, "End_Sequence") == 0)
653 break;
655 // Sequence Id.
656 else if(strcmp(ptr, "Id:") == 0)
657 parseSeqId();
659 // Particle for the sequence.
660 else if(strcmp(ptr, "Particle:") == 0)
661 parseSeqParticle(file, buff);
663 // Actor for the sequence.
664 else if(strcmp(ptr, "Actor:") == 0)
665 parseSeqActor(file, buff);
667 // Camera for the sequence.
668 else if(strcmp(ptr, "Camera:") == 0)
669 parseSeqCam(file, buff);
671 // Bad Keyword
672 else
673 nlwarning("Unknown keyword '%s' at line %d.", ptr, _Line);
677 // If the sequence Id is Valid -> create the sequence.
678 if(_CurrentSequence.Id >= 0)
680 map<uint, CSequence>::iterator itSeq = _Sequences.find((uint)_CurrentSequence.Id);
681 // Id already exists.
682 if(itSeq != _Sequences.end())
683 nlwarning("Sequence before line %d has the ID %d that already exists -> Sequence Not Created.", _Line, _CurrentSequence.Id);
684 // Insert the new actor.
685 else
686 _Sequences.insert(make_pair((uint)_CurrentSequence.Id, _CurrentSequence));
688 else
689 nlwarning("Sequence before line %d has no ID or a Bad one -> Sequence Not Created.", _Line);
690 }// parseSequence //
692 //-----------------------------------------------
693 // parseSeqId :
694 // Parse the current sequence Id.
695 //-----------------------------------------------
696 void CSceneParser::parseSeqId()
698 char *ptr = strtok(NULL, delimiter);
699 if(ptr != NULL)
700 _CurrentSequence.Id = atoi(ptr);
701 }// parseSeqId //
703 //-----------------------------------------------
704 // parseSeqParticle :
705 // Parse particle in the sequence.
706 //-----------------------------------------------
707 void CSceneParser::parseSeqParticle(ifstream &file, char *buff)
709 // Reset the current particle in the sequence.
710 _CurParticleSeq.reset();
712 while(!file.eof())
714 // Get next valid line.
715 getNextValidLine(file, buff);
717 char *ptr = strtok(buff, delimiter);
718 if(ptr != NULL)
720 // End of the actor definition.
721 if(strcmp(ptr, "End_Particle") == 0)
722 break;
724 // Actor in Sequence Id.
725 else if(strcmp(ptr, "Id:") == 0)
726 parseSeqParticleId();
728 // Actor in Sequence anims.
729 else if(strcmp(ptr, "Anims:") == 0)
730 parseSeqParticleAnims(file, buff);
732 // Bad Keyword
733 else
734 nlwarning("Unknown keyword '%s' at line %d.", ptr, _Line);
738 // If the particle's Id in the sequence is Valid -> create the particleSeq.
739 if(_CurParticleSeq.Id >= 0)
741 map<uint, CParticleSeq>::iterator itPartSeq = _CurrentSequence.ParticlesSeq.find((uint)_CurParticleSeq.Id);
742 // Id already exists.
743 if(itPartSeq != _CurrentSequence.ParticlesSeq.end())
744 nlwarning("Particle in Sequence before line %d has the ID %d that already exists -> Particle in the sequence Not Created.", _Line, _CurParticleSeq.Id);
745 // Insert the new particle in the sequence.
746 else
747 _CurrentSequence.ParticlesSeq.insert(make_pair((uint)_CurParticleSeq.Id, _CurParticleSeq));
749 else
750 nlwarning("Particle in Sequence before line %d has no ID or a Bad one -> Particle in the sequence Not Created.", _Line);
751 }// parseSeqParticle //
753 //-----------------------------------------------
754 // parseSeqParticleId :
755 // Parse the current particle's Id in the current sequence.
756 //-----------------------------------------------
757 void CSceneParser::parseSeqParticleId()
759 char *ptr = strtok(NULL, delimiter);
760 if(ptr != NULL)
761 _CurParticleSeq.Id = atoi(ptr);
762 }// parseSeqParticleId //
764 //-----------------------------------------------
765 // parseSeqParticleAnims :
766 // Parse anims used for the current particle in the current sequence.
767 //-----------------------------------------------
768 void CSceneParser::parseSeqParticleAnims(ifstream &file, char *buff)
770 while(!file.eof())
772 // Get next valid line.
773 getNextValidLine(file, buff);
775 char *ptr = strtok(buff, delimiter);
776 if(ptr != NULL)
778 // End of the actor definition.
779 if(strcmp(ptr, "End_Anims") == 0)
780 break;
781 // Meshes Name.
782 else
783 _CurParticleSeq.Anims.push_back(ptr);
786 }// parseSeqParticleAnims //
788 //-----------------------------------------------
789 // parseSeqActor :
790 // Parse an actor in a sequence.
791 //-----------------------------------------------
792 void CSceneParser::parseSeqActor(ifstream &file, char *buff)
794 // Reset the current sequence.
795 _CurrentActorSeq.reset();
797 while(!file.eof())
799 // Get next valid line.
800 getNextValidLine(file, buff);
802 char *ptr = strtok(buff, delimiter);
803 if(ptr != NULL)
805 // End of the actor definition.
806 if(strcmp(ptr, "End_Actor") == 0)
807 break;
809 // Actor in Sequence Id.
810 else if(strcmp(ptr, "Id:") == 0)
811 parseSeqActorId();
813 // Actor in Sequence anims.
814 else if(strcmp(ptr, "Anims:") == 0)
815 parseSeqActorAnims(file, buff);
817 // Bad Keyword
818 else
819 nlwarning("Unknown keyword '%s' at line %d.", ptr, _Line);
823 // If the actor's Id in the sequence is Valid -> create the actorSeq.
824 if(_CurrentActorSeq.Id >= 0)
826 map<uint, CActorSeq>::iterator itActSeq = _CurrentSequence.ActorsSeq.find((uint)_CurrentActorSeq.Id);
827 // Id already exists.
828 if(itActSeq != _CurrentSequence.ActorsSeq.end())
829 nlwarning("Actor in Sequence before line %d has the ID %d that already exists -> Actor in the sequence Not Created.", _Line, _CurrentActorSeq.Id);
830 // Insert the new actor.
831 else
832 _CurrentSequence.ActorsSeq.insert(make_pair((uint)_CurrentActorSeq.Id, _CurrentActorSeq));
834 else
835 nlwarning("Actor in Sequence before line %d has no ID or a Bad one -> Actor in the sequence Not Created.", _Line);
836 }// parseSeqActor //
838 //-----------------------------------------------
839 // parseSeqActorId :
840 // Parse the current actor's Id in the current sequence.
841 //-----------------------------------------------
842 void CSceneParser::parseSeqActorId()
844 char *ptr = strtok(NULL, delimiter);
845 if(ptr != NULL)
846 _CurrentActorSeq.Id = atoi(ptr);
847 }// parseSeqActorId //
849 //-----------------------------------------------
850 // parseSeqActorAnims :
851 // Parse anims used for the current actor in the current sequence.
852 //-----------------------------------------------
853 void CSceneParser::parseSeqActorAnims(ifstream &file, char *buff)
855 while(!file.eof())
857 // Get next valid line.
858 getNextValidLine(file, buff);
860 char *ptr = strtok(buff, delimiter);
861 if(ptr != NULL)
863 // End of the actor definition.
864 if(strcmp(ptr, "End_Anims") == 0)
865 break;
866 // Meshes Name.
867 else
868 _CurrentActorSeq.Anims.push_back(ptr);
871 }// parseSeqActorAnims //
873 //-----------------------------------------------
874 // parseSeqCam :
875 // Parse camera in the sequence.
876 //-----------------------------------------------
877 void CSceneParser::parseSeqCam(ifstream &file, char *buff)
879 while(!file.eof())
881 // Get next valid line.
882 getNextValidLine(file, buff);
884 char *ptr = strtok(buff, delimiter);
885 if(ptr != NULL)
887 // End of the actor definition.
888 if(strcmp(ptr, "End_Camera") == 0)
889 break;
890 // Meshes Name.
891 else
892 _CurrentSequence.CamAnims.push_back(ptr);
895 }// parseSeqCam //
898 ////////////////
899 // INIT AFTER //
900 //-----------------------------------------------
901 // initActors :
902 // Initialize Actors Position and rotation .
903 //-----------------------------------------------
904 void CSceneParser::initActors()
906 if(_IG_Init.empty())
907 return;
909 // Create the instance group with all start positions and rotations.
910 UInstanceGroup *IGInit = UInstanceGroup::createInstanceGroup(_IG_Init);
911 if(IGInit)
913 int nbInst = IGInit->getNumInstance();
914 map<uint, CActor>::iterator itActor;
915 for(int i = 0; i < nbInst; ++i )
917 sint id = atoi(IGInit->getInstanceName(i).c_str());
918 itActor = _Actors.find(id);
919 if(itActor != _Actors.end())
921 CActor &actor = (*itActor).second;
922 actor.Pos = IGInit->getInstancePos(i);
923 actor.Rot = IGInit->getInstanceRot(i);
925 else
926 nlwarning("CSceneParser::initActors : Actor %d is in the IG \"%s\" but is not in the script.", id, _IG_Init.c_str());
929 // Destroy the IG to initialize (all is already backup now).
930 delete IGInit;
931 IGInit = 0;
933 else
934 nlwarning("CSceneParser::initActors : Can't create the Instance group to initialize actors.");
935 }// initActors ///
938 //////////////
939 // PLAY SEQ //
940 //-----------------------------------------------
941 // apply :
942 // Initialize the scene with the parameters loaded from the script.
943 //-----------------------------------------------
944 void CSceneParser::apply()
946 // If the scene is already initialized -> reset the scene.
947 if(_Apply)
949 reset();
950 return;
953 // Create a play list manager for the scene.
954 _PlayListManager = Scene->createPlayListManager();
956 // Initialize the Camera and reset it the second time.
957 applyCamera();
959 // Initialize IG for the scenery (IG present from start to end like trees or torch.
960 applyIG();
962 // Initialize Particles.
963 applyParticles();
965 // Initialize Actors.
966 applyActors();
968 // Scene already aplly now.
969 _Apply = true;
970 }// apply //
972 //-----------------------------------------------
973 // reset :
974 // Reset the scene.
975 //-----------------------------------------------
976 void CSceneParser::reset()
978 // Camera in scene mode.
979 UserControls.mode(CUserControls::InterfaceMode);
981 // Reset all particles.
982 resetParticles();
984 // Reset all actors.
985 resetActors();
986 }// reset //
988 //-----------------------------------------------
989 // resetParticles :
990 // Reset all particles.
991 //-----------------------------------------------
992 void CSceneParser::resetParticles()
994 map<uint, CParticle>::iterator itPart = _Particles.begin();
995 for(itPart = _Particles.begin(); itPart != _Particles.end(); ++itPart)
997 // Get a reference on the particule.
998 CParticle &particle = (*itPart).second;
1000 // Check if the IG of particles is not already in the scene.
1001 if(particle.IGPtr && _IGInScene.find(particle.IGPtr) != _IGInScene.end())
1003 // Reset the playlist.
1004 particle.PlayList->resetAllChannels();
1006 // Remove from the set with all particle in the scene.
1007 _IGInScene.erase(particle.IGPtr);
1008 // Remove particles from scene.
1009 particle.IGPtr->removeFromScene(*Scene);
1010 Scene->deleteInstanceGroup (particle.IGPtr);
1012 // Load the IG of the particle.
1013 particle.IGPtr = 0;
1017 particle.IGPtr = UInstanceGroup::createInstanceGroup((*itPart).second.IG);
1019 catch(Exception &e){nlwarning("CSceneParser::resetParticles : %s", e.what());}
1022 }// resetParticles //
1024 //-----------------------------------------------
1025 // resetActors :
1026 // Reset all actors.
1027 //-----------------------------------------------
1028 void CSceneParser::resetActors()
1030 // Create new entities from actors
1031 map<uint, CActor>::iterator itActor;
1032 for(itActor = _Actors.begin(); itActor != _Actors.end(); ++itActor)
1034 // Get a reference on the actor.
1035 CActor &actor = (*itActor).second;
1037 // Get the Sid.
1038 Sid entityId(Sid::npc, (uint64)actor.Id);
1040 // Find the actor.
1041 CEntityCL *entity = getEntity(entityId);
1042 if(entity)
1044 // Position the entity.
1045 entity->pacsPos(actor.Pos);
1047 // Position the skeleton at the same position as the entity.
1048 if(entity->skeleton())
1050 entity->skeleton()->setPos(actor.Pos);
1051 entity->skeleton()->setRotQuat(actor.Rot);
1055 // Reset entity animations.
1056 resetAnimatedSceneObject(entityId);
1058 }// resetActors //
1061 //-----------------------------------------------
1062 // applyParticles :
1063 // Initialize the scene with the parameters loaded from the script for particles.
1064 //-----------------------------------------------
1065 void CSceneParser::applyParticles()
1067 map<uint, CParticle>::iterator itPart = _Particles.begin();
1068 for(itPart = _Particles.begin(); itPart != _Particles.end(); ++itPart)
1070 // Get a reference on the particule.
1071 CParticle &particle = (*itPart).second;
1073 // Create the animation set for the particule.
1074 particle.AnimationSet = Driver->createAnimationSet();
1076 // Add animations to the animation set.
1077 list<string>::iterator itPartAnim;
1078 for(itPartAnim = particle.Anims.begin(); itPartAnim != particle.Anims.end(); ++itPartAnim)
1080 uint idAnim = UAnimationSet::NotFound;
1083 idAnim = particle.AnimationSet->addAnimation((*itPartAnim + string(".anim")).c_str(), (*itPartAnim).c_str());
1085 catch(Exception &e) {nlwarning("%s", e.what());}
1087 if(idAnim != UAnimationSet::NotFound)
1089 particle.AnimToId.insert(make_pair((*itPartAnim).c_str(), idAnim));
1091 else
1092 nlwarning("CSceneParser::applyParticles : Anim %s cannot be add in the animation set", (*itPartAnim).c_str());
1095 // Build animation set
1096 particle.AnimationSet->build();
1098 // Create playlist.
1099 particle.PlayList = _PlayListManager->createPlayList(particle.AnimationSet);
1100 if(particle.PlayList)
1102 // Load the IG of the particle.
1103 particle.IGPtr = 0;
1106 particle.IGPtr = UInstanceGroup::createInstanceGroup((*itPart).second.IG);
1108 catch(Exception &e) {nlwarning("%s", e.what());}
1110 if(particle.IGPtr)
1112 // Get the position of Instances in IG.
1113 for(uint i = 0; i < particle.IGPtr->getNumInstance(); ++i )
1114 particle.IGPos.push_back(particle.IGPtr->getInstancePos(i));
1118 }// applyParticles //
1120 //-----------------------------------------------
1121 // applyCamera :
1122 // Initialize the Camera and reset it the second time.
1123 //-----------------------------------------------
1124 void CSceneParser::applyCamera()
1126 // Create the animation set for the camera if not already done.
1127 _AnimationSet = Driver->createAnimationSet();
1128 if(_AnimationSet)
1130 list<string>::iterator itCamAnims;
1131 for(itCamAnims = _CamAnims.begin(); itCamAnims != _CamAnims.end(); ++itCamAnims)
1133 uint idAnim = UAnimationSet::NotFound;
1136 idAnim = _AnimationSet->addAnimation((*itCamAnims + string(".anim")).c_str(), (*itCamAnims).c_str());
1138 catch(Exception &e) {nlwarning("%s", e.what());}
1140 if(idAnim != UAnimationSet::NotFound)
1141 _AnimCamToId.insert(make_pair((*itCamAnims).c_str(), idAnim));
1142 else
1143 nlwarning("CSceneParser::apply : Camera Anim %s cannot be add in the animation set", (*itCamAnims).c_str());
1146 // Build animation set
1147 _AnimationSet->build();
1149 // create playlist
1150 _PlayList = _PlayListManager->createPlayList( _AnimationSet );
1152 else
1153 nlwarning("CSceneParser::apply : AnimationSet cannot be created.");
1154 }// applyCamera //
1156 //-----------------------------------------------
1157 // applyIG :
1158 // Initialize IG for the scenery (IG present from start to end like trees or torch.
1159 //-----------------------------------------------
1160 void CSceneParser::applyIG()
1162 // Load Instances Groups for the scene.
1163 for(list<string>::iterator itIG = _IG.begin(); itIG != _IG.end(); ++itIG)
1165 UInstanceGroup *IGTemp = 0;
1168 IGTemp = UInstanceGroup::createInstanceGroup(*itIG);
1170 catch(Exception &e) {nlwarning("CSceneParser::applyIG : %s", e.what());}
1172 // Add Instance Group in the scene.
1173 if(IGTemp)
1174 IGTemp->addToScene(*Scene, Driver);
1176 }// applyIG //
1178 //-----------------------------------------------
1179 // applyActors :
1180 // Initialize actors.
1181 //-----------------------------------------------
1182 void CSceneParser::applyActors()
1184 // Create new entities from actors
1185 map<uint, CActor>::iterator itActor;
1186 for(itActor = _Actors.begin(); itActor != _Actors.end(); ++itActor)
1188 // Get a reference on the actor.
1189 CActor &actor = (*itActor).second;
1191 // Create the entity Sid.
1192 Sid entityId(Sid::npc, (uint64)actor.Id);
1194 // Create the entity type.
1195 CTypeEntity typeEntity;
1196 typeEntity.TypeInfo.TypeEntity = CTypeEntity::npc;
1197 typeEntity.TypeInfo.Kind = CTypeEntity::zorai;
1198 typeEntity.TypeInfo.Age = CTypeEntity::adult;
1199 typeEntity.TypeInfo.Sex = CTypeEntity::male;
1201 // Create the entity.
1202 CEntityCL *entityTmp = createEntity(entityId, typeEntity);
1203 if(entityTmp)
1205 // Get a reference on the entity.
1206 CEntityCL &entity = *entityTmp;
1208 // True if the entity fly.
1209 entity.flyer(actor.Fly);
1211 // Set the name of the entity
1212 entity.name(actor.Name);
1213 // Time for the current frame.
1214 entity.time(T1);
1215 // Set the entity position.
1216 entity.pacsPos(actor.Pos);
1217 // Set the Front.
1218 CMatrix m;
1219 m.identity();
1220 m.setRot(actor.Rot);
1221 entity.front((m * CVector::J).normed());
1222 // Set the direction like the front.
1223 entity.dir(entity.front());
1224 // Set the vector UP.
1225 entity.up(CVector(0.f,0.f,1.f));
1227 // Assign a skeleton.
1228 entity.skeleton(actor.Skeleton);
1230 // Position the entity.
1231 entity.pacsPos(actor.Pos);
1233 // Position the skeleton at the same position as the entity.
1234 if(entity.skeleton())
1236 entity.skeleton()->setPos(actor.Pos);
1237 entity.skeleton()->setRotQuat(actor.Rot);
1240 // Assign meshes used for the entity.
1241 uint count = 0;
1242 list<string>::iterator itMeshes;
1243 for(itMeshes = actor.Meshes.begin(); itMeshes != actor.Meshes.end(); ++itMeshes)
1245 // If there are too many meshes.
1246 if(count >= (uint)CEntityCL::NB_SLOT)
1248 nlwarning("CSceneParser::applyActors : Too many meshes for Actor %d.", actor.Id);
1249 break;
1252 entity.slot((CEntityCL::ESlots)count, *itMeshes);
1253 ++count;
1256 // Create the playlist
1257 addEntityClAnimatedSceneObject(entityId, actor.Anims);
1259 else
1260 nlwarning("CSceneParser::applyActors : Entity %d Not created", actor.Id);
1262 }// applyActors //
1265 //-----------------------------------------------
1266 // playSeq :
1267 // Play the sequence with the ID 'seq'.
1268 //-----------------------------------------------
1269 void CSceneParser::playSeq(uint seq, double timeInSec)
1271 // If the scene is not initialized -> return.
1272 if(!_Apply)
1273 return;
1275 // Camera in scene mode.
1276 UserControls.mode(CUserControls::SceneMode);
1278 _TimeStart = timeInSec;
1280 map<uint, CSequence>::iterator itSeq = _Sequences.find(seq);
1281 if(itSeq != _Sequences.end())
1283 // Get a reference on the sequence.
1284 CSequence &sequence = (*itSeq).second;
1286 // Log the time used for the sequence.
1287 nlwarning("Sequence: %d, Time: %f", seq, timeInSec);
1289 // Camera in the sequence.
1290 if(!sequence.CamAnims.empty())
1292 if(_PlayList)
1294 map<string, uint>::iterator itAnimCamId;
1295 for(itAnimCamId = _AnimCamToId.begin(); itAnimCamId != _AnimCamToId.end(); ++itAnimCamId)
1297 _PlayList->setTimeOrigin(0, timeInSec);
1298 _PlayList->setAnimation(0, (*itAnimCamId).second);
1303 // Particles in the sequence.
1304 map<uint, CParticleSeq>::iterator itPartSeq;
1305 for(itPartSeq = sequence.ParticlesSeq.begin(); itPartSeq != sequence.ParticlesSeq.end(); ++itPartSeq)
1307 CParticleSeq &particleSeq = (*itPartSeq).second;
1308 map<uint, CParticle>::iterator itPart = _Particles.find(particleSeq.Id);
1309 if(itPart != _Particles.end())
1311 // Get a reference on the particle.
1312 CParticle &particle = (*itPart).second;
1313 // Check if the IG has been created.
1314 if(particle.IGPtr)
1316 // Check if the IG of particles is not already in the scene.
1317 if(_IGInScene.find(particle.IGPtr) == _IGInScene.end())
1319 // Insert IG in the set of IG in the scene.
1320 _IGInScene.insert(particle.IGPtr);
1321 // Cluster.
1322 if(IGCity.find(particle.Cluster) == IGCity.end())
1323 Scene->setToGlobalInstanceGroup(particle.IGPtr);
1324 else
1325 particle.IGPtr->setClusterSystem(IGCity[particle.Cluster]);
1326 // Add particles to the scene.
1327 particle.IGPtr->addToScene(*Scene, Driver);
1328 // Unfreeze the IG.
1329 particle.IGPtr->unfreezeHRC();
1331 // Register all instances in the IG to a playlist.
1332 for(uint i = 0; i < particle.IGPtr->getNumInstance(); ++i )
1334 std::string iName = particle.IGPtr->getInstanceName( i );
1335 UInstance instance = particle.IGPtr->getByName( iName );
1336 particle.PlayList->registerTransform(instance);
1337 particle.PlayList->registerTransform(instance, (iName + ".").c_str());
1341 // Start the particle animation.
1342 map<string, uint>::iterator itAnimId;
1343 for(itAnimId = particle.AnimToId.begin(); itAnimId != particle.AnimToId.end(); ++itAnimId)
1345 particle.PlayList->setTimeOrigin(0, timeInSec);
1346 particle.PlayList->setAnimation(0, (*itAnimId).second);
1352 // Actors in the sequence.
1353 map<uint, CActorSeq>::iterator itActSeq;
1354 for(itActSeq = sequence.ActorsSeq.begin(); itActSeq != sequence.ActorsSeq.end(); ++itActSeq)
1356 CActorSeq &actorSeq = (*itActSeq).second;
1357 updateAnimationSequence(Sid(Sid::npc, (uint64)actorSeq.Id), actorSeq.Anims, 0 );
1360 }// playSeq //
1363 //-----------------------------------------------
1364 // update :
1365 // Update the scene.
1366 //-----------------------------------------------
1367 void CSceneParser::update(double timeInSec)
1369 // Nothing to update if the scene is not applied.
1370 if(!_Apply)
1371 return;
1373 // Update the scene currently playing.
1374 updateScene(timeInSec);
1376 // Update particles.
1377 updateParticles(timeInSec);
1379 // Animate the camera.
1380 updateCamera(timeInSec);
1382 // Update particle anims.
1383 if(_PlayListManager)
1384 _PlayListManager->animate(timeInSec);
1386 // Update actor position (for actor on another actor).
1387 updateActors();
1388 }// update //
1390 //-----------------------------------------------
1391 // updateCamera :
1392 // Update the camera (position, target, roll, fov)
1393 //-----------------------------------------------
1394 void CSceneParser::updateCamera(double timeInSec)
1396 // If there is a play list for the camera.
1397 if(_PlayList)
1399 // Get the Id of the animation in the slot 0.
1400 uint idAnim = _PlayList->getAnimation(0);
1401 if(idAnim != UPlayList::empty)
1403 UAnimation *animation = _AnimationSet->getAnimation(idAnim);
1404 if(animation)
1406 // Get Camera information from the animation (Pos, Target, Roll).
1407 UTrack* trackRollCam = animation->getTrackByName("Camera.roll");
1408 UTrack* trackFovCam = animation->getTrackByName("Camera.fov");
1409 UTrack* trackPosCam = animation->getTrackByName("Camera.PathPos");
1410 UTrack* trackPosTarget = animation->getTrackByName("Camera.Target.PathPos");
1411 if(trackPosCam && trackPosTarget)
1413 float rollCam = 0.f;
1414 CVector posCam;
1415 CVector posTarget;
1416 float difTime = (float)(timeInSec-_TimeStart);
1418 if(trackRollCam)
1419 trackRollCam->interpolate(difTime, rollCam);
1420 trackPosCam->interpolate(difTime, posCam);
1421 trackPosTarget->interpolate(difTime, posTarget);
1423 // Update camera transformations.
1424 UCamera cam = Scene->getCam();
1425 if(cam)
1427 cam->setTransformMode(UTransformable::RotQuat);
1428 cam->lookAt(posCam, posTarget, rollCam);
1429 if(trackFovCam)
1431 float fov;
1432 trackFovCam->interpolate(difTime, fov);
1433 CFrustum fr= cam->getFrustum();
1434 // change only the fov
1435 cam->setPerspective(fov, fr.getAspectRatio(), fr.Near, fr.Far);
1439 // Update camera transformations for the Root.
1440 cam = SceneRoot->getCam();
1441 if(cam)
1443 cam->setTransformMode(UTransformable::RotQuat);
1444 cam->lookAt(posCam, posTarget, rollCam);
1445 if(trackFovCam)
1447 float fov;
1448 trackFovCam->interpolate(difTime, fov);
1449 CFrustum fr= cam->getFrustum();
1450 // change only the fov
1451 cam->setPerspective(fov, fr.getAspectRatio(), fr.Near, fr.Far);
1458 }// updateCamera //
1460 //-----------------------------------------------
1461 // updateActors :
1462 // Update Actors.
1463 //-----------------------------------------------
1464 void CSceneParser::updateActors()
1466 // All actors in the scene.
1467 for(map<uint, CActor>::iterator itActor = _Actors.begin(); itActor != _Actors.end(); ++itActor)
1469 // Get a reference on the actor.
1470 CActor &actor = (*itActor).second;
1472 // If there is no actor to follow -> next actor.
1473 if(actor.Actor < 0)
1474 continue;
1476 // Get the entity pointer.
1477 CEntityCL *entity = getEntity(Sid(Sid::npc, (uint64)actor.Id));
1478 if(!entity)
1480 nlwarning("CSceneParser::updateActors : Cannot get the actor %d.", actor.Id);
1481 continue;
1484 // Get the target entity pointer.
1485 CEntityCL *entityTarget = getEntity(Sid(Sid::npc, (uint64)actor.Actor));
1486 if(!entityTarget)
1488 nlwarning("CSceneParser::updateActors : Cannot get the targeted actor %d.", actor.Actor);
1489 continue;
1492 // Changes the entity position.
1493 entity->pacsPos(entityTarget->pos());
1495 }// updateActors //
1497 //-----------------------------------------------
1498 // updateParticles :
1499 // Update particles.
1500 //-----------------------------------------------
1501 void CSceneParser::updateParticles(double timeInSec)
1503 for(map<uint, CParticle>::iterator itPart = _Particles.begin(); itPart != _Particles.end(); ++itPart)
1505 // Get a reference on the particule.
1506 CParticle &particle = (*itPart).second;
1508 // If the IG pointer is null -> Next particle.
1509 if(!(particle.IGPtr))
1510 continue;
1512 // If the play list is NULL -> Next particle
1513 if(!(particle.PlayList))
1514 continue;
1516 // Get the Id of the animation in the slot 0 -> if empty -> Next particle.
1517 uint idAnim = particle.PlayList->getAnimation(0);
1518 if(idAnim == UPlayList::empty)
1519 continue;
1521 // Get the animation pointer.
1522 UAnimation *animation = particle.AnimationSet->getAnimation(idAnim);
1523 if(!animation)
1524 continue;
1526 // Get the time difference.
1527 float difTime = (float)(timeInSec-_TimeStart);
1529 // Particle do not follow anything.
1530 if(particle.Actor < 0)
1532 updateParticlesNoActor(difTime, particle, *animation);
1534 // Particle follow an actor.
1535 else
1537 updateParticlesActor(difTime, particle, *animation);
1540 }// updateParticles //
1542 //-----------------------------------------------
1543 // updateParticlesNoActor :
1545 //-----------------------------------------------
1546 void CSceneParser::updateParticlesNoActor(float difTime, CParticle &particle, UAnimation &animation)
1548 // Animate all instances.
1549 for(uint i = 0; i < particle.IGPtr->getNumInstance(); ++i )
1551 std::string iName = particle.IGPtr->getInstanceName(i);
1552 UInstance instance = particle.IGPtr->getByName(iName);
1554 if(!instance)
1555 continue;
1557 instance->setTransformMode(UTransformable::RotQuat);
1559 // If the animation has no track of position.
1560 UTrack* trackPos = animation.getTrackByName("PathPos");
1561 if(!trackPos)
1562 trackPos = animation.getTrackByName(string(iName + "." + "PathPos").c_str());
1563 if(trackPos)
1565 CVector pos;
1566 trackPos->interpolate(difTime, pos);
1567 instance->setPos(pos);
1570 // If the animation has no track of rotation.
1571 UTrack* trackRot = animation.getTrackByName("PathRotQuat");
1572 if(!trackRot)
1573 trackRot = animation.getTrackByName(string(iName + "." + "PathRotQuat").c_str());
1574 if(trackRot)
1576 CQuat rot;
1577 if(trackRot->interpolate(difTime, rot))
1578 instance->setRotQuat(rot);
1579 else
1580 nlwarning("CSceneParser::updateParticles : Not a Quat!");
1583 }// updateParticlesNoActor //
1586 //-----------------------------------------------
1587 // updateParticlesActor :
1589 //-----------------------------------------------
1590 void CSceneParser::updateParticlesActor(float difTime, CParticle &particle, UAnimation &animation)
1592 // Get the entity pointer.
1593 CEntityCL *entity = getEntity(Sid(Sid::npc, (uint64)particle.Actor));
1594 if(!entity)
1596 nlwarning("CSceneParser::updateParticlesActor : cannot get the actor %d.", (uint64)particle.Actor);
1597 return;
1600 // If the entity has no skeleton -> Next particle.
1601 if(!entity->skeleton())
1603 nlwarning("The particle follow an entity %d without a skeleton.", (uint64)particle.Actor);
1604 return;
1607 // Matrix 90 degrees
1608 CMatrix m90;
1609 m90.identity();
1610 m90.rotateZ((float)(Pi/2.0));
1612 // Matrix of the entity.
1613 CMatrix mChar = entity->skeleton()->getMatrix();
1614 mChar.setPos(entity->pos());
1616 // Animate all instances.
1617 for(uint i = 0; i < particle.IGPtr->getNumInstance(); ++i )
1619 std::string iName = particle.IGPtr->getInstanceName(i);
1620 UInstance instance = particle.IGPtr->getByName(iName);
1622 if(!instance)
1623 continue;
1625 instance->setTransformMode(UTransformable::RotQuat);
1627 CMatrix mAnim;
1628 mAnim.identity();
1629 // If the animation has no track of position.
1630 UTrack* trackPos = animation.getTrackByName("PathPos");
1631 if(!trackPos)
1632 trackPos = animation.getTrackByName(string(iName + "." + "PathPos").c_str());
1633 if(trackPos)
1635 CVector pos;
1636 trackPos->interpolate(difTime, pos);
1637 mAnim.setPos(pos);
1640 // If the animation has no track of rotation.
1641 UTrack* trackRot = animation.getTrackByName("PathRotQuat");
1642 if(!trackRot)
1643 trackRot = animation.getTrackByName(string(iName + "." + "PathRotQuat").c_str());
1644 if(trackRot)
1646 CQuat rot;
1647 trackPos->interpolate(difTime, rot);
1648 mAnim.setRot(rot);
1651 CMatrix mFinal = mChar * m90 * mAnim;
1652 instance->setPos(mFinal.getPos());
1653 instance->setRotQuat(mFinal.getRot());
1655 }// updateParticlesActor //
1658 //-----------------------------------------------
1659 // loadScene :
1660 // Load a scene from a file and put it in memory.
1661 // \param filename : filename for the file that contains the scene.
1662 // \warning This function clear the old scene.
1663 //-----------------------------------------------
1664 void CSceneParser::loadScene(const string &filename)
1666 // Look for the file -> nlwarning and return if sceneFile is empty.
1667 string sceneFile = CPath::lookup(filename, false);
1668 if(sceneFile.empty())
1670 nlwarning("CSceneParser::loadScene : Can't find file \"%s\".", filename.c_str());
1671 return;
1674 // Open the file.
1675 ifstream file(sceneFile.c_str(), ios::in);
1676 if(file.is_open())
1678 // ...
1679 char tmpBuff[MAX_LINE_SIZE];
1681 // While the end of the file is not reached -> parse the script.
1682 while(!file.eof())
1684 // Get next valid line.
1685 getNextValidLine(file, tmpBuff);
1687 pair<sint, double> seq;
1688 // ...
1689 char *ptr = strtok(tmpBuff, delimiter);
1690 if(ptr != NULL)
1692 seq.first = atoi(ptr);
1693 ptr = strtok(NULL, delimiter);
1694 if(ptr != NULL)
1696 NLMISC::fromString(ptr, seq.second);
1697 _Scene.push_back(seq);
1702 // Close the File.
1703 file.close();
1705 else
1707 nlwarning("CSceneParser::loadScene : File \"%s\" can't be open.", sceneFile.c_str());
1708 return;
1710 }// loadScene //
1712 //-----------------------------------------------
1713 // playScene :
1714 // Play a scene in memory.
1715 // \param timeInSec : current time in second.
1716 //-----------------------------------------------
1717 void CSceneParser::playScene(double timeInSec)
1719 // Initialize the Iterator for the scene.
1720 _ItScene = _Scene.begin();
1721 // Initialize the time for the scene.
1722 _SceneStart = timeInSec;
1724 // Initialize or Reset the scene.
1725 apply();
1727 // Play the first sequence to play for this scene.
1728 updateScene(timeInSec);
1729 }// playScene //
1731 //-----------------------------------------------
1732 // updateScene :
1733 // Update the scene currently playing.
1734 // \param timeInSec : current time in second.
1735 //-----------------------------------------------
1736 void CSceneParser::updateScene(double timeInSec)
1738 // If there are still sequences in the scene.
1739 if(_ItScene != _Scene.end())
1741 double time = timeInSec-_SceneStart;
1742 if((*_ItScene).second <= time)
1744 // If the scene is finish -> Stop it.
1745 if((*_ItScene).first < 0)
1747 stopScene();
1749 else
1751 // Play the sequence.
1752 playSeq((*_ItScene).first, timeInSec);
1754 // Next sequence.
1755 _ItScene++;
1759 }// updateScene //
1761 //-----------------------------------------------
1762 // stopScene :
1763 // Stop the scene currently playing.
1764 //-----------------------------------------------
1765 void CSceneParser::stopScene()
1767 _ItScene = _Scene.end();
1768 _SceneStart = -1.f;
1769 }// stopScene //
1771 //-----------------------------------------------
1772 // Function to know if there is a scene currently playing.
1773 // \return bool : 'true' if there is a scene currently playing.
1774 //-----------------------------------------------
1775 bool CSceneParser::isScenePlaying()
1777 return (_ItScene != _Scene.end());
1778 }// isScenePlaying //