This commit is contained in:
Daveo 2001-01-12 22:40:39 +00:00
parent 3d74ef38c3
commit aeb95010d3
24 changed files with 7743 additions and 12 deletions

37
Utils/GinExp/ASCIIEXP.DSW Normal file
View File

@ -0,0 +1,37 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "asciiexp"=.\asciiexp.dsp - Package Owner=<4>
Package=<5>
{{{
begin source code control
"$/TP2psx/utils/GinExp", ZDXAAAAA
.
end source code control
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
begin source code control
"$/TP2psx/utils/GinExp", HFXAAAAA
.
end source code control
}}}
Package=<3>
{{{
}}}
###############################################################################

BIN
Utils/GinExp/ASCIIEXP.opt Normal file

Binary file not shown.

View File

@ -0,0 +1,753 @@
//**************************************************************************
//* Animout.cpp - Ascii File Exporter
//*
//* By Christer Janson
//* Kinetix Development
//*
//* January 20, 1997 CCJ Initial coding
//*
//* This module handles controller key output and controller sampling.
//*
//* Copyright (c) 1997, All Rights Reserved.
//***************************************************************************
#include "asciiexp.h"
#define ALMOST_ZERO 1.0e-3f
BOOL EqualPoint3(Point3 p1, Point3 p2);
/****************************************************************************
TM Animation output
****************************************************************************/
// Get hold of the transform controllers for the node...
void AsciiExp::ExportAnimKeys( INode* node )
{
BOOL bPosAnim;
BOOL bRotAnim;
BOOL bScaleAnim;
BOOL bDoKeys = FALSE;
// We can only export keys if all TM controllers are "known" to us.
// The reason for that is that some controllers control more than what
// they should. Consider a path position controller, if you turn on
// follow and banking, this position controller will also control
// rotation. If a node that had a path position controller also had a
// TCB rotation controller, the TCB keys would not describe the whole
// rotation of the node.
// For that reason we will only export keys if all controllers
// position, rotation and scale are linear, hybrid (bezier) or tcb.
/* if (!GetAlwaysSample())
{
Control* pC = node->GetTMController()->GetPositionController();
Control* rC = node->GetTMController()->GetRotationController();
Control* sC = node->GetTMController()->GetScaleController();
if (IsKnownController(pC) && IsKnownController(rC) && IsKnownController(sC))
{
bDoKeys = TRUE;
}
}
*/
if (bDoKeys)
{
// Only dump the track header if any of the controllers have keys
if (node->GetTMController()->GetPositionController()->NumKeys() ||
node->GetTMController()->GetRotationController()->NumKeys() ||
node->GetTMController()->GetScaleController()->NumKeys())
{
// fprintf(pStream,"%s\t%s {\n", indent.data(), ID_TM_ANIMATION);
// fprintf(pStream,"%s\t\t%s \"%s\"\n", indent.data(), ID_NODE_NAME, FixupName(node->GetName()));
DumpPosKeys(node->GetTMController()->GetPositionController());
DumpRotKeys(node->GetTMController()->GetRotationController());
DumpScaleKeys(node->GetTMController()->GetScaleController());
// fprintf(pStream,"%s\t}\n", indent.data());
}
}
else if (CheckForAnimation(node, bPosAnim, bRotAnim, bScaleAnim))
{
// fprintf(pStream,"%s\t%s {\n", indent.data(), ID_TM_ANIMATION);
// fprintf(pStream,"%s\t\t%s \"%s\"\n", indent.data(), ID_NODE_NAME, FixupName(node->GetName()));
if (bPosAnim) DumpPosSample(node);
if (bRotAnim) DumpRotSample(node);
if (bScaleAnim) DumpScaleSample(node);
// fprintf(pStream,"%s\t}\n", indent.data());
}
}
// To really see if a node is animated we can step through the animation range
// and decompose the TM matrix for every frame and examine the components.
// This way we can identify position, rotation and scale animation separately.
//
// Some controllers makes it problematic to examine the TMContollers instead of
// the actual TMMatrix. For example, a path controller is a position controller,
// but if you turn on follow and banking, it will also affect the rotation component.
// If we want to, we can examine the position, rotation and scale controllers and
// if they all are Linear, Hybrid (bezier) or TCB, then we could export the actual keys.
// This is not at all difficult, but the importer has to know the exact interpolation
// algorithm in order to use it. The source code to the interpolation routines are available
// to ADN members.
//
// For an example of how to export actual keys, look at DumpPoint3Keys() below.
// This method will check the actual controller to determine if the controller is known.
// If we know how to work this controller, its actual keys will be exported,
// otherwise the controller will be sampled using the user specified sampling frequency.
BOOL AsciiExp::CheckForAnimation(INode* node, BOOL& bPos, BOOL& bRot, BOOL& bScale)
{
TimeValue start = ip->GetAnimRange().Start();
TimeValue end = ip->GetAnimRange().End();
TimeValue t;
int delta = GetTicksPerFrame();
Matrix3 tm;
AffineParts ap;
Point3 firstPos;
float rotAngle, firstRotAngle;
Point3 rotAxis;
Point3 firstScaleFactor;
bPos = bRot = bScale = FALSE;
for (t=start; t<=end; t+=delta)
{
tm = node->GetNodeTM(t) * Inverse(node->GetParentTM(t));
decomp_affine(tm, &ap);
AngAxisFromQ(ap.q, &rotAngle, rotAxis);
if (t != start)
{
// We examine the rotation angle to see if the rotation component
// has changed.
// Although not entierly true, it should work.
// It is rare that the rotation axis is animated without
// the rotation angle being somewhat affected.
bPos = TRUE;
bRot = TRUE;
bScale = TRUE;
// if (!EqualPoint3(ap.t, firstPos)) bPos = TRUE;
// if (fabs(rotAngle - firstRotAngle) > ALMOST_ZERO) bRot = TRUE;
// if (!EqualPoint3(ap.k, firstScaleFactor)) bScale = TRUE;
}
else
{
firstPos = ap.t;
firstRotAngle = rotAngle;
firstScaleFactor = ap.k;
}
// No need to continue looping if all components are animated
if (bPos && bRot && bScale) break;
}
return bPos || bRot || bScale;
}
void AsciiExp::DumpPosQuatSample(INode* node)
{
// fprintf(pStream,"%s\t\t%s {\n", indent.data(), ID_POS_TRACK);
TimeValue start = ip->GetAnimRange().Start();
TimeValue end = ip->GetAnimRange().End();
TimeValue t;
int delta = GetTicksPerFrame();
Matrix3 tm;
AffineParts ap;
Point3 prevPos;
Quat prevQ;
Quat q;
char name[256];
sprintf( name, "%s", node->GetName() );
fprintf( tempStream, "OUTPUTTING - %s\n", name ); // DEBUG FILE
// fwrite( &name, sizeof(char), NAME_LENGTH, boneStream ); // WRITE BONE NAME
prevQ.Identity();
for (t=start; t<=end; t+=delta)
{
// TRANSLATION
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
}
}
void AsciiExp::DumpPosSample(INode* node)
{
// fprintf(pStream,"%s\t\t%s {\n", indent.data(), ID_POS_TRACK);
TimeValue start = ip->GetAnimRange().Start();
TimeValue end = ip->GetAnimRange().End();
TimeValue t;
int delta = GetTicksPerFrame();
Matrix3 tm;
AffineParts ap;
Point3 prevPos;
Quat prevQ;
Quat q;
char name[256];
sprintf( name, "%s", node->GetName() );
fprintf( tempStream, "OUTPUTTING - %s\n", name ); // DEBUG FILE
// fwrite( &name, sizeof(char), NAME_LENGTH, boneStream ); // WRITE BONE NAME
prevQ.Identity();
for (t=start; t<=end; t+=delta)
{
// TRANSLATION
tm = node->GetNodeTM(t);// * Inverse(node->GetParentTM(t));
decomp_affine(tm, &ap);
Point3 fpos;
Point3 pos = ap.t;
prevPos = pos;
fpos.x = pos.x;
fpos.y = pos.z;
fpos.z = -pos.y;
fprintf( tempStream, " POS = %f %f %f\n", pos.x, pos.z, -pos.y );
// fwrite( &fpos.x, sizeof(float), 1, boneStream ); // WRITE BONE X-POS
// fwrite( &fpos.y, sizeof(float), 1, boneStream ); // WRITE BONE Y-POS
// fwrite( &fpos.z, sizeof(float), 1, boneStream ); // WRITE BONE Z-POS
// ROTATION
tm = node->GetNodeTM(t);// * Inverse(node->GetParentTM(t));
decomp_affine(tm, &ap);
if (t == start)
{
q = ap.q;
prevQ = ap.q; // SAVE BASE ROTATION, THEN USE THIS AS ROTATION ORIGIN
}
else
{
q = ap.q / prevQ;
}
fprintf( tempStream, " QUAT = %f %f %f %f\n", q.x, q.y, q.z, q.w );
// fwrite( &q.x, sizeof(float), 1, boneStream ); // WRITE BONE ROT X-AXIS
// fwrite( &q.y, sizeof(float), 1, boneStream ); // WRITE BONE ROT Y-AXIS
// fwrite( &q.z, sizeof(float), 1, boneStream ); // WRITE BONE ROT Z-AXIS
// fwrite( &q.w, sizeof(float), 1, boneStream ); // WRITE BONE ROT W ANGLE
}
}
void AsciiExp::DumpRotSample(INode* node)
{
// fprintf(pStream,"%s\t\t%s {\n", indent.data(), ID_ROT_TRACK);
TimeValue start = ip->GetAnimRange().Start();
TimeValue end = ip->GetAnimRange().End();
TimeValue t;
int delta = GetTicksPerFrame();
Matrix3 tm;
AffineParts ap;
Quat prevQ;
prevQ.Identity();
for (t=start; t<=end; t+=delta)
{
tm = node->GetNodeTM(t) * Inverse(node->GetParentTM(t));
decomp_affine(tm, &ap);
// Rotation keys should be relative, so we need to convert these
// absolute samples to relative values.
Quat q = ap.q / prevQ;
prevQ = ap.q;
// No point in exporting null keys...
// if (q.IsIdentity()) continue;
// Output the sample
fprintf( tempStream, " QUAT = %f %f %f %f\n", q.x, q.y, q.z, q.w );
// fprintf(pStream, "%s\t\t\t%s %d\t%s\n", indent.data(), ID_ROT_SAMPLE, t, Format(q));
}
// fprintf(pStream,"%s\t\t}\n", indent.data());
}
void AsciiExp::DumpScaleSample(INode* node)
{
// fprintf(pStream,"%s\t\t%s {\n", indent.data(), ID_SCALE_TRACK);
TimeValue start = ip->GetAnimRange().Start();
TimeValue end = ip->GetAnimRange().End();
TimeValue t;
int delta = GetTicksPerFrame();
Matrix3 tm;
AffineParts ap;
Point3 prevFac;
for (t=start; t<=end; t+=delta)
{
tm = node->GetNodeTM(t) * Inverse(node->GetParentTM(t));
decomp_affine(tm, &ap);
// Skip identical keys
if (t!= start && EqualPoint3(ap.k, prevFac)) continue;
prevFac = ap.k;
// Output the sample
// fprintf(pStream, "%s\t\t\t%s %d\t%s %s\n", indent.data(), ID_SCALE_SAMPLE, t, Format(ap.k), Format(ap.u));
}
// fprintf(pStream,"%s\t\t}\n", indent.data());
}
// Output point3 keys if this is a known point3 controller that
// supports key operations. Otherwise we will sample the controller
// once for each frame to get the value.
// Point3 controllers can control, for example, color.
void AsciiExp::DumpPoint3Keys(Control* cont)
{
// Bug out if no controller.
if (!cont) return;
int i;
IKeyControl *ikc = NULL;
// If the user wants us to always sample, we will ignore the KeyControlInterface
// if (!GetAlwaysSample()) ikc = GetKeyControlInterface(cont);
// TCB point3
if (ikc && cont->ClassID() == Class_ID(TCBINTERP_POINT3_CLASS_ID, 0))
{
// fprintf(pStream,"%s\t\t%s {\n", indent.data(), ID_CONTROL_POINT3_TCB);
for (i=0; i<ikc->GetNumKeys(); i++)
{
ITCBPoint3Key key;
ikc->GetKey(i, &key);
fprintf( tempStream, " KEYPOS = %f %f %f\n", key.val.x, key.val.y, key.val.z );
// fprintf(pStream, "%s\t\t\t%s %d\t%s", indent.data(), ID_TCB_POINT3_KEY, key.time, Format(key.val));
// Add TCB specific data
// fprintf(pStream, "\t%s\t%s\t%s\t%s\t%s\n", Format(key.tens), Format(key.cont), Format(key.bias), Format(key.easeIn), Format(key.easeOut));
}
// fprintf(pStream,"%s\t\t}\n", indent.data());
}
// Bezier point3
else if (ikc && cont->ClassID() == Class_ID(HYBRIDINTERP_POINT3_CLASS_ID, 0))
{
// fprintf(pStream,"%s\t\t%s {\n", indent.data(), ID_CONTROL_POINT3_BEZIER);
for (i=0; i<ikc->GetNumKeys(); i++)
{
IBezPoint3Key key;
ikc->GetKey(i, &key);
fprintf( tempStream, " KEYPOS = %f %f %f\n", key.val.x, key.val.y, key.val.z );
// fprintf(pStream, "%s\t\t\t%s %d\t%s", indent.data(), ID_BEZIER_POINT3_KEY, key.time, Format(key.val));
// fprintf(pStream, "\t%s\t%s\t%d\n", Format(key.intan), Format(key.outtan), key.flags);
}
// fprintf(pStream,"%s\t\t}\n", indent.data());
}
// Bezier color
else if (ikc && cont->ClassID() == Class_ID(HYBRIDINTERP_COLOR_CLASS_ID, 0))
{
// fprintf(pStream,"%s\t\t%s {\n", indent.data(), ID_CONTROL_COLOR_BEZIER);
for (i=0; i<ikc->GetNumKeys(); i++)
{
IBezPoint3Key key;
ikc->GetKey(i, &key);
fprintf( tempStream, " KEYPOS = %f %f %f\n", key.val.x, key.val.y, key.val.z );
// fprintf(pStream, "%s\t\t\t%s %d\t%s", indent.data(), ID_BEZIER_POINT3_KEY, key.time, Format(key.val));
// fprintf(pStream, "\t%s\t%s\t%d\n", Format(key.intan), Format(key.outtan), key.flags);
}
// fprintf(pStream,"%s\t\t}\n", indent.data());
}
else
{
// Unknown controller, no key interface or sample on demand -
// This might be a procedural controller or something else we
// don't know about. The last resort is to get the value from the
// controller at every n frames.
TSTR name;
cont->GetClassName(name);
// fprintf(pStream,"%s\t\t%s \"%s\" {\n", indent.data(), ID_CONTROL_POINT3_SAMPLE, FixupName(name));
// If it is animated at all...
if (cont->IsAnimated())
{
// Get the range of the controller animation
Interval range;
// Get range of full animation
Interval animRange = ip->GetAnimRange();
TimeValue t = cont->GetTimeRange(TIMERANGE_ALL).Start();
Point3 value;
// While we are inside the animation...
while (animRange.InInterval(t))
{
// Sample the controller
range = FOREVER;
cont->GetValue(t, &value, range);
// Set time to start of controller validity interval
t = range.Start();
// Output the sample
fprintf( tempStream, " KEYPOS = %f %f %f\n", value.x, value.y, value.z );
// fprintf(pStream, "%s\t\t\t%s %d\t%s\n", indent.data(), ID_POINT3_KEY, t, Format(value));
// If the end of the controller validity is beyond the
// range of the animation
if (range.End() > cont->GetTimeRange(TIMERANGE_ALL).End())
{
break;
}
else
{
t = (range.End()/GetTicksPerFrame()+1) * GetTicksPerFrame();
}
}
}
// fprintf(pStream,"%s\t\t}\n", indent.data());
}
}
// Output float keys if this is a known float controller that
// supports key operations. Otherwise we will sample the controller
// once for each frame to get the value.
void AsciiExp::DumpFloatKeys(Control* cont)
{
if (!cont) return;
int i;
IKeyControl *ikc = NULL;
// If the user wants us to always sample, we will ignore the KeyControlInterface
// if (!GetAlwaysSample()) ikc = GetKeyControlInterface(cont);
// TCB float
if (ikc && cont->ClassID() == Class_ID(TCBINTERP_FLOAT_CLASS_ID, 0))
{
// fprintf(pStream,"%s\t\t%s {\n", indent.data(), ID_CONTROL_FLOAT_TCB);
for (i=0; i<ikc->GetNumKeys(); i++)
{
ITCBFloatKey key;
ikc->GetKey(i, &key);
// fprintf(pStream, "%s\t\t\t%s %d\t%s", indent.data(), ID_TCB_FLOAT_KEY, key.time, Format(key.val));
// fprintf(pStream, "\t%s\t%s\t%s\t%s\t%s\n", Format(key.tens), Format(key.cont), Format(key.bias), Format(key.easeIn), Format(key.easeOut));
}
// fprintf(pStream,"%s\t\t}\n", indent.data());
}
// Bezier float
else if (ikc && cont->ClassID() == Class_ID(HYBRIDINTERP_FLOAT_CLASS_ID, 0))
{
// fprintf(pStream,"%s\t\t%s {\n", indent.data(), ID_CONTROL_FLOAT_BEZIER);
for (i=0; i<ikc->GetNumKeys(); i++)
{
IBezFloatKey key;
ikc->GetKey(i, &key);
// fprintf(pStream, "%s\t\t\t%s %d\t%s", indent.data(), ID_BEZIER_FLOAT_KEY, key.time, Format(key.val));
// fprintf(pStream, "\t%s\t%s\t%d\n", Format(key.intan), Format(key.outtan), key.flags);
}
// fprintf(pStream,"%s\t\t}\n", indent.data());
}
else if (ikc && cont->ClassID() == Class_ID(LININTERP_FLOAT_CLASS_ID, 0))
{
// fprintf(pStream,"%s\t\t%s {\n", indent.data(), ID_CONTROL_FLOAT_LINEAR);
for (i=0; i<ikc->GetNumKeys(); i++)
{
ILinFloatKey key;
ikc->GetKey(i, &key);
// fprintf(pStream, "%s\t\t\t%s %d\t%s\n", indent.data(), ID_FLOAT_KEY, key.time, Format(key.val));
}
// fprintf(pStream,"%s\t\t}\n", indent.data());
}
else
{
// Unknown controller, no key interface or sample on demand -
// This might be a procedural controller or something else we
// don't know about. The last resort is to get the value from the
// controller at every n frames.
TSTR name;
cont->GetClassName(name);
// fprintf(pStream,"%s\t\t%s \"%s\" {\n", indent.data(), ID_CONTROL_FLOAT_SAMPLE, FixupName(name));
// If it is animated at all...
if (cont->IsAnimated())
{
// Get the range of the controller animation
Interval range;
// Get range of full animation
Interval animRange = ip->GetAnimRange();
TimeValue t = cont->GetTimeRange(TIMERANGE_ALL).Start();
float value;
// While we are inside the animation...
while (animRange.InInterval(t))
{
// Sample the controller
range = FOREVER;
cont->GetValue(t, &value, range);
// Set time to start of controller validity interval
t = range.Start();
// Output the sample
// fprintf(pStream, "%s\t\t\t%s %d\t%s\n", indent.data(), ID_FLOAT_KEY, t, Format(value));
// If the end of the controller validity is beyond the
// range of the animation
if (range.End() > cont->GetTimeRange(TIMERANGE_ALL).End())
{
break;
}
else
{
t = (range.End()/GetTicksPerFrame()+1) * GetTicksPerFrame();
}
}
}
// fprintf(pStream,"%s\t\t}\n", indent.data());
}
}
void AsciiExp::DumpPosKeys(Control* cont)
{
if (!cont) return;
int i;
IKeyControl *ikc = GetKeyControlInterface(cont);
// TCB position
if (ikc && cont->ClassID() == Class_ID(TCBINTERP_POSITION_CLASS_ID, 0))
{
int numKeys;
if (numKeys = ikc->GetNumKeys())
{
// fprintf(pStream,"%s\t\t%s {\n", indent.data(), ID_CONTROL_POS_TCB);
for (i=0; i<numKeys; i++)
{
ITCBPoint3Key key;
ikc->GetKey(i, &key);
// fprintf(pStream, "%s\t\t\t%s %d\t%s", indent.data(), ID_TCB_POS_KEY, key.time, Format(key.val));
// fprintf(pStream, "\t%s\t%s\t%s\t%s\t%s\n", Format(key.tens), Format(key.cont), Format(key.bias), Format(key.easeIn), Format(key.easeOut));
}
// fprintf(pStream,"%s\t\t}\n", indent.data());
}
}
// Bezier position
else if (ikc && cont->ClassID() == Class_ID(HYBRIDINTERP_POSITION_CLASS_ID, 0))
{
int numKeys;
if(numKeys = ikc->GetNumKeys())
{
// fprintf(pStream,"%s\t\t%s {\n", indent.data(), ID_CONTROL_POS_BEZIER);
for (i=0; i<numKeys; i++)
{
IBezPoint3Key key;
ikc->GetKey(i, &key);
// fprintf(pStream, "%s\t\t\t%s %d\t%s", indent.data(), ID_BEZIER_POS_KEY, key.time, Format(key.val));
// fprintf(pStream, "\t%s\t%s\t%d\n", Format(key.intan), Format(key.outtan), key.flags);
}
// fprintf(pStream,"%s\t\t}\n", indent.data());
}
}
// Linear position
else if (ikc && cont->ClassID() == Class_ID(LININTERP_POSITION_CLASS_ID, 0))
{
int numKeys;
if(numKeys = ikc->GetNumKeys())
{
// fprintf(pStream,"%s\t\t%s {\n", indent.data(), ID_CONTROL_POS_LINEAR);
for (i=0; i<numKeys; i++)
{
ILinPoint3Key key;
ikc->GetKey(i, &key);
// fprintf(pStream, "%s\t\t\t%s %d\t%s\n", indent.data(), ID_POS_KEY, key.time, Format(key.val));
}
// fprintf(pStream,"%s\t\t}\n", indent.data());
}
}
}
void AsciiExp::DumpRotKeys(Control* cont)
{
if (!cont) return;
int i;
IKeyControl *ikc = GetKeyControlInterface(cont);
if (ikc && cont->ClassID() == Class_ID(TCBINTERP_ROTATION_CLASS_ID, 0))
{
int numKeys;
if (numKeys = ikc->GetNumKeys())
{
// fprintf(pStream,"%s\t\t%s {\n", indent.data(), ID_CONTROL_ROT_TCB);
for (i=0; i<numKeys; i++)
{
ITCBRotKey key;
ikc->GetKey(i, &key);
// fprintf(pStream, "%s\t\t\t%s %d\t%s", indent.data(), ID_TCB_ROT_KEY, key.time, Format(key.val));
// fprintf(pStream, "\t%s\t%s\t%s\t%s\t%s\n", Format(key.tens), Format(key.cont), Format(key.bias), Format(key.easeIn), Format(key.easeOut));
}
// fprintf(pStream,"%s\t\t}\n", indent.data());
}
}
else if (ikc && cont->ClassID() == Class_ID(HYBRIDINTERP_ROTATION_CLASS_ID, 0))
{
int numKeys;
if (numKeys = ikc->GetNumKeys())
{
// fprintf(pStream,"%s\t\t%s {\n", indent.data(), ID_CONTROL_ROT_BEZIER);
for (i=0; i<numKeys; i++)
{
IBezQuatKey key;
ikc->GetKey(i, &key);
// Quaternions are converted to AngAxis when written to file
// There is no intan/outtan for Quat Rotations
// fprintf(pStream, "%s\t\t\t%s %d\t%s\n", indent.data(), ID_ROT_KEY, key.time, Format(key.val));
}
// fprintf(pStream,"%s\t\t}\n", indent.data());
}
}
else if (ikc && cont->ClassID() == Class_ID(LININTERP_ROTATION_CLASS_ID, 0))
{
int numKeys;
if (numKeys = ikc->GetNumKeys())
{
// fprintf(pStream,"%s\t\t%s {\n", indent.data(), ID_CONTROL_ROT_LINEAR);
for (i=0; i<numKeys; i++)
{
ILinRotKey key;
ikc->GetKey(i, &key);
// Quaternions are converted to AngAxis when written to file
// fprintf(pStream, "%s\t\t\t%s %d\t%s\n", indent.data(), ID_ROT_KEY, key.time, Format(key.val));
}
// fprintf(pStream,"%s\t\t}\n", indent.data());
}
}
}
void AsciiExp::DumpScaleKeys(Control* cont)
{
if (!cont) return;
int i;
IKeyControl *ikc = GetKeyControlInterface(cont);
if (ikc && cont->ClassID() == Class_ID(TCBINTERP_SCALE_CLASS_ID, 0))
{
int numKeys;
if (numKeys = ikc->GetNumKeys())
{
// fprintf(pStream,"%s\t\t%s {\n", indent.data(), ID_CONTROL_SCALE_TCB);
for (i=0; i<numKeys; i++)
{
ITCBScaleKey key;
ikc->GetKey(i, &key);
// fprintf(pStream, "%s\t\t\t%s %d\t%s", indent.data(), ID_TCB_SCALE_KEY, key.time, Format(key.val));
// fprintf(pStream, "\t%s\t%s\t%s\t%s\t%s\n", Format(key.tens), Format(key.cont), Format(key.bias), Format(key.easeIn), Format(key.easeOut));
}
// fprintf(pStream,"%s\t\t}\n", indent.data());
}
}
else if (ikc && cont->ClassID() == Class_ID(HYBRIDINTERP_SCALE_CLASS_ID, 0))
{
int numKeys;
if (numKeys = ikc->GetNumKeys())
{
// fprintf(pStream,"%s\t\t%s {\n", indent.data(), ID_CONTROL_SCALE_BEZIER);
for (i=0; i<numKeys; i++)
{
IBezScaleKey key;
ikc->GetKey(i, &key);
// fprintf(pStream, "%s\t\t\t%s %d\t%s", indent.data(), ID_BEZIER_SCALE_KEY, key.time, Format(key.val));
// fprintf(pStream, "\t%s\t%s\t%d\n", Format(key.intan), Format(key.outtan), key.flags);
}
// fprintf(pStream,"%s\t\t}\n", indent.data());
}
}
else if (ikc && cont->ClassID() == Class_ID(LININTERP_SCALE_CLASS_ID, 0))
{
int numKeys;
if (numKeys = ikc->GetNumKeys())
{
// fprintf(pStream,"%s\t\t%s {\n", indent.data(), ID_CONTROL_SCALE_LINEAR);
for (i=0; i<numKeys; i++)
{
ILinScaleKey key;
ikc->GetKey(i, &key);
// fprintf(pStream, "%s\t\t\t%s %d\t%s\n", indent.data(), ID_SCALE_KEY, key.time, Format(key.val));
}
// fprintf(pStream,"%s\t\t}\n", indent.data());
}
}
}
// Not truly the correct way to compare floats of arbitary magnitude...
BOOL EqualPoint3(Point3 p1, Point3 p2)
{
if (fabs(p1.x - p2.x) > ALMOST_ZERO) return FALSE;
if (fabs(p1.y - p2.y) > ALMOST_ZERO) return FALSE;
if (fabs(p1.z - p2.z) > ALMOST_ZERO) return FALSE;
return TRUE;
}
// Determine if a TM controller is known by the system.
AsciiExp::IsKnownController(Control* cont)
{
ulong partA, partB;
if (!cont) return FALSE;
partA = cont->ClassID().PartA();
partB = cont->ClassID().PartB();
if (partB != 0x00) return FALSE;
switch (partA)
{
case TCBINTERP_POSITION_CLASS_ID:
case TCBINTERP_ROTATION_CLASS_ID:
case TCBINTERP_SCALE_CLASS_ID:
case HYBRIDINTERP_POSITION_CLASS_ID:
case HYBRIDINTERP_ROTATION_CLASS_ID:
case HYBRIDINTERP_SCALE_CLASS_ID:
case LININTERP_POSITION_CLASS_ID:
case LININTERP_ROTATION_CLASS_ID:
case LININTERP_SCALE_CLASS_ID:
return TRUE;
}
return FALSE;
}

