324 lines
11 KiB
C++
324 lines
11 KiB
C++
|
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||
|
// Copyright (C) 2010 Winch Gate Property Limited
|
||
|
//
|
||
|
// This program is free software: you can redistribute it and/or modify
|
||
|
// it under the terms of the GNU Affero General Public License as
|
||
|
// published by the Free Software Foundation, either version 3 of the
|
||
|
// License, or (at your option) any later version.
|
||
|
//
|
||
|
// This program is distributed in the hope that it will be useful,
|
||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
// GNU Affero General Public License for more details.
|
||
|
//
|
||
|
// You should have received a copy of the GNU Affero General Public License
|
||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
|
|
||
|
|
||
|
|
||
|
#include "stdpch.h"
|
||
|
|
||
|
/////////////
|
||
|
// INCLUDE //
|
||
|
/////////////
|
||
|
// client
|
||
|
#include "animation_misc.h"
|
||
|
#include "animation.h"
|
||
|
// 3d
|
||
|
#include "nel/3d/u_track.h"
|
||
|
|
||
|
|
||
|
///////////
|
||
|
// USING //
|
||
|
///////////
|
||
|
using namespace NL3D;
|
||
|
|
||
|
|
||
|
////////////
|
||
|
// METHOD //
|
||
|
////////////
|
||
|
//---------------------------------------------------
|
||
|
// CAnimationMisc :
|
||
|
// Constructor.
|
||
|
//---------------------------------------------------
|
||
|
CAnimationMisc::CAnimationMisc()
|
||
|
{
|
||
|
}// CAnimationMisc //
|
||
|
|
||
|
//---------------------------------------------------
|
||
|
// interpolate :
|
||
|
// Function to get the position in animation at timeOffset.
|
||
|
// \param idAnim : id of the animation.
|
||
|
// \param timeOffset : time for the interpolation.
|
||
|
// \param result : is the reference on the value to get the result (position).
|
||
|
// \return bool : true if the parameter result is valid.
|
||
|
//---------------------------------------------------
|
||
|
bool CAnimationMisc::interpolate(UAnimationSet *animationSet, uint idAnim, double timeOffset, NLMISC::CVector &result)
|
||
|
{
|
||
|
// Get the animation set.
|
||
|
if(!animationSet)
|
||
|
{
|
||
|
nlwarning("CAnimationMisc::interpolate(CVector) : AnimationSet not allocated.");
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// Check the Animation
|
||
|
if(idAnim == UAnimationSet::NotFound)
|
||
|
return false;
|
||
|
|
||
|
// Get the animation pointer.
|
||
|
UAnimation *anim = animationSet->getAnimation(idAnim);
|
||
|
if(!anim)
|
||
|
{
|
||
|
nlwarning("CAnimationMisc::interpolate(CVector) : animationSet.getAnimation(%d) return NULL.", idAnim);
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// Get the track for the position.
|
||
|
UTrack* Track = anim->getTrackByName("pos");
|
||
|
if(!Track)
|
||
|
{
|
||
|
nlwarning("CAnimationMisc::interpolate(CVector) : track with the name 'pos' does not exist.");
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// Get the result.
|
||
|
return Track->interpolate((CAnimationTime)timeOffset, result);
|
||
|
}// interpolate //
|
||
|
|
||
|
//---------------------------------------------------
|
||
|
// interpolate :
|
||
|
// Function to get the rotation in an animation at timeOffset.
|
||
|
// \param animationSet : search the animation in this set.
|
||
|
// \param idAnim : id of the animation.
|
||
|
// \param timeOffset : time for the interpolation.
|
||
|
// \param result : is the reference on the value to get the result (rotation).
|
||
|
// \return bool : true if the parameter result is valid.
|
||
|
//---------------------------------------------------
|
||
|
bool CAnimationMisc::interpolate(UAnimationSet *animationSet, uint idAnim, double timeOffset, NLMISC::CQuat &result)
|
||
|
{
|
||
|
// Get the animation set.
|
||
|
if(!animationSet)
|
||
|
{
|
||
|
nlwarning("CAnimationMisc::interpolate(CQuat) : AnimationSet not allocated.");
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// Check the Animation
|
||
|
if(idAnim == UAnimationSet::NotFound)
|
||
|
return false;
|
||
|
|
||
|
// Get the animation pointer.
|
||
|
UAnimation *anim = animationSet->getAnimation(idAnim);
|
||
|
if(!anim)
|
||
|
{
|
||
|
nlwarning("CAnimationMisc::interpolate(CQuat) : animationSet.getAnimation(%d) return NULL.", idAnim);
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// Get the track for the position.
|
||
|
UTrack* Track = anim->getTrackByName("rotquat");
|
||
|
if(!Track)
|
||
|
{
|
||
|
nlwarning("CAnimationMisc::interpolate(CQuat) : track with the name 'PathRotQuat' or 'rotquat' does not exist.");
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// Get the result.
|
||
|
return Track->interpolate((CAnimationTime)timeOffset, result);
|
||
|
}// interpolate //
|
||
|
|
||
|
|
||
|
//---------------------------------------------------
|
||
|
// getAnimationLength :
|
||
|
// Return an animation length (in sec).
|
||
|
// \param animationSet : search the animation in this set.
|
||
|
// \param string animName : Animation Name.
|
||
|
// \return double : the length of the animation or 0 if any pb.
|
||
|
// \warning This Method is slower than the one with the animation Id instead of the animation Name.
|
||
|
//---------------------------------------------------
|
||
|
double CAnimationMisc::getAnimationLength(UAnimationSet *animationSet, const std::string &animName)
|
||
|
{
|
||
|
// Initialize the length to 0.0 like if there is an error.
|
||
|
double length = 0.0;
|
||
|
|
||
|
if(animationSet)
|
||
|
{
|
||
|
// Get the animation Id.
|
||
|
uint idAnim = animationSet->getAnimationIdByName(animName);
|
||
|
if(idAnim != UAnimationSet::NotFound)
|
||
|
length = getAnimationLength(animationSet, idAnim);
|
||
|
}
|
||
|
|
||
|
// Return the lenght of the animation or 0 is any pb.
|
||
|
return length;
|
||
|
}// getAnimationLength //
|
||
|
|
||
|
//---------------------------------------------------
|
||
|
// getAnimationLength :
|
||
|
// Return an animation length (in sec).
|
||
|
// \param animationSet : search the animation in this set.
|
||
|
// \param idAnim : id of the animation.
|
||
|
// \return double : the length of the animation or 0 if any pb.
|
||
|
//---------------------------------------------------
|
||
|
double CAnimationMisc::getAnimationLength(UAnimationSet *animationSet, uint idAnim)
|
||
|
{
|
||
|
// Initialize the length to 0.0 like if there is an error.
|
||
|
double length = 0.0;
|
||
|
|
||
|
// Check _AnimationSet.
|
||
|
if(animationSet)
|
||
|
{
|
||
|
// Check idAnim
|
||
|
if(idAnim != UAnimationSet::NotFound)
|
||
|
{
|
||
|
// Get the animation pointer and get the length.
|
||
|
UAnimation *anim = animationSet->getAnimation(idAnim);
|
||
|
if(anim)
|
||
|
length = anim->getEndTime() - anim->getBeginTime();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Return the lenght of the animation or 0 is any pb.
|
||
|
return length;
|
||
|
}// getAnimationLength //
|
||
|
|
||
|
|
||
|
//---------------------------------------------------
|
||
|
// getAnimationAverageSpeed :
|
||
|
// Get the average speed of an animation (in meters/sec).
|
||
|
// \param animationSet : search the animation in this set.
|
||
|
// \param string animName : Animation Name.
|
||
|
// \return double : the average speed (in m/s).
|
||
|
//---------------------------------------------------
|
||
|
double CAnimationMisc::getAnimationAverageSpeed(UAnimationSet *animationSet, const std::string &animName)
|
||
|
{
|
||
|
if(animationSet)
|
||
|
{
|
||
|
// Get the animation Id.
|
||
|
uint idAnim = animationSet->getAnimationIdByName(animName);
|
||
|
if(idAnim != UAnimationSet::NotFound)
|
||
|
return getAnimationAverageSpeed(animationSet, idAnim);
|
||
|
}
|
||
|
else
|
||
|
nlwarning("CAnimationMisc::getAnimationAverageSpeed : animationSet is NULL");
|
||
|
|
||
|
// Return the animation average speed.
|
||
|
return 0.0;
|
||
|
}// getAnimationAverageSpeed //
|
||
|
|
||
|
//---------------------------------------------------
|
||
|
// getAnimationAverageSpeed :
|
||
|
// Get the average speed of an animation (in meters/sec).
|
||
|
// \param animationSet : search the animation in this set.
|
||
|
// \param idAnim : id of the animation.
|
||
|
// \return double : the average speed (in m/s).
|
||
|
//---------------------------------------------------
|
||
|
double CAnimationMisc::getAnimationAverageSpeed(UAnimationSet *animationSet, uint idAnim)
|
||
|
{
|
||
|
// Initialize the length to 0.0 like if there is an error.
|
||
|
double length = getAnimationLength(animationSet, idAnim);
|
||
|
|
||
|
// Check the length.
|
||
|
if(length <= 0.0)
|
||
|
{
|
||
|
nlwarning("CEntityAnimationManager::getAnimationAverageSpeed : length <= 0.0 -> return speed = 0.0");
|
||
|
return 0.0;
|
||
|
}
|
||
|
|
||
|
// Get the distance done by the animation.
|
||
|
double move = 0.0;
|
||
|
NLMISC::CVector startPos, endPos;
|
||
|
if(interpolate(animationSet, idAnim, 0.0, startPos))
|
||
|
{
|
||
|
if(interpolate(animationSet, idAnim, length, endPos))
|
||
|
{
|
||
|
NLMISC::CVector mov = endPos - startPos;
|
||
|
move = mov.norm();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Return the animation average speed.
|
||
|
return (move / length);
|
||
|
}// getAnimationAverageSpeed //
|
||
|
|
||
|
|
||
|
//---------------------------------------------------
|
||
|
// getAnimationRotation :
|
||
|
// Get the rotation done by the animation (in radian).
|
||
|
// \param animationSet : search the animation in this set.
|
||
|
// \param string animName : Animation Name.
|
||
|
// \return double : the rotation (in radian).
|
||
|
//---------------------------------------------------
|
||
|
double CAnimationMisc::getAnimationRotation(NL3D::UAnimationSet *animationSet, const std::string &animName)
|
||
|
{
|
||
|
if(animationSet)
|
||
|
{
|
||
|
// Get the animation Id.
|
||
|
uint idAnim = animationSet->getAnimationIdByName(animName);
|
||
|
if(idAnim != UAnimationSet::NotFound)
|
||
|
return getAnimationRotation(animationSet, idAnim);
|
||
|
}
|
||
|
else
|
||
|
nlwarning("CAnimationMisc::getAnimationRotation : animationSet is NULL");
|
||
|
|
||
|
// Return the animation average speed.
|
||
|
return 0.0;
|
||
|
}// getAnimationRotation //
|
||
|
|
||
|
//---------------------------------------------------
|
||
|
// getAnimationRotation :
|
||
|
// Get the rotation done by the animation (in radian).
|
||
|
// \param animationSet : search the animation in this set.
|
||
|
// \param idAnim : id of the animation.
|
||
|
// \return double : the rotation (in radian).
|
||
|
//---------------------------------------------------
|
||
|
double CAnimationMisc::getAnimationRotation(NL3D::UAnimationSet *animationSet, uint idAnim)
|
||
|
{
|
||
|
// Check the animation Id.
|
||
|
if(idAnim != CAnimation::UnknownAnim)
|
||
|
{
|
||
|
CQuat currentAnimRotStart, currentAnimRotEnd;
|
||
|
if(CAnimationMisc::interpolate(animationSet, idAnim, 0.0, currentAnimRotStart))
|
||
|
{
|
||
|
double animLength = CAnimationMisc::getAnimationLength(animationSet, idAnim);
|
||
|
if(CAnimationMisc::interpolate(animationSet, idAnim, animLength, currentAnimRotEnd))
|
||
|
{
|
||
|
currentAnimRotStart.invert();
|
||
|
CQuat currentAnimRot = currentAnimRotStart * currentAnimRotEnd;
|
||
|
return fabs(currentAnimRot.getAngle());
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return 0.f;
|
||
|
}// getAnimationRotation //
|
||
|
|
||
|
//-----------------------------------------------
|
||
|
// Get the vector covered by the given animation.
|
||
|
// \param animationSet : search the animation in this set.
|
||
|
// \param idAnim : id of the animation.
|
||
|
// \param move : filled with the vector of the move if possible
|
||
|
// \return bool : true if 'move' has been filled, else false.
|
||
|
//-----------------------------------------------
|
||
|
bool CAnimationMisc::getAnimationMove(NL3D::UAnimationSet *animationSet, uint idAnim, NLMISC::CVector &move) // static
|
||
|
{
|
||
|
CVector startPos, endPos;
|
||
|
if(CAnimationMisc::interpolate(animationSet, idAnim, 0.0, startPos))
|
||
|
{
|
||
|
double animLength = CAnimationMisc::getAnimationLength(animationSet, idAnim);
|
||
|
if(animLength)
|
||
|
{
|
||
|
if(CAnimationMisc::interpolate(animationSet, idAnim, animLength, endPos))
|
||
|
{
|
||
|
// Well Done.
|
||
|
move = endPos - startPos;
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Something Wrong -> return false.
|
||
|
return false;
|
||
|
}// getAnimationMove //
|