718 lines
31 KiB
C++
718 lines
31 KiB
C++
/*
|
|
** Command & Conquer Renegade(tm)
|
|
** Copyright 2025 Electronic Arts Inc.
|
|
**
|
|
** This program is free software: you can redistribute it and/or modify
|
|
** it under the terms of the GNU 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 General Public License for more details.
|
|
**
|
|
** You should have received a copy of the GNU General Public License
|
|
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
/***********************************************************************************************
|
|
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
|
|
***********************************************************************************************
|
|
* *
|
|
* Project Name : WW3D *
|
|
* *
|
|
* $Archive:: /Commando/Code/ww3d2/hrawanim.cpp $*
|
|
* *
|
|
* Original Author:: Greg Hjelstrom *
|
|
* *
|
|
* $Author:: Jani_p $*
|
|
* *
|
|
* $Modtime:: 11/25/01 6:06p $*
|
|
* *
|
|
* $Revision:: 5 $*
|
|
* *
|
|
*---------------------------------------------------------------------------------------------*
|
|
* Functions: *
|
|
* HRawAnimClass::HRawAnimClass -- constructor *
|
|
* HRawAnimClass::~HRawAnimClass -- Destructor *
|
|
* HRawAnimClass::Free -- De-allocates all memory in use *
|
|
* HRawAnimClass::Load -- Loads hierarchy animation from a file *
|
|
* HRawAnimClass::read_channel -- Reads in a single channel of motion *
|
|
* HRawAnimClass::add_channel -- Adds a motion channel to the animation *
|
|
* HRawAnimClass::Get_Translation -- returns the translation vector for the given frame *
|
|
* HRawAnimClass::Get_Orientation -- returns a quaternion for the orientation of the pivot *
|
|
* HRawAnimClass::Get_XRotation -- Returns the X euler angle for the given pivot, frame *
|
|
* HRawAnimClass::Get_YRotation -- returns the Y Euler angle for the given pivot, frame *
|
|
* HRawAnimClass::Get_ZRotation -- returns the Z Euler angle for the given pivot, frame *
|
|
* HRawAnimClass::read_bit_channel -- read a bit channel from the file *
|
|
* HRawAnimClass::add_bit_channel -- install a bit channel into the animation *
|
|
* HRawAnimClass::Get_Visibility -- return visibility state for given pivot/frame *
|
|
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
|
|
|
#include "hrawanim.h"
|
|
#include "motchan.h"
|
|
#include "chunkio.h"
|
|
#include "assetmgr.h"
|
|
#include "htree.h"
|
|
|
|
|
|
struct NodeMotionStruct
|
|
{
|
|
NodeMotionStruct();
|
|
~NodeMotionStruct();
|
|
|
|
MotionChannelClass * X;
|
|
MotionChannelClass * Y;
|
|
MotionChannelClass * Z;
|
|
MotionChannelClass * XR;
|
|
MotionChannelClass * YR;
|
|
MotionChannelClass * ZR;
|
|
MotionChannelClass * Q;
|
|
|
|
BitChannelClass * Vis;
|
|
};
|
|
|
|
/***********************************************************************************************
|
|
* NodeMotionStruct::NodeMotionStruct -- constructor *
|
|
* *
|
|
* INPUT: *
|
|
* *
|
|
* OUTPUT: *
|
|
* *
|
|
* WARNINGS: *
|
|
* *
|
|
* HISTORY: *
|
|
*=============================================================================================*/
|
|
NodeMotionStruct::NodeMotionStruct() :
|
|
X(NULL),
|
|
Y(NULL),
|
|
Z(NULL),
|
|
XR(NULL),
|
|
YR(NULL),
|
|
ZR(NULL),
|
|
Q(NULL),
|
|
Vis(NULL)
|
|
{
|
|
}
|
|
|
|
|
|
/***********************************************************************************************
|
|
* NodeMotionStruct::~NodeMotionStruct -- destructor *
|
|
* *
|
|
* INPUT: *
|
|
* *
|
|
* OUTPUT: *
|
|
* *
|
|
* WARNINGS: *
|
|
* *
|
|
* HISTORY: *
|
|
* 10/23/98 GTH : Created. *
|
|
*=============================================================================================*/
|
|
NodeMotionStruct::~NodeMotionStruct()
|
|
{
|
|
if (X != NULL) {
|
|
delete X;
|
|
}
|
|
if (Y != NULL) {
|
|
delete Y;
|
|
}
|
|
if (Z != NULL) {
|
|
delete Z;
|
|
}
|
|
if (XR != NULL) {
|
|
delete XR;
|
|
}
|
|
if (YR != NULL) {
|
|
delete YR;
|
|
}
|
|
if (ZR != NULL) {
|
|
delete ZR;
|
|
}
|
|
if (Q != NULL) {
|
|
delete Q;
|
|
}
|
|
if (Vis != NULL) {
|
|
delete Vis;
|
|
}
|
|
}
|
|
|
|
|
|
/***********************************************************************************************
|
|
* HRawAnimClass::HRawAnimClass -- constructor *
|
|
* *
|
|
* INPUT: *
|
|
* *
|
|
* OUTPUT: *
|
|
* *
|
|
* WARNINGS: *
|
|
* *
|
|
* HISTORY: *
|
|
* 08/11/1997 GH : Created. *
|
|
*=============================================================================================*/
|
|
HRawAnimClass::HRawAnimClass(void) :
|
|
NumFrames(0),
|
|
NumNodes(0),
|
|
FrameRate(0),
|
|
NodeMotion(NULL)
|
|
{
|
|
memset(Name,0,W3D_NAME_LEN);
|
|
memset(HierarchyName,0,W3D_NAME_LEN);
|
|
}
|
|
|
|
|
|
/***********************************************************************************************
|
|
* HRawAnimClass::~HRawAnimClass -- Destructor *
|
|
* *
|
|
* INPUT: *
|
|
* *
|
|
* OUTPUT: *
|
|
* *
|
|
* WARNINGS: *
|
|
* *
|
|
* HISTORY: *
|
|
* 08/11/1997 GH : Created. *
|
|
*=============================================================================================*/
|
|
HRawAnimClass::~HRawAnimClass(void)
|
|
{
|
|
Free();
|
|
}
|
|
|
|
|
|
/***********************************************************************************************
|
|
* HRawAnimClass::Free -- De-allocates all memory in use *
|
|
* *
|
|
* INPUT: *
|
|
* *
|
|
* OUTPUT: *
|
|
* *
|
|
* WARNINGS: *
|
|
* *
|
|
* HISTORY: *
|
|
* 08/11/1997 GH : Created. *
|
|
*=============================================================================================*/
|
|
void HRawAnimClass::Free(void)
|
|
{
|
|
if (NodeMotion != NULL) {
|
|
delete[] NodeMotion;
|
|
}
|
|
}
|
|
|
|
|
|
/***********************************************************************************************
|
|
* HRawAnimClass::Load -- Loads hierarchy animation from a file *
|
|
* *
|
|
* INPUT: *
|
|
* *
|
|
* OUTPUT: *
|
|
* *
|
|
* WARNINGS: *
|
|
* *
|
|
* HISTORY: *
|
|
* 08/11/1997 GH : Created. *
|
|
*=============================================================================================*/
|
|
int HRawAnimClass::Load_W3D(ChunkLoadClass & cload)
|
|
{
|
|
bool pre30 = false;
|
|
|
|
/*
|
|
** First make sure we release any memory in use
|
|
*/
|
|
Free();
|
|
|
|
/*
|
|
** Open the first chunk, it should be the animation header
|
|
*/
|
|
if (!cload.Open_Chunk()) return LOAD_ERROR;
|
|
|
|
if (cload.Cur_Chunk_ID() != W3D_CHUNK_ANIMATION_HEADER) {
|
|
// ERROR: Expected Animation Header!
|
|
return LOAD_ERROR;
|
|
}
|
|
|
|
W3dAnimHeaderStruct aheader;
|
|
if (cload.Read(&aheader,sizeof(W3dAnimHeaderStruct)) != sizeof(W3dAnimHeaderStruct)) {
|
|
return LOAD_ERROR;
|
|
}
|
|
|
|
cload.Close_Chunk();
|
|
|
|
/*
|
|
** Check if the animation version is pre-3.0. If so, we need to add 1 to all of the
|
|
** bone indexes. In version 3.0 onward, all htree's use bone 0 as the root node.
|
|
*/
|
|
if (aheader.Version < W3D_MAKE_VERSION(3,0)) {
|
|
pre30 = true;
|
|
}
|
|
|
|
strcpy(Name,aheader.HierarchyName);
|
|
strcat(Name,".");
|
|
strcat(Name,aheader.Name);
|
|
|
|
// TSS chasing crash bug 05/26/99
|
|
WWASSERT(HierarchyName != NULL);
|
|
WWASSERT(aheader.HierarchyName != NULL);
|
|
WWASSERT(sizeof(HierarchyName) >= W3D_NAME_LEN);
|
|
strncpy(HierarchyName,aheader.HierarchyName,W3D_NAME_LEN);
|
|
|
|
HTreeClass * base_pose = WW3DAssetManager::Get_Instance()->Get_HTree(HierarchyName);
|
|
if (base_pose == NULL) {
|
|
goto Error;
|
|
}
|
|
NumNodes = base_pose->Num_Pivots();
|
|
|
|
NumFrames = aheader.NumFrames;
|
|
FrameRate = aheader.FrameRate;
|
|
|
|
NodeMotion = new NodeMotionStruct[ NumNodes ];
|
|
if (NodeMotion == NULL) {
|
|
goto Error;
|
|
}
|
|
|
|
/*
|
|
** Now, read in all of the other chunks (motion channels).
|
|
*/
|
|
MotionChannelClass * newchan;
|
|
BitChannelClass * newbitchan;
|
|
|
|
while (cload.Open_Chunk()) {
|
|
|
|
switch (cload.Cur_Chunk_ID()) {
|
|
|
|
case W3D_CHUNK_ANIMATION_CHANNEL:
|
|
if (!read_channel(cload,&newchan,pre30)) {
|
|
goto Error;
|
|
}
|
|
|
|
// (gth) if the channel is referring to a node which is outside the range,
|
|
// just throw away the channel. This probably means the animation must
|
|
// be re-exported
|
|
if (newchan->Get_Pivot() < NumNodes) {
|
|
add_channel(newchan);
|
|
} else {
|
|
WWDEBUG_SAY(("Animation %s referring to missing Bone! Please re-export.\n",Name));
|
|
delete newchan;
|
|
}
|
|
break;
|
|
|
|
case W3D_CHUNK_BIT_CHANNEL:
|
|
if (!read_bit_channel(cload,&newbitchan,pre30)) {
|
|
goto Error;
|
|
}
|
|
|
|
// (gth) if the channel is referring to a node which is outside the range,
|
|
// just throw away the channel. This probably means the animation must
|
|
// be re-exported
|
|
if (newbitchan->Get_Pivot() < NumNodes) {
|
|
add_bit_channel(newbitchan);
|
|
} else {
|
|
WWDEBUG_SAY(("Animation %s referring to missing Bone! Please re-export.\n",Name));
|
|
delete newbitchan;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
cload.Close_Chunk();
|
|
}
|
|
|
|
return OK;
|
|
|
|
Error:
|
|
|
|
Free();
|
|
return LOAD_ERROR;
|
|
|
|
}
|
|
|
|
/***********************************************************************************************
|
|
* HRawAnimClass::read_channel -- Reads in a single channel of motion *
|
|
* *
|
|
* INPUT: *
|
|
* *
|
|
* OUTPUT: *
|
|
* *
|
|
* WARNINGS: *
|
|
* *
|
|
* HISTORY: *
|
|
* 08/11/1997 GH : Created. *
|
|
*=============================================================================================*/
|
|
bool HRawAnimClass::read_channel(ChunkLoadClass & cload,MotionChannelClass * * newchan,bool pre30)
|
|
{
|
|
*newchan = new MotionChannelClass;
|
|
bool result = (*newchan)->Load_W3D(cload);
|
|
|
|
if (result && pre30) {
|
|
// (*newchan)->PivotIdx += 1;
|
|
(*newchan)->Set_Pivot((*newchan)->Get_Pivot()+1);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/***********************************************************************************************
|
|
* HRawAnimClass::add_channel -- Adds a motion channel to the animation *
|
|
* *
|
|
* INPUT: *
|
|
* *
|
|
* OUTPUT: *
|
|
* *
|
|
* WARNINGS: *
|
|
* *
|
|
* HISTORY: *
|
|
* 08/11/1997 GH : Created. *
|
|
*=============================================================================================*/
|
|
void HRawAnimClass::add_channel(MotionChannelClass * newchan)
|
|
{
|
|
int idx = newchan->Get_Pivot();
|
|
|
|
switch (newchan->Get_Type())
|
|
{
|
|
case ANIM_CHANNEL_X:
|
|
NodeMotion[idx].X = newchan;
|
|
break;
|
|
|
|
case ANIM_CHANNEL_Y:
|
|
NodeMotion[idx].Y = newchan;
|
|
break;
|
|
|
|
case ANIM_CHANNEL_Z:
|
|
NodeMotion[idx].Z = newchan;
|
|
break;
|
|
|
|
case ANIM_CHANNEL_XR:
|
|
NodeMotion[idx].XR = newchan;
|
|
break;
|
|
|
|
case ANIM_CHANNEL_YR:
|
|
NodeMotion[idx].YR = newchan;
|
|
break;
|
|
|
|
case ANIM_CHANNEL_ZR:
|
|
NodeMotion[idx].ZR = newchan;
|
|
break;
|
|
|
|
case ANIM_CHANNEL_Q:
|
|
NodeMotion[idx].Q = newchan;
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
/***********************************************************************************************
|
|
* HRawAnimClass::read_bit_channel -- read a bit channel from the file *
|
|
* *
|
|
* INPUT: *
|
|
* *
|
|
* OUTPUT: *
|
|
* *
|
|
* WARNINGS: *
|
|
* *
|
|
* HISTORY: *
|
|
* 1/19/98 GTH : Created. *
|
|
*=============================================================================================*/
|
|
bool HRawAnimClass::read_bit_channel(ChunkLoadClass & cload,BitChannelClass * * newchan,bool pre30)
|
|
{
|
|
*newchan = new BitChannelClass;
|
|
bool result = (*newchan)->Load_W3D(cload);
|
|
|
|
if (result && pre30) {
|
|
(*newchan)->PivotIdx += 1;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
/***********************************************************************************************
|
|
* HRawAnimClass::add_bit_channel -- install a bit channel into the animation *
|
|
* *
|
|
* INPUT: *
|
|
* *
|
|
* OUTPUT: *
|
|
* *
|
|
* WARNINGS: *
|
|
* *
|
|
* HISTORY: *
|
|
* 1/19/98 GTH : Created. *
|
|
*=============================================================================================*/
|
|
void HRawAnimClass::add_bit_channel(BitChannelClass * newchan)
|
|
{
|
|
int idx = newchan->Get_Pivot();
|
|
|
|
switch (newchan->Get_Type())
|
|
{
|
|
case BIT_CHANNEL_VIS:
|
|
NodeMotion[idx].Vis = newchan;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/***********************************************************************************************
|
|
* HRawAnimClass::Get_Translation -- returns the translation vector for the given fr *
|
|
* *
|
|
* INPUT: *
|
|
* *
|
|
* OUTPUT: *
|
|
* *
|
|
* WARNINGS: *
|
|
* *
|
|
* HISTORY: *
|
|
* 08/11/1997 GH : Created. *
|
|
*=============================================================================================*/
|
|
void HRawAnimClass::Get_Translation(Vector3& trans, int pividx, float frame ) const
|
|
{
|
|
struct NodeMotionStruct * motion = &NodeMotion[pividx];
|
|
|
|
if ( (motion->X == NULL) && (motion->Y == NULL) && (motion->Z == NULL) ) {
|
|
trans.Set(0.0f,0.0f,0.0f);
|
|
return;
|
|
}
|
|
|
|
// int frame0 = (int)frame;
|
|
int frame0=WWMath::Float_To_Long(frame-0.499999f);
|
|
|
|
int frame1 = frame0 + 1;
|
|
|
|
float ratio = frame - (float)frame0;
|
|
WWASSERT( (ratio >= -WWMATH_EPSILON) && (ratio < 1.0f + WWMATH_EPSILON) );
|
|
|
|
if ( frame1 >= NumFrames ) {
|
|
frame1 = 0;
|
|
}
|
|
|
|
Vector3 trans0(0.0f,0.0f,0.0f);
|
|
|
|
if (motion->X != NULL) {
|
|
motion->X->Get_Vector((int)frame0,&(trans0[0]));
|
|
}
|
|
if (motion->Y != NULL) {
|
|
motion->Y->Get_Vector((int)frame0,&(trans0[1]));
|
|
}
|
|
if (motion->Z != NULL) {
|
|
motion->Z->Get_Vector((int)frame0,&(trans0[2]));
|
|
}
|
|
|
|
if ( ratio == 0.0f ) {
|
|
trans=trans0;
|
|
return;
|
|
}
|
|
|
|
Vector3 trans1(0.0f,0.0f,0.0f);
|
|
|
|
if (motion->X != NULL) {
|
|
motion->X->Get_Vector((int)frame1,&(trans1[0]));
|
|
}
|
|
if (motion->Y != NULL) {
|
|
motion->Y->Get_Vector((int)frame1,&(trans1[1]));
|
|
}
|
|
if (motion->Z != NULL) {
|
|
motion->Z->Get_Vector((int)frame1,&(trans1[2]));
|
|
}
|
|
|
|
trans = Lerp( trans0, trans1, ratio );
|
|
}
|
|
|
|
/***********************************************************************************************
|
|
* HRawAnimClass::Get_Orientation -- returns a quaternion for the orientation of the *
|
|
* *
|
|
* INPUT: *
|
|
* *
|
|
* OUTPUT: *
|
|
* *
|
|
* WARNINGS: *
|
|
* *
|
|
* HISTORY: *
|
|
* 08/11/1997 GH : Created. *
|
|
*=============================================================================================*/
|
|
void HRawAnimClass::Get_Orientation(Quaternion& q, int pividx,float frame) const
|
|
{
|
|
// int frame0 = (int)frame;
|
|
int frame0=WWMath::Float_To_Long(frame-0.499999f);
|
|
int frame1 = frame0 + 1;
|
|
|
|
float ratio = frame - (float)frame0;
|
|
WWASSERT( (ratio >= -WWMATH_EPSILON) && (ratio < 1.0f + WWMATH_EPSILON) );
|
|
|
|
if ( frame1 >= NumFrames ) {
|
|
frame1 = 0;
|
|
}
|
|
|
|
float vals[4];
|
|
|
|
Quaternion q0(1);
|
|
if (NodeMotion[pividx].Q != NULL) {
|
|
NodeMotion[pividx].Q->Get_Vector((int)frame0,vals);
|
|
q0.Set(vals[0],vals[1],vals[2],vals[3]);
|
|
}
|
|
|
|
if ( ratio == 0.0f ) {
|
|
q=q0;
|
|
return;
|
|
}
|
|
|
|
Quaternion q1(1);
|
|
if (NodeMotion[pividx].Q != NULL) {
|
|
NodeMotion[pividx].Q->Get_Vector((int)frame1,vals);
|
|
q1.Set(vals[0],vals[1],vals[2],vals[3]);
|
|
}
|
|
|
|
Fast_Slerp(q, q0, q1, ratio );
|
|
}
|
|
|
|
/***********************************************************************************************
|
|
* HRawAnimClass::Get_Transform -- returns the transform matrix for the given frame *
|
|
* *
|
|
* INPUT: *
|
|
* *
|
|
* OUTPUT: *
|
|
* *
|
|
* WARNINGS: *
|
|
* *
|
|
* HISTORY: *
|
|
* 08/11/1997 GH : Created. *
|
|
*=============================================================================================*/
|
|
void HRawAnimClass::Get_Transform(Matrix3D& mtx, int pividx, float frame ) const
|
|
{
|
|
struct NodeMotionStruct * motion = &NodeMotion[pividx];
|
|
|
|
// if ( (motion->X == NULL) && (motion->Y == NULL) && (motion->Z == NULL) ) {
|
|
// trans.Set(0.0f,0.0f,0.0f);
|
|
// return;
|
|
// }
|
|
|
|
int frame0=WWMath::Float_To_Long(frame-0.499999f);
|
|
|
|
int frame1 = frame0 + 1;
|
|
|
|
float ratio = frame - (float)frame0;
|
|
WWASSERT( (ratio >= -WWMATH_EPSILON) && (ratio < 1.0f + WWMATH_EPSILON) );
|
|
|
|
if ( frame1 >= NumFrames ) {
|
|
frame1 = 0;
|
|
}
|
|
|
|
float vals[4];
|
|
Quaternion q0(1);
|
|
if (NodeMotion[pividx].Q != NULL) {
|
|
NodeMotion[pividx].Q->Get_Vector((int)frame0,vals);
|
|
q0.Set(vals[0],vals[1],vals[2],vals[3]);
|
|
}
|
|
|
|
if ( ratio == 0.0f ) {
|
|
mtx=::Build_Matrix3D(q0);
|
|
if (motion->X != NULL) motion->X->Get_Vector((int)frame0,&(mtx[0][3]));
|
|
if (motion->Y != NULL) motion->Y->Get_Vector((int)frame0,&(mtx[1][3]));
|
|
if (motion->Z != NULL) motion->Z->Get_Vector((int)frame0,&(mtx[2][3]));
|
|
return;
|
|
}
|
|
|
|
Quaternion q1(1);
|
|
if (NodeMotion[pividx].Q != NULL) {
|
|
NodeMotion[pividx].Q->Get_Vector((int)frame1,vals);
|
|
q1.Set(vals[0],vals[1],vals[2],vals[3]);
|
|
}
|
|
|
|
Quaternion q;
|
|
Fast_Slerp(q, q0, q1, ratio );
|
|
mtx=::Build_Matrix3D(q);
|
|
|
|
Vector3 trans0(0.0f,0.0f,0.0f);
|
|
if (motion->X != NULL) motion->X->Get_Vector((int)frame0,&(trans0[0]));
|
|
if (motion->Y != NULL) motion->Y->Get_Vector((int)frame0,&(trans0[1]));
|
|
if (motion->Z != NULL) motion->Z->Get_Vector((int)frame0,&(trans0[2]));
|
|
|
|
Vector3 trans1(0.0f,0.0f,0.0f);
|
|
if (motion->X != NULL) motion->X->Get_Vector((int)frame1,&(trans1[0]));
|
|
if (motion->Y != NULL) motion->Y->Get_Vector((int)frame1,&(trans1[1]));
|
|
if (motion->Z != NULL) motion->Z->Get_Vector((int)frame1,&(trans1[2]));
|
|
|
|
Vector3 trans = Lerp( trans0, trans1, ratio );
|
|
|
|
mtx.Set_Translation(trans);
|
|
}
|
|
|
|
/***********************************************************************************************
|
|
* HRawAnimClass::Get_Visibility -- return visibility state for given pivot/frame *
|
|
* *
|
|
* INPUT: *
|
|
* *
|
|
* OUTPUT: *
|
|
* *
|
|
* WARNINGS: *
|
|
* *
|
|
* HISTORY: *
|
|
* 1/19/98 GTH : Created. *
|
|
*=============================================================================================*/
|
|
bool HRawAnimClass::Get_Visibility(int pividx,float frame)
|
|
{
|
|
if (NodeMotion[pividx].Vis != NULL) {
|
|
return (NodeMotion[pividx].Vis->Get_Bit((int)frame) == 1);
|
|
}
|
|
|
|
// default to always visible...
|
|
return 1;
|
|
}
|
|
|
|
|
|
/***********************************************************************************************
|
|
* HRawAnimClass::Is_Node_Motion_Present -- return true if there is motion defined for this frame *
|
|
* *
|
|
* INPUT: *
|
|
* *
|
|
* OUTPUT: *
|
|
* *
|
|
* WARNINGS: *
|
|
* *
|
|
* HISTORY: *
|
|
* 3/23/99 EHC : Created. *
|
|
*=============================================================================================*/
|
|
bool HRawAnimClass::Is_Node_Motion_Present(int pividx)
|
|
{
|
|
WWASSERT((pividx >= 0) && (pividx < NumNodes));
|
|
|
|
if (NodeMotion[pividx].X != NULL) return true;
|
|
if (NodeMotion[pividx].Y != NULL) return true;
|
|
if (NodeMotion[pividx].Z != NULL) return true;
|
|
if (NodeMotion[pividx].XR != NULL) return true;
|
|
if (NodeMotion[pividx].YR != NULL) return true;
|
|
if (NodeMotion[pividx].ZR != NULL) return true;
|
|
if (NodeMotion[pividx].Q != NULL) return true;
|
|
if (NodeMotion[pividx].Vis != NULL) return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
bool HRawAnimClass::Has_X_Translation (int pividx)
|
|
{
|
|
WWASSERT((pividx >= 0) && (pividx < NumNodes));
|
|
return NodeMotion[pividx].X != NULL;
|
|
}
|
|
|
|
bool HRawAnimClass::Has_Y_Translation (int pividx)
|
|
{
|
|
WWASSERT((pividx >= 0) && (pividx < NumNodes));
|
|
return NodeMotion[pividx].Y != NULL;
|
|
}
|
|
|
|
bool HRawAnimClass::Has_Z_Translation (int pividx)
|
|
{
|
|
WWASSERT((pividx >= 0) && (pividx < NumNodes));
|
|
return NodeMotion[pividx].Z != NULL;
|
|
}
|
|
|
|
bool HRawAnimClass::Has_Rotation (int pividx)
|
|
{
|
|
WWASSERT((pividx >= 0) && (pividx < NumNodes));
|
|
return NodeMotion[pividx].Q != NULL;
|
|
}
|
|
|
|
bool HRawAnimClass::Has_Visibility (int pividx)
|
|
{
|
|
WWASSERT((pividx >= 0) && (pividx < NumNodes));
|
|
return NodeMotion[pividx].Vis != NULL;
|
|
}
|
|
|
|
|