991
Utils/GinExp/ExpBone.cpp Normal file
View 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 */

View File

@ -0,0 +1,237 @@
/*=========================================================================
.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::ExportCamera(INode* node)
{
INode * target = node->GetTarget();
CameraState cs;
TimeValue t = 0;
Interval valid = FOREVER;
Interval animRange = ip->GetAnimRange();
ObjectState os = node->EvalWorldState(t);
CameraObject * cam = (CameraObject *)os.obj;
cam->EvalCameraState(t, valid, &cs);
if (target)
{
WriteChunkHdr( (char*)CAMERA_ID, 0 );
fwrite( &totFrames, sizeof( Uint32 ), 1, expStream );
DumpCamPosSample( node );
DumpCamPosSample( target );
}
}
/*----------------------------------------------------------------------
---------------------------------------------------------------------- */
void AsciiExp::DumpCamPosSample(INode* node)
{
TimeValue start = ip->GetAnimRange().Start();
TimeValue end = ip->GetAnimRange().End();
TimeValue t;
int delta = GetTicksPerFrame() * 1;
Matrix3 tm;
AffineParts ap;
Point3 pos;
Point3 opos;
for (t=start; t<=end; t+=delta)
{
tm = node->GetNodeTM(t);
decomp_affine(tm, &ap);
pos = ap.t;
opos.x = pos.x;
opos.y = pos.z;
opos.z = pos.y;
fwrite( &opos.x, sizeof( float ), 1, expStream ); // WRITE CAMERA POSITION
fwrite( &opos.y, sizeof( float ), 1, expStream );
fwrite( &opos.z, sizeof( float ), 1, expStream );
}
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void AsciiExp::ExportLight(INode* node)
{
Interval valid = FOREVER;
Matrix3 mtx = node->GetNodeTM( 0 );
ObjectState os = node->EvalWorldState( 0 );
GenLight * light;
LightState ls;
AffineParts ap;
Point3 pos;
Point3 opos;
float ang[4];
Point3 oang;
Quat rot;
INode * target;
float hotsize;
float fallsize;
float attenStart;
float attenEnd;
if (!os.obj) return;
// EXPORT LIGHT
WriteChunkHdr( (char*)LIGHT_ID, 0 );
light = (GenLight*)os.obj;
light->EvalLightState( 0, valid, &ls );
fwrite( &ls.type, sizeof(long), 1, expStream );
decomp_affine( mtx, &ap );
pos = ap.t;
opos.x = pos.x;
opos.y = pos.z;
opos.z = pos.y;
fwrite( &opos.x, sizeof( float ), 1, expStream ); // WRITE LIGHT POSITION
fwrite( &opos.y, sizeof( float ), 1, expStream );
fwrite( &opos.z, sizeof( float ), 1, expStream );
rot.x = ap.q.x;
rot.y = ap.q.z;
rot.z = ap.q.y;
rot.w = ap.q.w;
QuatToEuler( rot, ang);
oang.x = ang[0];
oang.y = ang[1];
oang.z = ang[2];
// fwrite( &oang.x, sizeof( float ), 1, expStream ); // WRITE LIGHT ROTATION
// fwrite( &oang.y, sizeof( float ), 1, expStream );
// fwrite( &oang.z, sizeof( float ), 1, expStream );
target = node->GetTarget();
if (target)
{
mtx = target->GetNodeTM( 0 );
decomp_affine( mtx, &ap );
pos = ap.t;
opos.x = pos.x;
opos.y = pos.z;
opos.z = pos.y;
}
else
{
// opos.x = 0.f;
// opos.y = 0.f;
// opos.z = 0.f;
}
fwrite( &opos.x, sizeof( float ), 1, expStream ); // WRITE LIGHT POSITION
fwrite( &opos.y, sizeof( float ), 1, expStream );
fwrite( &opos.z, sizeof( float ), 1, expStream );
fwrite( &ls.color.r, sizeof( float ), 1, expStream );
fwrite( &ls.color.g, sizeof( float ), 1, expStream );
fwrite( &ls.color.b, sizeof( float ), 1, expStream );
fwrite( &ls.intens, sizeof( float ), 1, expStream );
hotsize = 0.f;
fallsize = 0.f;
attenStart = 0.f;
attenEnd = 0.f;
if (ls.type != OMNI_LIGHT)
{
hotsize = ls.hotsize;
fallsize = ls.fallsize;
}
if (ls.type != DIR_LIGHT && ls.useAtten)
{
attenStart = ls.attenStart;
attenEnd = ls.attenEnd;
}
fwrite( &hotsize, sizeof( float ), 1, expStream );
fwrite( &fallsize, sizeof( float ), 1, expStream );
fwrite( &attenStart, sizeof( float ), 1, expStream );
fwrite( &attenEnd, sizeof( float ), 1, expStream );
}
/*===========================================================================
end */

550
Utils/GinExp/ExpFFD.cpp Normal file
View File

@ -0,0 +1,550 @@
#include "max.h"
#include "asciiexp.h"
#define EDITMESH_CLASS_ID 0x00050
typedef Tab<Point3> Point3Tab;
//typedef Tab<AnimPoint3> AnimPoint3Tab;
typedef Tab<Face> FaceTab;
class XFormProc {
public:
virtual Point3 proc(Point3& p, Matrix3 &mat, Matrix3 &imat)=0;
virtual void SetMat( Matrix3& mat ) {}
};
class MoveXForm : public XFormProc {
private:
Point3 delta, tdelta;
public:
Point3 proc(Point3& p, Matrix3 &mat, Matrix3 &imat)
{ return p + tdelta; }
void SetMat( Matrix3& mat )
{ tdelta = VectorTransform(Inverse(mat),delta); }
MoveXForm(Point3 d) { delta = d; }
};
class RotateXForm : public XFormProc {
private:
Matrix3 rot, trot;
public:
Point3 proc(Point3& p, Matrix3 &mat, Matrix3 &imat)
{ return (trot*p)*imat; }
void SetMat( Matrix3& mat )
{ trot = mat * rot; }
RotateXForm(Quat q) { q.MakeMatrix(rot); }
};
class ScaleXForm : public XFormProc {
private:
Matrix3 scale, tscale;
public:
Point3 proc(Point3& p, Matrix3 &mat, Matrix3 &imat)
{ return (p*tscale)*imat; }
void SetMat( Matrix3& mat )
{ tscale = mat*scale; }
ScaleXForm(Point3 s) { scale = ScaleMatrix(s); }
};
class VertexDelta {
public:
Point3Tab deltas; //DS-- I needed this public
BitArray hide;
void SetSize(int size, BOOL clear=TRUE);
Point3 operator[](int i);
void Set(TimeValue t,int i, Point3& p);
void Move(TimeValue t,int i, const Point3& p);
void Apply(TimeValue t,Mesh& mesh);
void Scale(float f);
VertexDelta& operator=(VertexDelta& from);
~VertexDelta();
VertexDelta();
};
class TopoOp {
public:
virtual void Apply(Mesh& mesh)=0;
virtual TopoOp *Clone()=0;
virtual ~TopoOp() {}
};
typedef Tab<TopoOp*> TopoOpTab;
class FaceMap {
public:
DWORD v[3];
};
typedef Tab<FaceMap> FaceMapTab;
// Bits for attribs:
// First 3 bits are edge visibility
// 4th bit is face visibility
// 29,30 and 31 indicate which if any should be applied
#define ATTRIB_APPLY_EDGE (1<<31)
#define ATTRIB_APPLY_FACE (1<<30)
#define ATTRIB_APPLY_MATID (1<<29)
#define ATTRIB_APPLY_SMGROUP (1<<28)
// Mat ID takes bit 5-21
#define ATTRIB_MATID_SHIFT 5
#define ATTRIB_MATID_MASK 0xffff
class TopoDelta {
public:
DWORDTab cverts; // Clone verts
DWORDTab dverts; // Delete verts
Point3Tab nverts; // Add verts
Point3Tab nTverts; // Add texture verts
DWORDTab dfaces; // Delete faces
Tab<Face> nfaces; // New faces
Tab<TVFace> nTVfaces; // New texture vert faces
FaceMapTab map; // Remap faces
FaceMapTab tmap; // TVFace remap
DWORDTab attribs; // Changes attributes of a face.
DWORDTab smgroups; // Changes smooth groups for a face.
DWORD inputFaces; // Number of faces on input mesh
DWORD inputVerts; // Number of vertices input mesh has
};
class EditMeshData : public LocalModData {
public:
DWORD flags;
// These record the changes to the incomming object.
VertexDelta vdelta;
TopoDelta tdelta;
// The selection sets.
BitArray vsel;
BitArray fsel;
BitArray esel;
// Lists of named selection sets
NamedSelSetList vselSet;
NamedSelSetList fselSet;
NamedSelSetList eselSet;
// While an object is being edited, this exists.
// EMTempData *tempData;
};
inline float BPoly4(int i, float u)
{
float s = 1.0f-u;
switch (i) {
case 0: return s*s*s;
case 1: return 3.0f*u*s*s;
case 2: return 3.0f*u*u*s;
case 3: return u*u*u;
default: return 0.0f;
}
}
inline float BPoly3(int i, float u)
{
float s = 1.0f-u;
switch (i) {
case 0: return s*s;
case 1: return 2.0f*u*s;
case 2: return u*u;
default: return 0.0f;
}
}
inline float BPoly2(int i, float u)
{
switch (i) {
case 0: return 1.0f-u;
case 1: return u;
default: return 0.0f;
}
}
#define EPSILON 0.001f
Point3 FfdLatticeSize(Box3 box)
{
Point3 size = box.Max()-box.Min();
if (size.x==0.0f) size.x = 0.001f;
if (size.y==0.0f) size.y = 0.001f;
if (size.z==0.0f) size.z = 0.001f;
return size;
}
Matrix3 FFDMod::CompTM(TimeValue t,INode *inode,ModContext *mc)
{
// Compute a the transformation out of lattice space into world space
Matrix3 ntm = inode->GetObjTMBeforeWSM(t);
Matrix3 ctm(1);
if (mc && mc->tm) {
ntm = Inverse(*(mc->tm)) * ntm;
}
tmControl->GetValue(t,&ctm,FOREVER,CTRL_RELATIVE);
return ctm * ntm;
}
Box3 ComputeBBox(TimeValue t, INode *node) {
Box3 box; // The computed box
Matrix3 mat; // The Object TM
Matrix3 sclMat(1); // This will be used to apply the scaling
// Get the result of the pipeline at the current time
Object *obj = node->EvalWorldState(t).obj;
// Determine if the object is in world space or object space
// so we can get the correct TM. We can check this by getting
if (node->GetObjTMAfterWSM(t).IsIdentity()) {
mat = Inverse(node->GetObjTMBeforeWSM(t));
} else {
// It's in object space, get the Object TM.
mat = node->GetObjectTM(t);
}
// Extract just the scaling part from the TM
AffineParts parts;
decomp_affine(mat, &parts);
//ApplyScaling(sclMat, ScaleValue(parts.k*parts.f, parts.u));
// Get the bound box, and affect it by just
// the scaling portion
obj->GetDeformBBox(t, box, &sclMat);
return box;
}
void AsciiExp::ExportFFD( INode* node , FFDMod *FfdMod, ModContext *mc, Mesh *mesh)
{
TimeValue start = ip->GetAnimRange().Start();
TimeValue end = ip->GetAnimRange().End();
int delta = GetTicksPerFrame();
int nbCtrlPnts;
TimeValue t;
int i;
int Depth;
int Width;
int Height;
if (node->IsNodeHidden())
return;
if (FfdMod) {
ObjectState os;
Object * obj;
os = node->EvalWorldState( 0 );
obj = node->GetObjectRef();
while (obj && obj->SuperClassID() == GEN_DERIVOB_CLASS_ID) {
obj = ((IDerivedObject*)obj)->GetObjRef();
}
if (!obj) return;
if (FfdMod->ClassID() == FFD44_CLASS_ID) {
Depth = Width = Height = 4;
} else
if (FfdMod->ClassID() == FFD33_CLASS_ID) {
Depth = Width = Height = 3;
} else
if (FfdMod->ClassID() == FFD22_CLASS_ID) {
Depth = Width = Height = 2;
}
// Evaluate the TM controller
Matrix3 ctm(1);
FfdMod->tmControl->GetValue(start,&ctm,FOREVER,CTRL_RELATIVE);
// Get the ModContext TM (if there is one)
Matrix3 tm = mc->tm ? *mc->tm : Matrix3(1);
// Apply our TM to the MC TM
tm *= Inverse(ctm);
// The origin of the TM is the lower left corner of the
// box, not the center.
tm.SetTrans(tm.GetTrans()-mc->box->Min());
// Compute scale factors to normalize lattice space
// to the extents of the box.
Point3 s = FfdLatticeSize(*mc->box);
for (i=0; i<3; i++) {
if (s[i]==0.0f) s[i] = 1.0f;
else s[i] = 1.0f/s[i];
}
tm.Scale(s,TRUE);
Matrix3 itm = Inverse(tm);
AffineParts ap;
decomp_affine(tm, &ap);
nbCtrlPnts = FfdMod->NumCtrlPts();
WriteChunkHdr( (char*)FFD_ID, 0);
fwrite( &nCurObj, sizeof( Uint32 ), 1, expStream );
fwrite( &FfdNum, sizeof(Uint32), 1, expStream);
fwrite( &Width, sizeof( Uint32 ), 1, expStream );
fwrite( &Height, sizeof( Uint32 ), 1, expStream );
fwrite( &Depth, sizeof( Uint32 ), 1, expStream );
MRow *mr = tm.GetAddr();
fwrite( &mr[0][0], sizeof(MRow),1,expStream);
fwrite( &mr[1][0], sizeof(MRow),1,expStream);
fwrite( &mr[2][0], sizeof(MRow),1,expStream);
fwrite( &mr[3][0], sizeof(MRow),1,expStream);
int dd,dw,dh;
int nv = obj->NumPoints();
/* for (i=0; i<nv; i++) {
float tw = 0.f;
for (dw = 0; dw<Width; dw++) {
for (dd = 0; dd<Depth; dd++) {
for (dh = 0; dh<Height; dh++) {
float w;
Point3 pp = tm*obj->GetPoint(i);
if (pp.x>=-0.001f && pp.x<=1.001f && pp.y>=-0.001f && pp.y<=1.001f && pp.z>=-0.001f && pp.z<=1.001f) {
if (FfdMod->ClassID() == FFD44_CLASS_ID) {
w = BPoly4(dw,pp.x) * BPoly4(dd,pp.y) * BPoly4(dh,pp.z);
} else
if (FfdMod->ClassID() == FFD33_CLASS_ID) {
w = BPoly3(dw,pp.x) * BPoly3(dd,pp.y) * BPoly3(dh,pp.z);
} else
if (FfdMod->ClassID() == FFD22_CLASS_ID) {
w = BPoly2(dw,pp.x) * BPoly2(dd,pp.y) * BPoly2(dh,pp.z);
}
} else {
w = 0;
}
tw+=w;
}
}
}
}*/
fprintf( tempStream, "node = %s\n\n", node->GetName() );
fprintf( tempStream, "selected = ");
BitArray Selection = mesh->VertexTempSel();
for (dw = 0; dw<Width; dw++) {
for (dd = 0; dd<Depth; dd++) {
for (dh = 0; dh<Height; dh++) {
for (i=0; i<nv; i++) {
float w;
Point3 pp = tm*obj->GetPoint(i);
//if (pp.x>=-0.0001f && pp.x<=1.0001f && pp.y>=-0.0001f && pp.y<=1.0001f && pp.z>=-0.0001f && pp.z<=1.0001f) {
if (Selection[i])
{
if (FfdMod->ClassID() == FFD44_CLASS_ID) {
w = BPoly4(dw,pp.x) * BPoly4(dd,pp.y) * BPoly4(dh,pp.z);
} else
if (FfdMod->ClassID() == FFD33_CLASS_ID) {
w = BPoly3(dw,pp.x) * BPoly3(dd,pp.y) * BPoly3(dh,pp.z);
} else
if (FfdMod->ClassID() == FFD22_CLASS_ID) {
w = BPoly2(dw,pp.x) * BPoly2(dd,pp.y) * BPoly2(dh,pp.z);
}
fprintf( tempStream, "%d %f, ", i, w);
} else {
w = 0;
}
fwrite(&w, sizeof(float), 1, expStream);
}
fprintf( tempStream, "\nendselected\n");
}
}
}
WriteChunkHdr( (char*)ANIM_ID, 0);
fwrite( &CHANNEL_TYPE_FFD, sizeof( Uint32 ), 1, expStream );
fwrite( &nCurObj, sizeof( Uint32 ), 1, expStream );
fwrite( &totFrames, sizeof( Uint32 ), 1, expStream );
fwrite( &FfdNum, sizeof(Uint32), 1, expStream);
fwrite( &Width, sizeof( Uint32 ), 1, expStream );
fwrite( &Height, sizeof( Uint32 ), 1, expStream );
fwrite( &Depth, sizeof( Uint32 ), 1, expStream );
for (i=0; i<nbCtrlPnts; i++) {
for (t=start; t<=end; t+=delta) {
Matrix3 ntm = node->GetObjTMBeforeWSM(t);
Matrix3 ctm(1);
if (mc && mc->tm) {
ntm = Inverse(*(mc->tm)) * ntm;
}
FfdMod->tmControl->GetValue(t,&ctm,FOREVER,CTRL_RELATIVE);
Matrix3 mm = ctm * ntm;
Box3 lbox = *mc->box;
Matrix3 stm = ScaleMatrix(FfdLatticeSize(lbox));
stm.SetTrans(lbox.Min());
Point3 np = FfdMod->GetControlPoint(t,i);
Point3 p = stm*FfdMod->GetControlPoint(t, i);
Point3 p2 = mm * p;
fwrite(&p2.x, sizeof(float), 1, expStream);
fwrite(&p2.z, sizeof(float), 1, expStream);
fwrite(&p2.y, sizeof(float), 1, expStream);
}
}
TimeValue start = ip->GetAnimRange().Start();
TimeValue end = ip->GetAnimRange().End();
int delta = GetTicksPerFrame();
Control *c;
WriteChunkHdr( (char*)KEY_ID, 0);
fwrite( &CHANNEL_TYPE_FFD, sizeof( Uint32 ), 1, expStream );
fwrite( &CHANNEL_INFO_ALL, sizeof( Uint32) , 1, expStream);
fwrite( &nCurObj, sizeof( Uint32), 1, expStream );
fwrite( &FfdNum, sizeof(Uint32), 1, expStream);
fwrite( &nbCtrlPnts, sizeof( Uint32), 1, expStream );
for (i=0; i<nbCtrlPnts; i++) {
TimeList tl;
IKeyControl *ikeys;
ITCBPoint3Key tcbPosKey;
ITCBRotKey tcbRotKey;
ITCBScaleKey tcbSclKey;
IBezPoint3Key bezPosKey;
IBezQuatKey bezRotKey;
IBezScaleKey bezSclKey;
ILinPoint3Key linPosKey;
ILinRotKey linRotKey;
ILinScaleKey linSclKey;
int num;
TimeValue time;
tl.Clear();
c = FfdMod->GetPtCont(i);
if (c) {
ikeys = GetKeyControlInterface(c);
int blah = c->IsKeyable();
if (ikeys) {
num = ikeys->GetNumKeys();
if (num >0)
{
for (int j = 0; j<num; j++) {
if (c->ClassID() == Class_ID(TCBINTERP_POINT3_CLASS_ID, 0)) {
ikeys->GetKey(j, &tcbPosKey);
time = tcbPosKey.time;
} else
if (c->ClassID() == Class_ID(HYBRIDINTERP_POINT3_CLASS_ID, 0)) {
ikeys->GetKey(j, &bezPosKey);
time = bezPosKey.time;
}
tl.Add(time);
}
}
}
}
if (!tl.Count()) {
tl.Add(ip->GetAnimRange().Start());
}
num = tl.Count();
fwrite(&num, sizeof(int), 1, expStream);
for ( int j = 0; j<num; j++) {
time = tl.Get(j);
Matrix3 ntm = node->GetObjTMBeforeWSM(time);
Matrix3 ctm(1);
if (mc && mc->tm) {
ntm = Inverse(*(mc->tm)) * ntm;
}
FfdMod->tmControl->GetValue(time,&ctm,FOREVER,CTRL_RELATIVE);
Matrix3 mm = ctm * ntm;
Box3 lbox = *mc->box;
Matrix3 stm = ScaleMatrix(FfdLatticeSize(lbox));
stm.SetTrans(lbox.Min());
Point3 np = FfdMod->GetControlPoint(time,i);
Point3 p = stm*FfdMod->GetControlPoint(time, i);
Point3 p2 = mm * p;
time = (time - start)/delta;
fwrite(&time, sizeof(int), 1, expStream);
fwrite(&p2.x, sizeof(float), 1, expStream);
fwrite(&p2.z, sizeof(float), 1, expStream);
fwrite(&p2.y, sizeof(float), 1, expStream);
}
}
}
}
bool AsciiExp::FindFFDModifier (INode* node)
{
// Get object from node. Abort if no object.
Object* ObjectPtr = node->GetObjectRef();
FfdNum = 0;
bool Found= false;
if (!ObjectPtr)
return false;
// Is derived object ?
int needDel;
while (ObjectPtr->SuperClassID() == GEN_DERIVOB_CLASS_ID)
{
IDerivedObject* DerivedObjectPtr = static_cast<IDerivedObject*>(ObjectPtr);
ObjectPtr = DerivedObjectPtr->GetObjRef();
}
TriObject * tri = GetTriObjectFromObject(ObjectPtr, ip->GetAnimRange().Start(), needDel);
if (!tri) return false;
Mesh* mesh = &tri->mesh;
BitArray SaveVtx = mesh->vertSel;
BitArray SaveFce = mesh->faceSel;
BitArray SaveEdg = mesh->edgeSel;
ObjectPtr = node->GetObjectRef();
while (ObjectPtr->SuperClassID() == GEN_DERIVOB_CLASS_ID)
{
// Yes -> Cast.
IDerivedObject* DerivedObjectPtr = static_cast<IDerivedObject*>(ObjectPtr);
// Iterate over all entries of the modifier stack.
int ModStackIndex = DerivedObjectPtr->NumModifiers() - 1;
while (ModStackIndex >= 0 )
{
// Get current modifier.
Modifier* ModifierPtr = DerivedObjectPtr->GetModifier(ModStackIndex);
ModContext *modContext = DerivedObjectPtr->GetModContext(ModStackIndex);
// Is this FFD ?
if (ModifierPtr->ClassID() == FFD44_CLASS_ID ||
ModifierPtr->ClassID() == FFD33_CLASS_ID ||
ModifierPtr->ClassID() == FFD22_CLASS_ID)
{
// Yes -> Exit.
ExportFFD(node, (FFDMod*)ModifierPtr, modContext, mesh);
FfdNum++;
Found = true;
} else
if (ModifierPtr->ClassID() == Class_ID(EDITMESH_CLASS_ID,0))
{
EditMeshData *meshData = (EditMeshData*)modContext->localData;
mesh->vertSel = meshData->vsel;
mesh->faceSel = meshData->fsel;
mesh->edgeSel = meshData->esel;
}
// Next modifier stack entry.
ModStackIndex--;
}
ObjectPtr = DerivedObjectPtr->GetObjRef();
}
mesh->vertSel = SaveVtx;
mesh->faceSel = SaveFce;
mesh->edgeSel = SaveEdg;
if (needDel) delete tri;
return Found;
}

262
Utils/GinExp/ExpFileIo.cpp Normal file
View File

@ -0,0 +1,262 @@
/*=========================================================================
FILEIO.CPP
Author: Tim Swann @ CLIMAX
Created:
Project:
Purpose:
Copyright (c) 1998 Climax Development Ltd
===========================================================================*/
/*----------------------------------------------------------------------
Includes
-------- */
#include "AsciiExp.h"
#include "ExpFileIO.h"
/* Std Lib
------- */
/* Glib
---- */
/* Local
----- */
/* Graphics
-------- */
/*----------------------------------------------------------------------
Tyepdefs && Defines
------------------- */
/*----------------------------------------------------------------------
Structure defintions
-------------------- */
/*----------------------------------------------------------------------
Positional Vars
--------------- */
/*----------------------------------------------------------------------
Function Prototypes
------------------- */
/*----------------------------------------------------------------------
Vars
---- */
/*----------------------------------------------------------------------
Data
---- */
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void FIO_Stripfileinfo(char * Name, char * fname, char * ext, char * dir, char * drive)
{
char tdrive[_MAX_DRIVE];
char tdir[_MAX_DIR];
char tfname[_MAX_FNAME];
char text[_MAX_EXT];
_splitpath(Name, tdrive, tdir, tfname, text);
if (fname)
strcpy(fname, tfname);
if (ext)
strcpy(ext, text);
if (dir)
strcpy(dir, tdir);
if (drive)
strcpy(drive, tdrive);
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
bool FIO_FileExists(const char * Name)
{
int hFile;
/* Open input file */
hFile = _open(Name, _O_RDONLY | _O_BINARY);
if(hFile != -1)
{
_close(hFile); // file close
return(TRUE);
}
else
{
return(FALSE);
}
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void * FIO_Read(char const * Name, int Offset)
{
int hFile;
long filelen;
void * pAddr;
long pos;
/* Open input file */
hFile = _open(Name, _O_RDONLY | _O_BINARY);
if(hFile != -1)
{
filelen = FIO_FileLen(Name); // length of file
pAddr = malloc(filelen); // allocate mainmemory
pos = _lseek( hFile, Offset, SEEK_SET );
if( pos == -1 ) assert(!"File seek");
filelen -= pos;
_read(hFile, pAddr, filelen); // read in file
_close(hFile); // file close
}
else
{
assert(0);
}
return pAddr;
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
bool FIO_ReadAtAddr(char const * Name, unsigned char * Dest, int Len, int Offset)
{
int hFile;
long filelen;
long pos;
/* Open input file */
hFile = _open(Name, _O_RDONLY | _O_BINARY);
if(hFile != -1)
{
filelen = FIO_FileLen(Name); // length of file
if (Len && (Len < filelen)) filelen = Len;
pos = _lseek( hFile, Offset, SEEK_SET );
if( pos == -1 ) assert(!"File seek");
_read(hFile, Dest, filelen); // read in file
_close(hFile); // file close
}
else
{
assert(0);
}
return TRUE;
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
int FIO_FileLen(const char * Name)
{
int hFile;
int filelen = 0;
/* Open input file */
hFile = _open(Name, _O_RDONLY | _O_BINARY);
if(hFile != -1)
{
filelen = _filelength(hFile); // length of file
_close(hFile); // file close
}
return filelen;
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
bool FIO_Save(const char * Name,unsigned char * Addr,int Len)
{
HANDLE hFile;
UINT fResult;
DWORD nWrited;
/* Open output file */
hFile = CreateFile( Name, /* output filename */
GENERIC_WRITE, /* mode = write */
0, /* share mode = not share */
NULL, /* security attribute = cancel */
CREATE_ALWAYS, /* create file always */
FILE_ATTRIBUTE_NORMAL, /* file attribute = normal */
NULL /* template file = non */
);
if(hFile)
{
fResult = WriteFile(hFile, /* IN : file handle */
Addr, /* IN : pointer to write data */
(DWORD)Len, /* IN : number of data in bytes */
&nWrited, /* OUT : number of data just writed */
NULL /* IN : pointer to OVERLAPPED structure */
);
CloseHandle(hFile); /* close file */
if(fResult == FALSE)
assert(!("SaveFile: ERROR Can not write file %s",Name));
}
else
{
return FALSE;
}
return TRUE;
}
/*===========================================================================
end */

63
Utils/GinExp/ExpFileIo.h Normal file
View File

@ -0,0 +1,63 @@
/*=========================================================================
FILEIO.H
Author: Tim Swann @ CLIMAX
Created:
Project:
Purpose:
Copyright (c) 1998 Climax Development Ltd
===========================================================================*/
#ifndef __FILEIO__
#define __FILEIO__
/*----------------------------------------------------------------------
Includes
-------- */
/* Std Lib
------- */
/* Glib
---- */
/* Local
----- */
/*----------------------------------------------------------------------
Tyepdefs && Defines
------------------- */
/*----------------------------------------------------------------------
Structure defintions
-------------------- */
/*----------------------------------------------------------------------
Globals
------- */
/* Vars
---- */
/* Data
---- */
/* Functions
--------- */
void * FIO_Read(char const * Name, int Offset = 0);
bool FIO_ReadAtAddr(char const * Name,unsigned char * Dest,int Len = 0, int Offset = 0);
int FIO_FileLen(const char * Name);
bool FIO_FileExists(const char * Name);
bool FIO_Save(const char * Name,unsigned char * Addr,int Len);
void FIO_Stripfileinfo(char * Name, char * fname = NULL, char * ext = NULL, char * dir = NULL, char * drive = NULL);
/*---------------------------------------------------------------------- */
#endif /* __FILEIO__ */
/*===========================================================================
end */

741
Utils/GinExp/ExpMain.cpp Normal file
View File

@ -0,0 +1,741 @@
/*=========================================================================
EXPMAIN.CPP
Author: Tim Swann @ CLIMAX
Created:
Project:
Purpose:
Copyright (c) 1998 Climax Development Ltd
===========================================================================*/
/*----------------------------------------------------------------------
Includes
-------- */
#include "Asciiexp.h"
#include "ExpFileIO.h"
/* Std Lib
------- */
/* Glib
---- */
/* Local
----- */
/* Graphics
-------- */
/*----------------------------------------------------------------------
Tyepdefs && Defines
------------------- */
#define NINJAEXP_CLASS_ID Class_ID(0x689c7996, 0x13531d0d)
/*----------------------------------------------------------------------
Structure defintions
-------------------- */
/*----------------------------------------------------------------------
Positional Vars
--------------- */
/*----------------------------------------------------------------------
Function Prototypes
------------------- */
/*----------------------------------------------------------------------
Vars
---- */
static HINSTANCE hInstance;
static AsciiExpClassDesc AsciiExpDesc;
static bool controlsInit = FALSE;
/*----------------------------------------------------------------------
Data
---- */
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
BOOL WINAPI DllMain(HINSTANCE hinstDLL,ULONG fdwReason,LPVOID lpvReserved)
{
hInstance = hinstDLL;
// Initialize the custom controls. This should be done only once.
if (!controlsInit)
{
controlsInit = TRUE;
InitCustomControls(hInstance);
InitCommonControls();
}
return (TRUE);
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
__declspec( dllexport ) const TCHAR* LibDescription()
{
return GetString(IDS_LIBDESCRIPTION);
}
__declspec( dllexport ) int LibNumberClasses()
{
return 1;
}
__declspec( dllexport ) ClassDesc* LibClassDesc(int i)
{
switch(i) {
case 0: return GetAsciiExpDesc();
default: return 0;
}
}
__declspec( dllexport ) ULONG LibVersion()
{
return VERSION_3DSMAX;
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
ClassDesc * GetAsciiExpDesc(void)
{
return &AsciiExpDesc;
}
TCHAR * GetString(int id)
{
static TCHAR buf[256];
if (hInstance)
return LoadString(hInstance, id, buf, sizeof(buf)) ? buf : NULL;
return NULL;
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
AsciiExp::AsciiExp()
{
}
AsciiExp::~AsciiExp()
{
}
int AsciiExp::ExtCount()
{
return 1;
}
const TCHAR * AsciiExp::Ext(int n)
{
switch(n)
{
case 0:
return _T("GIN");
}
return _T("");
}
const TCHAR * AsciiExp::LongDesc()
{
return GetString(IDS_LONGDESC);
}
const TCHAR * AsciiExp::ShortDesc()
{
return GetString(IDS_SHORTDESC);
}
const TCHAR * AsciiExp::AuthorName()
{
return _T("Tim Swann / Mike Armstrong");
}
const TCHAR * AsciiExp::CopyrightMessage()
{
return GetString(IDS_COPYRIGHT);
}
const TCHAR * AsciiExp::OtherMessage1()
{
return _T("");
}
const TCHAR * AsciiExp::OtherMessage2()
{
return _T("");
}
unsigned int AsciiExp::Version()
{
return 100;
}
static BOOL CALLBACK AboutBoxDlgProc(HWND hWnd, UINT msg,
WPARAM wParam, LPARAM lParam)
{
switch (msg) {
case WM_INITDIALOG:
CenterWindow(hWnd, GetParent(hWnd));
break;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDOK:
EndDialog(hWnd, 1);
break;
}
break;
default:
return FALSE;
}
return TRUE;
}
void AsciiExp::ShowAbout(HWND hWnd)
{
// DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, AboutBoxDlgProc, 0);
}
static BOOL CALLBACK ExportDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
AsciiExp * exp = (AsciiExp*)GetWindowLong(hWnd, GWL_USERDATA);
switch (msg)
{
case WM_INITDIALOG:
exp = (AsciiExp*)lParam;
SetWindowLong(hWnd,GWL_USERDATA,lParam);
CenterWindow(hWnd, GetParent(hWnd));
// CheckDlgButton(hWnd, IDC_ANIMCHECK, exp->GetExportAnimFlag());
break;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK:
// exp->SetExportAnimFlag(IsDlgButtonChecked(hWnd, IDC_ANIMCHECK));
EndDialog(hWnd, 1);
break;
case IDCANCEL:
EndDialog(hWnd, 0);
break;
}
break;
default:
return FALSE;
}
return TRUE;
}
// Dummy function for progress bar
DWORD WINAPI fn(LPVOID arg)
{
return(0);
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
#if MAX_RELEASE == 2500
int AsciiExp::DoExport(const TCHAR * name, ExpInterface * ei, Interface * i, BOOL suppressPrompts)
#else
int AsciiExp::DoExport(const TCHAR * name, ExpInterface * ei, Interface * i, BOOL suppressPrompts,DWORD options)
#endif
{
int numChildren;
// NodeCount = 0;
// GRAB THE INTERFACE POINTER
ip = i;
MAX_hWnd = ip->GetMAXHWnd();
// SetExportAnimFlag(0);
// if (!suppressPrompts && !DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_ASCIIEXPORT_DLG), MAX_hWnd, ExportDlgProc, (LPARAM)this)) return 1;
tempStream = NULL;
expStream = NULL;
nbChunks = 0;
// GET SCENE FILENAME
sprintf( SceneName, "%s", FixupName(ip->GetCurFileName()) );
_strupr( SceneName );
// OPEN DEBUG TEXT FILE
tempStream = _tfopen("C:\\ExpDebug.txt",_T("wt"));
if (!tempStream) return 0;
fprintf( tempStream, "TEST\n" );
// OPEN OUTPUT FILE
_splitpath(name, drive, dir, fname, ext);
sprintf(filename, "%s%s%s.GIN", drive, dir, fname);
_strlwr(filename);
expStream = _tfopen(filename, _T("wb"));
if (!expStream) return 0;
// WRITE FILE HEADER
if (WriteChunkHdr( (char*)FILE_ID, 0 ))
{
// STARTUP THE PROGRESS BAR
// if (GetExportAnimFlag())
// ip->ProgressStart("Exporting with Anims", TRUE, fn, NULL);
// else
ip->ProgressStart("Exporting without Vertex Anims", TRUE, fn, NULL);
Weights = NULL;
nTotalNodeCount = 0;
nCurNode = 0;
nCurObj = 0;
nbFrames = 0;
totFrames = 0;
nbWeights = 0;
NbEmmitters = 0;
GetNoFrames();
fwrite(&totFrames, sizeof(int), 1, expStream);
WriteChunkHdr( (char*)VERSION_ID, 0);
int MyVer = VERSION;
fwrite(&MyVer, sizeof(int), 1, expStream);
OrigProcess(ip->GetRootNode());
FfdProcess(ip->GetRootNode(), nTotalNodeCount);
ExportTree();
numChildren = ip->GetRootNode()->NumberOfChildren();
for (int idx=0; idx<numChildren; idx++)
{
if (ip->GetCancel()) break;
nodeEnum( ip->GetRootNode()->GetChildNode(idx));
}
ExportMaterialList();
}
// WRITE FILE TERMINATOR HEADER
WriteChunkHdr( (char*)TERMINATOR_ID, 0 );
// Close the streams
if (tempStream) fclose(tempStream);
if (expStream) fclose(expStream);
if (Weights) free(Weights);
// FILL IN CHUNK SIZES
CalcChunkSizes();
// WE'RE DONE. FINISH THE PROGRESS BAR.
ip->ProgressEnd();
/* if (!DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_ENDDIALOG), MAX_hWnd, ExportDlgProc, (LPARAM)this))
{
return 1;
}*/
return 1;
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
BOOL AsciiExp::nodeEnum(INode* node)
{
nCurNode++;
ip->ProgressUpdate((int)((float)nCurNode/nTotalNodeCount*100.0f));
if (ip->GetCancel()) return FALSE;
ExportNode(node);
for (int c = 0; c < node->NumberOfChildren(); c++)
{
if (!nodeEnum(node->GetChildNode(c))) return FALSE;
}
return TRUE;
}
void AsciiExp::BoneProcess(INode* node, int& nodeCount)
{
nodeCount++;
// GET WEIGHTS BEFORE BONES ARE EXPORTED
ExportWeights( node );
for (int c = 0; c < node->NumberOfChildren(); c++)
{
BoneProcess(node->GetChildNode(c), nodeCount);
}
}
void AsciiExp::FfdProcess(INode* node, int& nodeCount)
{
nodeCount++;
// GET WEIGHTS BEFORE BONES ARE EXPORTED
// ExportFFD( node );
Control *cont = node->GetTMController();
if (cont) {
if ((cont->ClassID() == BIPSLAVE_CONTROL_CLASS_ID) ||
(cont->ClassID() == BIPBODY_CONTROL_CLASS_ID) ||
(cont->ClassID() == FOOTPRINT_CLASS_ID))
{
IBipedExport *BipIface = (IBipedExport *) cont->GetInterface(I_BIPINTERFACE);
if (BipIface)
{
//BipIface->RemoveNonUniformScale(1);
}
}
}
for (int c = 0; c < node->NumberOfChildren(); c++)
{
FfdProcess(node->GetChildNode(c), nodeCount);
}
}
void AsciiExp::OrigProcess(INode *node)
{
char TempName[256];
sprintf(TempName, "%s", node->GetName());
_strupr(TempName);
if (strcmp(TempName, "ORIGIN")==0) {
Matrix3 tm = node->GetObjTMAfterWSM( ip->GetAnimRange().Start() );
AffineParts ap;
decomp_affine(tm, &ap);
WriteChunkHdr( (char*)ORIG_ID, 0);
fwrite(&ap.t.x, sizeof(float), 1, expStream);
fwrite(&ap.t.z, sizeof(float), 1, expStream);
fwrite(&ap.t.y, sizeof(float), 1, expStream);
}
for (int c = 0; c < node->NumberOfChildren(); c++)
{
OrigProcess(node->GetChildNode(c));
}
}
void AsciiExp::GetNoFrames( void )
{
TimeValue start = ip->GetAnimRange().Start();
TimeValue end = ip->GetAnimRange().End();
TimeValue t;
int delta = GetTicksPerFrame();
Object * obj = ip->GetRootNode()->EvalWorldState(ip->GetAnimRange().Start()).obj;
totFrames = 0;
for (t=start; t<=end; t+=delta) totFrames++;
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void AsciiExp::ExportNode(INode* node)
{
ObjectState os = node->EvalWorldState(ip->GetAnimRange().Start());
OutputDebugString(node->GetName());
if (os.obj)
{
switch(os.obj->SuperClassID())
{
case GEOMOBJECT_CLASS_ID:
ip->ProgressStart("Export Model", TRUE, fn, NULL);
ExportModel( node );
break;
case HELPER_CLASS_ID:
ip->ProgressStart("Export Helper", TRUE, fn, NULL);
break;
case CAMERA_CLASS_ID:
ip->ProgressStart("Export Camera", TRUE, fn, NULL);
ExportCamera( node );
break;
case LIGHT_CLASS_ID:
ip->ProgressStart("Export Light", TRUE, fn, NULL);
ExportLight(node);
break;
}
}
ExportProp(node);
}
/*----------------------------------------------------------------------
Function: Misc Utility functions
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
/*----------------------------------------------------------------------
Function: Misc Utility functions
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
static Point3 basic_tva[3] =
{
Point3(0.0,0.0,0.0),Point3(1.0,0.0,0.0),Point3(1.0,1.0,0.0)
};
static Point3 basic_tvb[3] =
{
Point3(1.0,1.0,0.0),Point3(0.0,1.0,0.0),Point3(0.0,0.0,0.0)
};
static int nextpt[3] = {1,2,0};
static int prevpt[3] = {2,0,1};
BOOL AsciiExp::TMNegParity(Matrix3 &m)
{
return (DotProd(CrossProd(m.GetRow(0),m.GetRow(1)),m.GetRow(2))<0.0)?1:0;
}
TriObject * AsciiExp::GetTriObjectFromNode(INode *node, TimeValue t, int &deleteIt)
{
deleteIt = FALSE;
Object *obj = node->EvalWorldState(t).obj;
ObjectState os = obj->Eval(t);
obj = os.obj;
if (obj && obj->CanConvertToType(Class_ID(TRIOBJ_CLASS_ID, 0)))
{
TriObject *tri = (TriObject *) obj->ConvertToType(t, Class_ID(TRIOBJ_CLASS_ID, 0));
if (obj != tri) deleteIt = TRUE;
return tri;
}
else
{
return NULL;
}
}
TriObject * AsciiExp::GetTriObjectFromObject(Object *obj, TimeValue t, int &deleteIt)
{
deleteIt = FALSE;
if (obj && obj->CanConvertToType(Class_ID(TRIOBJ_CLASS_ID, 0)))
{
TriObject *tri = (TriObject *) obj->ConvertToType(t, Class_ID(TRIOBJ_CLASS_ID, 0));
if (obj != tri) deleteIt = TRUE;
return tri;
}
else
{
return NULL;
}
}
void AsciiExp::make_face_uv(Face *f, Point3 *tv)
{
int na,nhid,i;
Point3 *basetv;
/* make the invisible edge be 2->0 */
nhid = 2;
if (!(f->flags&EDGE_A)) nhid=0;
else if (!(f->flags&EDGE_B)) nhid = 1;
else if (!(f->flags&EDGE_C)) nhid = 2;
na = 2-nhid;
basetv = (f->v[prevpt[nhid]]<f->v[nhid]) ? basic_tva : basic_tvb;
for (i=0; i<3; i++)
{
tv[i] = basetv[na];
na = nextpt[na];
}
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
bool AsciiExp::WriteChunkHdr( char* ChunkID, long Size )
{
SizeTab[nbChunks] = ftell( expStream );
if (SizeTab[nbChunks] & 0x3) assert(0);
//SizeTab[nbChunks] /= 4;
int sl = strlen(ChunkID) + 1;
if (sl&3) {
sl += 4 - (sl & 3);
}
fwrite( ChunkID, sl, 1, expStream );
fwrite( &Size, sizeof(Uint32), 1, expStream );
nbChunks++;
if(nbChunks >= MAX_FILE_CHUNKS)
{
MessageBox( MAX_hWnd, "INCREASE MAX_FILE_CHUNKS", "ERROR", MB_OK);
return false;
}
return true;
}
void AsciiExp::CalcChunkSizes( void )
{
int hFile;
long filelen;
char * filebuf;
hFile = _open(filename, _O_RDONLY | _O_BINARY);
if(hFile != -1)
{
filelen = FIO_FileLen(filename); // length of file
filebuf = (char *)malloc(filelen); // allocate mainmemory
_read(hFile, filebuf, filelen); // read in file
_close(hFile); // file close
}
else
{
assert(0);
}
for (int i=0;i<(nbChunks-1);i++)
{
long offset;
long filepos;
filepos = SizeTab[i];
int sl = strlen(&filebuf[filepos]) + 1;
if (sl&3) {
sl += 4 - (sl & 3);
}
filepos += sl;
offset = (SizeTab[i+1] - filepos - 4);
//offset -= 8; // DON'T INCLUDE CHUNK HDR IN CHUNK SIZE
*(long*)&filebuf[filepos] = offset;
}
FIO_Save( filename, (unsigned char *)filebuf, filelen);
free( filebuf );
if(expStream) fclose( expStream);
}
/*----------------------------------------------------------------------
Function: String manipulation functions
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
#define CTL_CHARS 40
#define SINGLE_QUOTE 39
TCHAR* AsciiExp::FixupName(TCHAR* name)
{
static char buffer[256];
TCHAR* cPtr;
_tcscpy(buffer, name);
cPtr = buffer;
while(*cPtr)
{
if (*cPtr <= CTL_CHARS || *cPtr == '-')
*cPtr = _T('_');
cPtr++;
}
return buffer;
}
/*===========================================================================
end */

View File

@ -0,0 +1,518 @@
/*=========================================================================
EXPMATERIAL.CPP
Author: Tim Swann @ CLIMAX
Created:
Project:
Purpose:
Copyright (c) 1998 Climax Development Ltd
===========================================================================*/
/*----------------------------------------------------------------------
Includes
-------- */
#include "AsciiExp.h"
#include "string.h"
/* Std Lib
------- */
/* Glib
---- */
/* Local
----- */
/* Graphics
-------- */
/*----------------------------------------------------------------------
Tyepdefs && Defines
------------------- */
/*----------------------------------------------------------------------
Structure defintions
-------------------- */
/*----------------------------------------------------------------------
Positional Vars
--------------- */
/*----------------------------------------------------------------------
Function Prototypes
------------------- */
/*----------------------------------------------------------------------
Vars
---- */
/*----------------------------------------------------------------------
Data
---- */
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void AsciiExp::ExportMaterialList(void)
{
int numMtls = mtlList.Count();
int i = 0;
nbTexs = 0;
nbMats = 0;
if (numMtls)
{
// EXPORT TEXTURE FILE LIST
for (i=0; i<numMtls; i++) DumpMaterial( mtlList.GetMtl(i), i, -1 );
if (nbTexs)
{
WriteChunkHdr( (char*)TEXTURE_ID, 0 );
fwrite( &nbTexs, sizeof(Uint32), 1, expStream );
for (int t=0;t<nbTexs;t++)
{
int PathLen = strlen(TexList[t]) + 1;
if (PathLen&3) {
PathLen += 4 - (PathLen & 3);
}
fwrite( &TexList[t], sizeof(char), PathLen, expStream );
}
}
// EXPORT MATERIAL LIST
if (nbMats)
{
WriteChunkHdr( (char*)MATERIAL_ID, 0 );
fwrite( &nbMats, sizeof(Uint32), 1, expStream );
fwrite( &nCurObj, sizeof(Uint32), 1, expStream );
for (int m=0;m<nbMats;m++)
{
fwrite( &MatList[m].material.diffuse.alpha, sizeof(float), 1, expStream);
fwrite( &MatList[m].material.diffuse.colour.r, sizeof(float), 1, expStream);
fwrite( &MatList[m].material.diffuse.colour.g, sizeof(float), 1, expStream);
fwrite( &MatList[m].material.diffuse.colour.b, sizeof(float), 1, expStream);
fwrite( &MatList[m].material.specular.alpha, sizeof(float), 1, expStream);
fwrite( &MatList[m].material.specular.colour.r, sizeof(float), 1, expStream);
fwrite( &MatList[m].material.specular.colour.g, sizeof(float), 1, expStream);
fwrite( &MatList[m].material.specular.colour.b, sizeof(float), 1, expStream);
fwrite( &MatList[m].material.tex_flags, sizeof(Uint32), 1, expStream);
fwrite( &MatList[m].material.attr_flags, sizeof(Uint32), 1, expStream);
}
}
}
}
/*----------------------------------------------------------------------
---------------------------------------------------------------------- */
char *makerelative(char const *basepath,char const *newpath, char *outstr)
{
#define FF_PATHNAMEMAX 256
char temp1[FF_PATHNAMEMAX];
char temp2[FF_PATHNAMEMAX];
int i, j, match;
// Are the filenames the same?
match = 0;
for (j = 0; j < FF_PATHNAMEMAX; j++)
{
if (basepath[j] != newpath[j])
{
match = 0;
break;
}
else if (basepath[j] == '.') // Matching
{
match = 1;
break;
}
else if (basepath[j] == 0) // Identical
{
match = 0;
break;
}
}
if (match) // Matching paths and filenames
{
strcpy(outstr, "#");
strcat(outstr, &newpath[j]);
}
else if (basepath[0] != newpath[0]) // Drive letters are different
strcpy(outstr, newpath);
else
{
// Find the paths
strcpy(temp1, basepath);
for (i = strlen(temp1) - 1; i >= 0; i--)
if (temp1[i] == '\\')
break;
else
temp1[i] = 0;
strcpy(temp2, newpath);
for (i = strlen(temp2) - 1; i >= 0; i--)
if (temp2[i] == '\\')
break;
else
temp2[i] = 0;
// Are the paths the same?
strcpy(outstr, "");
if (strcmp(temp1, temp2) == 0) // Paths are the same
{
j = strlen(temp1);
}
else // Paths are different
{
j = 2; // Drives are the same
// Find different bits
for (i = 0; i < (int) strlen(temp1); i++)
{
if ((temp1[i] == '\\') && (temp2[i] == '\\'))
j = i + 1;
else
if (temp1[i] != temp2[i])
break;
}
if (j > 3)
{
for (i = j; i < (int) strlen(temp1); i++)
if (temp1[i] == '\\')
strcat(outstr,"..\\");
}
else
j = 2;
}
strcat(outstr, &newpath[j]);
}
return outstr;
}
bool FileExists(const char* Name)
{
FILE *f = fopen(Name,"rb");
if (f)
{
fclose(f);
return true;
}
return false;
}
TSTR AsciiExp::FindTextureFName(TSTR MapName)
{
char Out[256];
_splitpath(filename, drive, dir, fname, ext);
TSTR GinDir = TSTR(drive)+TSTR(dir);
_splitpath(MapName, drive, dir, fname, ext);
TSTR DriveDir = TSTR(drive)+TSTR(dir);
TSTR FName = TSTR(fname) + TSTR(ext);
if (!FileExists(GinDir + FName))
{
MapName = ip->GetCurFilePath();
_splitpath(MapName, drive, dir, fname, ext);
DriveDir = TSTR(drive)+TSTR(dir);
if (!FileExists(GinDir + FName))
{
int i=0;
while (i<TheManager->GetMapDirCount())
{
DriveDir = TheManager->GetMapDir(i);
DriveDir = DriveDir + TSTR("\\");
if (FileExists(DriveDir + FName)) {
break;
}
i++;
}
if (i==TheManager->GetMapDirCount())
{
DriveDir = TSTR("");
}
}
}
GinDir.toLower();
DriveDir.toLower();
makerelative(GinDir, DriveDir, Out);
return TSTR(Out);
}
void AsciiExp::DumpTexture( Mtl* mtl, int matno, int subno )
{
Texmap * subTex = mtl->GetSubTexmap(ID_DI);
TSTR N = mtl->GetName();
if (mtl->ClassID() == Class_ID(DMTL_CLASS_ID, 0))
{
if (subTex && subTex->ClassID() == Class_ID(BMTEX_CLASS_ID, 0))
{
// If it is a standard material we can see if the map is enabled.
if (((StdMat*)mtl)->MapEnabled(ID_DI))
{
Bool found = FALSE;
int texidx = nbTexs;
char TexListTemp[256];
TSTR mapName = ((BitmapTex *)subTex)->GetMapName();
TSTR RelativePath = FindTextureFName(mapName);
_splitpath(mapName, drive, dir, fname, ext);
if (RelativePath.isNull())
{
sprintf( TexListTemp, "%s%s", fname, ext);
} else
{
sprintf( TexListTemp, "%s%s%s", RelativePath, fname, ext);
}
for (int t=0;t<nbTexs;t++)
{
if (!strcmp(TexList[t], TexListTemp))
{
texidx = t;
found = TRUE;
}
}
if (!found)
{
strcpy( TexList[nbTexs], TexListTemp );
nbTexs++;
if(nbTexs>= MAXCOUNT) MessageBox( MAX_hWnd, "nbTexs Overflow", "ERROR", MB_OK);
}
MatList[matno].SubTex[(subno+1)] = texidx;
}
}
}
if (mtl->NumSubMtls() > 0)
{
for (int i=0; i<mtl->NumSubMtls(); i++)
{
Mtl * subMtl = mtl->GetSubMtl(i);
if (subMtl)
{
DumpTexture( subMtl, matno, i );
}
}
}
}
int AsciiExp::getTextureId( Mtl *mtl )
{
Texmap * subTex = mtl->GetSubTexmap(ID_DI);
TSTR N = mtl->GetName();
if (mtl->ClassID() == Class_ID(DMTL_CLASS_ID, 0))
{
if (subTex && subTex->ClassID() == Class_ID(BMTEX_CLASS_ID, 0))
{
// If it is a standard material we can see if the map is enabled.
if (((StdMat*)mtl)->MapEnabled(ID_DI))
{
Bool found = FALSE;
int texidx = nbTexs;
char TexListTemp[256];
TSTR mapName = ((BitmapTex *)subTex)->GetMapName();
TSTR RelativePath = FindTextureFName(mapName);
_splitpath(mapName, drive, dir, fname, ext);
fprintf( tempStream, " texName = %s\n", fname );
if (RelativePath.isNull())
{
sprintf( TexListTemp, "%s%s", fname, ext);
} else
{
sprintf( TexListTemp, "%s%s%s", RelativePath, fname, ext);
}
for (int t=0;t<nbTexs;t++)
{
if (!strcmp(TexList[t], TexListTemp))
{
return t;
}
}
if (!found)
{
strcpy( TexList[nbTexs], TexListTemp );
nbTexs++;
if(nbTexs>= MAXCOUNT) MessageBox( MAX_hWnd, "nbTexs Overflow", "ERROR", MB_OK);
return nbTexs-1;
}
}
}
}
return -1;
}
/*----------------------------------------------------------------------
---------------------------------------------------------------------- */
void AsciiExp::DumpMaterial( Mtl* mtl, int matno, int subno , bool recurse)
{
Color col;
float alpha;
Uint32 AttrFlags = 0;
if (!mtl) return;
sprintf( MatList[nbMats].name, "%s", FixupName( mtl->GetName() ) );
fprintf( tempStream, "matName = %s %d\n", mtl->GetName(), nbMats );
// WE KNOW THE STANDARD MATERIAL, SO WE CAN GET SOME EXTRA INFO
if (mtl->ClassID() == Class_ID(DMTL_CLASS_ID, 0))
{
StdMat * std;
std = (StdMat*)mtl;
int tmap = getTextureId(mtl);
if (std->MapEnabled(ID_DI) && tmap != -1) AttrFlags |= GIN_FLAG_USE_TEXTURE;
if (std->MapEnabled(ID_RL)) AttrFlags |= GIN_FLAG_USE_ENVTEXTURE;
if (std->GetTwoSided()) AttrFlags |= GIN_FLAG_DOUBLE_SIDE;
if (std->GetSelfIllum( 0 ) > 0.2f ) AttrFlags |= GIN_FLAG_IGNORE_LIGHT;
AttrFlags |= (std->GetTransparencyType()<<3);
col = std->GetDiffuse( 0 );
alpha = std->GetOpacity( 0 );
if (std->MapEnabled(ID_DI)) {
MatList[nbMats].material.diffuse.alpha = alpha;
MatList[nbMats].material.diffuse.colour = col;
} else {
MatList[nbMats].material.diffuse.alpha = alpha;
MatList[nbMats].material.diffuse.colour = col;
}
col = std->GetSpecular( 0 );
MatList[nbMats].material.specular.alpha = alpha;
MatList[nbMats].material.specular.colour = col;
MatList[nbMats].material.exponent = 6.f;
fprintf( tempStream, " tmap = %d\n\n", tmap );
MatList[nbMats].material.tex_flags = tmap;
MatList[nbMats].material.attr_flags = AttrFlags;
nbMats++;
} else
{
if (mtl->ClassID() != Class_ID(MULTI_CLASS_ID, 0))
{
memset(&MatList[nbMats], 0, sizeof(MATLIST));
MatList[nbMats].material.tex_flags = -1;
nbMats++;
}
}
if (mtl->NumSubMtls() > 0)
{
int c = (recurse) ? 1 : mtl->NumSubMtls();
for (int i=0; i< c ; i++)
{
Mtl* subMtl = mtl->GetSubMtl(i);
if (subMtl)
{
DumpMaterial( subMtl, matno, i , true);
} else
{
nbMats++;
}
}
}
if(nbMats>= MAXCOUNT) MessageBox( MAX_hWnd, "nbMats Overflow", "ERROR", MB_OK);
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
int MtlKeeper::GetSubMtlCount(Mtl* mtl, bool recurse)
{
int Count = 0;
if (!mtl)
return 0;
if (mtl->ClassID() == Class_ID(DMTL_CLASS_ID, 0))
Count ++;
if (mtl->NumSubMtls() > 0)
{
int c = (recurse) ? 1 : mtl->NumSubMtls();
for (int i=0; i<c; i++)
{
Mtl* subMtl = mtl->GetSubMtl(i);
if (subMtl)
{
Count += GetSubMtlCount( subMtl, true);
} else
{
Count ++;
}
}
}
return Count;
}
BOOL MtlKeeper::AddMtl(Mtl* mtl)
{
if (!mtl) return FALSE;
int numMtls = mtlTab.Count();
for (int i=0; i<numMtls; i++)
{
if (mtlTab[i] == mtl) return FALSE;
}
mtlTab.Append(1, &mtl, 25);
return TRUE;
}
int MtlKeeper::GetMtlID(Mtl* mtl)
{
int numMtls = mtlTab.Count();
int CurIdx = 0;
int count = 0;
for (int i=0; i<numMtls; i++)
{
if (mtlTab[i] == mtl) return count;
count += GetSubMtlCount(mtlTab[i], false);
}
return -1;
}
int MtlKeeper::Count()
{
return mtlTab.Count();
}
Mtl* MtlKeeper::GetMtl(int id)
{
return mtlTab[id];
}
/*===========================================================================
end */

952
Utils/GinExp/ExpModel.cpp Normal file
View File

@ -0,0 +1,952 @@
/*=========================================================================
EXPMODEL.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::ExportModel(INode* node)
{
ObjectState os = node->EvalWorldState( ip->GetAnimRange().Start() );
char nodeName[256];
// Targets are actually geomobjects, but we will export them
// from the camera and light objects, so we skip them here.
if (os.obj->ClassID() == Class_ID(TARGET_CLASS_ID, 0)) return;
ip->ProgressUpdate(0,0,"Export Model0");
sprintf(nodeName, "%s", node->GetName());
strupr(nodeName);
if (nodeName[0] != 'R' ||
nodeName[1] != 'O' ||
nodeName[2] != 'O' ||
nodeName[3] != 'T')
{
ip->ProgressUpdate(0,0,"Export ModelRoot");
WriteChunkHdr( (char*)OBJ_ID, 0 );
fwrite(&totFrames, sizeof(int), 1, expStream);
fwrite(nodeName, MAX_NAME_LENGTH, 1, expStream);
ip->ProgressUpdate(0,0,"Export Model-Mesh");
ExportMesh( node );
}
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void AsciiExp::ExportMesh( INode* node )
{
Matrix3 tm = node->GetObjTMAfterWSM( ip->GetAnimRange().Start() );
Uint32 EvalFlags = 0;
Point3 ObjPos;
Point3 ObjRot;
Point3 ObjSca;
Point3 center = Point3(0.f, 0.f, 0.f);
AffineParts ap;
Mesh * mesh;
ObjectState os;
Object * obj;
BOOL needDel;
TriObject * tri;
os = node->EvalWorldState( ip->GetAnimRange().Start() );
obj = node->EvalWorldState( ip->GetAnimRange().Start() ).obj;
Mtl * nodeMtl = node->GetMtl();
if (!nodeMtl) return;
if (!os.obj) return;
if (!obj->IsRenderable()) return;
if (node->IsNodeHidden()) return;
if (!obj || os.obj->SuperClassID() != GEOMOBJECT_CLASS_ID) return; // Safety net. This shouldn't happen.
tri = GetTriObjectFromNode(node, ip->GetAnimRange().Start(), needDel);
if (!tri) return;
mesh = &tri->mesh;
mtlList.AddMtl(nodeMtl);
ip->ProgressUpdate(0,0,"ExportMeshList");
ExportMeshList( node, mesh );
ip->ProgressUpdate(0,0,"ExportPoints");
ExportPoints( node, mesh );
ip->ProgressUpdate(0,0,"ExportVectors");
ExportVectors( node, mesh);
ip->ProgressUpdate(0,0,"ExportVectorsDone");
if (needDel) delete tri;
tri = GetTriObjectFromNode(node, ip->GetAnimRange().End(), needDel);
if (!tri) return;
mesh = &tri->mesh;
ip->ProgressUpdate(0,0,"ExportNormals");
ExportNormals( node, mesh );
if (needDel) delete tri;
ip->ProgressUpdate(0,0,"ExportNormalsDone");
tm = node->GetObjTMAfterWSM(ip->GetAnimRange().Start());// * Inverse(node->GetParentTM(t));
decomp_affine(tm, &ap);
ip->ProgressUpdate(0,0,"WriteHeader0");
WriteChunkHdr( (char*)MODEL_ID, 0 );
fwrite( &nCurObj, sizeof(long), 1, expStream );
char NodeName[MAX_NAME_LENGTH];
sprintf(NodeName,"%s",node->GetName());
// fwrite( node->GetName(), MAX_NAME_LENGTH, 1, expStream);
fwrite( NodeName, MAX_NAME_LENGTH, 1, expStream);
fwrite( &radius, sizeof(float), 1, expStream );
fwrite( &center.x, sizeof(float), 1, expStream );
fwrite( &center.y, sizeof(float), 1, expStream );
fwrite( &center.z, sizeof(float), 1, expStream );
fwrite( &ap.t.x, sizeof(float), 1, expStream );
fwrite( &ap.t.z, sizeof(float), 1, expStream );
fwrite( &ap.t.y, sizeof(float), 1, expStream );
//ProgressUpdate(int pct, BOOL showPct = TRUE, TCHAR *title = NULL)=0
ip->ProgressUpdate(0,0,"WriteHeaderDone");
ip->ProgressUpdate(0,0,"FindPhysiqueModifier");
if (FindPhysiqueModifier(node))
{
ip->ProgressUpdate(0,0,"ExportWeights");
ExportWeights(node);
}
else
ip->ProgressUpdate(0,0,"FindFFDModifier");
if (FindFFDModifier(node))
{
}
else
{
ip->ProgressUpdate(0,0,"ExportNodeAnimMesh");
ExportNodeAnimMesh( node );
}
// ExportAnimMesh( node );
ip->ProgressUpdate(0,0,"FindEditableMesh");
FindEditableMesh(node);
ip->ProgressUpdate(0,0,"ExportVisTrack");
ExportVisTrack( node );
nCurObj++;
}
void AsciiExp::FindEditableMesh(INode *node)
{
Object *o = node->GetObjectRef();
while (o && o->SuperClassID() == GEN_DERIVOB_CLASS_ID)
{
o = ((IDerivedObject*)o)->GetObjRef();
}
if (o && o->ClassID() == Class_ID(EDITTRIOBJ_CLASS_ID,0))
{
ExportMeshVertAnim(node, (EditTriObject*)o);
}
}
void AsciiExp::ExportMeshVertAnim(INode *node, EditTriObject *e)
{
TimeValue start = ip->GetAnimRange().Start();
TimeValue end = ip->GetAnimRange().End();
int delta = GetTicksPerFrame();
int Controls = e->cont.Count();
Matrix3 tm = node->GetObjTMAfterWSM( ip->GetAnimRange().Start() );
Point3 p;
Controls = 0;
for (int i=0; i<e->cont.Count(); i++) {
if (e->cont[i]) {
Controls++;
}
}
ITCBPoint3Key tcbPosKey;
IBezPoint3Key bezPosKey;
WriteChunkHdr( (char*)KEY_ID, 0);
fwrite( &CHANNEL_TYPE_VERTEX, sizeof( Uint32 ), 1, expStream );
fwrite( &CHANNEL_INFO_POSITION, sizeof( Uint32) , 1, expStream);
fwrite( &nCurObj, sizeof( Uint32 ), 1, expStream );
fwrite( &Controls, sizeof(int), 1, expStream);
for (i=0; i<e->cont.Count(); i++) {
if (e->cont[i]) {
Control *c = GetControlInterface(e->cont[i]);
IKeyControl *ikeys;
TimeList tl;
TimeValue time;
tl.Clear();
if (c) {
ikeys = GetKeyControlInterface(c);
int num = ikeys->GetNumKeys();
for (int j = 0; j<num; j++)
{
if (c->ClassID() == Class_ID(TCBINTERP_POINT3_CLASS_ID, 0)) {
ikeys->GetKey(j, &tcbPosKey);
time = tcbPosKey.time;
}
else
if (c->ClassID() == Class_ID(HYBRIDINTERP_POINT3_CLASS_ID, 0))
{
ikeys->GetKey(j, &bezPosKey);
time = bezPosKey.time;
}
tl.Add(time);
}
num = tl.Count();
fwrite(&i, sizeof(int), 1, expStream);
fwrite(&num, sizeof(int), 1, expStream);
for (j=0; j<num; j++) {
time = tl.Get(j);
tm = node->GetObjTMAfterWSM(time);
e->cont[i]->GetValue(time,&p,FOREVER);
p = tm * p;
time = (time-start) / delta;
fwrite(&time, sizeof(int), 1, expStream);
fwrite(&p.x, sizeof(float), 1, expStream);
fwrite(&p.z, sizeof(float), 1, expStream);
fwrite(&p.y, sizeof(float), 1, expStream);
}
}
}
}
}
/*----------------------------------------------------------------------
---------------------------------------------------------------------- */
int GetSubMtlCount(Mtl* mtl, bool recurse = false)
{
int Count = 0;
if (!mtl)
return 0;
if (mtl->ClassID() == Class_ID(DMTL_CLASS_ID, 0))
Count ++;
if (mtl->NumSubMtls() > 0)
{
int c = (recurse) ? 1 : mtl->NumSubMtls();
for (int i=0; i<c; i++)
{
Mtl* subMtl = mtl->GetSubMtl(i);
if (subMtl)
{
Count += GetSubMtlCount( subMtl, true);
}
}
}
return Count;
}
void AsciiExp::ExportMeshList(INode * node, Mesh * mesh)
{
MtlID matid;
MtlID matref;
Mtl * nodeMtl = node->GetMtl();
int m;
ObjectState os;
Object * obj;
Matrix3 tm = node->GetObjTMAfterWSM( ip->GetAnimRange().Start() );
BOOL negScale = TMNegParity(tm);
int vx1, vx2, vx3;
const char * name = node->GetName();
// fprintf( tempStream, "MESHLIST = %s\n\n", name );
obj = node->EvalWorldState( ip->GetAnimRange().Start() ).obj;
mesh->buildNormals();
// Order of the vertices. Get 'em counter clockwise if the objects is
// negatively scaled.
if (negScale)
{
vx1 = 2;
vx2 = 1;
vx3 = 0;
}
else
{
vx1 = 0;
vx2 = 1;
vx3 = 2;
}
int MtlCount = GetSubMtlCount(nodeMtl);
if (MtlCount == 0) return;
// Find all mesh materials used
nbMeshs = 0;
for (int i=0; i<mesh->getNumFaces(); i++)
{
Bool found = FALSE;
matid = ((unsigned long)mesh->getFaceMtlIndex(i)) % MtlCount;
// fprintf( tempStream, "MATID = %d - FACEID = %d\n", mesh->faces[i].getMatID(), mesh->getFaceMtlIndex(i) );
for (int f=0;f<nbMeshs;f++)
{
if (matid == MeshSet[f].MatId)
{
MeshSet[f].nbFaces++;
found = TRUE;
break;
}
}
if (!found)
{
MeshSet[nbMeshs].MatId = matid;
MeshSet[nbMeshs].nbFaces = 1;
nbMeshs++;
if(nbMeshs>= MAXCOUNT) MessageBox( MAX_hWnd, "nbMeshs Overflow", "ERROR", MB_OK);
}
}
// Sort material id's for ease of access
for (m=0;m<nbMeshs;m++)
{
for (int m2=0;m2<(nbMeshs-1);m2++)
{
if (MeshSet[m2].MatId > MeshSet[m2+1].MatId)
{
MESH_SET meshset = MeshSet[m2];
MeshSet[m2] = MeshSet[m2+1];
MeshSet[m2+1] = meshset;
}
}
}
for (m=0;m<nbMeshs;m++)
{
int nbFaces;
// EXPORT POLY CONNECT LIST - PER MESH
WriteChunkHdr( (char*)POLY_ID, 0 );
fwrite( &nCurObj, sizeof(Uint16), 1, expStream );
fwrite( &m, sizeof(Uint16), 1, expStream );
nbFaces = MeshSet[m].nbFaces;
fwrite( &nbFaces, sizeof(Uint32), 1, expStream );
for (i=0; i<mesh->getNumFaces(); i++)
{
matid = ((unsigned long)mesh->getFaceMtlIndex(i)) % MtlCount;
if (matid == MeshSet[m].MatId)
{
fwrite( &mesh->faces[i].v[vx1], sizeof(long), 1, expStream );
fwrite( &mesh->faces[i].v[vx2], sizeof(long), 1, expStream );
fwrite( &mesh->faces[i].v[vx3], sizeof(long), 1, expStream );
long HF0=mesh->faces[i].getEdgeVis(vx1);
long HF1=mesh->faces[i].getEdgeVis(vx2);
long HF2=mesh->faces[i].getEdgeVis(vx3);
fwrite( &HF0, sizeof(long), 1, expStream );
fwrite( &HF1, sizeof(long), 1, expStream );
fwrite( &HF2, sizeof(long), 1, expStream );
// fprintf( tempStream, "Face = %d - HF= %d %d %d\n", i,HF0,HF1,HF2);
}
}
// EXPORT FACE MAP TEXCOORDS IF WE HAVE THEM...
if (obj->HasUVW())
{
if (!CheckForAndExportFaceMap(nodeMtl, mesh, m))
{
// If not, export standard tverts
int numTVx = mesh->getNumTVerts();
if (numTVx)
{
int nbFaces;
WriteChunkHdr( (char*)UV_ID, 0 );
fwrite( &nCurObj, sizeof(Uint16), 1, expStream );
fwrite( &m, sizeof(Uint16), 1, expStream );
nbFaces = MeshSet[m].nbFaces;
fwrite( &nbFaces, sizeof(Uint32), 1, expStream );
for (i=0; i<mesh->getNumFaces(); i++)
{
matid = ((unsigned long)mesh->getFaceMtlIndex(i)) % MtlCount;
if (matid == MeshSet[m].MatId)
{
UVVert tv;
int idx;
idx = mesh->tvFace[i].t[vx1];
tv = mesh->tVerts[idx];
fwrite(&tv.x, sizeof(float), 1, expStream);
fwrite(&tv.y, sizeof(float), 1, expStream);
idx = mesh->tvFace[i].t[vx2];
tv = mesh->tVerts[idx];
fwrite(&tv.x, sizeof(float), 1, expStream);
fwrite(&tv.y, sizeof(float), 1, expStream);
idx = mesh->tvFace[i].t[vx3];
tv = mesh->tVerts[idx];
fwrite(&tv.x, sizeof(float), 1, expStream);
fwrite(&tv.y, sizeof(float), 1, expStream);
}
}
}
}
}
{
int nbFaces;
WriteChunkHdr( (char*)FACENORMAL_ID, 0 );
fwrite( &nCurObj, sizeof(Uint16), 1, expStream );
fwrite( &m, sizeof(Uint16), 1, expStream );
nbFaces = MeshSet[m].nbFaces;
fwrite( &nbFaces, sizeof(Uint32), 1, expStream );
for (i=0; i<mesh->getNumFaces(); i++)
{
matid = ((unsigned long)mesh->getFaceMtlIndex(i)) % MtlCount;
if (matid == MeshSet[m].MatId)
{
Point3 n=GetVertexNormal(mesh, i,mesh->getRVertPtr(mesh->faces[i].v[vx1]));
fwrite(&n.x, sizeof(float), 1, expStream);
fwrite(&n.y, sizeof(float), 1, expStream);
fwrite(&n.z, sizeof(float), 1, expStream);
n=GetVertexNormal(mesh, i,mesh->getRVertPtr(mesh->faces[i].v[vx2]));
fwrite(&n.x, sizeof(float), 1, expStream);
fwrite(&n.y, sizeof(float), 1, expStream);
fwrite(&n.z, sizeof(float), 1, expStream);
n=GetVertexNormal(mesh, i,mesh->getRVertPtr(mesh->faces[i].v[vx3]));
fwrite(&n.x, sizeof(float), 1, expStream);
fwrite(&n.y, sizeof(float), 1, expStream);
fwrite(&n.z, sizeof(float), 1, expStream);
}
}
}
// tris[result].VertNormals[s] = Normalize(transpose * (m * get_vertex_normal(&triobj->mesh, j, triobj->mesh.getRVertPtr(fces[j].v[s]))));
if (mesh->getNumVertCol())
{
Point3 vc;
WriteChunkHdr( (char*)VCOL_ID, 0 );
fwrite( &nCurObj, sizeof(Uint32), 1, expStream );
fwrite( &m , sizeof(Uint32), 1, expStream );
int nbFaces = MeshSet[m].nbFaces;
fwrite( &nbFaces, sizeof(Uint32), 1, expStream );
for (i=0; i<mesh->getNumFaces(); i++)
{
matid = ((unsigned long)mesh->getFaceMtlIndex(i)) % MtlCount;
if (matid == MeshSet[m].MatId)
{
TVFace *f = &mesh->vcFace[i];
int vert = f->t[vx1];
vc = mesh->vertCol[vert];
fwrite(&vc.x, sizeof(float), 1, expStream);
fwrite(&vc.y, sizeof(float), 1, expStream);
fwrite(&vc.z, sizeof(float), 1, expStream);
vert = f->t[vx2];
vc = mesh->vertCol[vert];
fwrite(&vc.x, sizeof(float), 1, expStream);
fwrite(&vc.y, sizeof(float), 1, expStream);
fwrite(&vc.z, sizeof(float), 1, expStream);
vert = f->t[vx3];
vc = mesh->vertCol[vert];
fwrite(&vc.x, sizeof(float), 1, expStream);
fwrite(&vc.y, sizeof(float), 1, expStream);
fwrite(&vc.z, sizeof(float), 1, expStream);
}
}
}
}
// EXPORT MESHSET INFO
WriteChunkHdr( (char*)MESH_ID, 0 );
fwrite( &nCurObj, sizeof(long), 1, expStream );
fwrite( &nbMeshs, sizeof(long), 1, expStream );
int NodeMatRef = mtlList.GetMtlID(nodeMtl);
for (m=0;m<nbMeshs;m++)
{
matref = MeshSet[m].MatId + NodeMatRef;
// fprintf( tempStream, "matIdx = %d %d\n", MeshSet[m].MatId, matref );
fwrite(&matref, sizeof(Uint16), 1, expStream);
fwrite(&MeshSet[m].nbFaces, sizeof(Uint16), 1, expStream);
Uint32 TempStore;
TempStore = m;
fwrite(&TempStore, sizeof(Uint32), 1, expStream); // polt list
TempStore = -1;
fwrite(&TempStore, sizeof(Uint32), 1, expStream); // attr list
fwrite(&TempStore, sizeof(Uint32), 1, expStream); // normal list
TempStore = -1;
if (!mesh->vertCol)
TempStore = m;
fwrite(&TempStore, sizeof(Uint32), 1, expStream); // vertex col list
TempStore = -1;
if (obj->HasUVW())
TempStore = m;
fwrite(&TempStore, sizeof(Uint32), 1, expStream); // texture list
}
}
/*----------------------------------------------------------------------
---------------------------------------------------------------------- */
BOOL AsciiExp::CheckForAndExportFaceMap(Mtl* mtl, Mesh* mesh, int meshno)
{
MtlID matid;
ULONG matreq;
return FALSE;
if (!mtl || !mesh) return FALSE;
matreq = mtl->Requirements(-1);
// ARE WE USING FACE MAPPING?
if (!(matreq & MTLREQ_FACEMAP)) return FALSE;
// OK, WE HAVE A FACEMAP SITUATION HERE...
WriteChunkHdr( (char*)UV_ID, 0 );
fwrite( &nCurObj, sizeof(Uint16), 1, expStream );
fwrite( &meshno, sizeof(Uint16), 1, expStream );
Uint32 mnf = MeshSet[meshno].nbFaces;
fwrite( &mnf, sizeof(Uint32), 1, expStream );
for (int i=0; i<mesh->getNumFaces(); i++)
{
matid = mesh->getFaceMtlIndex(i);//faces[i].getMatID();
if (matid == MeshSet[meshno].MatId)
{
Point3 tv[3];
Face * f;
// NJS_COLOR uv;
f = &mesh->faces[i];
make_face_uv( f, tv );
fwrite(&tv[0].x, sizeof(float), 1, expStream);
fwrite(&tv[0].y, sizeof(float), 1, expStream);
fwrite(&tv[1].x, sizeof(float), 1, expStream);
fwrite(&tv[1].y, sizeof(float), 1, expStream);
fwrite(&tv[2].x, sizeof(float), 1, expStream);
fwrite(&tv[2].y, sizeof(float), 1, expStream);
}
}
return TRUE;
}
/*----------------------------------------------------------------------
---------------------------------------------------------------------- */
void AsciiExp::ExportPoints(INode * node, Mesh * mesh)
{
Matrix3 tm = node->GetObjTMAfterWSM( ip->GetAnimRange().Start() );
Point3 Trans;
int nbVerts;
radius = 0.f;
nbVerts = mesh->getNumVerts();
// EXPORT MODEL POINTS
WriteChunkHdr( (char*)POINTS_ID, 0 );
fwrite( &nCurObj, sizeof(Uint32), 1, expStream );
fwrite( &nbVerts, sizeof(Uint32), 1, expStream );
for (int i=0; i<nbVerts; i++)
{
Point3 v1;
Point3 v2;
tm = node->GetObjTMAfterWSM( ip->GetAnimRange().Start() );
v1 = mesh->verts[i];
//v2 = VectorTransform( tm, v1 );
//v2 += tm.GetTrans();
v2 = tm * v1;
Trans = v2;
//Trans.y = Trans.y;
fwrite( &Trans.x, sizeof(float), 1, expStream );
fwrite( &Trans.z, sizeof(float), 1, expStream );
fwrite( &Trans.y, sizeof(float), 1, expStream );
if (radius < fabs(Trans.x)) radius = (float)fabs(Trans.x);
if (radius < fabs(Trans.y)) radius = (float)fabs(Trans.y);
if (radius < fabs(Trans.z)) radius = (float)fabs(Trans.z);
}
}
void AsciiExp::ExportVectors(INode * node, Mesh * mesh)
{
Matrix3 tm = node->GetObjTMAfterWSM( ip->GetAnimRange().Start() );
Point3 Trans;
int nbVerts;
radius = 0.f;
nbVerts = mesh->getNumVerts();
// EXPORT MODEL POINTS
WriteChunkHdr( (char*)VECT_ID, 0 );
fwrite( &nCurObj, sizeof(Uint32), 1, expStream );
fwrite( &nbVerts, sizeof(Uint32), 1, expStream );
for (int i=0; i<nbVerts; i++)
{
Point3 v1;
v1 = mesh->verts[i];
fwrite( &v1.x, sizeof(float), 1, expStream );
fwrite( &v1.z, sizeof(float), 1, expStream );
fwrite( &v1.y, sizeof(float), 1, expStream );
}
}
/*----------------------------------------------------------------------
---------------------------------------------------------------------- */
void AsciiExp::ExportNormals(INode * node, Mesh * mesh)
{
int nbVerts;
Point3 * vnorms;
Point3 fn; // Face normal
Point3 vn; // Vertex normal
int i;
Matrix3 tm = node->GetObjTMAfterWSM( ip->GetAnimRange().End() );
BOOL negScale = TMNegParity(tm);
int vx1, vx2, vx3;
if (negScale)
{
vx1 = 2;
vx2 = 1;
vx3 = 0;
}
else
{
vx1 = 0;
vx2 = 1;
vx3 = 2;
}
mesh->buildNormals();
nbVerts = mesh->getNumVerts();
vnorms = new Point3[nbVerts];
for (i=0; i<mesh->getNumVerts(); i++)
{
vnorms[i] = GetAverageVertNormal(node, mesh, i);
}
// EXPORT MODEL NORMALS
WriteChunkHdr( (char*)NORMAL_ID, 0 );
fwrite( &nCurObj, sizeof(Uint32), 1, expStream );
fwrite( &nbVerts, sizeof(Uint32), 1, expStream );
for (i=0; i<nbVerts; i++)
{
vn = vnorms[i];
fwrite( &vn.x, sizeof(float), 1, expStream );
fwrite( &vn.z, sizeof(float), 1, expStream );
fwrite( &vn.y, sizeof(float), 1, expStream );
}
delete vnorms;
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
Point3 AsciiExp::GetVertexNormal(Mesh* mesh, int faceNo, RVertex* rv)
{
Face* f = &mesh->faces[faceNo];
DWORD smGroup = f->smGroup;
int numNormals;
Point3 vertexNormal;
// Is normal specified
// SPCIFIED is not currently used, but may be used in future versions.
if (rv->rFlags & SPECIFIED_NORMAL)
{
// fprintf( pStream, "SPECIFIED_NORMAL\n");
vertexNormal = rv->rn.getNormal();
}
// If normal is not specified it's only available if the face belongs
// to a smoothing group
else if ((numNormals = rv->rFlags & NORCT_MASK) && smGroup)
{
// If there is only one vertex is found in the rn member.
if (numNormals == 1)
{
// fprintf( pStream, "SINGLE SMOOTHING GROUP\n");
vertexNormal = rv->rn.getNormal();
}
else
{
// fprintf( pStream, "SMOOTHING GROUP %d\n", numNormals);
// If two or more vertices are there you need to step through them
// and find the vertex with the same smoothing group as the current face.
// You will find multiple normals in the ern member.
for (int i = 0; i < numNormals; i++)
{
vertexNormal = rv->ern[i].getNormal();
}
}
}
else
{
// fprintf( pStream, "NO SMOOTHING GROUP\n");
// Get the normal from the Face if no smoothing groups are there
vertexNormal = mesh->getFaceNormal(faceNo);
}
return vertexNormal;
}
Point3 AsciiExp::GetAverageVertNormal(INode *node, Mesh* mesh, int VertNo)
{
int i;
int c=0;
Matrix3 tm = node->GetNodeTM(ip->GetAnimRange().Start());
tm.NoTrans();
Point3 n= Point3(0.f,0.f,0.f);
for (i=0; i<mesh->getNumFaces(); i++) {
if (mesh->faces[i].v[0] == VertNo || mesh->faces[i].v[1] == VertNo || mesh->faces[i].v[2] == VertNo)
{
Point3 p0 = tm * mesh->verts[mesh->faces[i].v[0]];
Point3 p1 = tm * mesh->verts[mesh->faces[i].v[1]];
Point3 p2 = tm * mesh->verts[mesh->faces[i].v[2]];
Point3 Nrm = Normalize(CrossProd(p0 - p1, p0 - p2));
n += Nrm;
c ++;
}
}
n /= (float)c;
return Normalize(n);
}
void AsciiExp::ExportNodeAnimMesh( INode* node )
{
INode *parent;
Matrix3 parentTM, nodeTM, localTM;
parent = node->GetParentNode();
TimeValue start = ip->GetAnimRange().Start();
TimeValue end = ip->GetAnimRange().End();
int delta = GetTicksPerFrame();
TimeValue t;
Matrix3 tm;
Matrix3 StartM;
AffineParts ap;
int i;
Quat q;
Quat StartQ, StartU;
Point3 StartP, StartS;
nodeTM = node->GetNodeTM(start);
parentTM = parent->GetNodeTM(start);
StartM = nodeTM*Inverse(parentTM);
for (t=start; t<=end; t+=delta)
{
nodeTM = node->GetNodeTM(t);
parentTM = parent->GetNodeTM(t);
tm = nodeTM*Inverse(parentTM);
for (i=0;i<4;i++) {
Point3 m0 = StartM.GetRow(i);
Point3 m1 = tm.GetRow(i);
if (fabs(m0.x-m1.x)>0.001 ||
fabs(m0.y-m1.y)>0.001 ||
fabs(m0.z-m1.z)>0.001)
break;
}
if (i!=4)
break;
}
if (t==end)
return;
char text[250];
sprintf(text,"%s", node->GetName());
WriteChunkHdr( (char*)ANIM_ID, 0);
fwrite( &CHANNEL_TYPE_NODE, sizeof( Uint32 ), 1, expStream );
fwrite( &nCurObj, sizeof( Uint32 ), 1, expStream );
fwrite( &totFrames, sizeof( Uint32 ), 1, expStream );
for (t=start; t<=end; t+=delta) {
// TRANSLATION
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 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
}
}
void AsciiExp::ExportVisTrack( INode* node )
{
Control *VisControl = node->GetVisController();
if (VisControl) {
float VisF;
TimeValue start = ip->GetAnimRange().Start();
TimeValue end = ip->GetAnimRange().End();
int delta = GetTicksPerFrame();
TimeValue t;
WriteChunkHdr( (char*)VIS_ID, 0);
fwrite( &nCurObj, sizeof( Uint32 ), 1, expStream );
fwrite( &totFrames, sizeof( Uint32 ), 1, expStream );
for (t=start; t<=end; t+=delta) {
Interval I = Interval(t, t);
VisControl->GetValue(t, &VisF, I, CTRL_ABSOLUTE);
fwrite( &VisF, sizeof(float), 1, expStream);
}
}
}
void AsciiExp::ExportAnimMesh( INode* node )
{
TimeValue start = ip->GetAnimRange().Start();
TimeValue end = ip->GetAnimRange().End();
int delta = GetTicksPerFrame();
BOOL needDel;
Mesh *mesh;
TriObject *tri;
TimeValue t;
WriteChunkHdr( (char*)ANIM_ID, 0);
fwrite( &CHANNEL_TYPE_VERTEX, sizeof( Uint32 ), 1, expStream );
fwrite( &nCurObj, sizeof( Uint32 ), 1, expStream );
fwrite( &totFrames, sizeof( Uint32 ), 1, expStream );
for (t=start; t<=end; t+=delta)
{
tri = GetTriObjectFromNode(node, t, needDel);
if (!tri) return;
mesh = &tri->mesh;
Matrix3 tm = node->GetObjTMAfterWSM( t );
for (int i=0; i<mesh->getNumVerts(); i++)
{
Point3 v1;
Point3 v2;
v1 = mesh->verts[i];
v2 = tm * v1;
fwrite( &v2.x, sizeof(float), 1, expStream );
fwrite( &v2.z, sizeof(float), 1, expStream );
fwrite( &v2.y, sizeof(float), 1, expStream );
}
if (needDel) tri->DeleteThis();
}
}
/*===========================================================================
end */

536
Utils/GinExp/ExpTree.cpp Normal file
View File

@ -0,0 +1,536 @@
#include "AsciiExp.h"
Matrix3 Uniform_Matrix(Matrix3 orig_cur_mat)
{
AffineParts parts;
Matrix3 mat;
///Remove scaling from orig_cur_mat
//1) Decompose original and get decomposition info
decomp_affine(orig_cur_mat, &parts);
//2) construct 3x3 rotation from quaternion parts.q
parts.q.MakeMatrix(mat);
//3) construct position row from translation parts.t
mat.SetRow(3, parts.t);
return(mat);
}
//GET_RELATIVE_MATRIX: RETURNS RELATIVE
//MATRIX WITHOUT NON_UNIFORM SCALING
Matrix3 Get_Relative_Matrix(INode *node, int t)
{
/* Note: This function removes the non-uniform scaling
from MAX node transformations. before multiplying the
current node by the inverse of its parent. The
removal must be done on both nodes before the
multiplication and Inverse are applied. This is especially
useful for Biped export (which uses non-uniform scaling on
its body parts.) */
INode *p_node = node->GetParentNode();
Matrix3 orig_cur_mat; // for current and parent
Matrix3 orig_par_mat; // original matrices
Matrix3 cur_mat; // for current and parent
Matrix3 par_mat; // decomposed matrices
//Get transformation matrices
orig_cur_mat = node->GetNodeTM(t);
if (p_node)
{
orig_par_mat = p_node->GetNodeTM(t);
} else
{
orig_par_mat.IdentityMatrix();
}
char Text[256];
sprintf(Text, "%s", node->GetName());
cur_mat = orig_cur_mat;
par_mat = orig_par_mat;
/* Control *c = node->GetTMController();
if (c)
{
if ((c->ClassID() == BIPSLAVE_CONTROL_CLASS_ID) ||
(c->ClassID() == BIPBODY_CONTROL_CLASS_ID) ||
(c->ClassID() == FOOTPRINT_CLASS_ID))
{
//Decompose each matrix
cur_mat = Uniform_Matrix(orig_cur_mat);
}
}
if (p_node)
{
c = p_node->GetTMController();
if (c)
{
if ((c->ClassID() == BIPSLAVE_CONTROL_CLASS_ID) ||
(c->ClassID() == BIPBODY_CONTROL_CLASS_ID) ||
(c->ClassID() == FOOTPRINT_CLASS_ID))
{
par_mat = Uniform_Matrix(orig_par_mat);
}
}
}*/
//then return relative matrix in coordinate space of parent
return(cur_mat * Inverse( par_mat));
}
void AsciiExp::ExportTree()
{
WriteChunkHdr( (char*)TREE_ID, 0);
ExportTreeNodes(ip->GetRootNode());
WriteChunkHdr( (char*)ANIM_ID, 0);
fwrite( &CHANNEL_TYPE_TREE, sizeof( Uint32 ), 1, expStream );
// Change by Dave - Need frame count!!
fwrite( &totFrames, sizeof( Uint32 ), 1, expStream );
ExportTreeAnim(ip->GetRootNode());
/*
WriteChunkHdr( (char*)MOTION_ID, 0);
fwrite( &totFrames, sizeof( Uint32 ), 1, expStream );
ExportMotionAnim(ip->GetRootNode());
*/
WriteChunkHdr( (char*)KEY_ID, 0);
fwrite( &CHANNEL_TYPE_TREE, sizeof( Uint32 ), 1, expStream );
fwrite( &CHANNEL_INFO_ALL, sizeof( Uint32) , 1, expStream);
ExportTreeKeyAnim(ip->GetRootNode());
ExportParticles();
}
void AsciiExp::ExportParticles()
{
WriteChunkHdr( (char*)PART_ID, 0);
fwrite(&NbEmmitters, sizeof(int), 1, expStream);
NbEmmitters = 0;
ExportParticleNodes(ip->GetRootNode());
}
void AsciiExp::ExportParticleNodes( INode *node)
{
ObjectState os = node->EvalWorldState( ip->GetAnimRange().Start() );
Object * obj = node->EvalWorldState(ip->GetAnimRange().Start()).obj;
if (obj && obj->GetInterface(I_PARTICLEOBJ))
{
fwrite(&NbEmmitters, sizeof(int), 1, expStream);
Control *VisControl = node->GetVisController();
if (VisControl) {
float VisF;
TimeValue start = ip->GetAnimRange().Start();
TimeValue end = ip->GetAnimRange().End();
int delta = GetTicksPerFrame();
TimeValue t;
fwrite( &totFrames, sizeof( Uint32 ), 1, expStream );
for (t=start; t<=end; t+=delta) {
Interval I = Interval(t, t);
VisControl->GetValue(t, &VisF, I, CTRL_ABSOLUTE);
fwrite( &VisF, sizeof(float), 1, expStream);
}
} else
{
float VisF = 1.f;
TimeValue start = ip->GetAnimRange().Start();
TimeValue end = ip->GetAnimRange().End();
int delta = GetTicksPerFrame();
TimeValue t;
fwrite( &totFrames, sizeof( Uint32 ), 1, expStream );
for (t=start; t<=end; t+=delta) {
fwrite( &VisF, sizeof(float), 1, expStream);
}
}
}
NbEmmitters ++;
int nbChilds = node->NumberOfChildren();
fwrite( &nbChilds, sizeof(int), 1, expStream);
for (int c=0;c<nbChilds;c++) // RUN THROUGH ALL OF THE CHILDREN
{
INode *ChildNode = node->GetChildNode(c);
if (ChildNode) ExportParticleNodes( ChildNode );
}
}
void AsciiExp::ExportTreeNodes( INode * node )
{
INode * ChildNode;
long nbChilds;
Matrix3 tm;
AffineParts ap;
char name[256];
ObjectState os = node->EvalWorldState( ip->GetAnimRange().Start() );
Object * obj = node->EvalWorldState(ip->GetAnimRange().Start()).obj;
if (obj && obj->GetInterface(I_PARTICLEOBJ))
{
NbEmmitters ++;
}
// 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
// BONE TRANSLATION
/*Dave!! tm = node->GetNodeTM( ip->GetAnimRange().Start() ) * Inverse(node->GetParentTM(ip->GetAnimRange().Start()));*/
tm = Get_Relative_Matrix(node , ip->GetAnimRange().Start());
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);
fwrite( &ap.k.z, sizeof(float), 1, expStream);
fwrite( &ap.k.y, sizeof(float), 1, expStream);
fwrite( &ap.u.x, sizeof(float), 1, expStream);
fwrite( &ap.u.z, sizeof(float), 1, expStream);
fwrite( &ap.u.y, sizeof(float), 1, expStream);
fwrite( &ap.u.w, sizeof(float), 1, expStream);
Matrix3 m0(TRUE);
Matrix3 m1(TRUE);
Matrix3 m2(TRUE);
Matrix3 m3(TRUE);
Matrix3 m4(TRUE);
m0.SetTrans(ap.t);
ap.q.MakeMatrix(m1);
ap.u.MakeMatrix(m2);
m3.Scale(ap.k);
m4 = Inverse(m2);
Matrix3 j = m0 * m1 * m4 * m3 * m2;
Matrix3 y = m2 * m3 * m4 * m1 * m0;
// EXPORT CHILDREN
nbChilds = ValidateBoneKids( node );
fwrite( &nbChilds, sizeof(long), 1, expStream ); // WRITE BONE CHILD COUNT
nbBones++;
nbChilds = node->NumberOfChildren();
for (int c=0;c<nbChilds;c++) // RUN THROUGH ALL OF THE CHILDREN
{
ChildNode = node->GetChildNode(c);
if (ChildNode) ExportTreeNodes( ChildNode );
}
}
/*
void AsciiExp::ExportMotionAnim( INode* node)
{
TimeValue start = ip->GetAnimRange().Start();
TimeValue end = ip->GetAnimRange().End();
TimeValue t;
int delta = GetTicksPerFrame();
Matrix3 tm;
AffineParts ap;
INode * ChildNode;
long nbChilds;
Control *Cnt= node->GetTMController();
if (Cnt)
if (Cnt->ClassID() == BIPBODY_CONTROL_CLASS_ID)
for (t=start; t<=end; t+=delta)
{
// tm = node->GetNodeTM(t) * Inverse(node->GetParentTM(t));
tm = node->GetNodeTM(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
}
nbChilds = node->NumberOfChildren();
for (int c=0;c<nbChilds;c++) // RUN THROUGH ALL OF THE CHILDREN (Just cos Im lazy)
{
ChildNode = node->GetChildNode(c);
if (ChildNode) ExportMotionAnim( ChildNode );
}
}
*/
void AsciiExp::ExportTreeAnim( 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;
char name[256];
sprintf( name, "%s", node->GetName() );
for (t=start; t<=end; t+=delta)
{
// tm = node->GetNodeTM(t) * Inverse(node->GetParentTM(t));
tm = Get_Relative_Matrix(node , 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();
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) ExportTreeAnim( ChildNode );
}
}
void AsciiExp::ExportTreeKeyAnim( 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;
TSTR Name = node->GetName();
TimeList tl;
tl.Clear();
INode *KeyNode = node;
c = KeyNode->GetTMController();
if (c) {
if ((c->ClassID() == BIPSLAVE_CONTROL_CLASS_ID) ||
(c->ClassID() == BIPBODY_CONTROL_CLASS_ID) ||
(c->ClassID() == FOOTPRINT_CLASS_ID))
{
for (i=0; i<c->NumSubs(); i++)
{
Animatable *a = c->SubAnim(i);
int k = a->NumKeys();
for (int j=0; j<k; j++)
{
time = a->GetKeyTime(j);
if (time > start && time < end)
tl.Add( time );
}
}
int k = c->NumKeys();
for (int j=0; j<k; j++)
{
time = c->GetKeyTime(j);
if (time > start && time < end)
tl.Add( time );
}
}
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;
}
if (time > start && time < end)
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;
}
if (time > start && time < end)
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;
}
if (time > start && time < end)
tl.Add(time);
}
}
}
}
}
if (tl.Count())
{
tl.Add(start);
tl.Add(end);
}
num = tl.Count();
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));
tm = Get_Relative_Matrix(node , 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();
fwrite( &nbChilds, sizeof(int), 1, expStream);
for (int cn=0;cn<nbChilds;cn++) // RUN THROUGH ALL OF THE CHILDREN
{
ChildNode = node->GetChildNode(cn);
if (ChildNode) ExportTreeKeyAnim( ChildNode);
}
}

96
Utils/GinExp/ExpUProp.cpp Normal file
View File

@ -0,0 +1,96 @@
/*=========================================================================
EXPUPROP.CPP
Author: Dave
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:
---------------------------------------------------------------------- */
const char UPROP_ID[] = MAKE_LONG( 'P', 'R', 'O', 'P' );
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void AsciiExp::ExportProp( INode* node )
{
ObjectState os;
Object * obj;
TSTR UPBuffer;
Uint32 Len;
Uint32 ModNum=nCurNode;
char *TxtPtr;
os = node->EvalWorldState( ip->GetAnimRange().Start() );
obj = node->EvalWorldState( ip->GetAnimRange().Start() ).obj;
if (!os.obj) return;
// if (!obj->IsRenderable()) return;
if (node->IsNodeHidden()) return;
// if (!obj || os.obj->SuperClassID() != GEOMOBJECT_CLASS_ID) return; // Safety net. This shouldn't happen.
node->GetUserPropBuffer(UPBuffer);
Len=UPBuffer.Length();//strlen(UPBuffer);
Len=(Len+3)&0xfffc;
TxtPtr=UPBuffer.data();
WriteChunkHdr( (char*)UPROP_ID, 0 );
fwrite( &ModNum, sizeof(Uint32), 1, expStream );
fwrite( &Len, sizeof(Uint32), 1, expStream );
fwrite( TxtPtr, sizeof(char), Len, expStream );
}

958
Utils/GinExp/Triobjed.h Normal file
View File

@ -0,0 +1,958 @@
/**********************************************************************
*<
FILE: triobjed.h
DESCRIPTION: Editable Triangle Mesh Object
CREATED BY: Rolf Berteig
HISTORY: created 4 March 1996
*> Copyright (c) 1996, All Rights Reserved.
**********************************************************************/
#ifndef __TRIOBJED__
#define __TRIOBJED__
#include "meshadj.h"
typedef Tab<Point3> Point3Tab;
#ifdef _SUBMTLASSIGNMENT
#include "sbmtlapi.h"
#endif
// Selection levels
#define SL_OBJECT 0
#define SL_VERTEX 1
#define SL_FACE 2
#define SL_EDGE 3
#define ALIGN_CONST 0
#define ALIGN_VIEW 1
#define DEF_PICKBOX_SIZE 4
class WeldVertCMode;
class CreateVertCMode;
class BuildFaceCMode;
class DivideEdgeCMode;
class TurnEdgeCMode;
class AttachPickMode;
class ExtrudeCMode;
class AlignFaceCMode;
class FlipNormCMode;
class CutEdgeCMode; // SCA
#define CID_CREATEVERT CID_USER + 973
#define CID_BUILDFACE CID_USER + 975
#define CID_WELDVERT CID_USER + 978
#define CID_DIVIDEEDGE CID_USER + 979
#define CID_TURNEDGE CID_USER + 980
#define CID_EXTRUDE CID_USER + 990
#define CID_ALIGNFACE CID_USER + 1000
#define CID_FLIPNORM CID_USER + 1010
#define CID_CUTEDGE CID_USER + 1020 // SCA
#define SELTYPE_SINGLE 1
#define SELTYPE_POLY 2
#define SELTYPE_ELEMENT 3
#define IDC_SELSINGLE 0x4010
#define IDC_SELPOLY 0x4011
#define IDC_SELELEMENT 0x4012
#define MAX_MATID 0xffff
class NamedSelSetList {
public:
Tab<BitArray*> sets;
Tab<TSTR*> names;
~NamedSelSetList();
BitArray &operator[](int i) {return *sets[i];}
int Count() {return sets.Count();}
void AppendSet(BitArray &nset,TSTR &name);
void DeleteSet(int i);
IOResult Load(ILoad *iload);
IOResult Save(ISave *isave);
void SetSize(int size);
NamedSelSetList& operator=(NamedSelSetList& from);
void DeleteSetElements(BitArray &set,int m=1);
int FindSet(TSTR &name);
};
#ifdef _SUBMTLASSIGNMENT
class EditTriObject : public TriObject, public EventUser, public ISubMtlAPI {
#else
class EditTriObject : public TriObject, public EventUser {
#endif
public:
// Class vars
static HWND hParams1;
static HWND hParams2;
static HACCEL hAccel;
static Interface *ip;
static MoveModBoxCMode *moveMode;
static RotateModBoxCMode *rotMode;
static UScaleModBoxCMode *uscaleMode;
static NUScaleModBoxCMode *nuscaleMode;
static SquashModBoxCMode *squashMode;
static SelectModBoxCMode *selectMode;
static WeldVertCMode *weldVertMode;
static CreateVertCMode *createVertMode;
static BuildFaceCMode* buildFaceMode;
static TurnEdgeCMode* turnEdgeMode;
static DivideEdgeCMode* divideEdgeMode;
static AttachPickMode* attachPickMode;
static ExtrudeCMode* extrudeMode;
static AlignFaceCMode* alignFaceMode;
static FlipNormCMode* flipMode;
static CutEdgeCMode * cutEdgeMode; // SCA
static float falloff, pinch, bubble;
static int selType;
static float normScale;
static BOOL selByVert;
static BOOL inBuildFace;
static BOOL faceUIValid;
static BOOL inNormalMove;
static BOOL ignoreBackfaces, ignoreBackedges;
static BOOL ignoreVisEdge;
static int pickBoxSize;
static int weldBoxSize;
static int attachMat;
static BOOL condenseMat;
static bool sliceSplit, cutQuadSafe, cutRefine;
static Quat sliceRot;
static Point3 sliceCenter;
static float sliceSize;
static bool sliceMode;
// Cache for computing coord. systems
static FaceClusterList *clust;
static Point3Tab *centers;
static Point3Tab *normals;
static DWORDTab *vclust;
static Tab<float> *distTab;
Point3Tab &CoordCenters();
Point3Tab &CoordNormals();
DWORDTab &VertClusters();
Tab<float> *EdgeDistTab(int iterations);
void FreeDistTab();
void FreeCoordCaches();
void MakeClusterList();
void InvalidateCoordCaches(BOOL selChange=FALSE);
NamedSelSetList vselSet;
NamedSelSetList fselSet;
NamedSelSetList eselSet;
Tab<Control*> cont;
EditTriObject();
// Animatable methods
void DeleteThis() {delete this;}
Class_ID ClassID() {return Class_ID(EDITTRIOBJ_CLASS_ID,0);}
void GetClassName(TSTR& s) ;//{s = GetString(IDS_RB_EDITABLEMESH);}
void BeginEditParams(IObjParam *ip, ULONG flags,Animatable *prev);
void EndEditParams(IObjParam *ip, ULONG flags,Animatable *next);
int NumSubs() {return cont.Count();}
Animatable* SubAnim(int i);
TSTR SubAnimName(int i);
BOOL AssignController(Animatable *control,int subAnim);
int SubNumToRefNum(int subNum) {return subNum;}
BOOL SelectSubAnim(int subNum);
// Reference methods
int NumRefs() {return cont.Count();}
RefTargetHandle GetReference(int i);
void SetReference(int i, RefTargetHandle rtarg);
void CreateContArray();
void SynchContArray();
//BOOL BypassTreeView();
void DeletePointConts(BitArray &set);
void PlugControllersSel(TimeValue t,BitArray &set);
BOOL PlugControl(TimeValue t,int i);
void SetPointAnim(TimeValue t, int i, Point3 pt);
BOOL CloneVertCont(int from, int to);
RefResult NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget, PartID& partID, RefMessage message);
// BaseObject methods
ObjectState Eval(TimeValue time);
void Transform(TimeValue t, Matrix3& partm, Matrix3 tmAxis, BOOL localOrigin, Matrix3 xfrm, BOOL ar, int type);
void Move(TimeValue t, Matrix3& partm, Matrix3& tmAxis, Point3& val, BOOL localOrigin=FALSE);
void Rotate(TimeValue t, Matrix3& partm, Matrix3& tmAxis, Quat& val, BOOL localOrigin=FALSE);
void Scale(TimeValue t, Matrix3& partm, Matrix3& tmAxis, Point3& val, BOOL localOrigin=FALSE);
void TransformStart(TimeValue t) {if (ip) ip->LockAxisTripods(TRUE);}
void TransformFinish(TimeValue t) {if (ip) ip->LockAxisTripods(FALSE); InvalidateCoordCaches(); FreeDistTab();}
void TransformCancel(TimeValue t) {if (ip) ip->LockAxisTripods(FALSE); FreeDistTab();}
int Display(TimeValue t, INode* inode, ViewExp *vpt, int flags);
void GetWorldBoundBox (TimeValue t, INode * inode, ViewExp* vp, Box3& box);
void GetLocalBoundBox (TimeValue t, INode* inode, ViewExp* vp, Box3& box);
int HitTest(TimeValue t, INode* inode, int type, int crossing, int flags, IPoint2 *p, ViewExp *vpt, ModContext* mc);
void CloneSelSubComponents(TimeValue t);
void AcceptCloneSelSubComponents(TimeValue t);
void SelectSubComponent(
HitRecord *hitRec, BOOL selected, BOOL all, BOOL invert=FALSE);
void ClearSelection(int selLevel);
void SelectAll(int selLevel);
void InvertSelection(int selLevel);
void ActivateSubobjSel(int level, XFormModes& modes );
void GetSubObjectCenters(SubObjAxisCallback *cb,TimeValue t,INode *node,ModContext *mc);
void GetSubObjectTMs(SubObjAxisCallback *cb,TimeValue t,INode *node,ModContext *mc);
// Object methods
TCHAR *GetObjectName() ;//{ return GetString(IDS_RB_EDITABLEMESH);}
BOOL IsSubClassOf(Class_ID classID);
BOOL SupportsNamedSubSels() {return TRUE;}
void ActivateSubSelSet(TSTR &setName);
void NewSetFromCurSel(TSTR &setName);
void RemoveSubSelSet(TSTR &setName);
void SetupNamedSelDropDown();
int NumNamedSelSets();
TSTR GetNamedSelSetName(int i);
void SetNamedSelSetName(int i,TSTR &newName);
void NewSetByOperator(TSTR &newName,Tab<int> &sets,int op);
// Reference methods
RefTargetHandle Clone(RemapDir& remap = NoRemap());
IOResult Load(ILoad *iload);
IOResult Save(ISave *isave);
// From EventUser
void Notify() {DeleteSelected();/*delete key was pressed*/}
// Local methods
void VertsHaveBeenDeleted(BitArray &set);
NamedSelSetList &GetSelSet();
void KeyboardAccelerator(int id);
void RemoveRollupPages();
void SetRollupPages();
int GetSubobjectLevel();
void SetSubobjectLevel(int level);
void SetSelType(int type);
void HoldVerts();
void HoldTopology();
void DeleteSelected();
Point3 CalcRegionAffect(Point3 v,Point3 center,Point3 delta);
Point3 CalcRegionAffect(float dist,Point3 delta);
void DeleteVertSet(BitArray set);
void DeleteFaceSet(BitArray set, BitArray *isoVert);
void HideSelectedVerts();
void UnhideAllVerts();
void HideSelectedFaces();
void UnhideAllFaces();
BOOL WeldSelectedVerts(float thresh);
void WeldSelectedVerts(Point3 pt);
void CollapseSelectedVerts();
void CollapseSelFaces();
void CollapseSelEdges();
void WeldVertSet(BitArray set,Point3 *weldPoint=NULL);
void AddNewVertex(Point3 pt);
void BuildNewFace(int *v);
void MakePlanar();
float GetPolyFaceThesh();
HitRecord *VertHitsToFaceHits(HitRecord *hitRec,BOOL all);
DWORD GetSelSmoothBits(DWORD &invalid);
void SetSelSmoothBits(DWORD bits,DWORD which);
void SelectBySmoothGroup(DWORD bits,BOOL clear);
void AutoSmooth(float thresh);
DWORD GetUsedSmoothBits();
int GetSelMatIndex();
void SetSelMatIndex(int index);
void SelectByMat(int index,BOOL clear);
void InvalidateSurfaceUI();
void FlipSelNormals();
void FlipANormal(int ix);
void UnifySelNormals();
void DetachVertFaces(TSTR &name,BOOL doFaces,BOOL del=TRUE,BOOL elem=FALSE);
void ShowNormals();
void SetSelEdgeVis(BOOL onOff);
void AutoEdge(float angle);
void AttachObject(INode *node);
void MultiAttachObject(INodeTab &nodeTab);
void TesselateFaces(float tens,BOOL edge);
void ExplodeFaces(float thresh, BOOL objs, TSTR &name);
void DoExtrude();
void StartExtrudeMode();
void BeginNormalMove(TimeValue t);
void EndNormalMove(TimeValue t,BOOL accept);
void NormalMove(TimeValue t, float amount);
void CloneSelVerts();
void CloneSelFaces(BitArray &set);
void BreakVerts();
void RemoveIsoVerts();
void AlignVertsTo(int which);
void AlignFacesTo(int which,DWORD f);
Matrix3 ComputeAlignTM(int which, float &zcent);
void SetEdgeVisCheckState();
void NSCopy();
void NSPaste();
BOOL GetUniqueSetName(TSTR &name);
int SelectNamedSet();
void SelectByNormal(BOOL front);
void SetNumSelLabel();
Color GetSelVertColor();
void SetSelVertColor(Color c);
void SelectVertByColor(Point3 selcol,int selDeltaR,int selDeltaG,int selDeltaB,BOOL add,BOOL sub);
BOOL AllocateVertColor();
BOOL SplitSharedVertCol();
void CreateCurveFromEdge(TSTR name,int curveType,BOOL ignoreHiddenEdges);
void SelectOpenEdges();
BOOL DoAttachMatOptionDialog();
int DoCut (Point3 & viewNorm, DWORD e1, float prop1, DWORD e2, float prop2); // SCA
void Slice ();
void EnterSliceMode (HWND hwnd);
void ExitSliceMode (HWND hwnd);
#ifdef _SUBMTLASSIGNMENT
void* GetInterface(ULONG id);
MtlID GetNextAvailMtlID();
BOOL HasFaceSelection();
void SetSelFaceMtlID(MtlID id, BOOL bResetUnsel = FALSE);
int GetSelFaceUniqueMtlID();
int GetSelFaceAnyMtlID();
int GetMaxMtlID();
#endif
};
// --- Command Modes -----------------------------------------------
class ExtrudeMouseProc : public MouseCallBack {
private:
MoveTransformer moveTrans;
EditTriObject *eo;
Interface *ip;
IPoint2 om;
public:
ExtrudeMouseProc(EditTriObject* o, IObjParam *i)
: moveTrans(i) {eo=o;ip=i;}
int proc(
HWND hwnd,
int msg,
int point,
int flags,
IPoint2 m );
};
class ExtrudeSelectionProcessor : public GenModSelectionProcessor {
protected:
HCURSOR GetTransformCursor();
public:
ExtrudeSelectionProcessor(ExtrudeMouseProc *mc, EditTriObject *o, IObjParam *i)
: GenModSelectionProcessor(mc,o,i) {}
};
class ExtrudeCMode : public CommandMode {
private:
ChangeFGObject fgProc;
ExtrudeSelectionProcessor mouseProc;
ExtrudeMouseProc eproc;
EditTriObject* eo;
public:
ExtrudeCMode(EditTriObject* o, IObjParam *i) :
fgProc(o), mouseProc(&eproc,o,i), eproc(o,i) {eo=o;}
int Class() { return MODIFY_COMMAND; }
int ID() { return CID_EXTRUDE; }
MouseCallBack *MouseProc(int *numPoints) { *numPoints=2; return &mouseProc; }
ChangeForegroundCallback *ChangeFGProc() { return &fgProc; }
BOOL ChangeFG( CommandMode *oldMode ) { return oldMode->ChangeFGProc() != &fgProc; }
void EnterMode();
void ExitMode();
};
class AttachPickMode :
public PickModeCallback,
public PickNodeCallback {
public:
EditTriObject* eo;
IObjParam *ip;
AttachPickMode(EditTriObject* o, IObjParam *i)
{eo=o;ip=i;}
BOOL HitTest(IObjParam *ip,HWND hWnd,ViewExp *vpt,IPoint2 m,int flags);
BOOL Pick(IObjParam *ip,ViewExp *vpt);
void EnterMode(IObjParam *ip);
void ExitMode(IObjParam *ip);
BOOL Filter(INode *node);
BOOL RightClick(IObjParam *ip,ViewExp *vpt) {return TRUE;}
PickNodeCallback *GetFilter() {return this;}
};
class WeldVertMouseProc : public MoveModBox {
private:
EditTriObject *et;
IObjParam *ip;
public:
WeldVertMouseProc(EditTriObject* e, IObjParam *i)
: MoveModBox(e,i) {et=e;ip=i;}
BOOL HitTestVerts(IPoint2 &m, ViewExp *vpt,int &v);
int proc(
HWND hwnd,
int msg,
int point,
int flags,
IPoint2 m );
};
class WeldVertSelectionProcessor : public GenModSelectionProcessor {
protected:
HCURSOR GetTransformCursor();
public:
WeldVertSelectionProcessor(WeldVertMouseProc *mc, Object *o, IObjParam *i)
: GenModSelectionProcessor(mc,o,i) {}
};
class WeldVertCMode : public CommandMode {
private:
ChangeFGObject fgProc;
WeldVertSelectionProcessor mouseProc;
WeldVertMouseProc eproc;
EditTriObject* et;
public:
WeldVertCMode(EditTriObject* mod, IObjParam *i) :
fgProc(mod), mouseProc(&eproc,mod,i), eproc(mod,i) {et=mod;}
int Class() { return MODIFY_COMMAND; }
int ID() { return CID_WELDVERT; }
MouseCallBack *MouseProc(int *numPoints) {*numPoints=2; return &mouseProc;}
ChangeForegroundCallback *ChangeFGProc() {return &fgProc; }
BOOL ChangeFG( CommandMode *oldMode ) {return oldMode->ChangeFGProc() != &fgProc;}
void EnterMode();
void ExitMode();
};
class CreateVertMouseProc : public MouseCallBack {
private:
EditTriObject *et;
IObjParam *ip;
public:
CreateVertMouseProc(EditTriObject* mod, IObjParam *i)
{et=mod;ip=i;}
int proc(
HWND hwnd,
int msg,
int point,
int flags,
IPoint2 m );
};
class CreateVertCMode : public CommandMode {
private:
ChangeFGObject fgProc;
CreateVertMouseProc proc;
EditTriObject* et;
public:
CreateVertCMode(EditTriObject* mod, IObjParam *i)
: fgProc(mod), proc(mod,i) {et=mod;}
int Class() { return MODIFY_COMMAND; }
int ID() { return CID_CREATEVERT; }
MouseCallBack *MouseProc(int *numPoints) {*numPoints=1; return &proc;}
ChangeForegroundCallback *ChangeFGProc() {return &fgProc;}
BOOL ChangeFG(CommandMode *oldMode) {return oldMode->ChangeFGProc()!= &fgProc;}
void EnterMode();
void ExitMode();
};
class BuildFaceMouseProc : public MouseCallBack {
private:
EditTriObject *et;
IObjParam *ip;
int vts[3];
IPoint3 mpts[3];
int pt;
IPoint2 lm;
public:
BuildFaceMouseProc(EditTriObject* e, IObjParam *i);
void DrawFace(HWND hWnd,IPoint2 &m);
BOOL HitTestVerts(IPoint2 &m, ViewExp *vpt,int &v);
int proc(
HWND hwnd,
int msg,
int point,
int flags,
IPoint2 m );
};
class BuildFaceCMode : public CommandMode {
private:
ChangeFGObject fgProc;
BuildFaceMouseProc proc;
EditTriObject *et;
public:
BuildFaceCMode(EditTriObject* e, IObjParam *i)
: fgProc(e), proc(e,i) {et=e;}
int Class() { return MODIFY_COMMAND; }
int ID() { return CID_BUILDFACE; }
MouseCallBack *MouseProc(int *numPoints) {*numPoints=999999; return &proc;}
ChangeForegroundCallback *ChangeFGProc() {return &fgProc;}
BOOL ChangeFG(CommandMode *oldMode) {return oldMode->ChangeFGProc()!= &fgProc;}
void EnterMode();
void ExitMode();
};
class AlignFaceMouseProc : public MouseCallBack {
public:
EditTriObject *et;
IObjParam *ip;
int which;
AlignFaceMouseProc(EditTriObject* e, IObjParam *i)
{et=e;ip=i;which=ALIGN_CONST;}
HitRecord *HitTestFaces(IPoint2 &m, ViewExp *vpt);
int proc(
HWND hwnd,
int msg,
int point,
int flags,
IPoint2 m );
};
class AlignFaceCMode : public CommandMode {
public:
ChangeFGObject fgProc;
AlignFaceMouseProc proc;
EditTriObject* et;
AlignFaceCMode(EditTriObject* e, IObjParam *i)
: fgProc(e), proc(e,i ) {et=e;}
int Class() { return MODIFY_COMMAND; }
int ID() { return CID_ALIGNFACE; }
MouseCallBack *MouseProc(int *numPoints) {*numPoints=1; return &proc;}
ChangeForegroundCallback *ChangeFGProc() {return &fgProc;}
BOOL ChangeFG(CommandMode *oldMode) {return oldMode->ChangeFGProc()!= &fgProc;}
void EnterMode();
void ExitMode();
};
class FlipNormMouseProc : public MouseCallBack {
public:
EditTriObject *et;
IObjParam *ip;
FlipNormMouseProc(EditTriObject* e, IObjParam *i)
{et=e;ip=i;}
HitRecord *HitTestFaces(IPoint2 &m, ViewExp *vpt);
int proc(
HWND hwnd,
int msg,
int point,
int flags,
IPoint2 m );
};
class FlipNormCMode : public CommandMode {
public:
ChangeFGObject fgProc;
FlipNormMouseProc proc;
EditTriObject* et;
FlipNormCMode(EditTriObject* e, IObjParam *i)
: fgProc(e), proc(e,i ) {et=e;}
int Class() {return MODIFY_COMMAND;}
int ID() {return CID_FLIPNORM;}
MouseCallBack *MouseProc(int *numPoints) {*numPoints=1; return &proc;}
ChangeForegroundCallback *ChangeFGProc() {return &fgProc;}
BOOL ChangeFG(CommandMode *oldMode) {return oldMode->ChangeFGProc()!= &fgProc;}
void EnterMode();
void ExitMode();
};
class PickEdgeMouseProc : public MouseCallBack {
public:
EditTriObject *et;
IObjParam *ip;
PickEdgeMouseProc(EditTriObject* e, IObjParam *i)
{et=e;ip=i;}
HitRecord *HitTestEdges(IPoint2 &m, ViewExp *vpt);
int proc(
HWND hwnd,
int msg,
int point,
int flags,
IPoint2 m );
virtual void EdgePick(DWORD edge)=0;
};
class DivideEdgeProc : public PickEdgeMouseProc {
public:
DivideEdgeProc(EditTriObject* e, IObjParam *i) : PickEdgeMouseProc(e,i) {}
void EdgePick(DWORD edge);
};
class TurnEdgeProc : public PickEdgeMouseProc {
public:
TurnEdgeProc(EditTriObject* e, IObjParam *i) : PickEdgeMouseProc(e,i) {}
void EdgePick(DWORD edge);
};
class DivideEdgeCMode : public CommandMode {
private:
ChangeFGObject fgProc;
DivideEdgeProc proc;
EditTriObject* et;
public:
DivideEdgeCMode(EditTriObject* e, IObjParam *i)
: fgProc(e), proc(e,i) {et=e;}
int Class() { return MODIFY_COMMAND; }
int ID() { return CID_DIVIDEEDGE; }
MouseCallBack *MouseProc(int *numPoints) {*numPoints=1; return &proc;}
ChangeForegroundCallback *ChangeFGProc() {return &fgProc;}
BOOL ChangeFG(CommandMode *oldMode) {return oldMode->ChangeFGProc()!= &fgProc;}
void EnterMode();
void ExitMode();
};
class TurnEdgeCMode : public CommandMode {
private:
ChangeFGObject fgProc;
TurnEdgeProc proc;
EditTriObject* et;
public:
TurnEdgeCMode(EditTriObject* e, IObjParam *i)
: fgProc(e), proc(e,i) {et=e;}
int Class() { return MODIFY_COMMAND; }
int ID() { return CID_TURNEDGE; }
MouseCallBack *MouseProc(int *numPoints) {*numPoints=1; return &proc;}
ChangeForegroundCallback *ChangeFGProc() {return &fgProc;}
BOOL ChangeFG(CommandMode *oldMode) {return oldMode->ChangeFGProc()!= &fgProc;}
void EnterMode();
void ExitMode();
};
class CutEdgeProc : public MouseCallBack { // SCA -- derived from DivideEdgeProc.
public:
EditTriObject *et;
IObjParam *ip;
DWORD e1;
bool e1set;
float prop1;
IPoint2 m1, oldm2;
CutEdgeProc(EditTriObject* e, IObjParam *i) { et=e; ip=i; e1set = FALSE;}
HitRecord *HitTestEdges(IPoint2 &m, ViewExp *vpt);
int proc(HWND hwnd, int msg, int point, int flags, IPoint2 m );
void DrawCutter (HWND hWnd,IPoint2 &m);
};
class CutEdgeCMode : public CommandMode { // SCA
private:
ChangeFGObject fgProc;
CutEdgeProc proc;
EditTriObject* et;
public:
CutEdgeCMode(EditTriObject* e, IObjParam *i)
: fgProc(e), proc(e,i) {et=e;}
int Class() { return MODIFY_COMMAND; }
int ID() { return CID_CUTEDGE; }
MouseCallBack *MouseProc(int *numPoints) {*numPoints=20; return &proc;}
ChangeForegroundCallback *ChangeFGProc() {return &fgProc;}
BOOL ChangeFG(CommandMode *oldMode) {return oldMode->ChangeFGProc()!= &fgProc;}
void EnterMode();
void ExitMode();
};
// --- Restore objects ---------------------------------------------
class MeshSelRestore : public RestoreObj {
public:
BitArray undo, redo;
EditTriObject *et;
int level;
MeshSelRestore(EditTriObject *et);
void Restore(int isUndo);
void Redo();
TSTR Description() {return TSTR(_T("Mesh Sel"));}
};
class MeshVertRestore : public RestoreObj {
public:
Tab<Point3> undo, redo;
EditTriObject *et;
MeshVertRestore(EditTriObject *et);
void Restore(int isUndo);
void Redo();
void EndHold() {et->ClearAFlag(A_HELD);}
TSTR Description() {return TSTR(_T("Mesh Vert"));}
};
class MeshVertColorRestore : public RestoreObj {
public:
Tab<VertColor> undo, redo;
EditTriObject *et;
MeshVertColorRestore(EditTriObject *et);
void Restore(int isUndo);
void Redo();
void EndHold() {et->ClearAFlag(A_HELD);}
TSTR Description() {return TSTR(_T("Mesh Vert Color"));}
};
class MeshTopoRestore : public RestoreObj {
public:
EditTriObject *et;
Tab<Point3> uverts, rverts;
Tab<Point3> uTverts, rTverts;
Tab<Face> ufaces, rfaces;
Tab<TVFace> utvFaces, rtvFaces;
Tab<VertColor> uvertCol, rvertCol;
Tab<TVFace> uvcFaces, rvcFaces;
BitArray uvertSel, ufaceSel, uedgeSel, uvertHide;
BitArray rvertSel, rfaceSel, redgeSel, rvertHide;
BOOL undone;
Tab<Control*> ucont, rcont;
MeshTopoRestore(EditTriObject *et);
void Restore(int isUndo);
void Redo();
void EndHold() {et->ClearAFlag(A_HELD);}
TSTR Description() {return TSTR(_T("Mesh Topo"));}
};
class MeshVertHideRestore : public RestoreObj {
public:
BitArray undo, redo;
EditTriObject *et;
MeshVertHideRestore(EditTriObject *et);
void Restore(int isUndo);
void Redo();
TSTR Description() {return TSTR(_T("Mesh Vert Hide"));}
};
class MeshFaceHideRestore : public RestoreObj {
public:
BitArray undo, redo;
EditTriObject *et;
MeshFaceHideRestore(EditTriObject *et);
void Restore(int isUndo);
void Redo();
TSTR Description() {return TSTR(_T("Mesh Face Hide"));}
};
class MeshFaceMatRestore : public RestoreObj {
public:
Tab<MtlID> undo, redo;
EditTriObject *et;
MeshFaceMatRestore(EditTriObject *et);
void Restore(int isUndo);
void Redo();
void EndHold() {et->ClearAFlag(A_HELD);}
TSTR Description() {return TSTR(_T("Mesh Face Mat"));}
};
class MeshFaceSmoothRestore : public RestoreObj {
public:
Tab<DWORD> undo, redo;
EditTriObject *et;
MeshFaceSmoothRestore(EditTriObject *et);
void Restore(int isUndo);
void Redo();
void EndHold() {et->ClearAFlag(A_HELD);}
TSTR Description() {return TSTR(_T("Mesh Face Smooth"));}
};
class MeshEdgeVisRestore : public RestoreObj {
public:
Tab<DWORD> undo, redo;
EditTriObject *et;
MeshEdgeVisRestore(EditTriObject *et);
void Restore(int isUndo);
void Redo();
void EndHold() {et->ClearAFlag(A_HELD);}
TSTR Description() {return TSTR(_T("Mesh Edge Vis"));}
};
class FaceIndexRec {
public:
DWORD v[3], flags;
};
class UVFaceIndexRec {
public:
DWORD v[3];
};
class MeshFaceIndexRestore : public RestoreObj {
public:
Tab<FaceIndexRec> undo, redo;
Tab<UVFaceIndexRec> tundo, tredo;
EditTriObject *et;
MeshFaceIndexRestore(EditTriObject *et);
void Restore(int isUndo);
void Redo();
TSTR Description() {return TSTR(_T("Mesh Face Index"));}
};
class AppendSetRestore : public RestoreObj {
public:
BitArray set;
TSTR name;
NamedSelSetList *setList;
EditTriObject *et;
AppendSetRestore(NamedSelSetList *sl,EditTriObject *e) {
setList = sl; et = e;
}
void Restore(int isUndo) {
set = *setList->sets[setList->Count()-1];
name = *setList->names[setList->Count()-1];
setList->DeleteSet(setList->Count()-1);
if (et->ip) et->ip->NamedSelSetListChanged();
}
void Redo() {
setList->AppendSet(set,name);
if (et->ip) et->ip->NamedSelSetListChanged();
}
TSTR Description() {return TSTR(_T("Append Set"));}
};
class DeleteSetRestore : public RestoreObj {
public:
BitArray set;
TSTR name;
int index;
NamedSelSetList *setList;
EditTriObject *et;
DeleteSetRestore(int i,NamedSelSetList *sl,EditTriObject *e) {
setList = sl; et = e; index = i;
set = *setList->sets[index];
name = *setList->names[index];
}
void Restore(int isUndo) {
BitArray *n = new BitArray(set);
TSTR *nm = new TSTR(name);
setList->sets.Insert(index,1,&n);
setList->names.Insert(index,1,&nm);
if (et->ip) et->ip->NamedSelSetListChanged();
}
void Redo() {
setList->DeleteSet(index);
if (et->ip) et->ip->NamedSelSetListChanged();
}
TSTR Description() {return TSTR(_T("Delete Set"));}
};
class SetNameRestore : public RestoreObj {
public:
TSTR undo, redo;
int index;
NamedSelSetList *setList;
EditTriObject *et;
SetNameRestore(int i,NamedSelSetList *sl,EditTriObject *e) {
index = i; setList = sl; et = e;
undo = *setList->names[index];
}
void Restore(int isUndo) {
redo = *setList->names[index];
*setList->names[index] = undo;
if (et->ip) et->ip->NamedSelSetListChanged();
}
void Redo() {
*setList->names[index] = redo;
if (et->ip) et->ip->NamedSelSetListChanged();
}
TSTR Description() {return TSTR(_T("Set Name"));}
};
class AttachHitByName : public HitByNameDlgCallback {
public:
EditTriObject *eo;
AttachHitByName(EditTriObject *e) {eo=e;}
TCHAR *dialogTitle();// {return GetString(IDS_RB_MULTIATTACH);}
TCHAR *buttonText();// {return GetString(IDS_RB_ATTACH);}
int filter(INode *node);
void proc(INodeTab &nodeTab);
};
// --- tridata.cpp functions ---------------------------------------
float AffectRegionFunction(float dist,float falloff,float pinch,float bubble);
Point3 FaceNormal(Mesh &mesh, DWORD fi);
Point3 FaceCenter(Mesh &mesh, DWORD fi);
BOOL AnyFaceVertSelected(Mesh &mesh, DWORD fi);
Point3 AverageSelVertNormal(Mesh& mesh);
Point3 AverageSelVertCenter(Mesh& mesh);
void BuildAverageNormals(Mesh& mesh, Point3Tab& normals);
void MatrixFromNormal(Point3& normal, Matrix3& mat);
void BitArrayDeleteSet(BitArray &ba,BitArray &set,int m=1);
void MeshDeleteVertices(Mesh &mesh,BitArray& set);
void MeshDeleteFaces(Mesh &mesh,BitArray& set);
void PolyFromFace(Mesh& mesh,AdjFaceList &al,DWORD f,BitArray &set,float thresh,BOOL ignoreVisEdge);
void ElementFromFace(Mesh &mesh, AdjFaceList &al,DWORD f, BitArray &set);
AdjFaceList *BuildAdjFaceList(Mesh &mesh);
int GetEdgeIndex(Face &f,DWORD v0,DWORD v1);
DWORD GetOtherIndex(Face *f,DWORD v0,DWORD v1);
float AngleBetweenFaces(Mesh *mesh,DWORD f0, DWORD f1);
void FaceCenterTessellate(Mesh *mesh);
void EdgeTessellate(Mesh *mesh, AdjEdgeList *ae, AdjFaceList *af, float tens);
BOOL IsEdgeSelected(MEdge edge,Face *faces,BitArray &esel);
BOOL IsFaceSelected(MEdge edge,BitArray &fsel);
BOOL IsEdgeVisible(MEdge edge,Face *faces);
Point3 ButterFlySubdivide(MEdge edg,Mesh *mesh,AdjFaceList *af,float tens);
Point3 EdgeCenter(MEdge edge,Point3 *verts);
void ElemExplodeFaces(Mesh *mesh, float thresh, AdjFaceList *af);
void ObjExplodeFaces(EditTriObject *eo,
INode *node, TSTR &name, Interface *ip,
Mesh *mesh, float thresh, AdjFaceList *af);
void SwapEdgeVerts(Face *f,DWORD& v1,DWORD& v2);
DWORD GetFaceVertIndex(Face &f,DWORD v);
void EdgeTessellate(Mesh *mesh, AdjEdgeList *ae, AdjFaceList *af, float tens);
void ExtrudeFaces(EditTriObject *eo, Mesh& mesh,
BitArray& sel, AdjEdgeList& el, BOOL doFace);
BOOL GetDetachObjectName(HWND hDlg,TSTR &name, BOOL &elem);
void DeselectHiddenFaces(Mesh &mesh);
void SyncSelectionSets(Mesh &mesh);
#endif //__TRIOBJED__

BIN
Utils/GinExp/asciiexp.aps Normal file

Binary file not shown.

View File

@ -0,0 +1,8 @@
LIBRARY GinExp
EXPORTS
LibDescription @1
LibNumberClasses @2
LibClassDesc @3
LibVersion @4
SECTIONS
.data READ WRITE

201
Utils/GinExp/asciiexp.dsp Normal file
View File

@ -0,0 +1,201 @@
# Microsoft Developer Studio Project File - Name="asciiexp" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=ASCIIEXP - WIN32 RELEASE
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "asciiexp.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "asciiexp.mak" CFG="ASCIIEXP - WIN32 RELEASE"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "asciiexp - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "asciiexp - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""$/KatBox/Project/asciiexp", VHBAAAAA"
# PROP Scc_LocalPath "."
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "asciiexp - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir ".\Release"
# PROP BASE Intermediate_Dir ".\Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir ".\Release"
# PROP Intermediate_Dir ".\Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /G6 /MD /W3 /GX /Od /I "..\..\..\include" /I "c:\3dsmax3_1\MaxSDK\INCLUDE" /I "c:\3dsmax3_1\cstudio\docs" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
# SUBTRACT CPP /YX /Yc /Yu
# ADD BASE MTL /nologo /D "NDEBUG" /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
# ADD LINK32 KERNEL32.LIB USER32.LIB GDI32.LIB WINSPOOL.LIB COMDLG32.LIB ADVAPI32.LIB SHELL32.LIB OLE32.LIB OLEAUT32.LIB UUID.LIB ODBC32.LIB ODBCCP32.LIB COMCTL32.LIB /nologo /base:"0X02C60000" /subsystem:windows /dll /incremental:yes /machine:I386 /out:"C:\3dsmax3_1\plugins\GinExp.dle"
!ELSEIF "$(CFG)" == "asciiexp - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir ".\Debug"
# PROP BASE Intermediate_Dir ".\Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir ".\Debug"
# PROP Intermediate_Dir ".\Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /G6 /MDd /W3 /Gm /GX /ZI /Od /I "c:\3dsmax3_1\MaxSDK\INCLUDE" /I "c:\3dsmax3_1\cstudio\docs" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
# SUBTRACT CPP /YX /Yc /Yu
# ADD BASE MTL /nologo /D "_DEBUG" /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386
# ADD LINK32 KERNEL32.LIB USER32.LIB GDI32.LIB WINSPOOL.LIB COMDLG32.LIB ADVAPI32.LIB SHELL32.LIB OLE32.LIB OLEAUT32.LIB UUID.LIB ODBC32.LIB ODBCCP32.LIB COMCTL32.LIB /nologo /base:"0X02C60000" /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"C:\3dsmax3_1\plugins\GinExp.dle"
# SUBTRACT LINK32 /pdb:none
!ENDIF
# Begin Target
# Name "asciiexp - Win32 Release"
# Name "asciiexp - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
# Begin Source File
SOURCE=.\asciiexp.def
# End Source File
# Begin Source File
SOURCE=.\asciiexp.rc
# End Source File
# Begin Source File
SOURCE=.\ExpBone.cpp
# End Source File
# Begin Source File
SOURCE=.\ExpCamLight.cpp
# End Source File
# Begin Source File
SOURCE=.\ExpFFD.cpp
!IF "$(CFG)" == "asciiexp - Win32 Release"
!ELSEIF "$(CFG)" == "asciiexp - Win32 Debug"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\ExpFileIo.cpp
# End Source File
# Begin Source File
SOURCE=.\ExpFileIo.h
# End Source File
# Begin Source File
SOURCE=.\ExpMain.cpp
# End Source File
# Begin Source File
SOURCE=.\ExpMaterial.cpp
# End Source File
# Begin Source File
SOURCE=.\ExpModel.cpp
# End Source File
# Begin Source File
SOURCE=.\ExpTree.cpp
# End Source File
# Begin Source File
SOURCE=.\ExpUProp.cpp
# End Source File
# Begin Source File
SOURCE=.\resource.h
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
# Begin Source File
SOURCE=.\asciiexp.h
# End Source File
# Begin Source File
SOURCE=.\ffd.h
# End Source File
# Begin Source File
SOURCE=.\Triobjed.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
# End Group
# Begin Group "Libraries"
# PROP Default_Filter "*.lib"
# Begin Source File
SOURCE=\3dsmax3_1\MaxSDK\LIB\CORE.LIB
# End Source File
# Begin Source File
SOURCE=\3dsmax3_1\MaxSDK\LIB\GEOM.LIB
# End Source File
# Begin Source File
SOURCE=\3dsmax3_1\MaxSDK\LIB\MESH.LIB
# End Source File
# Begin Source File
SOURCE=\3dsmax3_1\Maxsdk\Lib\Bmm.lib
# End Source File
# Begin Source File
SOURCE=\3dsmax3_1\Maxsdk\lib\maxutil.lib
# End Source File
# End Group
# End Target
# End Project

456
Utils/GinExp/asciiexp.h Normal file
View File

@ -0,0 +1,456 @@
//**************************************************************************
//* Asciiexp.h - Katana File Exporter
//*
//* By Tim Swann
//* Climax Development
//*
//* July 7, 1998 TS Initial coding
//*
//* Class definition
//*
//* Copyright (c) 1998, All Rights Reserved.
//***************************************************************************
#ifndef __ASCIIEXP__H
#define __ASCIIEXP__H
#define MAXCOUNT (256*16)
#include <fcntl.h>
#include <io.h>
#include <Max.h>
#include "Resource.h"
#include "Istdplug.h"
#include "Stdmat.h"
#include "Decomp.h"
#include "Shape.h"
#include "Interpik.h"
//#include "Asciitok.h"
#include "PhyExp.h"
#include "triobjed.h"
#include "ffd.h"
#include "Bmmlib.h"
#include "bipexp.h"
//#include <Kamui.h>
//#include <NinjaWin.h>
//#include <Nindows.h>
//#include <NjDef.h>
typedef unsigned int Uint32;
typedef unsigned short Uint16;
typedef unsigned char Uint8;
typedef bool Bool;
extern ClassDesc * GetAsciiExpDesc();
extern TCHAR * GetString(int id);
extern HINSTANCE hInstance;
extern DWORD WINAPI fn(LPVOID arg);
//#define MAKE_LONG( a,b,c,d ) (a | (b<<8) | (c<<16) | (d<<24))
#define MAKE_LONG(a,b,c,d) { a, b, c, d, 0}
#define MAX_FILE_CHUNKS (4096*2)
#define OMNI_LIGHT 0 // Omnidirectional
#define TSPOT_LIGHT 1 // Targeted
#define DIR_LIGHT 2 // Directional
#define FSPOT_LIGHT 3 // Free
#define TDIR_LIGHT 4 // Targeted directional
#define GIN_FLAG_USE_TEXTURE 1
#define GIN_FLAG_DOUBLE_SIDE 2
#define GIN_FLAG_IGNORE_LIGHT 4
#define GIN_FLAG_USE_ENVTEXTURE 32
const Uint32 MAX_NODES = 1000; // MAX NODES IN SCENE
const Uint32 MAX_CHUNKFILE_CHUNK_DEPTH = 20; // MAXIMUM NESTED DEPTH OF CHUNKS IN A CHUNKFILE:
const Uint32 MAX_NAME_LENGTH = 32; // MAXIMUM LENGTH OF A NAME STRING
const Uint32 ID_SIZE = 4; // SIZE OF CHUNK ID
// ANIMATION CHANNEL DEFINITIONS
const Uint32 CHANNEL_TYPE_NONE = 0; // NO CHANNEL APPLIED
const Uint32 CHANNEL_TYPE_VERTEX = 1; // VERTEX ANIMATION
const Uint32 CHANNEL_TYPE_BONE = 2; // BONE ANIMATION
const Uint32 CHANNEL_TYPE_WEIGHTS = 3; // BONE VERTEX WEIGHT ANIMATION
const Uint32 CHANNEL_TYPE_NORMALS = 4; // NORMAL ANIMATION
const Uint32 CHANNEL_TYPE_FFD = 5; // FFD ANIMATION
const Uint32 CHANNEL_TYPE_NODE = 6; // NODE ANIMATION
const Uint32 CHANNEL_TYPE_TREE = 7; // NODE ANIMATION
const Uint32 CHANNEL_INFO_POSITION = 0; // NO CHANNEL APPLIED
const Uint32 CHANNEL_INFO_ROTATION = 1; // VERTEX ANIMATION
const Uint32 CHANNEL_INFO_SCALE = 2; // BONE ANIMATION
const Uint32 CHANNEL_INFO_ALL = 3; // BONE ANIMATION
// COUNT OF NUMBER OF FLOATS FOR EACH ANIMATION CHANNEL TYPE
const Uint32 ChannelTypeSize[] = { 0, 3, 7, 1, 3 };
const char FILE_ID[] = MAKE_LONG( 'G', 'I', 'N', '4' );
const char OBJ_ID[] = MAKE_LONG( 'O', 'B', 'J', '4' );
const char POLY_ID[] = MAKE_LONG( 'P', 'O', 'L', 'Y' );
const char UV_ID[] = MAKE_LONG( 'M', 'A', 'P', '4' );
const char MESH_ID[] = MAKE_LONG( 'M', 'E', 'S', 'H' );
const char POINTS_ID[] = MAKE_LONG( 'P', 'T', 'S', '4' );
const char NORMAL_ID[] = MAKE_LONG( 'N', 'O', 'R', 'M' );
const char MODEL_ID[] = MAKE_LONG( 'M', 'O', 'D', '4' );
const char TEXTURE_ID[] = MAKE_LONG( 'T', 'E', 'X', '4' );
const char MATERIAL_ID[] = MAKE_LONG( 'M', 'A', 'T', '4' );
const char CAMERA_ID[] = MAKE_LONG( 'C', 'A', 'M', '4' );
const char LIGHT_ID[] = MAKE_LONG( 'L', 'G', 'H', 'T' );
const char BONE_ID[] = MAKE_LONG( 'B', 'O', 'N', 'E' );
const char ANIM_ID[] = MAKE_LONG( 'A', 'N', 'I', 'M' );
const char FFD_ID[] = MAKE_LONG( 'F', 'F', 'D', '4' );
const char VCOL_ID[] = MAKE_LONG( 'V', 'C', 'O', 'L' );
const char PART_ID[] = MAKE_LONG( 'P', 'A', 'R', 'T' );
const char VIS_ID[] = MAKE_LONG( 'V', 'I', 'S', '4' );
const char KEY_ID[] = MAKE_LONG( 'K', 'E', 'Y', '4' );
const char FACENORMAL_ID[] = MAKE_LONG( 'F', 'N', 'R', 'M' );
const char OBJNODE_ID[] = MAKE_LONG( 'N', 'O', 'D', 'E' );
const char ORIG_ID[] = MAKE_LONG( 'O', 'R', 'I', 'G' );
const char VERSION_ID[] = MAKE_LONG( 'V', 'E', 'R', 'S' );
const char KID_ID[] = MAKE_LONG( 'K', 'I', 'D', '4' );
const char TREE_ID[] = MAKE_LONG( 'T', 'R', 'E', 'E' );
const char VECT_ID[] = MAKE_LONG( 'V', 'E', 'C', 'T' );
//const char MOTION_ID[] = MAKE_LONG( 'M', 'O', 'V', 'E' );
const char TERMINATOR_ID[] = {0};
#define VERSION 131 // Version number * 100
#define KATEXP_CLASS_ID Class_ID(0x37bf4fd7, 0x29976333) // CLASS_ID
const float MPI = 3.1415926535897932384626433932795028841792f;
const float HALF_PI = (MPI / 2);
const float ONE_DEGREE = 0.0174532925199432957692369076848861271344f;
const float INV_ONE_DEGREE = 1/ONE_DEGREE;
#define DELTA 1e-6 // error tolerance
enum {VX, VY, VZ, VW}; // axes
inline float DEG2RAD (float dval) { return(dval*ONE_DEGREE); }
inline float RAD2DEG (float dval) { return(dval*(INV_ONE_DEGREE)); }
#define NJD_PI 3.14159265358979323846
#define NJM_DEG_RAD(n) ((n) * NJD_PI / 180.0) // deg -> rad
#define NJM_DEG_ANG(n) (((Angle)(((n) * 65536.0) / 360.0)) & 0x0000ffff) // deg -> ang
#define NJM_RAD_ANG(n) (((Angle)(((n) * 65536.0) / (2 * NJD_PI))) & 0xffff) // rad -> ang
#define NJM_RAD_DEG(n) ((n) * 180.0 / NJD_PI) // rad -> deg
#define NJM_ANG_DEG(n) ((n) * 360.0 / 65536.0) // ang -> deg
#define NJM_ANG_RAD(n) ((n) * (2 * NJD_PI) / 65536.0) // ang -> rad
const float UV_X = 255.f;
const float UV_Y = -255.f;
typedef struct
{
INode *N;
int Id;
} NODE_ID;
typedef struct
{
MtlID MatId;
Uint16 nbFaces;
} MESH_SET;
typedef struct
{
Color colour;
float alpha;
} COLOURDEF;
typedef struct
{
COLOURDEF diffuse;
COLOURDEF specular;
float exponent;
Uint32 tex_flags;
Uint32 attr_flags;
} MATERIAL;
typedef struct
{
char name[256];
MATERIAL material;
Uint16 TexID;
Uint16 SubTex[256];
} MATLIST;
#define MAX_BONE_NODES 64
typedef struct
{
int nodecount;
int vertno;
char names[MAX_BONE_NODES][256];
float weights[MAX_BONE_NODES];
int NodeId[MAX_BONE_NODES];
Point3 Offsets[MAX_BONE_NODES];
} WEIGHTS;
class MtlKeeper
{
public:
int MtlCount;
int GetSubMtlCount(Mtl* mtl, bool recurse);
BOOL AddMtl(Mtl* mtl);
int GetMtlID(Mtl* mtl);
int Count();
Mtl* GetMtl(int id);
Tab<Mtl*> mtlTab;
};
class TimeList {
TimeValue Value[1000];
int count;
public:
TimeList() {
count = 0;
}
void Add(TimeValue t) {
int i,j;
for (i = 0 ;i<count; i++) {
if (Value[i] == t) {
return;
}
if (Value[i]>t) {
for (j = count; j>i; j--) {
Value[j] = Value[j-1];
}
Value[i] = t;
count++;
return;
}
}
Value[count] = t;
count++;
}
void Clear() {
count = 0;
}
int Count() {
return count;
}
TimeValue Get(int p) {
return Value[p];
}
};
class AsciiExp : public SceneExport
{
public:
AsciiExp();
~AsciiExp();
// SceneExport methods
int ExtCount(); // Number of extensions supported
const TCHAR * Ext(int n); // Extension #n (i.e. "ASC")
const TCHAR * LongDesc(); // Long ASCII description (i.e. "Ascii Export")
const TCHAR * ShortDesc(); // Short ASCII description (i.e. "Ascii")
const TCHAR * AuthorName(); // ASCII Author name
const TCHAR * CopyrightMessage(); // ASCII Copyright message
const TCHAR * OtherMessage1(); // Other message #1
const TCHAR * OtherMessage2(); // Other message #2
unsigned int Version(); // Version number * 100 (i.e. v3.01 = 301)
void ShowAbout(HWND hWnd); // Show DLL's "About..." box
#if MAX_RELEASE == 2500
int DoExport(const TCHAR *name,ExpInterface *ei,Interface *i, BOOL suppressPrompts=FALSE); // Export file
#else
int DoExport(const TCHAR *name,ExpInterface *ei,Interface *i, BOOL suppressPrompts=FALSE,DWORD options=0); // Export file
#endif
// Node enumeration
BOOL nodeEnum(INode* node);
void BoneProcess(INode* node, int& nodeCount);
void FfdProcess(INode* node, int& nodeCount);
void PreProcessBone( INode* node );
void NodePreProcess(INode *node);
// High level export
void ExportNode(INode * node);
void ExportMaterialList();
void ExportModel(INode* node);
void ExportAnimMesh(INode* node);
void ExportCamera(INode* node);
void ExportLight(INode* node);
void ExportTree();
// Mid level export
void ExportMesh(INode* node);
void ExportBones( INode* node );
void ExportMaterial(INode* node);
void ExportAnimKeys(INode* node);
void ExportFFD( INode* node , FFDMod *FfdMod, ModContext *mc, Mesh *);
// Low level export
void ExportBoneKeyAnim( INode* node );
void ExportBoneKeyAnimPos( INode* node );
void ExportBoneKeyAnimRot( INode* node );
void ExportBoneKeyAnimScl( INode* node );
void ExportBoneKeyAnimPos( INode* node , TimeList tl);
void ExportBoneKeyAnimRot( INode* node , TimeList tl);
void ExportBoneKeyAnimScl( INode* node , TimeList tl);
void ExportNodeKeyAnim( INode *node);
void ExportNodeKeyPos( INode *node);
void ExportNodeKeyRot( INode *node);
void ExportNodeKeyScl( INode *node);
void ExportMeshList(INode * node, Mesh * mesh);
void ExportPoints(INode * node, Mesh * mesh);
void ExportVectors(INode * node, Mesh * mesh);
void ExportNormals(INode * node, Mesh * mesh);
void ExportVertCols(INode * node, Mesh * mesh);
void ExportVisTrack( INode* node );
void ExportBoneAnim( INode* node );
void ExportLimb( INode* nodeptr );
void ExportWeights( INode* nodeptr );
void ExportNodeAnimMesh( INode* node );
void ExportMeshVertAnim(INode *node, EditTriObject *e);
void DumpMeshAnim(INode* node, TimeValue t);
void CalcMeshAnimInfo(INode* node, TimeValue t);
void DumpPoly(PolyLine* line, Matrix3 tm);
void DumpMatrix3(Matrix3* m);
void DumpMaterial(Mtl* mtl, int matno, int subno , bool recurse = false);
void DumpJointParams(JointParams* joint);
void DumpUVGen(StdUVGen* uvGen);
void DumpCamPosSample(INode* node);
void DumpPosSample(INode* node);
void DumpPosQuatSample(INode* node);
void DumpRotSample(INode* node);
void DumpScaleSample(INode* node);
void DumpPoint3Keys(Control* cont);
void DumpFloatKeys(Control* cont);
void DumpPosKeys(Control* cont);
void DumpRotKeys(Control* cont);
void DumpScaleKeys(Control* cont);
void DumpTexture( Mtl* mtl, int matno, int subno );
void ExportTreeNodes( INode * node );
void ExportTreeAnim( INode* node );
void ExportTreeKeyAnim( INode* node);
void ExportMotionAnim( INode* node);
// Erm, dunno export
void ExportProp( INode* node );
// Misc methods
int getTextureId( Mtl *mtl );
void SubAnims(Animatable *a);
bool IsBoned(INode *node);
bool WriteChunkHdr( char* ChunkID, long Size );
void CalcChunkSizes( void );
void GetNoFrames( void );
int ValidateBoneKids( INode * nodeptr );
Modifier * FindPhysiqueModifier (INode* node, ModContext**mc);
Modifier * FindPhysiqueModifier (INode* nodePtr);
bool FindFFDModifier (INode* node);
void FindEditableMesh(INode *node);
TCHAR * GetMapID(Class_ID cid, int subNo);
Point3 GetVertexNormal(Mesh* mesh, int faceNo, RVertex* rv);
BOOL CheckForAndExportFaceMap(Mtl* mtl, Mesh* mesh, int matno);
void make_face_uv(Face *f, Point3 *tv);
BOOL TMNegParity(Matrix3 &m);
TCHAR * FixupName(TCHAR* name);
BOOL CheckForAnimation(INode* node, BOOL& pos, BOOL& rot, BOOL& scale);
TriObject * GetTriObjectFromNode(INode *node, TimeValue t, int &deleteIt);
TriObject * GetTriObjectFromObject(Object *obj, TimeValue t, int &deleteIt);
BOOL IsKnownController(Control* cont);
Point3 GetAverageVertNormal(INode *node, Mesh* mesh, int VertNo);
void OrigProcess(INode *node);
TSTR FindTextureFName(TSTR MapName);
void ExportParticles();
void ExportParticleNodes(INode *node);
// Interface to member variables
inline Interface * GetInterface() { return ip; }
// void SetExportAnimFlag(int State) {ExportAnimFlag=State;}
// int GetExportAnimFlag() {return(ExportAnimFlag);}
private:
// int ExportAnimFlag;
char drive[_MAX_DRIVE];
char dir[_MAX_DIR];
char fname[_MAX_FNAME];
char ext[_MAX_EXT];
char filename[_MAX_DRIVE+_MAX_DIR+_MAX_FNAME+_MAX_EXT];
int Export[MAX_NODES];
char SceneName[256];
char MeshFname[256];
Interface * ip;
ModContext *PhyMc;
FILE * tempStream; // Temp debug file
FILE * expStream; // EXPORT file
int nbChunks;
long SizeTab[MAX_FILE_CHUNKS];
int nTotalNodeCount;
int nCurNode;
int nCurObj;
int nbFrames;
Uint32 totFrames;
int CurBone;
int NbEmmitters;
float radius;
int nbBones;
int nbWeights;
WEIGHTS * Weights;
int FfdNum;
int nbTexs;
char TexList[MAXCOUNT][64];
int nbMats;
MATLIST MatList[MAXCOUNT];
int nbMeshs;
MESH_SET MeshSet[MAXCOUNT];
HWND MAX_hWnd;
// char BoxString[MAXCOUNT];
MtlKeeper mtlList;
// NODE_ID NodeList[MAXCOUNT];
// int NodeCount;
};
class AsciiExpClassDesc : public ClassDesc
{
public:
int IsPublic() { return 1; }
void * Create(BOOL loading = FALSE) { return new AsciiExp; }
const TCHAR* ClassName() { return GetString(IDS_ASCIIEXP); }
SClass_ID SuperClassID() { return SCENE_EXPORT_CLASS_ID; }
Class_ID ClassID() { return KATEXP_CLASS_ID; }
const TCHAR* Category() { return GetString(IDS_CATEGORY); }
};
#endif // __ASCIIEXP__H

BIN
Utils/GinExp/asciiexp.ncb Normal file

Binary file not shown.

174
Utils/GinExp/asciiexp.rc Normal file
View File

@ -0,0 +1,174 @@
//Microsoft Developer Studio generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
#ifndef _MAC
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 2,0,0,0
PRODUCTVERSION 2,0,0,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "Comments", "KATANA file exporter (plugin)\0"
VALUE "CompanyName", "Climax\0"
VALUE "FileDescription", "katexp\0"
VALUE "FileVersion", "2, 0, 0, 0\0"
VALUE "InternalName", "KatExp\0"
VALUE "LegalCopyright", "Copyright © 1998 Climax.\0"
VALUE "OriginalFilename", "KatExp.dle\0"
VALUE "ProductName", "3D Studio MAX\0"
VALUE "ProductVersion", "2, 0, 0, 0\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
#endif // !_MAC
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE DISCARDABLE
BEGIN
IDS_ASCIIEXP "GinExp"
IDS_CATEGORY "Standard"
IDS_EXTENSION1 "GIN"
IDS_LONGDESC "3D Studio MAX Climax Scene Exporter"
IDS_SHORTDESC "Climax Export"
IDS_COPYRIGHT "Copyight (c) 1998 by Climax"
IDS_PROGRESS_MSG1 "Please wait skinning up"
IDS_VERSIONSTRING "Climax Export Version"
IDS_LIBDESCRIPTION "Climax file exporter (Climax)"
IDS_PROGRESS_MSG2 "Please wait skinning up2"
END
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// English (U.K.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_ASCIIEXPORT_DLG DIALOG DISCARDABLE 0, 0, 186, 95
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "GinExport Options"
FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "OK",IDOK,129,7,50,14
CONTROL "Check1",IDC_ANIMCHECK,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,16,22,9,11
LTEXT "Export Anim",IDC_ANIMTEXT,26,23,76,12
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
IDD_ASCIIEXPORT_DLG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 179
TOPMARGIN, 7
BOTTOMMARGIN, 88
END
END
#endif // APSTUDIO_INVOKED
#endif // English (U.K.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

104
Utils/GinExp/ffd.h Normal file
View File

@ -0,0 +1,104 @@
#ifndef FFD_H
#define FFD_H
#include "iparamm.h"
#include "istdplug.h"
// This is the FFD Modifier's class ID.
#define FFD44_CLASS_ID Class_ID(0x21325596, 0x2cd10bd8)
#define FFD33_CLASS_ID Class_ID(0x21325596, 0x2cd10bd9)
#define FFD22_CLASS_ID Class_ID(0x21325596, 0x2cd10bd0)
class FFDMod : public Modifier {
public:
// An addition transformation from "Mod Space".
// Let's the user move/rotate/scale the source box
Control *tmControl;
// Parameter block to store parameters
IParamBlock *pblock;
// This BitArray will be set to a length of 64. 1 bit for
// each point indicating its selection state.
BitArray sel;
// A cache of the input object's bounding box.
Box3 lbox;
// Class variables -- these are only used by one instance
// of this class at a time while it is being edited in
// the command panel.
static IObjParam *ip;
static IParamMap *pmapParam;
static MoveModBoxCMode *moveMode;
static RotateModBoxCMode *rotMode;
static UScaleModBoxCMode *uscaleMode;
static NUScaleModBoxCMode *nuscaleMode;
static SquashModBoxCMode *squashMode;
static SelectModBoxCMode *selectMode;
FFDMod();
~FFDMod();
// From Animatable
void DeleteThis() {delete this;}
void BeginEditParams(IObjParam *ip, ULONG flags,Animatable *prev);
void EndEditParams(IObjParam *ip,ULONG flags,Animatable *next);
CreateMouseCallBack* GetCreateMouseCallBack() {return NULL;}
BOOL AssignController(Animatable *control,int subAnim);
int SubNumToRefNum(int subNum);
BOOL SelectSubAnim(int subNum);
// From BaseObject/Object
int Display(TimeValue t, INode* inode, ViewExp *vpt, int flags, ModContext *mc);
void GetWorldBoundBox(TimeValue t,INode* inode, ViewExp *vpt, Box3& box, ModContext *mc);
int HitTest(TimeValue t, INode* inode, int type, int crossing, int flags, IPoint2 *p, ViewExp *vpt, ModContext* mc);
void SelectSubComponent(HitRecord *hitRec, BOOL selected, BOOL all, BOOL invert=FALSE);
void ClearSelection(int selLevel);
void SelectAll(int selLevel);
void InvertSelection(int selLevel);
void ActivateSubobjSel(int level, XFormModes& modes);
void Move(TimeValue t, Matrix3& partm, Matrix3& tmAxis, Point3& val, BOOL localOrigin);
void Rotate(TimeValue t, Matrix3& partm, Matrix3& tmAxis, Quat& val, BOOL localOrigin);
void Scale(TimeValue t, Matrix3& partm, Matrix3& tmAxis, Point3& val, BOOL localOrigin);
void GetSubObjectCenters(SubObjAxisCallback *cb,TimeValue t,INode *node,ModContext *mc);
void GetSubObjectTMs(SubObjAxisCallback *cb,TimeValue t,INode *node,ModContext *mc);
void TransformStart(TimeValue t) {if (ip) ip->LockAxisTripods(TRUE);}
void TransformFinish(TimeValue t) {if (ip) ip->LockAxisTripods(FALSE);}
void TransformCancel(TimeValue t) {if (ip) ip->LockAxisTripods(FALSE);}
// From Modifier
ChannelMask ChannelsUsed() {return PART_GEOM|PART_TOPO|PART_SELECT|PART_SUBSEL_TYPE;}
ChannelMask ChannelsChanged() {return PART_GEOM;}
Class_ID InputType() {return defObjectClassID;}
Interval LocalValidity(TimeValue t);
void ModifyObject(TimeValue t, ModContext &mc, ObjectState *os, INode *node);
// From ReferenceTarget/Maker
int NumRefs() {return 66;}
RefTargetHandle GetReference(int i);
void SetReference(int i, RefTargetHandle rtarg);
int NumSubs() {return 66;}
Animatable* SubAnim(int i);
TSTR SubAnimName(int i);
IOResult Load(ILoad *iload);
IOResult Save(ISave *isave);
RefResult NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget, PartID& partID, RefMessage message);
int DrawControlPoints(TimeValue t,ViewExp *vpt,GraphicsWindow *gw,Box3 box,BOOL ht=FALSE,INode *inode=NULL,ModContext *mc=NULL,int flags=0);
Matrix3 CompTM(TimeValue t,INode *inode,ModContext *mc);
void PlugControllers(TimeValue t);
virtual int NumCtrlPts()=0;
virtual Control* GetPtCont(int i)=0;
virtual void SetPtCont(int i,Control *c)=0;
virtual Point3& GetPt(int i)=0;
virtual Point3 *GetPtPtr()=0;
virtual int GridWidth()=0;
virtual int GridIndex(int i,int j,int k)=0;
virtual Point3 GetControlPoint(TimeValue t, int i, int src=FALSE)=0;
};
#endif

68
Utils/GinExp/resource.h Normal file
View File

@ -0,0 +1,68 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by asciiexp.rc
//
#define IDS_VERSION 1
#define IDS_ASCIIEXP 1
#define IDS_CATEGORY 2
#define IDS_EXTENSION1 3
#define IDS_LONGDESC 4
#define IDS_SHORTDESC 5
#define IDS_COPYRIGHT 6
#define IDS_PROGRESS_MSG 7
#define IDS_PROGRESS_MSG1 7
#define IDS_VERSIONSTRING 8
#define IDS_LIBDESCRIPTION 9
#define IDS_PROGRESS_MSG2 10
#define IDD_PANEL 101
#define IDD_ABOUTBOX 102
#define IDD_ASCIIEXPORT_DLG 103
#define IDB_BITMAP1 108
#define IDB_BITMAP2 110
#define IDB_BITMAP3 113
#define IDD_ENDDIALOG 115
#define IDB_BITMAP4 116
#define IDC_CLOSEBUTTON 1000
#define IDC_MESHDATA 1002
#define IDC_ANIMKEYS 1003
#define IDC_MATERIAL 1004
#define IDC_MESHANIM 1005
#define IDC_NORMALS 1006
#define IDC_SPRITEPAGE 1006
#define IDC_TEXCOORDS 1007
#define IDC_CAMERAANIM 1007
#define IDC_OBJ_GEOM 1008
#define IDC_SPRITEPAGE3 1008
#define IDC_BONEDATA 1008
#define IDC_OBJ_SHAPE 1009
#define IDC_BONEANIM 1009
#define IDC_OBJ_CAMLIGHT 1010
#define IDC_OBJ_CAMERA 1010
#define IDC_OBJ_HELPER 1011
#define IDC_CAMLIGHTANIM 1013
#define IDC_RADIO_USEKEYS 1016
#define IDC_RADIO_SAMPLE 1017
#define IDC_IKJOINTS 1018
#define IDC_OBJ_LIGHT 1019
#define IDC_VERTEXCOLORS 1020
#define IDC_ANIMCHECK 1023
#define IDC_ANIMTEXT 1024
#define IDC_CONT_STEP 1155
#define IDC_CONT_STEP_SPIN 1156
#define IDC_MESH_STEP 1157
#define IDC_MESH_STEP_SPIN 1158
#define IDC_STATIC_FRAME 1161
#define IDC_STATIC_FRAME_SPIN 1162
#define IDC_PREC 1163
#define IDC_PREC_SPIN 1164
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 118
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1025
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@ -4,11 +4,39 @@
#include "system\global.h"
#include "Game\Thing.h"
#include "Gfx\Skel.h"
#include "gfx\anim.h"
#include "Player\Player.h"
// to be removed
#include "fileio\fileio.h"
#include "utils\utils.h"
#include "gfx\tpage.h"
#include "gfx\prim.h"
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
CPlayer::CPlayer()
{
SetRenderObj(&Skel);
SetAnimateObj(&Skel);
};
/*****************************************************************************/
CPlayer::~CPlayer()
{
}
/*****************************************************************************/
void CPlayer::init()
{
sActor3dHdr *Hdr=Skel.Load(ACTORS_SPONGEBOB_A3D);
Skel.Init(Hdr);
TPLoadTex(ACTORS_SPONGEBOB_TEX);
Skel.setAnimDatabase(CAnimDB::GetPlayerAnimBank());
}
/*****************************************************************************/
@ -17,14 +45,7 @@ void CPlayer::shutdown()
}
/*****************************************************************************/
void CPlayer::think()
void CPlayer::Animate()
{
Skel.Animate(this);
}
/*****************************************************************************/
void CPlayer::render()
{
}
/*****************************************************************************/

View File

@ -5,21 +5,26 @@
#ifndef __PLAYER_H__
#define __PLAYER_H__
#include <dstructs.h>
#include "Game/Thing.h"
#include "Gfx/Skel.h"
/*****************************************************************************/
class CPlayer : public CThing
{
public:
CPlayer();
virtual ~CPlayer();
virtual ~CPlayer();
void init();
void shutdown();
void think();
void render();
void Animate();
protected:
CSkel Skel;
};
/*****************************************************************************/