This commit is contained in:
parent
3d74ef38c3
commit
aeb95010d3
24 changed files with 7743 additions and 12 deletions
991
Utils/GinExp/ExpBone.cpp
Normal file
991
Utils/GinExp/ExpBone.cpp
Normal file
|
@ -0,0 +1,991 @@
|
|||
/*=========================================================================
|
||||
|
||||
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 */
|
Loading…
Add table
Add a link
Reference in a new issue