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

138 lines
4.7 KiB
C++

// Implementation of Packed BSpline Controller
#include "stdafx.h"
#include "Controller.h"
#include "ControllerPackedBSpline.h"
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Loads (initializes) controller from the given chunk. The chunk descriptor is followed by the
// chunk data immediately. Returns true if successful
// PARAMETERS:
// pChunk - the header of the chunk to load data from. This is the start of the chunk in memory-mapped file normally.
// nSize - size of the chunk in bytes, including the header structure
// scale - factor to scale the positional data after successful load
// pILog - ILog
// RETURNS:
// true if successfully loaded the controller, false otherwise (controller is not ready)
bool CControllerPackedBSpline::Load (const CONTROLLER_CHUNK_DESC_0826* pChunk, int nSize, float scale)
{
// create one of the possible representations of packed spline, depending on the
// format of the chunk: either 1- or 2-byte fixed point numbers and either closed or open spline
switch (pChunk->type)
{
case CTRL_BSPLINE_1C:
m_pRot = new TBSplineVec3dPacked<false,unsigned char>();
m_pPos = new TBSplineVec3dPacked<false,unsigned char>();
break;
case CTRL_BSPLINE_2C:
m_pRot = new TBSplineVec3dPacked<false,unsigned short>();
m_pPos = new TBSplineVec3dPacked<false,unsigned short>();
break;
case CTRL_BSPLINE_1O:
m_pRot = new TBSplineVec3dPacked<true,unsigned char>();
m_pPos = new TBSplineVec3dPacked<true,unsigned char>();
break;
case CTRL_BSPLINE_2O:
m_pRot = new TBSplineVec3dPacked<true,unsigned short>();
m_pPos = new TBSplineVec3dPacked<true,unsigned short>();
break;
default:
return false;
};
// The chunk must be at least big enough to contain the header structure
if (nSize < sizeof (CONTROLLER_CHUNK_DESC_0826))
return false;
// controller identification will be subsequently used for bone binding
m_nControllerId = pChunk->nControllerId;
//
if(pChunk->chdr.ChunkType != ChunkType_Controller || pChunk->chdr.ChunkVersion != CONTROLLER_CHUNK_DESC_0826::VERSION)
{
GetLog()->LogToFile("CControllerPackedBSpline::Load: File version error");
return false;
}
// go to the positional raw data subchunk
char* pRawData = (char*)(pChunk+1);
// remaining chunk piece size
int nRawDataSize = nSize - sizeof (CONTROLLER_CHUNK_DESC_0826);
// try to construct the position spline from the raw data
int nPosDataSize = m_pPos->unpack (pRawData, nRawDataSize);
if (!nPosDataSize)
return false; // couldn't construct
// the positional data has been successfully constructed
// now scale it by the given factor
m_pPos->scale (scale);
// proceed with the rotation subchunk
nRawDataSize -= nPosDataSize;
pRawData += nPosDataSize;
int nRotDataSize = m_pRot->unpack (pRawData, nRawDataSize);
if (!nRotDataSize)
return false;
nRawDataSize -= nRotDataSize;
pRawData += nRotDataSize;
if (nRawDataSize != 0)
{
// the chunk loaded ok, but not all of its data has been used
GetLog()->LogToFile("CControllerPackedBSpline::Load: %d extra bytes at hte end of the chunk", nRawDataSize );
}
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// returns position of the controller at the given time
CryQuat CControllerPackedBSpline::GetOrientation (float t)
{
return exp ( quaternionf(0,CControllerPackedBSpline::GetOrientation2(t)) );
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// returns position of the controller at the given time
Vec3 CControllerPackedBSpline::GetPosition (float t)
{
return m_pPos->getValue (t/*/BSplineKnots::g_nStdTicksPerSecond*/);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// retrieves the position and orientation within one call
// may be optimal in some applications
void CControllerPackedBSpline::GetValue (float t, CryQuat& q, Vec3 &p)
{
q = GetOrientation(t);
p = GetPosition(t);
}
// retrieves the position and orientation (in the logarithmic space, i.e. instead of quaternion, its logarithm is returned)
// may be optimal for motion interpolation
void CControllerPackedBSpline::GetValue2 (float t, PQLog& pq)
{
pq.vPos = GetPosition(t);
pq.vRotLog = GetOrientation2(t);
}
// returns the orientation of the controller at the given time, in logarithmic space
Vec3 CControllerPackedBSpline::GetOrientation2(float t)
{
return m_pRot->getValue (t/*/BSplineKnots::g_nStdTicksPerSecond*/);
}
ILog* CControllerPackedBSpline::GetLog()const
{
return g_GetLog();
}
size_t CControllerPackedBSpline::sizeofThis ()const
{
return sizeof(*this) + m_pPos->sizeofThis() + m_pRot->sizeofThis();
}