Resolve "Toggle Free Look with Hotkey"
[ryzomcore.git] / ryzom / client / src / animation_misc.cpp
blob60b13c83c13388724375e5bfc4003f9aa16e0bcf
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"
21 /////////////
22 // INCLUDE //
23 /////////////
24 // client
25 #include "animation_misc.h"
26 #include "animation.h"
27 // 3d
28 #include "nel/3d/u_track.h"
30 #ifdef DEBUG_NEW
31 #define new DEBUG_NEW
32 #endif
34 ///////////
35 // USING //
36 ///////////
37 using namespace NL3D;
40 ////////////
41 // METHOD //
42 ////////////
43 //---------------------------------------------------
44 // CAnimationMisc :
45 // Constructor.
46 //---------------------------------------------------
47 CAnimationMisc::CAnimationMisc()
49 }// CAnimationMisc //
51 //---------------------------------------------------
52 // interpolate :
53 // Function to get the position in animation at timeOffset.
54 // \param idAnim : id of the animation.
55 // \param timeOffset : time for the interpolation.
56 // \param result : is the reference on the value to get the result (position).
57 // \return bool : true if the parameter result is valid.
58 //---------------------------------------------------
59 bool CAnimationMisc::interpolate(UAnimationSet *animationSet, uint idAnim, double timeOffset, NLMISC::CVector &result)
61 // Get the animation set.
62 if(!animationSet)
64 nlwarning("CAnimationMisc::interpolate(CVector) : AnimationSet not allocated.");
65 return false;
68 // Check the Animation
69 if(idAnim == UAnimationSet::NotFound)
70 return false;
72 // Get the animation pointer.
73 UAnimation *anim = animationSet->getAnimation(idAnim);
74 if(!anim)
76 nlwarning("CAnimationMisc::interpolate(CVector) : animationSet.getAnimation(%d) return NULL.", idAnim);
77 return false;
80 // Get the track for the position.
81 UTrack* Track = anim->getTrackByName("pos");
82 if(!Track)
84 nlwarning("CAnimationMisc::interpolate(CVector) : track with the name 'pos' does not exist.");
85 return false;
88 // Get the result.
89 return Track->interpolate((CAnimationTime)timeOffset, result);
90 }// interpolate //
92 //---------------------------------------------------
93 // interpolate :
94 // Function to get the rotation in an animation at timeOffset.
95 // \param animationSet : search the animation in this set.
96 // \param idAnim : id of the animation.
97 // \param timeOffset : time for the interpolation.
98 // \param result : is the reference on the value to get the result (rotation).
99 // \return bool : true if the parameter result is valid.
100 //---------------------------------------------------
101 bool CAnimationMisc::interpolate(UAnimationSet *animationSet, uint idAnim, double timeOffset, NLMISC::CQuat &result)
103 // Get the animation set.
104 if(!animationSet)
106 nlwarning("CAnimationMisc::interpolate(CQuat) : AnimationSet not allocated.");
107 return false;
110 // Check the Animation
111 if(idAnim == UAnimationSet::NotFound)
112 return false;
114 // Get the animation pointer.
115 UAnimation *anim = animationSet->getAnimation(idAnim);
116 if(!anim)
118 nlwarning("CAnimationMisc::interpolate(CQuat) : animationSet.getAnimation(%d) return NULL.", idAnim);
119 return false;
122 // Get the track for the position.
123 UTrack* Track = anim->getTrackByName("rotquat");
124 if(!Track)
126 //nlwarning("CAnimationMisc::interpolate(CQuat) : track with the name 'PathRotQuat' or 'rotquat' does not exist.");
127 return false;
130 // Get the result.
131 return Track->interpolate((CAnimationTime)timeOffset, result);
132 }// interpolate //
135 //---------------------------------------------------
136 // getAnimationLength :
137 // Return an animation length (in sec).
138 // \param animationSet : search the animation in this set.
139 // \param string animName : Animation Name.
140 // \return double : the length of the animation or 0 if any pb.
141 // \warning This Method is slower than the one with the animation Id instead of the animation Name.
142 //---------------------------------------------------
143 double CAnimationMisc::getAnimationLength(UAnimationSet *animationSet, const std::string &animName)
145 // Initialize the length to 0.0 like if there is an error.
146 double length = 0.0;
148 if(animationSet)
150 // Get the animation Id.
151 uint idAnim = animationSet->getAnimationIdByName(animName);
152 if(idAnim != UAnimationSet::NotFound)
153 length = getAnimationLength(animationSet, idAnim);
156 // Return the length of the animation or 0 is any pb.
157 return length;
158 }// getAnimationLength //
160 //---------------------------------------------------
161 // getAnimationLength :
162 // Return an animation length (in sec).
163 // \param animationSet : search the animation in this set.
164 // \param idAnim : id of the animation.
165 // \return double : the length of the animation or 0 if any pb.
166 //---------------------------------------------------
167 double CAnimationMisc::getAnimationLength(UAnimationSet *animationSet, uint idAnim)
169 // Initialize the length to 0.0 like if there is an error.
170 double length = 0.0;
172 // Check _AnimationSet.
173 if(animationSet)
175 // Check idAnim
176 if(idAnim != UAnimationSet::NotFound)
178 // Get the animation pointer and get the length.
179 UAnimation *anim = animationSet->getAnimation(idAnim);
180 if(anim)
181 length = anim->getEndTime() - anim->getBeginTime();
185 // Return the length of the animation or 0 is any pb.
186 return length;
187 }// getAnimationLength //
190 //---------------------------------------------------
191 // getAnimationAverageSpeed :
192 // Get the average speed of an animation (in meters/sec).
193 // \param animationSet : search the animation in this set.
194 // \param string animName : Animation Name.
195 // \return double : the average speed (in m/s).
196 //---------------------------------------------------
197 double CAnimationMisc::getAnimationAverageSpeed(UAnimationSet *animationSet, const std::string &animName)
199 if(animationSet)
201 // Get the animation Id.
202 uint idAnim = animationSet->getAnimationIdByName(animName);
203 if(idAnim != UAnimationSet::NotFound)
204 return getAnimationAverageSpeed(animationSet, idAnim);
206 else
207 nlwarning("CAnimationMisc::getAnimationAverageSpeed : animationSet is NULL");
209 // Return the animation average speed.
210 return 0.0;
211 }// getAnimationAverageSpeed //
213 //---------------------------------------------------
214 // getAnimationAverageSpeed :
215 // Get the average speed of an animation (in meters/sec).
216 // \param animationSet : search the animation in this set.
217 // \param idAnim : id of the animation.
218 // \return double : the average speed (in m/s).
219 //---------------------------------------------------
220 double CAnimationMisc::getAnimationAverageSpeed(UAnimationSet *animationSet, uint idAnim)
222 // Initialize the length to 0.0 like if there is an error.
223 double length = getAnimationLength(animationSet, idAnim);
225 // Check the length.
226 if(length <= 0.0)
228 nlwarning("CEntityAnimationManager::getAnimationAverageSpeed : length <= 0.0 -> return speed = 0.0");
229 return 0.0;
232 // Get the distance done by the animation.
233 double move = 0.0;
234 NLMISC::CVector startPos, endPos;
235 if(interpolate(animationSet, idAnim, 0.0, startPos))
237 if(interpolate(animationSet, idAnim, length, endPos))
239 NLMISC::CVector mov = endPos - startPos;
240 move = mov.norm();
244 // Return the animation average speed.
245 return (move / length);
246 }// getAnimationAverageSpeed //
249 //---------------------------------------------------
250 // getAnimationRotation :
251 // Get the rotation done by the animation (in radian).
252 // \param animationSet : search the animation in this set.
253 // \param string animName : Animation Name.
254 // \return double : the rotation (in radian).
255 //---------------------------------------------------
256 double CAnimationMisc::getAnimationRotation(NL3D::UAnimationSet *animationSet, const std::string &animName)
258 if(animationSet)
260 // Get the animation Id.
261 uint idAnim = animationSet->getAnimationIdByName(animName);
262 if(idAnim != UAnimationSet::NotFound)
263 return getAnimationRotation(animationSet, idAnim);
265 else
266 nlwarning("CAnimationMisc::getAnimationRotation : animationSet is NULL");
268 // Return the animation average speed.
269 return 0.0;
270 }// getAnimationRotation //
272 //---------------------------------------------------
273 // getAnimationRotation :
274 // Get the rotation done by the animation (in radian).
275 // \param animationSet : search the animation in this set.
276 // \param idAnim : id of the animation.
277 // \return double : the rotation (in radian).
278 //---------------------------------------------------
279 double CAnimationMisc::getAnimationRotation(NL3D::UAnimationSet *animationSet, uint idAnim)
281 // Check the animation Id.
282 if(idAnim != CAnimation::UnknownAnim)
284 CQuat currentAnimRotStart, currentAnimRotEnd;
285 if(CAnimationMisc::interpolate(animationSet, idAnim, 0.0, currentAnimRotStart))
287 double animLength = CAnimationMisc::getAnimationLength(animationSet, idAnim);
288 if(CAnimationMisc::interpolate(animationSet, idAnim, animLength, currentAnimRotEnd))
290 currentAnimRotStart.invert();
291 CQuat currentAnimRot = currentAnimRotStart * currentAnimRotEnd;
292 return fabs(currentAnimRot.getAngle());
297 return 0.f;
298 }// getAnimationRotation //
300 //-----------------------------------------------
301 // Get the vector covered by the given animation.
302 // \param animationSet : search the animation in this set.
303 // \param idAnim : id of the animation.
304 // \param move : filled with the vector of the move if possible
305 // \return bool : true if 'move' has been filled, else false.
306 //-----------------------------------------------
307 bool CAnimationMisc::getAnimationMove(NL3D::UAnimationSet *animationSet, uint idAnim, NLMISC::CVector &move) // static
309 CVector startPos, endPos;
310 if(CAnimationMisc::interpolate(animationSet, idAnim, 0.0, startPos))
312 double animLength = CAnimationMisc::getAnimationLength(animationSet, idAnim);
313 if(animLength)
315 if(CAnimationMisc::interpolate(animationSet, idAnim, animLength, endPos))
317 // Well Done.
318 move = endPos - startPos;
319 return true;
324 // Something Wrong -> return false.
325 return false;
326 }// getAnimationMove //