Files
FC1/CryAnimation/Controller.h
romkazvo 34d6c5d489 123
2023-08-07 19:29:24 +08:00

129 lines
4.8 KiB
C++

/////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Crytek Character Animation source code
//
// History:
// Created by Sergiy Migdalskiy
//
// Notes:
// IController interface declaration
// See the IController comment for more info
//
/////////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef _CRYTEK_CONTROLLER_HEADER_
#define _CRYTEK_CONTROLLER_HEADER_
#include "StringUtils.h"
#include "CryHeaders.h"
//////////////////////////////////////////////////////////////////////////////////////////
// interface IController
// Describes the position and orientation of an object, changing in time.
// Responsible for loading itself from a binary file, calculations
//////////////////////////////////////////////////////////////////////////////////////////
class IController: public _reference_target_t
{
public:
// each controller has an ID, by which it is identifiable
virtual unsigned GetID () const = 0;
// returns the orientation of the controller at the given time
virtual CryQuat GetOrientation (float t) = 0;
// returns the orientation of the controller at the given time, in logarithmic space
virtual Vec3 GetOrientation2 (float t) = 0;
// returns position of the controller at the given time
virtual Vec3 GetPosition (float t) = 0;
// returns scale of the controller at the given time
virtual Vec3 GetScale (float t) = 0;
// retrieves the position and orientation within one call
// may be optimal in some applications
virtual void GetValue (float t, CryQuat& q, Vec3 &p) = 0;
// retrieves the position and orientation (in the logarithmic space, i.e. instead of quaternion, its logarithm is returned)
// may be optimal for motion interpolation
struct PQLog
{
Vec3 vPos;
Vec3 vRotLog; // logarithm of the rotation
string toString()const {return "{pos:" + CryStringUtils::toString(vPos)+", rot="+CryStringUtils::toString (vRotLog) + "}";}
// returns the rotation quaternion
CryQuat getOrientation()const;
// resets the state to zero
void reset ();
// blends the pqSource[0] and pqSource[1] with weights 1-fBlend and fBlend into pqResult
void blendPQ (const PQLog* pqSource, float fBlend);
// blends the pqFrom and pqTo with weights 1-fBlend and fBlend into pqResult
void blendPQ (const PQLog& pqFrom, const PQLog& pqTo, float fBlend);
// builds the matrix out of the position and orientation stored in this PQLog
void buildMatrix(Matrix44& mat)const;
// a special version of the buildMatrix that adds a rotation to the rotation of this PQLog
void buildMatrixPlusRot(Matrix44& mat, const CryQuat& qRotPlus) const;
// returns the equivalent rotation in logarithmic space (the quaternion of which is negative the original)
Vec3 getComplementaryRotLog() const;
// constructs the position/rotation from the given matrix
void assignFromMatrix (const Matrix44& mat);
PQLog operator * (float f)const
{
PQLog res;
res.vPos = this->vPos * f;
res.vRotLog = this->vRotLog * f;
return res;
}
const PQLog& operator += (const PQLog& pq)
{
this->vPos += pq.vPos;
this->vRotLog += pq.vRotLog;
return *this;
}
};
virtual void GetValue2 (float t, PQLog& pq) = 0;
// returns the start time
virtual float GetTimeStart () = 0;
// returns the end time
virtual float GetTimeEnd() = 0;
virtual size_t sizeofThis () const = 0;
virtual bool IsLooping() const { return false; };
};
TYPEDEF_AUTOPTR(IController);
//typedef IController*IController_AutoPtr;
// adjusts the rotation of these PQs: if necessary, flips them or one of them (effectively NOT changing the whole rotation,but
// changing the rotation angle to Pi-X and flipping the rotation axis simultaneously)
// this is needed for blending between animations represented by quaternions rotated by ~PI in quaternion space
// (and thus ~2*PI in real space)
extern void AdjustLogRotations (Vec3& vRotLog1, Vec3& vRotLog2);
extern void AdjustLogRotationTo (const Vec3& vRotLog1, Vec3& vRotLog2);
extern void AdjustLogRotation(Vec3& vRotLog);
//////////////////////////////////////////////////////////////////////////
// This class is a non-trivial predicate used for sorting an
// ARRAY OF smart POINTERS to IController's. That's why I need a separate
// predicate class for that. Also, to avoid multiplying predicate classes,
// there are a couple of functions that are also used to find a IController
// in a sorted by ID array of IController* pointers, passing only ID to the
// lower_bound function instead of creating and passing a dummy IController*
class AnimCtrlSortPred
{
public:
bool operator() (const IController_AutoPtr& a, const IController_AutoPtr& b) {assert (a!=(IController*)NULL && b != (IController*)NULL); return a->GetID() < b->GetID();}
bool operator() (const IController_AutoPtr& a, unsigned nID) {assert (a != (IController*)NULL);return a->GetID() < nID;}
};
#endif