1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
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.
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/>.
23 #include "nel/3d/animation_time.h"
24 #include "nel/3d/u_animation.h"
25 #include "nel/3d/u_track.h"
26 #include "nel/3d/u_bone.h"
27 #include "nel/misc/command.h"
29 #include "game_share/draw_section.h"
31 #include "animated_scene_object.h"
32 #include "user_entity.h"
37 using namespace NLMISC
;
39 using namespace NLNET
;
41 // some extern of client
42 extern CUserEntity
*UserEntity
;
46 // map of anilated scene object
47 TMapCAnimatedSceneObject AnimatedSceneObject
;
50 // Constructor for moving object, create entity (mesh, skeleton) and build animation on it
51 CAnimatedSceneObject::CAnimatedSceneObject( const string
& ObjectName
, const string
& ClusterIG
, const string
& MeshName
, const string
& SkeletonName
, const list
< string
>& Animations
, const CVector
& Position
, const CQuat
& Rotation
, float Distance
)
53 _ObjectName
= ObjectName
;
54 _ClusterIG
= ClusterIG
;
56 _SkeletonName
= SkeletonName
;
60 _Distance
= Distance
* Distance
; //square distance for optimize distance calculation
62 // create play list manager and animation set
63 _PlayListManager
= Scene
->createPlayListManager();
64 _AnimationSet
= Driver
->createAnimationSet();
67 for( list
< string
>::const_iterator it
= Animations
.begin(); it
!= Animations
.end(); ++it
)
72 idAnim
= _AnimationSet
->addAnimation( ( *it
+ string(".anim")).c_str(), (*it
).c_str() );
76 idAnim
= UAnimationSet::NotFound
;
77 if( idAnim
== UAnimationSet::NotFound
)
79 nlwarning( "CAnimatedSceneObject::CAnimatedSceneObject Animation %s not found for object %s", (*it
).c_str(), _ObjectName
.c_str() );
83 _MapAnimation
.insert( make_pair( *it
, idAnim
) );
86 // build animation set
87 _AnimationSet
->build();
90 _PlayList
= _PlayListManager
->createPlayList( _AnimationSet
);
92 _Status
= SAnimationStatus();
93 _Status
.RandomAnim
= 1;
94 _Status
.ApplyDisplacement
= 0;
96 // load instance and bind to skeleton
97 _Instance
= Scene
->createInstance( _MeshName
);
98 if( _Instance
== NULL
)
100 nlerror("CAnimatedSceneObject::CAnimatedSceneObject createInstance %s returned 0 -> no shape.", _MeshName
.c_str() );
104 _Transform
= _Instance
;
107 // load skeleton, bind mesh and init position, rotation, cluster
108 if(!_SkeletonName
.empty())
110 _Skeleton
= Scene
->createSkeleton(_SkeletonName
);
111 if( _Skeleton
== NULL
)
113 nlerror("CAnimatedSceneObject::CAnimatedSceneObject createSkeleton %s returned 0 -> no skeleton.", _SkeletonName
.c_str() );
115 _Transform
= _Skeleton
;
116 _Skeleton
->bindSkin( _Instance
);
118 if(ClientCfg
.Shadows
)
120 _Skeleton
->enableCastShadowMap(true);
124 // register skeleton in playlist
125 _PlayList
->registerTransform( _Transform
);
127 // Initialise squeleton initial state
128 if( _MapAnimation
.begin() != _MapAnimation
.end() )
130 _PlayList
->setAnimation( 0, (*_MapAnimation
.begin()).second
);
131 _PlayList
->setTimeOrigin(0, 0 );
132 _PlayList
->setSpeedFactor( 0, 1 );
133 _PlayListManager
->animate( 0 );
136 _Transform
->setClusterSystem( IGCity
[_ClusterIG
] );
137 _Transform
->setPos( _Position
);
138 _Transform
->setRotQuat( _Rotation
);
140 _IdAnimationPlayed
= -1;
144 // Constructor for moving object, it not create entity (mesh, skeleton) but build animation on pre-exist entity
145 CAnimatedSceneObject::CAnimatedSceneObject( const CEntityId
& Id
, const list
< std::string
>& Animations
)
157 CEntityCL
*entity
= getEntity(Id
);
160 _Skeleton
= *entity
->skeleton();
161 _Transform
= _Skeleton
;
163 _Position
= _Skeleton
->getPos();
164 _Rotation
= _Skeleton
->getRotQuat();
166 // create play list manager and animation set
167 _PlayListManager
= Scene
->createPlayListManager();
168 _AnimationSet
= Driver
->createAnimationSet();
171 for( list
< string
>::const_iterator its
= Animations
.begin(); its
!= Animations
.end(); ++its
)
176 idAnim
= _AnimationSet
->addAnimation( ( *its
+ string(".anim") ).c_str(), (*its
).c_str() );
180 idAnim
= UAnimationSet::NotFound
;
181 if( idAnim
== UAnimationSet::NotFound
)
183 nlwarning( "CAnimatedSceneObject::CAnimatedSceneObject Animation %s not found for entity CEntityId(%u,%f)", (*its
).c_str(), Id
.Type
, (double)(sint64
)Id
.Id
);
187 _MapAnimation
.insert( make_pair( *its
, idAnim
) );
190 // build animation set
191 _AnimationSet
->build();
194 _PlayList
= _PlayListManager
->createPlayList( _AnimationSet
);
196 _Status
= SAnimationStatus();
197 _Status
.SequenceAnim
= 1;
198 _Status
.ApplyDisplacement
= 1;
200 // register skeleton in playlist
201 _PlayList
->registerTransform( *entity
->skeleton() );
203 // Snap to ground(the snap check if it's a flyer).
204 entity
->pacsPos(_Position
);
205 entity
->snapToGround();
206 _Position
= entity
->pos();
210 current
.setRot (_Rotation
);
212 // Rotation 90 degrees
215 rot90
.rotateZ (-(float)Pi
/2);
218 _Transform
->unfreezeHRC();
220 _Transform
->setPos(_Position
);
221 _Transform
->setRotQuat(current
.getRot());
223 _Transform
->freezeHRC();
225 _IdAnimationPlayed
= -1;
227 if( _Id
.Type
== RYZOMID::npc
)
229 sendEndSequenceMessage( _Id
, 1 );
235 _AnimationSet
= NULL
;
236 _PlayListManager
= NULL
;
241 // Constructor for moving object, init by UTransform
242 CAnimatedSceneObject::CAnimatedSceneObject( const CEntityId
& Id
, UTransform
*Transform
, const list
< std::string
>& Animations
, bool displacement
)
251 _Transform
= Transform
;
256 _Position
= _Transform
->getPos();
257 _Rotation
= _Transform
->getRotQuat();
259 // create play list manager and animation set
260 _PlayListManager
= Scene
->createPlayListManager();
261 _AnimationSet
= Driver
->createAnimationSet();
264 for( list
< string
>::const_iterator its
= Animations
.begin(); its
!= Animations
.end(); ++its
)
269 idAnim
= _AnimationSet
->addAnimation( ( *its
+ string(".anim") ).c_str(), (*its
).c_str() );
273 idAnim
= UAnimationSet::NotFound
;
274 if( idAnim
== UAnimationSet::NotFound
)
276 nlwarning( "CAnimatedSceneObject::CAnimatedSceneObject Animation %s not found for entity CEntityId(%u,%f)", (*its
).c_str(), Id
.Type
, (double)(sint64
)Id
.Id
);
280 _MapAnimation
.insert( make_pair( *its
, idAnim
) );
283 _Status
= SAnimationStatus();
284 _Status
.SequenceAnim
= 1;
285 _Status
.ApplyDisplacement
= displacement
;
287 if( Animations
.begin() != Animations
.end() )
289 // build animation set
290 _AnimationSet
->build();
293 _PlayList
= _PlayListManager
->createPlayList( _AnimationSet
);
295 // register skeleton in playlist
296 _PlayList
->registerTransform( _Transform
);
298 _IdAnimationPlayed
= -1;
303 // Reset intial pos and rot matrix
304 void CAnimatedSceneObject::resetInitialPos( void )
306 _IdAnimationPlayed
= -1;
309 _Position
= _Transform
->getPos();
310 _Rotation
= _Transform
->getRotQuat();
312 CEntityCL
*entity
= getEntity(_Id
);
315 // Snap to ground(the snap check if it's a flyer).
316 entity
->pacsPos(_Position
);
317 entity
->snapToGround();
318 _Position
= entity
->pos();
323 current
.setRot (_Rotation
);
325 // Rotation 90 degrees
328 rot90
.rotateZ (-(float)Pi
/2);
331 _Transform
->unfreezeHRC();
333 _Transform
->setPos(_Position
);
334 _Transform
->setRotQuat(current
.getRot());
336 _Transform
->freezeHRC();
341 CAnimatedSceneObject::~CAnimatedSceneObject()
343 if( _Instance
!= NULL
&& !_MeshName
.empty() )
345 Scene
->deleteInstance( _Instance
);
348 if( _Skeleton
!= NULL
&& !_SkeletonName
.empty() )
350 Scene
->deleteSkeleton( _Skeleton
);
353 if( _PlayListManager
!= NULL
)
355 if( _PlayList
!= NULL
)
357 _PlayListManager
->deletePlayList( _PlayList
);
359 if( _AnimationSet
!= NULL
)
361 Driver
->deleteAnimationSet( _AnimationSet
);
363 Scene
->deletePlayListManager( _PlayListManager
);
366 _MapAnimation
.clear();
367 _SequenceAnimation
.clear();
371 // Start an animation, if object have more than one animation, it choose one randomly
372 void CAnimatedSceneObject::StartRandomAnimation( double time
, float speedFactor
)
374 if( _Transform
!= NULL
)
376 _Transform
->unfreezeHRC();
379 uint numAnimation
= _MapAnimation
.size();
380 numAnimation
= ( rand() * numAnimation
) / RAND_MAX
;
381 map
< string
, uint
>::iterator it
= _MapAnimation
.begin();
382 for(uint i
= 0; i
< numAnimation
; ++i
) ++it
;
383 numAnimation
= (*it
).second
;
385 _PlayList
->setAnimation( 0, numAnimation
);
386 _IdAnimationPlayed
= numAnimation
;
387 _StartAnimationTime
= time
;
388 _OldAnimationTime
= _StartAnimationTime
;
389 _PlayList
->setTimeOrigin(0, _StartAnimationTime
);
390 _PlayList
->setSpeedFactor( 0, speedFactor
);
392 if( _Transform
!= NULL
)
394 _Position
= _Transform
->getPos();
395 _Rotation
= _Transform
->getRotQuat();
397 CEntityCL
*entity
= getEntity(_Id
);
400 // Snap to ground(the snap check if it's a flyer).
401 entity
->pacsPos(_Position
);
402 entity
->snapToGround();
403 _Position
= entity
->pos();
406 // Read start animation rotation and position
407 _PreviousRotation
= CQuat::Identity
;
408 _PreviousTranslation
= CVector::Null
;
410 // read an animation for init matrix
411 UTrack
* Track
= _AnimationSet
->getAnimation( _IdAnimationPlayed
)->getTrackByName( "PathRotQuat" );
414 Track
= _AnimationSet
->getAnimation( _IdAnimationPlayed
)->getTrackByName( "Bip01.PathRotQuat" );
418 Track
= _AnimationSet
->getAnimation( _IdAnimationPlayed
)->getTrackByName( "rotquat" );
422 Track
->interpolate( 0, _PreviousRotation
);
425 Track
= _AnimationSet
->getAnimation( _IdAnimationPlayed
)->getTrackByName( "PathPos" );
428 Track
= _AnimationSet
->getAnimation( _IdAnimationPlayed
)->getTrackByName( "Bip01.PathPos" );
432 Track
= _AnimationSet
->getAnimation( _IdAnimationPlayed
)->getTrackByName( "pathpos" );
436 Track
->interpolate( 0, _PreviousTranslation
);
441 animation
.identity();
442 animation
.setPos (_PreviousTranslation
);
443 animation
.setRot (_PreviousRotation
);
446 // reset orientation of skeleton
449 current
.setRot( _Rotation
);
456 current
.setRot (I
, J
, K
);
457 current
.setPos (_Position
);
459 _AnimTransformation
= current
;
465 _AnimTransformation
.setPos( _AnimTransformation
.getPos() - CVectorD( 0, 0, entity
->pos().z
) );
472 // Start next animation
473 void CAnimatedSceneObject::StartNextAnimation( double time
, float speedFactor
)
475 if( _SequenceAnimation
.begin() != _SequenceAnimation
.end() )
477 if( _Transform
!= NULL
)
479 _Transform
->unfreezeHRC();
482 string animName
= *_SequenceAnimation
.begin();
483 _SequenceAnimation
.pop_front();
485 map
< string
, uint
>::iterator it
= _MapAnimation
.find( animName
);
486 if( it
!= _MapAnimation
.end() )
488 uint idAnim
= (*it
).second
;
490 _PlayList
->setAnimation( 0, idAnim
);
491 _IdAnimationPlayed
= idAnim
;
492 _StartAnimationTime
= time
;
493 _OldAnimationTime
= _StartAnimationTime
;
494 _PlayList
->setTimeOrigin(0, _StartAnimationTime
);
495 _PlayList
->setSpeedFactor( 0, speedFactor
);
497 if( _Transform
!= NULL
)
499 _Position
= _Transform
->getPos();
500 _Rotation
= _Transform
->getRotQuat();
502 CEntityCL
*entity
= getEntity(_Id
);
505 // Snap to ground(the snap check if it's a flyer).
506 entity
->pacsPos(_Position
);
507 entity
->snapToGround();
508 _Position
= entity
->pos();
511 // Read start animation rotation and position
512 _PreviousRotation
= CQuat::Identity
;
513 _PreviousTranslation
= CVector::Null
;
515 // read an animation for init matrix
516 UTrack
* Track
= _AnimationSet
->getAnimation( _IdAnimationPlayed
)->getTrackByName( "PathRotQuat" );
519 Track
= _AnimationSet
->getAnimation( _IdAnimationPlayed
)->getTrackByName( "Bip01.PathRotQuat" );
523 Track
= _AnimationSet
->getAnimation( _IdAnimationPlayed
)->getTrackByName( "rotquat" );
527 Track
->interpolate( 0, _PreviousRotation
);
530 Track
= _AnimationSet
->getAnimation( _IdAnimationPlayed
)->getTrackByName( "PathPos" );
533 Track
= _AnimationSet
->getAnimation( _IdAnimationPlayed
)->getTrackByName( "Bip01.PathPos" );
537 Track
= _AnimationSet
->getAnimation( _IdAnimationPlayed
)->getTrackByName( "pathpos" );
541 Track
->interpolate( 0, _PreviousTranslation
);
546 animation
.identity();
547 animation
.setPos (_PreviousTranslation
);
548 animation
.setRot (_PreviousRotation
);
550 // reset orientation of skeleton
553 current
.setRot( _Rotation
);
560 current
.setRot (I
, J
, K
);
561 current
.setPos (_Position
);
563 _AnimTransformation
= current
;
567 if(!entity
->flyer() )
569 _AnimTransformation
.setPos( _AnimTransformation
.getPos() - CVectorD( 0, 0, entity
->pos().z
) );
575 if( _SequenceAnimation
.size() == 1 )
577 sendEndSequenceMessage( _Id
, idSequence() );
582 //StartAnimation( string("FY_HOM_idlecycle") );
587 // Start animation cooresponding to numAnim
588 void CAnimatedSceneObject::StartAnimation( string
& nameAnim
, double time
, float speedFactor
)
590 if( _Transform
!= NULL
)
592 _Transform
->unfreezeHRC();
595 map
< string
, uint
>::iterator it
= _MapAnimation
.find( nameAnim
);
596 if( it
!= _MapAnimation
.end() )
598 uint numAnimation
= (*it
).second
;
600 _PlayList
->setAnimation( 0, numAnimation
);
601 _IdAnimationPlayed
= numAnimation
;
602 _StartAnimationTime
= time
;
603 _OldAnimationTime
= _StartAnimationTime
;
604 _PlayList
->setTimeOrigin(0, _StartAnimationTime
);
605 _PlayList
->setSpeedFactor( 0, speedFactor
);
608 if( _Transform
!= NULL
)
610 _Position
= _Transform
->getPos();
611 _Rotation
= _Transform
->getRotQuat();
613 CEntityCL
*entity
= getEntity(_Id
);
616 // Snap to ground(the snap check if it's a flyer).
617 entity
->pacsPos(_Position
);
618 entity
->snapToGround();
619 _Position
= entity
->pos();
622 // Read start animation rotation and position
623 _PreviousRotation
= CQuat::Identity
;
624 _PreviousTranslation
= CVector::Null
;
626 // read an animation for init matrix
627 UTrack
* Track
= _AnimationSet
->getAnimation( _IdAnimationPlayed
)->getTrackByName( "PathRotQuat" );
630 Track
= _AnimationSet
->getAnimation( _IdAnimationPlayed
)->getTrackByName( "Bip01.PathRotQuat" );
634 Track
= _AnimationSet
->getAnimation( _IdAnimationPlayed
)->getTrackByName( "rotquat" );
638 Track
->interpolate( 0, _PreviousRotation
);
641 Track
= _AnimationSet
->getAnimation( _IdAnimationPlayed
)->getTrackByName( "PathPos" );
644 Track
= _AnimationSet
->getAnimation( _IdAnimationPlayed
)->getTrackByName( "Bip01.PathPos" );
648 Track
= _AnimationSet
->getAnimation( _IdAnimationPlayed
)->getTrackByName( "pathpos" );
652 Track
->interpolate( 0, _PreviousTranslation
);
657 animation
.identity();
658 animation
.setPos (_PreviousTranslation
);
659 animation
.setRot (_PreviousRotation
);
661 // reset orientation of skeleton
664 current
.setRot( _Rotation
);
671 current
.setRot (I
, J
, K
);
672 current
.setPos (_Position
);
674 _AnimTransformation
= current
;
678 if( !entity
->flyer() )
680 _AnimTransformation
.setPos( _AnimTransformation
.getPos() - CVectorD( 0, 0, entity
->pos().z
) );
688 // remove the initial animation offset
689 void CAnimatedSceneObject::removeOffsetAnimation ()
691 // Read start animation rotation and position
692 _PreviousRotation
= CQuat::Identity
;
693 _PreviousTranslation
= CVector::Null
;
695 // read an animation for init matrix
696 UTrack
* Track
= _AnimationSet
->getAnimation( _IdAnimationPlayed
)->getTrackByName( "PathRotQuat" );
699 Track
= _AnimationSet
->getAnimation( _IdAnimationPlayed
)->getTrackByName( "Bip01.PathRotQuat" );
703 Track
= _AnimationSet
->getAnimation( _IdAnimationPlayed
)->getTrackByName( "rotquat" );
707 Track
->interpolate( 0, _PreviousRotation
);
710 Track
= _AnimationSet
->getAnimation( _IdAnimationPlayed
)->getTrackByName( "PathPos" );
713 Track
= _AnimationSet
->getAnimation( _IdAnimationPlayed
)->getTrackByName( "Bip01.PathPos" );
717 Track
= _AnimationSet
->getAnimation( _IdAnimationPlayed
)->getTrackByName( "pathpos" );
721 Track
->interpolate( 0, _PreviousTranslation
);
724 // Remove first frame animation from transform
725 CVector position
= _Transform
->getPos ();
726 CQuat rotation
= _Transform
->getRotQuat ();
728 // Build current matrix
731 current
.setPos (position
);
732 current
.setRot (rotation
);
734 // Build invert first frame matrix
736 firstFrame
.identity ();
737 firstFrame
.setPos (_PreviousTranslation
);
738 firstFrame
.setRot (_PreviousRotation
);
739 firstFrame
.invert ();
741 // Remove the first frame animation
742 current
*= firstFrame
;
744 // Rotation 90 degrees
747 rot90
.rotateZ (-(float)Pi
/2);
751 _Transform
->setPos (current
.getPos());
752 _Transform
->setRotQuat (current
.getRot());
756 // update (add to end list) Animation sequence with sequence
757 void CAnimatedSceneObject::updateAnimationSequence( const list
< string
>& sequence
)
759 for( list
< string
>::const_iterator it
= sequence
.begin(); it
!= sequence
.end(); ++it
)
761 _SequenceAnimation
.push_back( (*it
) );
766 // Process logic and displacement and setup visual animation
767 void CAnimatedSceneObject::applyObjectAnimationTimeslice( double time
)
769 _PlayListManager
->animate( time
);
771 // Apply displacement if mode set and displacement animation exist
772 if( _Status
.ApplyDisplacement
== 1 )
774 CQuat rot
= CQuat::Identity
;
775 CVector translation
= CVector::Null
;
776 // Read position and rotation in appropriate UTrack
777 UTrack
* Track
= _AnimationSet
->getAnimation( _IdAnimationPlayed
)->getTrackByName( "PathRotQuat" );
780 Track
= _AnimationSet
->getAnimation( _IdAnimationPlayed
)->getTrackByName( "Bip01.PathRotQuat" );
784 Track
= _AnimationSet
->getAnimation( _IdAnimationPlayed
)->getTrackByName( "rotquat" );
788 Track
->interpolate( (float)(time
- _StartAnimationTime
) * _PlayList
->getSpeedFactor( 0 ), rot
);
791 Track
= _AnimationSet
->getAnimation( _IdAnimationPlayed
)->getTrackByName( "PathPos" );
794 Track
= _AnimationSet
->getAnimation( _IdAnimationPlayed
)->getTrackByName( "Bip01.PathPos" );
798 Track
= _AnimationSet
->getAnimation( _IdAnimationPlayed
)->getTrackByName( "pathpos" );
802 Track
->interpolate( (float)(time
- _StartAnimationTime
) * _PlayList
->getSpeedFactor( 0 ), translation
);
804 applyDeltaRotationAndPosition( rot
, translation
);
807 processLogicTemp( (_OldAnimationTime
- _StartAnimationTime
) * _PlayList
->getSpeedFactor( 0 ), (time
- _StartAnimationTime
) * _PlayList
->getSpeedFactor( 0 ) );
808 _OldAnimationTime
= time
;
812 // manage object animation
813 // TODO: manage other type animation than trigger distance and sequence list
814 void CAnimatedSceneObject::manageObjectAnimation( double Time
, CVector userPos
)
818 if( _IdAnimationPlayed
!= -1 )
820 if( Time
> ( _StartAnimationTime
+ (double) _AnimationSet
->getAnimation( _IdAnimationPlayed
)->getEndTime() / _PlayList
->getSpeedFactor( 0 ) ) )
822 overLoop
= Time
- _StartAnimationTime
- (double) _AnimationSet
->getAnimation( _IdAnimationPlayed
)->getEndTime() / _PlayList
->getSpeedFactor( 0 );
823 /* nlinfo("overLoop %f Time %f Start %f getEndTime() %f speedFactor() %f",
827 _AnimationSet->getAnimation( _IdAnimationPlayed )->getEndTime(),
828 _PlayList->getSpeedFactor( 0 ));
830 nlassert( overLoop
>= 0 );
832 // play through logic and movement of end of last animation before animation change
833 nlassert( Time
-overLoop
>= _StartAnimationTime
);
834 applyObjectAnimationTimeslice(Time
-overLoop
);
835 nlassert( Time
>= _StartAnimationTime
);
837 if( _Status
.LoopAnim
)
839 if( _StartAnimationTime
== 0 )
843 _StartAnimationTime
= Time
- overLoop
;
845 nlassert( Time
>= _StartAnimationTime
);
847 _PlayList
->setTimeOrigin( 0, _StartAnimationTime
);
851 removeOffsetAnimation ();
852 if( _Transform
!= NULL
)
854 _Transform
->freezeHRC();
856 _IdAnimationPlayed
= -1;
861 if( _IdAnimationPlayed
== -1 )
863 if( _Status
.CodeAnim
!= 1 )
865 if( ( _Distance
== 0 ) || ( ( userPos
- _Position
).sqrnorm() < _Distance
) )
867 if( _Status
.RandomAnim
== 1 )
869 StartRandomAnimation( Time
- overLoop
);
871 else if ( _Status
.SequenceAnim
== 1 )
873 StartNextAnimation( Time
- overLoop
);
879 float angle
= (float)((((uint32
)Time
* 1000)%(uint32
)(1000*2*Pi
))*0.001);
884 CQuat rot = CQuat (CVector (0, 0, 1), angle) * _Transform->getRotQuat();
887 _Transform
->setRotQuat( rot
.getRot() );
891 if( _IdAnimationPlayed
!= -1 )
893 // play through anim visuals and logic and movement for the timeslice
894 applyObjectAnimationTimeslice(Time
);
898 // Apply animation rotation and translation
899 void CAnimatedSceneObject::applyDeltaRotationAndPosition( CQuat
& rot
, CVector
& trans
)
901 if( _Transform
!= NULL
)
905 animation
.identity();
906 animation
.setPos (trans
);
907 animation
.setRot (rot
);
911 composed
= _AnimTransformation
* animation
;
913 _Rotation
= composed
.getRot();
914 _Position
= composed
.getPos();
916 CEntityCL
*entity
= getEntity(_Id
);
919 // \todo GUIGUI : TO CHECK
921 if( !entity
->flyer() )
922 _Position
.z
+= entity
->pos().z
;
924 entity
->pacsPos(_Position
);
925 entity
->snapToGround();
927 if( !entity
->flyer() )
928 _Position
.z
= entity
->pos().z
+ composed
.getPos().z
;
931 if( !entity
->flyer() )
933 _Position
.z
+= entity
->pos().z
;
934 entity
->pacsPos(_Position
);
935 entity
->snapToGround();
936 _Position
.z
= entity
->pos().z
+ composed
.getPos().z
;
940 entity
->pos(_Position
);
945 _Transform
->setRotQuat(_Rotation
);
946 _Transform
->setPos(_Position
);
951 // Instanciate an object and add it to map
952 void addAnimatedSceneObject( const string
& AnimatedSceneObjectName
, const string
& ClusterIG
, const string
& MeshName
, const string
& SkeletonName
, const list
<string
>& Animations
, const CVector
& Position
, const CQuat
& Rotation
, float Distance
)
954 if( AnimatedSceneObject
.find( AnimatedSceneObjectName
) == AnimatedSceneObject
.end() )
956 CAnimatedSceneObject
* o
= new CAnimatedSceneObject( AnimatedSceneObjectName
, ClusterIG
, MeshName
, SkeletonName
, Animations
, Position
, Rotation
, Distance
);
960 AnimatedSceneObject
.insert( make_pair( AnimatedSceneObjectName
, o
) );
965 void addEntityClAnimatedSceneObject( const CEntityId
& Id
, const list
< string
>& Animations
)
967 string test
= string( "CEntityId") + toString( Id
.Type
) + toString( Id
.Id
);
968 if( AnimatedSceneObject
.find( string( "CEntityId") + toString( Id
.Type
) + toString( Id
.Id
) ) == AnimatedSceneObject
.end() )
970 CAnimatedSceneObject
* o
= new CAnimatedSceneObject( Id
, Animations
);
974 AnimatedSceneObject
.insert( make_pair( string( "CEntityId") + toString( Id
.Type
) + toString( Id
.Id
), o
) );
979 void addUknowTypeSceneObject( const CEntityId
& Id
, NL3D::UTransform
*Transform
, const std::list
< std::string
>& Animations
, bool displacement
)
981 if( AnimatedSceneObject
.find( string( "CEntityId") + toString( Id
.Type
) + toString( Id
.Id
) ) == AnimatedSceneObject
.end() )
983 CAnimatedSceneObject
* o
= new CAnimatedSceneObject( Id
, Transform
, Animations
, displacement
);
987 AnimatedSceneObject
.insert( make_pair( string( "CEntityId") + toString( Id
.Type
) + toString( Id
.Id
), o
) );
992 // manage animated object
993 void manageAnimatedSceneObject( double Time
)
995 for( TMapCAnimatedSceneObject::iterator it
= AnimatedSceneObject
.begin(); it
!= AnimatedSceneObject
.end(); ++it
)
997 (*it
).second
->manageObjectAnimation( Time
, View
.viewPos() );
1002 void deleteAnimatedSceneObject( const string
& AnimatedSceneObjectName
)
1004 TMapCAnimatedSceneObject::iterator it
= AnimatedSceneObject
.find( AnimatedSceneObjectName
);
1005 if( it
!= AnimatedSceneObject
.end() )
1007 delete (*it
).second
;
1008 AnimatedSceneObject
.erase( it
);
1012 // update sequence animation
1013 void updateAnimationSequence( const CEntityId
& id
, const list
< string
>& sequence
, uint32 idSequence
)
1015 TMapCAnimatedSceneObject::iterator it
;
1017 for( it
= AnimatedSceneObject
.begin(); it
!= AnimatedSceneObject
.end(); ++it
)
1019 if( (*it
).second
->getId() == id
)
1025 if( it
!= AnimatedSceneObject
.end() )
1027 (*it
).second
->updateAnimationSequence( sequence
);
1028 (*it
).second
->idSequence( idSequence
);
1032 // Reset animation for the entity and break the current one.
1033 void resetAnimatedSceneObject(const CEntityId
& id
)
1035 for(TMapCAnimatedSceneObject::iterator it
= AnimatedSceneObject
.begin(); it
!= AnimatedSceneObject
.end(); ++it
)
1037 if((*it
).second
->getId() == id
)
1039 (*it
).second
->breakCurrentAnimation();
1040 (*it
).second
->resetSequence();
1041 (*it
).second
->resetInitialPos();
1047 void sendEndSequenceMessage( const CEntityId
& id
, uint32 idSequence
)
1051 "ANIME_BAR_MAN_END",
1052 SAnimeBarManEnd end
;
1054 end
.SlotNumber
= idSequence
;
1062 //---------------------------------------------------
1065 //---------------------------------------------------
1066 void CAnimatedSceneObject::processLogicTemp( double startOffset
, double endOffset
)
1068 static uint32 previousSoundIndex
= 0;
1070 // get the logical animation data across the current anim segment
1071 UTrack
* soundTrack
= NULL
;
1072 vector
<CAnimationTime
> result
;
1074 // EAM->processLogic( _AnimationsGlobalId[MOVING], startOffset, endOffset, soundTrack, result);
1076 // get infos about the anim
1078 char *soundTrackName
= "NoteTrack";
1079 soundTrack
= _AnimationSet
->getAnimation( _IdAnimationPlayed
)->getTrackByName( soundTrackName
);
1080 if( soundTrack
!= NULL
)
1082 UTrackKeyframer
* soundTrackKF
= dynamic_cast<UTrackKeyframer
*>(soundTrack
);
1083 if( soundTrackKF
== NULL
)
1085 nlerror("The track %s is not a key framer track",soundTrackName
);
1088 soundTrackKF
->getKeysInRange((float)startOffset
, (float)endOffset
, result
);
1096 vector
<CAnimationTime
>::iterator itResult
;
1097 for( itResult
= result
.begin(); itResult
!= result
.end(); ++itResult
)
1100 double keyTime
= *itResult
;
1101 nlinfo("keyTime = %f result size : %d",*itResult
,result
.size());
1103 if( !soundTrack
->interpolate( *itResult
, soundName
) )
1105 nlwarning("The key at offset %f is not a string",*itResult
);
1109 /* // if there are step sounds
1110 if( soundName == "step" )
1113 UGlobalPosition globalPos;
1114 getPrimitive()->getGlobalPosition(globalPos, dynamicWI);
1115 uint32 material = GR->getMaterial( globalPos );
1117 // choose the sound type soft/hard
1119 if( Type.TypeInfo.Sex == CTypeEntity::male )
1121 if( Type.TypeInfo.Sex == CTypeEntity::female )
1124 vector<string> sounds;
1125 uint32 soundSourceId;
1127 // choose the sound for the move type
1128 if( _AnimationsStateKey[MOVING] == "walk" )
1130 if( SoundMngr->getSounds( material, WALK, soft, sounds ) )
1132 string name = chooseRandom(sounds,previousSoundIndex );
1133 SoundMngr->spawnSound( name , pos ());
1137 nlwarning("<CEntityCL::updatePos> : there is no walk step sound for the material %d",material);
1138 SoundMngr->spawnSource( "Fwrks_Clac_1", pos() );
1141 _SoundSourcesId.push_back( soundSourceId );
1143 else*/ if (soundName
.find ("snd_") != string::npos
)
1145 // need to spawn a sound linked to the anim
1146 SoundMngr
->spawnSource( soundName
, _Position
);
1147 nlwarning ("launching sound for anim event from notetrack '%s'", soundName
.c_str());
1151 nlwarning ("unknown notetrack event: '%s'", soundName
.c_str());
1158 } // processAnimSounds //