SBSPSS/Utils/GinExp/ExpBone.cpp
2001-01-12 22:40:39 +00:00

992 lines
26 KiB
C++

/*=========================================================================
EXPBONE.CPP
Author: Tim Swann @ CLIMAX
Created:
Project:
Purpose:
Copyright (c) 1998 Climax Development Ltd
===========================================================================*/
/*----------------------------------------------------------------------
Includes
-------- */
#include "AsciiExp.h"
/* Std Lib
------- */
/* Glib
---- */
/* Local
----- */
/* Graphics
-------- */
/*----------------------------------------------------------------------
Tyepdefs && Defines
------------------- */
/*----------------------------------------------------------------------
Structure defintions
-------------------- */
/*----------------------------------------------------------------------
Positional Vars
--------------- */
/*----------------------------------------------------------------------
Function Prototypes
------------------- */
/*----------------------------------------------------------------------
Vars
---- */
/*----------------------------------------------------------------------
Data
---- */
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void AsciiExp::ExportBones( INode* node )
{
nbBones = 0;
WriteChunkHdr( (char*)BONE_ID, 0);
fwrite( &nCurObj, sizeof( Uint32 ), 1, expStream );
ExportLimb( node );
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
static bool ThisIsABone( INode * node )
{
bool retval = false;
char * nodeName;
nodeName = node->GetName();
// if (nodeName[0] == 'R' &&
// nodeName[1] == 'O' &&
// nodeName[2] == 'O' &&
// nodeName[3] == 'T') retval = true;
retval = true;
return (retval);
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
int AsciiExp::ValidateBoneKids( INode * node )
{
int nbChilds = node->NumberOfChildren();
int childCnt = 0;
return nbChilds;
}
bool IsParent(INode *p, INode *c)
{
while (!c->IsRootNode()) {
c=c->GetParentNode();
if (c==p)
return true;
}
return false;
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void AsciiExp::ExportLimb( INode * node )
{
INode * ChildNode;
ObjectState os = node->EvalWorldState( ip->GetAnimRange().Start() );
Object * obj = node->EvalWorldState(ip->GetAnimRange().Start()).obj;
long nbChilds;
Matrix3 tm;
AffineParts ap;
Quat q;
char name[256];
Point3 fpos;
Point3 pos, p2;
// EXPORT BONE
sprintf( name, "%s", node->GetName() );
fprintf( tempStream, "OUTPUTTING - %s\n", name ); // DEBUG FILE
fwrite( &name, sizeof(char), MAX_NAME_LENGTH, expStream ); // WRITE BONE NAME
// EXPORT WEIGHTS
long nbVerts = 0;
if (nbWeights)
{
fprintf( tempStream, "WEIGHTS:\n" );
for (int i=0;i<nbWeights;i++)
{
for (int n=0;n<Weights[i].nodecount;n++)
{
if (!strcmp(node->GetName(), Weights[i].names[n])) nbVerts++;
}
}
fprintf( tempStream, " nbVerts = %d\n", nbVerts );
fwrite( &nbVerts, sizeof(long), 1, expStream ); // WRITE BONE WEIGHT COUNT
if (nbVerts)
{
for (int i=0;i<nbWeights;i++)
{
for (int n=0;n<Weights[i].nodecount;n++)
{
if (!strcmp(node->GetName(), Weights[i].names[n]))
{
fwrite( &Weights[i].vertno, sizeof(long), 1, expStream );
fwrite( &Weights[i].weights[n], sizeof(float), 1, expStream );
fwrite( &Weights[i].Offsets[n].x, sizeof(float), 1, expStream);
fwrite( &Weights[i].Offsets[n].z, sizeof(float), 1, expStream);
fwrite( &Weights[i].Offsets[n].y, sizeof(float), 1, expStream);
}
}
}
}
} else {
fwrite( &nbVerts, sizeof(long), 1, expStream ); // WRITE BONE WEIGHT COUNT
}
// EXPORT CHILDREN
nbBones++;
nbChilds = node->NumberOfChildren();
fwrite( &nbChilds, sizeof(int), 1, expStream);
for (int c=0;c<nbChilds;c++) // RUN THROUGH ALL OF THE CHILDREN
{
ChildNode = node->GetChildNode(c);
if (ChildNode) ExportLimb( ChildNode );
}
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void AsciiExp::ExportBoneAnim( INode* node )
{
TimeValue start = ip->GetAnimRange().Start();
TimeValue end = ip->GetAnimRange().End();
TimeValue t;
int delta = GetTicksPerFrame();
Matrix3 tm;
AffineParts ap;
Point3 prevPos;
Point3 startScale;
Quat prevQ;
Quat scaleQ;
Quat q;
Quat InvQ;
INode * ChildNode;
ObjectState os = node->EvalWorldState( ip->GetAnimRange().Start() );
Object * obj = node->EvalWorldState(ip->GetAnimRange().Start()).obj;
long nbChilds;
for (t=start; t<=end; t+=delta)
{
// TRANSLATION
if (0)//node->IsRootNode())
{
tm = node->GetNodeTM( t );
} else
{
tm = node->GetNodeTM(t) * Inverse(node->GetParentTM(t));
}
decomp_affine(tm, &ap);
fwrite( &ap.t.x, sizeof(float), 1, expStream ); // WRITE BONE X-POS
fwrite( &ap.t.z, sizeof(float), 1, expStream ); // WRITE BONE Y-POS
fwrite( &ap.t.y, sizeof(float), 1, expStream ); // WRITE BONE Z-POS
fwrite( &ap.q.x, sizeof(float), 1, expStream ); // WRITE BONE ROT X-AXIS
fwrite( &ap.q.z, sizeof(float), 1, expStream ); // WRITE BONE ROT Y-AXIS
fwrite( &ap.q.y, sizeof(float), 1, expStream ); // WRITE BONE ROT Z-AXIS
fwrite( &ap.q.w, sizeof(float), 1, expStream ); // WRITE BONE ROT W ANGLE
fwrite( &ap.k.x, sizeof(float), 1, expStream ); // WRITE BONE X-POS
fwrite( &ap.k.z, sizeof(float), 1, expStream ); // WRITE BONE Y-POS
fwrite( &ap.k.y, sizeof(float), 1, expStream ); // WRITE BONE Z-POS
fwrite( &ap.u.x, sizeof(float), 1, expStream ); // WRITE BONE ROT X-AXIS
fwrite( &ap.u.z, sizeof(float), 1, expStream ); // WRITE BONE ROT Y-AXIS
fwrite( &ap.u.y, sizeof(float), 1, expStream ); // WRITE BONE ROT Z-AXIS
fwrite( &ap.u.w, sizeof(float), 1, expStream ); // WRITE BONE ROT W ANGLE
}
nbChilds = node->NumberOfChildren();
for (int c=0;c<nbChilds;c++) // RUN THROUGH ALL OF THE CHILDREN
{
ChildNode = node->GetChildNode(c);
if (ChildNode) ExportBoneAnim( ChildNode );
}
}
void AsciiExp::ExportBoneKeyAnim( INode* node)
{
TimeValue start = ip->GetAnimRange().Start();
TimeValue end = ip->GetAnimRange().End();
int delta = GetTicksPerFrame();
Matrix3 tm;
AffineParts ap, StartAp;
Point3 prevPos;
Point3 startScale;
Quat prevQ;
Quat scaleQ;
Quat q;
Quat InvQ;
INode * ChildNode;
ObjectState os = node->EvalWorldState( ip->GetAnimRange().Start() );
Object * obj = node->EvalWorldState(ip->GetAnimRange().Start()).obj;
long nbChilds;
int num;
int i;
int FrameN;
Interval ivalid;
IKey k;
Control *c;
IKeyControl *ikeys;
ITCBPoint3Key tcbPosKey;
ITCBRotKey tcbRotKey;
ITCBScaleKey tcbSclKey;
IBezPoint3Key bezPosKey;
IBezQuatKey bezRotKey;
IBezScaleKey bezSclKey;
ILinPoint3Key linPosKey;
ILinRotKey linRotKey;
ILinScaleKey linSclKey;
TimeValue time;
if (node->EvalWorldState(ip->GetAnimRange().Start()).obj) {
TimeList tl;
tl.Clear();
INode *KeyNode = node;
c = KeyNode->GetTMController();
if (c) {
c = c->GetPositionController();
if (c) {
ikeys = GetKeyControlInterface(c);
if (ikeys) {
num = ikeys->GetNumKeys();
if (num >0)
{
for (i = 0; i<num; i++) {
if (c->ClassID() == Class_ID(TCBINTERP_POSITION_CLASS_ID, 0)) {
ikeys->GetKey(i, &tcbPosKey);
time = tcbPosKey.time;
} else
if (c->ClassID() == Class_ID(HYBRIDINTERP_POSITION_CLASS_ID, 0)) {
ikeys->GetKey(i, &bezPosKey);
time = bezPosKey.time;
} else
if (c->ClassID() == Class_ID(LININTERP_POSITION_CLASS_ID, 0)) {
ikeys->GetKey(i, &linPosKey);
time = linPosKey.time;
}
tl.Add(time);
}
}
}
}
}
c = KeyNode->GetTMController();
if (c) {
c = c->GetRotationController();
if (c) {
ikeys = GetKeyControlInterface(c);
if (ikeys) {
num = ikeys->GetNumKeys();
if (num >0)
{
for (i = 0; i<num; i++) {
if (c->ClassID() == Class_ID(TCBINTERP_ROTATION_CLASS_ID, 0)) {
ikeys->GetKey(i, &tcbRotKey);
int rots;
if (i)
{
ITCBRotKey oldtcbRotKey;
ikeys->GetKey(i-1, &oldtcbRotKey);
rots = fabs(tcbRotKey.val.angle - oldtcbRotKey.val.angle) / (0.6667 * PI) + 1;
for (int k=1; k<rots; k++)
{
tl.Add(oldtcbRotKey.time+(int)((float)k*(tcbRotKey.time-oldtcbRotKey.time)/rots));
}
}
time = tcbRotKey.time;
} else
if (c->ClassID() == Class_ID(HYBRIDINTERP_ROTATION_CLASS_ID, 0)) {
ikeys->GetKey(i, &bezRotKey);
time = bezRotKey.time;
} else
if (c->ClassID() == Class_ID(LININTERP_ROTATION_CLASS_ID, 0)) {
ikeys->GetKey(i, &linRotKey);
time = linRotKey.time;
}
tl.Add(time);
}
}
}
}
}
c = KeyNode->GetTMController();
if (c) {
c = c->GetScaleController();
if (c) {
ikeys = GetKeyControlInterface(c);
if (ikeys) {
num = ikeys->GetNumKeys();
if (num >0)
{
for (i = 0; i<num; i++) {
if (c->ClassID() == Class_ID(TCBINTERP_SCALE_CLASS_ID, 0)) {
ikeys->GetKey(i, &tcbSclKey);
time = tcbSclKey.time;
} else
if (c->ClassID() == Class_ID(HYBRIDINTERP_SCALE_CLASS_ID, 0)) {
ikeys->GetKey(i, &bezSclKey);
time = bezSclKey.time;
} else
if (c->ClassID() == Class_ID(LININTERP_SCALE_CLASS_ID, 0)) {
ikeys->GetKey(i, &linSclKey);
time = linSclKey.time;
}
tl.Add(time);
}
}
}
}
}
if (tl.Count()) {
num = tl.Count();
WriteChunkHdr( (char*)KEY_ID, 0);
fwrite( &CHANNEL_TYPE_BONE, sizeof( Uint32 ), 1, expStream );
fwrite( &CHANNEL_INFO_ALL, sizeof( Uint32) , 1, expStream);
fwrite( &nCurObj, sizeof( Uint32 ), 1, expStream );
fwrite( &CurBone, sizeof( Uint32 ), 1, expStream );
fwrite( &num, sizeof( Uint32 ), 1, expStream );
for (num = 0; num <tl.Count(); num++) {
time = tl.Get(num);
tm = node->GetNodeTM(time) * Inverse(node->GetParentTM(time));
FrameN = (int)((float)(time - start) / delta);
decomp_affine(tm, &ap);
if (num == 0)
StartAp = ap;
fwrite( &FrameN, sizeof(Uint32), 1, expStream);
fwrite( &ap.t.x, sizeof(float), 1, expStream ); // WRITE BONE X-POS
fwrite( &ap.t.z, sizeof(float), 1, expStream ); // WRITE BONE Y-POS
fwrite( &ap.t.y, sizeof(float), 1, expStream ); // WRITE BONE Z-POS
fwrite( &ap.q.x, sizeof(float), 1, expStream ); // WRITE BONE X-POS
fwrite( &ap.q.z, sizeof(float), 1, expStream ); // WRITE BONE Y-POS
fwrite( &ap.q.y, sizeof(float), 1, expStream ); // WRITE BONE Z-POS
fwrite( &ap.q.w, sizeof(float), 1, expStream ); // WRITE BONE Z-POS
fwrite( &ap.k.x, sizeof(float), 1, expStream ); // WRITE BONE X-POS
fwrite( &ap.k.z, sizeof(float), 1, expStream ); // WRITE BONE Y-POS
fwrite( &ap.k.y, sizeof(float), 1, expStream ); // WRITE BONE Z-POS
fwrite( &ap.u.x, sizeof(float), 1, expStream ); // WRITE BONE X-POS
fwrite( &ap.u.z, sizeof(float), 1, expStream ); // WRITE BONE Y-POS
fwrite( &ap.u.y, sizeof(float), 1, expStream ); // WRITE BONE Z-POS
fwrite( &ap.u.w, sizeof(float), 1, expStream ); // WRITE BONE Z-POS
}
}
}
CurBone++;
nbChilds = node->NumberOfChildren();
for (int cn=0;cn<nbChilds;cn++) // RUN THROUGH ALL OF THE CHILDREN
{
ChildNode = node->GetChildNode(cn);
if (ChildNode) ExportBoneKeyAnim( ChildNode);
}
}
void AsciiExp::ExportBoneKeyAnimPos( INode* node)
{
TimeValue start = ip->GetAnimRange().Start();
TimeValue end = ip->GetAnimRange().End();
int delta = GetTicksPerFrame();
Matrix3 tm;
AffineParts ap;
Point3 prevPos;
Point3 startScale;
Quat prevQ;
Quat scaleQ;
Quat q;
Quat InvQ;
INode * ChildNode;
ObjectState os = node->EvalWorldState( ip->GetAnimRange().Start() );
Object * obj = node->EvalWorldState(ip->GetAnimRange().Start()).obj;
long nbChilds;
int num;
int i;
int FrameN;
Interval ivalid;
IKey k;
Control *c;
IKeyControl *ikeys;
ITCBPoint3Key tcbPosKey;
ITCBRotKey tcbRotKey;
ITCBScaleKey tcbScaleKey;
IBezPoint3Key bezPosKey;
IBezQuatKey bezRotKey;
IBezScaleKey bezScaleKey;
ILinPoint3Key linPosKey;
ILinRotKey linRotKey;
ILinScaleKey linScaleKey;
TimeValue time;
if (node->EvalWorldState(ip->GetAnimRange().Start()).obj) {
TimeList tl;
tl.Clear();
INode *KeyNode = node;
while (KeyNode) {
c = KeyNode->GetTMController();
if (c) {
c = c->GetPositionController();
if (c) {
ikeys = GetKeyControlInterface(c);
if (ikeys) {
num = ikeys->GetNumKeys();
if (num >0)
{
for (i = 0; i<num; i++) {
if (c->ClassID() == Class_ID(TCBINTERP_POSITION_CLASS_ID, 0)) {
ikeys->GetKey(i, &tcbPosKey);
time = tcbPosKey.time;
} else
if (c->ClassID() == Class_ID(HYBRIDINTERP_POSITION_CLASS_ID, 0)) {
ikeys->GetKey(i, &bezPosKey);
time = bezPosKey.time;
} else
if (c->ClassID() == Class_ID(LININTERP_POSITION_CLASS_ID, 0)) {
ikeys->GetKey(i, &linPosKey);
time = linPosKey.time;
}
tl.Add(time);
}
}
}
}
}
if (KeyNode->IsRootNode())
break;
KeyNode = KeyNode->GetParentNode();
}
if (tl.Count()) {
num = tl.Count();
WriteChunkHdr( (char*)KEY_ID, 0);
fwrite( &CHANNEL_TYPE_BONE, sizeof( Uint32 ), 1, expStream );
fwrite( &CHANNEL_INFO_POSITION, sizeof( Uint32) , 1, expStream);
fwrite( &nCurObj, sizeof( Uint32 ), 1, expStream );
fwrite( &CurBone, sizeof( Uint32 ), 1, expStream );
fwrite( &num, sizeof( Uint32 ), 1, expStream );
for (num = 0; num <tl.Count(); num++) {
time = tl.Get(num);
tm = node->GetNodeTM(time) * Inverse(node->GetParentTM(time));
FrameN = (int)((float)(time - start) / delta);
decomp_affine(tm, &ap);
fwrite( &FrameN, sizeof(Uint32), 1, expStream);
fwrite( &ap.t.x, sizeof(float), 1, expStream ); // WRITE BONE X-POS
fwrite( &ap.t.z, sizeof(float), 1, expStream ); // WRITE BONE Y-POS
fwrite( &ap.t.y, sizeof(float), 1, expStream ); // WRITE BONE Z-POS
}
}
}
CurBone++;
nbChilds = node->NumberOfChildren();
for (int cn=0;cn<nbChilds;cn++) // RUN THROUGH ALL OF THE CHILDREN
{
ChildNode = node->GetChildNode(cn);
if (ChildNode) ExportBoneKeyAnimPos( ChildNode);
}
}
void AsciiExp::ExportBoneKeyAnimRot( INode* node)
{
TimeValue start = ip->GetAnimRange().Start();
TimeValue end = ip->GetAnimRange().End();
int delta = GetTicksPerFrame();
Matrix3 tm;
AffineParts ap;
Point3 prevPos;
Point3 startScale;
Quat prevQ;
Quat scaleQ;
Quat q;
Quat InvQ;
INode * ChildNode;
ObjectState os = node->EvalWorldState( ip->GetAnimRange().Start() );
Object * obj = node->EvalWorldState(ip->GetAnimRange().Start()).obj;
long nbChilds;
int num;
int i;
int FrameN;
Interval ivalid;
IKey k;
Control *c;
IKeyControl *ikeys;
ITCBPoint3Key tcbPosKey;
ITCBRotKey tcbRotKey;
ITCBScaleKey tcbScaleKey;
IBezPoint3Key bezPosKey;
IBezQuatKey bezRotKey;
IBezScaleKey bezScaleKey;
ILinPoint3Key linPosKey;
ILinRotKey linRotKey;
ILinScaleKey linScaleKey;
TimeValue time;
if (node->EvalWorldState(ip->GetAnimRange().Start()).obj) {
TimeList tl;
tl.Clear();
INode *KeyNode = node;
while (KeyNode) {
c = KeyNode->GetTMController();
if (c) {
c = c->GetRotationController();
if (c) {
ikeys = GetKeyControlInterface(c);
if (ikeys) {
num = ikeys->GetNumKeys();
if (num >0)
{
for (i = 0; i<num; i++) {
if (c->ClassID() == Class_ID(TCBINTERP_ROTATION_CLASS_ID, 0)) {
ikeys->GetKey(i, &tcbRotKey);
time = tcbRotKey.time;
} else
if (c->ClassID() == Class_ID(HYBRIDINTERP_ROTATION_CLASS_ID, 0)) {
ikeys->GetKey(i, &bezRotKey);
time = bezRotKey.time;
} else
if (c->ClassID() == Class_ID(LININTERP_ROTATION_CLASS_ID, 0)) {
ikeys->GetKey(i, &linRotKey);
time = linRotKey.time;
}
tl.Add(time);
}
}
}
}
}
if (KeyNode->IsRootNode())
break;
KeyNode = KeyNode->GetParentNode();
}
if (tl.Count()) {
num = tl.Count();
WriteChunkHdr( (char*)KEY_ID, 0);
fwrite( &CHANNEL_TYPE_BONE, sizeof( Uint32 ), 1, expStream );
fwrite( &CHANNEL_INFO_ROTATION, sizeof( Uint32) , 1, expStream);
fwrite( &nCurObj, sizeof( Uint32 ), 1, expStream );
fwrite( &CurBone, sizeof( Uint32 ), 1, expStream );
fwrite( &num, sizeof( Uint32 ), 1, expStream );
for (num = 0; num <tl.Count(); num++) {
time = tl.Get(num);
tm = node->GetNodeTM(time) * Inverse(node->GetParentTM(time));
FrameN = (int)((float)(time - start) / delta);
decomp_affine(tm, &ap);
fwrite( &FrameN, sizeof(Uint32), 1, expStream);
fwrite( &ap.q.x, sizeof(float), 1, expStream ); // WRITE BONE X-POS
fwrite( &ap.q.z, sizeof(float), 1, expStream ); // WRITE BONE Y-POS
fwrite( &ap.q.y, sizeof(float), 1, expStream ); // WRITE BONE Z-POS
fwrite( &ap.q.w, sizeof(float), 1, expStream ); // WRITE BONE Z-POS
}
}
}
CurBone++;
nbChilds = node->NumberOfChildren();
for (int cn=0;cn<nbChilds;cn++) // RUN THROUGH ALL OF THE CHILDREN
{
ChildNode = node->GetChildNode(cn);
if (ChildNode) ExportBoneKeyAnimRot( ChildNode);
}
}
void AsciiExp::ExportBoneKeyAnimScl( INode* node)
{
TimeValue start = ip->GetAnimRange().Start();
TimeValue end = ip->GetAnimRange().End();
int delta = GetTicksPerFrame();
Matrix3 tm;
AffineParts ap;
Point3 prevPos;
Point3 startScale;
Quat prevQ;
Quat scaleQ;
Quat q;
Quat InvQ;
INode * ChildNode;
ObjectState os = node->EvalWorldState( ip->GetAnimRange().Start() );
Object * obj = node->EvalWorldState(ip->GetAnimRange().Start()).obj;
long nbChilds;
int num;
int i;
int FrameN;
Interval ivalid;
IKey k;
Control *c;
IKeyControl *ikeys;
ITCBPoint3Key tcbPosKey;
ITCBRotKey tcbRotKey;
ITCBScaleKey tcbSclKey;
IBezPoint3Key bezPosKey;
IBezQuatKey bezRotKey;
IBezScaleKey bezSclKey;
ILinPoint3Key linPosKey;
ILinRotKey linRotKey;
ILinScaleKey linSclKey;
TimeValue time;
char text[200];
sprintf(text, "%s", node->GetName());
if (node->EvalWorldState(ip->GetAnimRange().Start()).obj) {
TimeList tl;
tl.Clear();
INode *KeyNode = node;
while (KeyNode) {
c = KeyNode->GetTMController();
if (c) {
c = c->GetScaleController();
if (c) {
ikeys = GetKeyControlInterface(c);
if (ikeys) {
num = ikeys->GetNumKeys();
if (num >0)
{
for (i = 0; i<num; i++) {
if (c->ClassID() == Class_ID(TCBINTERP_SCALE_CLASS_ID, 0)) {
ikeys->GetKey(i, &tcbSclKey);
time = tcbSclKey.time;
} else
if (c->ClassID() == Class_ID(HYBRIDINTERP_SCALE_CLASS_ID, 0)) {
ikeys->GetKey(i, &bezSclKey);
time = bezSclKey.time;
} else
if (c->ClassID() == Class_ID(LININTERP_SCALE_CLASS_ID, 0)) {
ikeys->GetKey(i, &linSclKey);
time = linSclKey.time;
}
tl.Add(time);
}
}
}
}
}
if (KeyNode->IsRootNode())
break;
KeyNode = KeyNode->GetParentNode();
}
if (tl.Count()) {
num = tl.Count();
WriteChunkHdr( (char*)KEY_ID, 0);
fwrite( &CHANNEL_TYPE_BONE, sizeof( Uint32 ), 1, expStream );
fwrite( &CHANNEL_INFO_SCALE, sizeof( Uint32) , 1, expStream);
fwrite( &nCurObj, sizeof( Uint32 ), 1, expStream );
fwrite( &CurBone, sizeof( Uint32 ), 1, expStream );
fwrite( &num, sizeof( Uint32 ), 1, expStream );
for (num = 0; num <tl.Count(); num++) {
time = tl.Get(num);
tm = node->GetNodeTM(time) * Inverse(node->GetParentTM(time));
FrameN = (int)((float)(time - start) / delta);
decomp_affine(tm, &ap);
fwrite( &FrameN, sizeof(Uint32), 1, expStream);
fwrite( &ap.k.x, sizeof(float), 1, expStream ); // WRITE BONE X-POS
fwrite( &ap.k.z, sizeof(float), 1, expStream ); // WRITE BONE Y-POS
fwrite( &ap.k.y, sizeof(float), 1, expStream ); // WRITE BONE Z-POS
fwrite( &ap.u.x, sizeof(float), 1, expStream ); // WRITE BONE X-POS
fwrite( &ap.u.z, sizeof(float), 1, expStream ); // WRITE BONE Y-POS
fwrite( &ap.u.y, sizeof(float), 1, expStream ); // WRITE BONE Z-POS
fwrite( &ap.u.w, sizeof(float), 1, expStream ); // WRITE BONE Z-POS
}
}
}
CurBone++;
nbChilds = node->NumberOfChildren();
for (int cn=0;cn<nbChilds;cn++) // RUN THROUGH ALL OF THE CHILDREN
{
ChildNode = node->GetChildNode(cn);
if (ChildNode) ExportBoneKeyAnimScl( ChildNode);
}
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void AsciiExp::ExportWeights( INode* node )
{
Object * objPtr = NULL;
Modifier * phyMod = NULL;
IPhysiqueExport * phyExport = NULL;
IPhyContextExport * contextExport = NULL;
IPhyVertexExport * vtxExport = NULL;
IPhyRigidVertex * rvtExport = NULL;
IPhyBlendedRigidVertex * brvExport = NULL;
Point3 offsetvector;
INode * bonenode = NULL;
float weight = 0.f;
int nbNodes = 0;
int vtype = 0;
INode * RootNode = NULL;
ModContext *mc;
Weights = NULL;
phyMod = FindPhysiqueModifier (node, &mc);
if (phyMod)
{
PhyMc = mc;
phyExport = (IPhysiqueExport *)phyMod->GetInterface( I_PHYINTERFACE );
if (phyExport)
{
contextExport = (IPhyContextExport *)phyExport->GetContextInterface( node );
if (contextExport)
{
contextExport->ConvertToRigid( TRUE );
contextExport->AllowBlending( TRUE );
nbWeights = contextExport->GetNumberVertices();
Weights = (WEIGHTS *)malloc( nbWeights * sizeof(WEIGHTS) );
for (int i=0;i<nbWeights;i++)
{
vtxExport = (IPhyVertexExport *)contextExport->GetVertexInterface( i );
if (vtxExport)
{
vtype = vtxExport->GetVertexType();
if (vtype == RIGID_TYPE)
{
rvtExport = (IPhyRigidVertex *)vtxExport;
bonenode = rvtExport->GetNode();
Weights[i].vertno = i;
Weights[i].nodecount = 1;
Weights[i].weights[0] = 1.f;
Weights[i].Offsets[0] = rvtExport->GetOffsetVector();
sprintf( Weights[i].names[0], "%s", bonenode->GetName() );
}
else
{
brvExport = (IPhyBlendedRigidVertex *)vtxExport;
nbNodes = brvExport->GetNumberNodes();
Weights[i].vertno = i;
Weights[i].nodecount = nbNodes;
if (nbNodes > MAX_BONE_NODES)
{
MessageBox( MAX_hWnd, "INCREASE MAX_BONE_NODES", "ERROR", MB_OK );
return;
}
for (int n=0;n<nbNodes;n++)
{
bonenode = brvExport->GetNode( n );
weight = brvExport->GetWeight( n );
offsetvector = brvExport->GetOffsetVector( n );
Weights[i].weights[n] = weight;
Weights[i].Offsets[n] = brvExport->GetOffsetVector(n);
sprintf( Weights[i].names[n], "%s", bonenode->GetName() );
}
}
contextExport->ReleaseVertexInterface( vtxExport );
}
}
}
}
ExportBones(ip->GetRootNode());
if (Weights) {
free (Weights);
Weights = NULL;
}
}
}
bool AsciiExp::IsBoned(INode *node)
{
if (FindPhysiqueModifier(node))
return true;
return false;
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
Modifier * AsciiExp::FindPhysiqueModifier (INode* node, ModContext**mc)
{
// Get object from node. Abort if no object.
Object* ObjectPtr = node->GetObjectRef();
if (!ObjectPtr) return NULL;
// Is derived object ?
if (ObjectPtr->SuperClassID() == GEN_DERIVOB_CLASS_ID)
{
// Yes -> Cast.
IDerivedObject* DerivedObjectPtr = static_cast<IDerivedObject*>(ObjectPtr);
// Iterate over all entries of the modifier stack.
int ModStackIndex = 0;
while (ModStackIndex < DerivedObjectPtr->NumModifiers())
{
// Get current modifier.
Modifier* ModifierPtr = DerivedObjectPtr->GetModifier(ModStackIndex);
// Is this Physique ?
if (ModifierPtr->ClassID() == Class_ID(PHYSIQUE_CLASS_ID_A, PHYSIQUE_CLASS_ID_B))
{
*mc = DerivedObjectPtr->GetModContext(ModStackIndex);
// Yes -> Exit.
return ModifierPtr;
}
// Next modifier stack entry.
ModStackIndex++;
}
}
// Not found.
return NULL;
}
Modifier * AsciiExp::FindPhysiqueModifier (INode* node)
{
// Get object from node. Abort if no object.
Object* ObjectPtr = node->GetObjectRef();
if (!ObjectPtr) return NULL;
// Is derived object ?
if (ObjectPtr->SuperClassID() == GEN_DERIVOB_CLASS_ID)
{
// Yes -> Cast.
IDerivedObject* DerivedObjectPtr = static_cast<IDerivedObject*>(ObjectPtr);
// Iterate over all entries of the modifier stack.
int ModStackIndex = 0;
while (ModStackIndex < DerivedObjectPtr->NumModifiers())
{
// Get current modifier.
Modifier* ModifierPtr = DerivedObjectPtr->GetModifier(ModStackIndex);
// Is this Physique ?
if (ModifierPtr->ClassID() == Class_ID(PHYSIQUE_CLASS_ID_A, PHYSIQUE_CLASS_ID_B))
{
// Yes -> Exit.
return ModifierPtr;
}
// Next modifier stack entry.
ModStackIndex++;
}
}
// Not found.
return NULL;
}
/*===========================================================================
end */