This commit is contained in:
parent
3d74ef38c3
commit
aeb95010d3
24 changed files with 7743 additions and 12 deletions
952
Utils/GinExp/ExpModel.cpp
Normal file
952
Utils/GinExp/ExpModel.cpp
Normal 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( ¢er.x, sizeof(float), 1, expStream );
|
||||
fwrite( ¢er.y, sizeof(float), 1, expStream );
|
||||
fwrite( ¢er.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 */
|
Loading…
Add table
Add a link
Reference in a new issue