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 "stdpch.h" // First include for pre-compiled headers.
25 #include "nel/misc/path.h"
27 #include "animation_set.h"
28 #include "animation_misc.h"
29 #include "debug_client.h"
30 #include "client_cfg.h"
32 #include "nel/georges/u_form.h"
33 #include "nel/georges/u_form_elm.h"
34 #include "nel/georges/u_form_loader.h"
43 using namespace NLMISC
;
44 using namespace NLGEORGES
;
51 //-----------------------------------------------
54 //-----------------------------------------------
55 CAnimationSet::CAnimationSet()
59 _AboutFaceAngle
= 3.0*Pi
/4.0;
70 //-----------------------------------------------
72 //-----------------------------------------------
73 void CAnimationSet::init(CAnimationSetSheet
*sheet
, NL3D::UAnimationSet
*animationSet
)
76 _AnimationStates
.resize(_Sheet
->AnimationStates
.size());
77 for (uint32 i
= 0; i
< _AnimationStates
.size(); ++i
)
79 _AnimationStates
[i
].init(&_Sheet
->AnimationStates
[i
], animationSet
);
82 const CAnimationState
*animState
= getAnimationState (CAnimationStateSheet::Walk
);
85 // Compute the distance to break the idle (done according to the walk state).
86 CAnimation::TAnimId walkId
= animState
->chooseAnim(0, EGSPD::CPeople::Unknown
, GSGENDER::male
);
87 // Check the animation Id.
88 if(walkId
!= CAnimation::UnknownAnim
)
91 const CAnimation
*walkAnim
= animState
->getAnimation(walkId
);
93 // Compute the dist made by the walk animation.
95 if(CAnimationMisc::getAnimationMove(animationSet
, walkAnim
->id(), mov
))
97 _WalkDist
= fabs(mov
.y
);
98 _MaxDist
= ClientCfg
.MinDistFactor
*_WalkDist
;
100 _WalkLength
= CAnimationMisc::getAnimationLength(animationSet
, walkAnim
->id());
102 animState
= getAnimationState (CAnimationStateSheet::Run
);
105 // Get the run animation ID.
106 CAnimation::TAnimId runId
= animState
->chooseAnim(0, EGSPD::CPeople::Unknown
, GSGENDER::male
);
107 if(runId
!= CAnimation::UnknownAnim
)
110 const CAnimation
*runAnim
= animState
->getAnimation(runId
);
113 if(CAnimationMisc::getAnimationMove(animationSet
, runAnim
->id(), mov
))
114 _RunDist
= fabs(mov
.y
);
115 _RunLength
= CAnimationMisc::getAnimationLength(animationSet
, runAnim
->id());
117 // Get the walk average speed.
118 double aveWalk
= CAnimationMisc::getAnimationAverageSpeed(animationSet
, walkAnim
->id());
119 // Get the run average speed.
120 double aveRun
= CAnimationMisc::getAnimationAverageSpeed(animationSet
, runAnim
->id());
121 pushInfoStr(NLMISC::toString("Walk speed(%f).", aveWalk
));
122 pushInfoStr(NLMISC::toString("Run speed(%f).", aveRun
));
124 // Check animations average speed for walk and run.
126 pushDebugStr(NLMISC::toString("Walk speed(%f) > Run speed(%f) !", aveWalk
, aveRun
));
129 double ave
= (aveWalk
+aveRun
)/2.0;
131 // Compute the min speed to run when walking.
132 _SpeedToRun
= (ave
+ aveRun
)/2.0;
133 // Compute the max speed to walk when running.
134 _SpeedToWalk
= (ave
+ aveWalk
)/2.0;
136 // No animation found to run.
138 if(_Sheet
->IsRunEssential
)
139 pushDebugStr("No animation found to run: speedToRun and speedToWalk will return the default value.");
142 // No animation found to walk.
144 if(_Sheet
->IsWalkEssential
)
145 pushDebugStr("No animation found to walk: maxDist, speedToRun and speedToWalk will return the default value.");
148 // Compute the angle after the one the character should turn (left/or right).
149 animState
= getAnimationState (CAnimationStateSheet::TurnLeft
);
152 CAnimation::TAnimId turnLeftId
= animState
->chooseAnim(0, EGSPD::CPeople::Unknown
, GSGENDER::male
);
153 // Check the animation Id.
154 if(turnLeftId
!= CAnimation::UnknownAnim
)
157 const CAnimation
*anim
= animState
->getAnimation(turnLeftId
);
160 CQuat currentAnimRotStart
, currentAnimRotEnd
;
161 if(CAnimationMisc::interpolate(animationSet
, anim
->id(), 0.0, currentAnimRotStart
))
163 double animLength
= CAnimationMisc::getAnimationLength(animationSet
, turnLeftId
);
164 if(CAnimationMisc::interpolate(animationSet
, anim
->id(), animLength
, currentAnimRotEnd
))
166 currentAnimRotStart
.invert();
167 CQuat currentAnimRot
= currentAnimRotStart
* currentAnimRotEnd
;
168 _Angle
= 0.75 * fabs(currentAnimRot
.getAngle());
176 //-----------------------------------------------
177 // getAnimationStateByIndex
178 //-----------------------------------------------
179 CAnimationState
*CAnimationSet::getAnimationStateByIndex(uint index
)
181 if (index
>= _AnimationStates
.size()) return NULL
;
182 return &_AnimationStates
[index
];
184 }// getAnimationStateByIndex //