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/>.
25 #include "animation_misc.h"
26 #include "animation.h"
28 #include "nel/3d/u_track.h"
43 //---------------------------------------------------
46 //---------------------------------------------------
47 CAnimationMisc::CAnimationMisc()
51 //---------------------------------------------------
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.
64 nlwarning("CAnimationMisc::interpolate(CVector) : AnimationSet not allocated.");
68 // Check the Animation
69 if(idAnim
== UAnimationSet::NotFound
)
72 // Get the animation pointer.
73 UAnimation
*anim
= animationSet
->getAnimation(idAnim
);
76 nlwarning("CAnimationMisc::interpolate(CVector) : animationSet.getAnimation(%d) return NULL.", idAnim
);
80 // Get the track for the position.
81 UTrack
* Track
= anim
->getTrackByName("pos");
84 nlwarning("CAnimationMisc::interpolate(CVector) : track with the name 'pos' does not exist.");
89 return Track
->interpolate((CAnimationTime
)timeOffset
, result
);
92 //---------------------------------------------------
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.
106 nlwarning("CAnimationMisc::interpolate(CQuat) : AnimationSet not allocated.");
110 // Check the Animation
111 if(idAnim
== UAnimationSet::NotFound
)
114 // Get the animation pointer.
115 UAnimation
*anim
= animationSet
->getAnimation(idAnim
);
118 nlwarning("CAnimationMisc::interpolate(CQuat) : animationSet.getAnimation(%d) return NULL.", idAnim
);
122 // Get the track for the position.
123 UTrack
* Track
= anim
->getTrackByName("rotquat");
126 //nlwarning("CAnimationMisc::interpolate(CQuat) : track with the name 'PathRotQuat' or 'rotquat' does not exist.");
131 return Track
->interpolate((CAnimationTime
)timeOffset
, result
);
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.
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.
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.
172 // Check _AnimationSet.
176 if(idAnim
!= UAnimationSet::NotFound
)
178 // Get the animation pointer and get the length.
179 UAnimation
*anim
= animationSet
->getAnimation(idAnim
);
181 length
= anim
->getEndTime() - anim
->getBeginTime();
185 // Return the length of the animation or 0 is any pb.
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
)
201 // Get the animation Id.
202 uint idAnim
= animationSet
->getAnimationIdByName(animName
);
203 if(idAnim
!= UAnimationSet::NotFound
)
204 return getAnimationAverageSpeed(animationSet
, idAnim
);
207 nlwarning("CAnimationMisc::getAnimationAverageSpeed : animationSet is NULL");
209 // Return the animation average speed.
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
);
228 nlwarning("CEntityAnimationManager::getAnimationAverageSpeed : length <= 0.0 -> return speed = 0.0");
232 // Get the distance done by the animation.
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
;
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
)
260 // Get the animation Id.
261 uint idAnim
= animationSet
->getAnimationIdByName(animName
);
262 if(idAnim
!= UAnimationSet::NotFound
)
263 return getAnimationRotation(animationSet
, idAnim
);
266 nlwarning("CAnimationMisc::getAnimationRotation : animationSet is NULL");
268 // Return the animation average speed.
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());
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
);
315 if(CAnimationMisc::interpolate(animationSet
, idAnim
, animLength
, endPos
))
318 move
= endPos
- startPos
;
324 // Something Wrong -> return false.
326 }// getAnimationMove //