Jump to content
  • Advertisement
Sign in to follow this  
break_r

Maya 7 and .X

This topic is 4831 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

It's that time of year again. A new version of Maya comes out and .X file exporters aren't available. So you wait, because implementing an exporter seems complex and you're lazy. =) Besides, Microsoft will release one with the next SDK update (maybe). However, the .X file exporter is typically broken, and causes no end of frustration. Yes, .X file is a legacy format, and yes, it's template-based and can be parsed with relative ease. Yes, it will most likely be updated to an XML-based format in version 10. But you know what? I'm sick of them! Time to roll up the sleeves and create my own mesh format. Which sounds great, because I have no idea what I'm getting into =P Advice? Links? Suggestions? Regards.

Share this post


Link to post
Share on other sites
Advertisement
Goog idea! I did the same and i was suprised how easy it is to write a maya exporter. ok i started with the simple maya exporter plug-in from rob-the-blokes maya exporter factfile On his homepage he describes everything you need for a maya exporter including materials,textures,skinning and other useful stuff. You should have a working Maya exporter for Vertices and Indices within a day without problems. UVs should be a little harder(at least they were for me) because they are stored using UVIndices and at first i didn't understand how they work..if you don't figure it out yourself write me a pm...

hope this helps

regards,
m4gnus

[Edited by - m4gnus on August 27, 2005 8:13:13 AM]

Share this post


Link to post
Share on other sites
Here is one I wrote a couple of years ago; I based it off of Microsoft's example. It's the first one I wrote and very sloppy... It should give you some ideas on how to implement it though.

(Sorry if the formatting gets messed up)

XMayaAPI.h

#ifndef XMAYAAPI_H
#define XMAYAAPI_H

#define WIN32_LEAN_AND_MEAN
#define WIN32_EXTRA_LEAN
#include <Windows.h>
#include <Math.h>
#include <IOStream.h>

#include <Maya/MSimple.h>
#include <Maya/MObject.h>
#include <Maya/MIkSystem.h>
#include <Maya/MDagPath.h>
#include <Maya/MPlug.h>
#include <Maya/MSelectionList.h>
#include <Maya/MColor.h>
#include <Maya/MMatrix.h>
#include <Maya/MQuaternion.h>
#include <Maya/MEulerRotation.h>
#include <Maya/MTime.h>
#include <Maya/MIntArray.h>
#include <Maya/MFloatArray.h>
#include <Maya/MFloatVectorArray.h>
#include <Maya/MFloatPointArray.h>
#include <Maya/MPointArray.h>
#include <Maya/MObjectArray.h>
#include <Maya/MDagPathArray.h>
#include <Maya/MPlugArray.h>
#include <Maya/MAnimControl.h>
#include <Maya/MAnimUtil.h>
#include <Maya/MFnPlugin.h>
#include <Maya/MFnDagNode.h>
#include <Maya/MFnTransform.h>
#include <Maya/MFnIKJoint.h>
#include <Maya/MFnMesh.h>
#include <Maya/MFnNurbsSurface.h>
#include <Maya/MFnSubd.h>
#include <Maya/MFnLambertShader.h>
#include <Maya/MFnBlinnShader.h>
#include <Maya/MFnPhongShader.h>
#include <Maya/MFnSkinCluster.h>
#include <Maya/MFnWeightGeometryFilter.h>
#include <Maya/MFnBlendShapeDeformer.h>
#include <Maya/MFnMatrixData.h>
#include <Maya/MFnSet.h>
#include <Maya/MItSelectionList.h>
#include <Maya/MItDependencyGraph.h>
#include <Maya/MItDependencyNodes.h>
#include <Maya/MItDag.h>
#include <Maya/MItGeometry.h>
#include <Maya/MItMeshPolygon.h>
#include <Maya/MItMeshVertex.h>
#include <Maya/MPxFileTranslator.h>
typedef float FLOAT2[2];
typedef float FLOAT3[3];

#endif //--XMAYAAPI_H



XTranslator.h


#ifndef XTRANSLATOR_H
#define XTRANSLATOR_H
#include "UXMMesh.h"

class XMeshTranslator: public MPxFileTranslator
{
public:
XMeshTranslator(){}
~XMeshTranslator(){}

bool canBeOpened() const{return false;}
bool haveReadMethod() const{return false;}
bool haveWriteMethod() const{return true;}

public:
static void *creator(){return new XMeshTranslator();}
MStatus reader(const MFileObject& UXMFile, const MString& Options, MPxFileTranslator::FileAccessMode Mode){return MS::kSuccess;}
MStatus writer(const MFileObject& UXMFile, const MString& Options, MPxFileTranslator::FileAccessMode Mode);

MString defaultExtension() const{return "uxm";}
MFileKind identifyFile(const MFileObject& FileName, const char *Buffer, short Size) const{return kIsMyFileType;}
};

#endif //--XTRANSLATOR_H



UXMMesh.h


#ifndef UXMMESH_H
#define UXMMESH_H
#include "XMayaAPI.h"

struct UXMHEADER
{
UXMHEADER() : MNUM(5),
Version(1),
NumVertices(0),
NumNormals(0),
NumUVs(0),
NumFaces(0),
NumIndices(0),
NumMaterials(0)
{
//--
}

DWORD MNUM;
DWORD Version;
DWORD NumVertices;
DWORD NumNormals;
DWORD NumUVs;
DWORD NumFaces;
DWORD NumIndices;
DWORD NumMaterials;
};

struct UXMFACE
{
UXMFACE() : NumIndices(0),
Indices(NULL)
{
//--
}

~UXMFACE()
{
delete[] Indices;
}

DWORD UVID;
DWORD* Indices;
DWORD NumIndices;
};

struct UXMMATERIAL
{
UXMMATERIAL() : Shininess(0.0f),
Transparency(0.0f)
{
Ambient[0] = 0.2f;
Ambient[1] = 0.2f;
Ambient[2] = 0.2f;
Diffuse[0] = 0.8f;
Diffuse[1] = 0.8f;
Diffuse[2] = 0.8f;
Emissive[0] = 0.0f;
Emissive[1] = 0.0f;
Emissive[2] = 0.0f;
Specular[0] = 1.0f;
Specular[1] = 1.0f;
Specular[2] = 1.0f;
}
~UXMMATERIAL(){}

FLOAT3 Ambient;
FLOAT3 Diffuse;
FLOAT3 Emissive;
FLOAT3 Specular;
FLOAT Shininess;
char Name[256];
FLOAT Transparency;
char TextureFile[256];
};

struct UXMMESH
{
UXMMESH()
{
m_MeshName = NULL;
m_NumUVs = 0;
m_NumFaces = 0;
m_NumIndices = 0;
m_NumNormals = 0;
m_NumVertices = 0;
m_NumMaterials = 0;
m_UVs = NULL;
m_Faces = NULL;
m_Normals = NULL;
m_Vertices = NULL;
m_Materials = NULL;
}

~UXMMESH()
{
delete[] m_UVs;
delete[] m_Faces;
delete[] m_Normals;
delete[] m_Vertices;
delete[] m_Materials;
}

PCHAR m_MeshName;
DWORD m_NumUVs;
DWORD m_NumFaces;
DWORD m_NumIndices;
DWORD m_NumNormals;
DWORD m_NumVertices;
DWORD m_NumMaterials;

FLOAT2 *m_UVs;
UXMFACE *m_Faces;
FLOAT3 *m_Normals;
FLOAT3 *m_Vertices;
UXMMATERIAL *m_Materials;
};

#endif //--UXMMESH_H



UXMExporter.cpp


#include "XTranslator.h"

int EXPORTSCENE(MString Filename);
int EXPORTSHAPE(MString Filename, MDagPath& Transform);
int EXPORTMESH(MString Filename, MDagPath& Transform, MDagPath& MeshPath, UXMMESH *Mesh);

MStatus initializePlugin(MObject Object)
{
MStatus Status = MS::kSuccess;
MFnPlugin Plugin(Object, "ULTIMAX_EXPORTER", "4.5", "Any");
Status = Plugin.registerFileTranslator("UXM_Mesh", "XMeshTranslator.rgb", XMeshTranslator::creator);
if(!Status){Status.perror("Unable To Register File Translator");}
return Status;
}

MStatus uninitializePlugin(MObject Object)
{
MStatus Status = MS::kSuccess;
MFnPlugin Plugin(Object);
Status = Plugin.deregisterFileTranslator("ULTIMAX_EXPORTER");
if(!Status){Status.perror("Unable To Unregister File Translator");}
return Status;
}

MStatus XMeshTranslator::writer(const MFileObject& UXMFile, const MString& Options, MPxFileTranslator::FileAccessMode Mode)
{
MStatus Status = MS::kSuccess;

cout << "------------------------------------------------------------------------------------------------------\n";
cout << "|¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶|\n";
cout << "|¶¶ ©2003 Ariel Productions ¶¶|\n";
cout << "|¶¶ All Rights Reserved ¶¶|\n";
cout << "|¶¶¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¶¶|\n";
cout << "| |\n";
cout << "|¶¶¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¶¶|\n";
cout << "|¶¶ Programmer - James Dougherty ¶¶|\n";
cout << "|¶¶ Object - Maya UltimaX Mesh Exporter ¶¶|\n";
cout << "|¶¶ Plug-In Version - 1.0 ¶¶|\n";
cout << "|¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶|\n\n";

MString Filename = UXMFile.fullName();
MString FileExtension = Filename.substring(Filename.rindex('.'), Filename.length() - 1);
if(FileExtension != ".uxm" && FileExtension != ".UXM"){Filename += ".uxm";}

cout << "Initializing Scene Data...\n";
MItDag DAG(MItDag::kDepthFirst, MFn::kTransform);
MDagPathArray VisibleNodes;
cout << "Completed Initializing Scene Data...\n\n";

cout << "Exporting UltimaX Mesh To: \"" << Filename << "\"..." << endl;
for(DAG.reset(); !DAG.isDone(); DAG.next())
{
bool NodeVisible;
MPlug Visibility;
MFnDagNode DAGNode;
MDagPath Path;

Status = DAG.getPath(Path); if(!Status){continue;}
Status = DAGNode.setObject(Path); if(!Status){continue;}
Visibility = DAGNode.findPlug("visibility", &Status); if(!Status){continue;}
Status = Visibility.getValue(NodeVisible); if(!Status || !NodeVisible){continue;}
Status = Visibility.setValue(false); if(!Status){continue;}
VisibleNodes.append(Path);
}

if(EXPORTSCENE(Filename) == -1)
{
cout << "\n[ERROR] Unable to Export Scene...\n\n";
}

for(DWORD NodeID = 0; NodeID < VisibleNodes.length(); NodeID++)
{
MPlug Visibility;
MFnDagNode DAGNode;

Status = DAGNode.setObject(VisibleNodes[NodeID]); if(!Status){continue;}
Visibility = DAGNode.findPlug("visibility", &Status); if(!Status){continue;}
Status = Visibility.setValue(true); if(!Status){continue;}
}

cout << "Completed Exporting UltimaX Mesh...\n\n";
cout << "------------------------------------------------------------------------------------------------------\n\n";
cout.flush();
return Status;
}

int EXPORTSCENE(MString Filename)
{
MStatus Status = MS::kSuccess;
MItDag DAG(MItDag::kBreadthFirst, MFn::kTransform, &Status);
if(!Status){return -1;}

for(; !DAG.isDone() && DAG.depth() <= 1; DAG.next())
{
MDagPath DAGPath;
Status = DAG.getPath(DAGPath);
if(!Status){cout << "[WARNING] Ignoring shape..." << endl; continue;}
EXPORTSHAPE(Filename, DAGPath);
}
return 0;
}

int EXPORTSHAPE(MString Filename, MDagPath& Transform)
{
MFnTransform nTransform;
MStatus Status;
UXMMESH Mesh;
MItDag DAG;

char *Name = new char[1 + Transform.partialPathName().length()];
if(Name == NULL){return -1;}
strcpy(Name, Transform.partialPathName().asChar());
for(DWORD i = 0; Name != '\0'; i++){if(Name == ' ' || Name == '|'){Name = '_';}}

if((Name = new char[1 + Transform.partialPathName().length()]) == NULL){return -1;}
strcpy(Name, Transform.partialPathName().asChar());
for (i = 0; Name != '\0'; i++){if (Name == ' ' || Name == '|'){Name = '_';}}

if(Transform.hasFn(MFn::kMesh))
{
MDagPath Path = Transform;
Path.extendToShape();
cout << "\n\tExporting \"" << Transform.fullPathName().asChar() << "\"...\n\n";
EXPORTMESH(Filename, Transform, Path, &Mesh);
}

DAG.reset(Transform.node(), MItDag::kBreadthFirst, MFn::kTransform);
DAG.next();
for(; !DAG.isDone() && DAG.depth() == 1; DAG.next())
{
MDagPath Path;
DAG.getPath(Path);
EXPORTSHAPE(Filename, Path);
}
return 0;
}

int EXPORTMESH(MString Filename, MDagPath& Transform, MDagPath& MeshPath, UXMMESH *Mesh)
{
char* CopyData = "## Created By Maya UltimaX Mesh Exporter V1.0 ##";
MItMeshPolygon POLYGON(MObject::kNullObj);
MStatus Status = MStatus::kSuccess;
MFloatPointArray Vertices;
MFloatVectorArray Normals;
DWORD InstanceNumber = 0;
MObjectArray Shaders;
char* TexFile = "NT";
MIntArray ShaderMap;
MFloatArray Us, Vs;
UXMHEADER Header;
char* Character;
DWORD VertexID;
MMatrix World;
MFnMesh nMesh;
DWORD IndexID;
FILE *File;
DWORD ID;

World = Transform.inclusiveMatrix();
if(!MeshPath.hasFn(MFn::kMesh))
{
cout << "[ERROR] Object could not be loaded..." << endl;
goto UXMERROR;
}

Status = nMesh.setObject(MeshPath);
if(!Status)
{
cout << "[ERROR] Object could not be loaded..." << endl;
goto UXMERROR;
}

if((Mesh->m_MeshName = new char[1 + nMesh.name().length()]) == NULL){goto UXMERROR;}
strcpy(Mesh->m_MeshName, nMesh.name().asChar());
for(Character = Mesh->m_MeshName; *Character != '\0'; Character++){if(*Character == ' ' || *Character == '|'){*Character = '_';}}
if(MeshPath.isInstanced()){InstanceNumber = MeshPath.instanceNumber();}

Mesh->m_NumVertices = (DWORD)nMesh.numVertices();
if(Mesh->m_NumVertices > 0)
{
if((Mesh->m_Vertices = new FLOAT3[Mesh->m_NumVertices]) == NULL)
{
cout << "[ERROR] Not enough memory to store data.\n";
goto UXMERROR;
}
}else{
cout << "[ERROR] Object has no vertices..." << endl;
goto UXMERROR;
}

Mesh->m_NumNormals = (DWORD)nMesh.numNormals();
if(Mesh->m_NumNormals > 0)
{
if((Mesh->m_Normals = new FLOAT3[Mesh->m_NumNormals]) == NULL)
{
cout << "[ERROR] Not enough memory to store data.\n";
goto UXMERROR;
}
}

Mesh->m_NumUVs = (DWORD)nMesh.numUVs();
if(Mesh->m_NumUVs > 0)
{
if((Mesh->m_UVs = new FLOAT2[Mesh->m_NumUVs]) == NULL)
{
cout << "[ERROR] Not enough memory to store data.\n";
goto UXMERROR;
}
}

Status = nMesh.getConnectedShaders(InstanceNumber, Shaders, ShaderMap);
if(!Status)
{
cout << "[ERROR] No shaders found.\n";
goto UXMERROR;
}

Mesh->m_NumMaterials = Shaders.length();
if(Mesh->m_NumMaterials == 0){goto ExitMaterials;}
Mesh->m_Materials = new UXMMATERIAL[Mesh->m_NumMaterials];
if(Mesh->m_Materials == NULL)
{
cout << "[ERROR] Not enough memory to store data.\n";
goto UXMERROR;
}

for(ID = 0; ID < Mesh->m_NumMaterials; ID++)
{
MPlug mShader = MFnDependencyNode(Shaders[ID]).findPlug("surfaceShader", &Status);
if(!Status || mShader.isNull())
{
cout << "[WARNING] Using default material... No material specified\n";
continue;
}else{
MFnDependencyNode ShaderNode;
MPlugArray Plugs;

Status = ShaderNode.setObject(mShader.node());
if(Status)
{
strcpy(Mesh->m_Materials[ID].Name, ShaderNode.name().asChar());
for(Character = Mesh->m_Materials[ID].Name; *Character != '\0'; Character++){if(*Character == ' ' || *Character == '|'){*Character = '_';}}
}

mShader.connectedTo(Plugs, true, false, &Status);
if(!Status || Plugs.length() != 1)
{
cout << "[WARNING] Using default material... Error getting shader\n";
continue;
}

MColor Diffuse(Mesh->m_Materials[ID].Diffuse[0], Mesh->m_Materials[ID].Diffuse[1], Mesh->m_Materials[ID].Diffuse[2]);
MColor Specular(Mesh->m_Materials[ID].Specular[0], Mesh->m_Materials[ID].Specular[1], Mesh->m_Materials[ID].Specular[2]);
MColor Emissive(Mesh->m_Materials[ID].Emissive[0], Mesh->m_Materials[ID].Emissive[1], Mesh->m_Materials[ID].Emissive[2]);
MColor Transparency(Mesh->m_Materials[ID].Transparency, Mesh->m_Materials[ID].Transparency, Mesh->m_Materials[ID].Transparency);
float Coeff = 1.0f;

switch(Plugs[0].node().apiType())
{
case MFn::kLambert:
{
MFnLambertShader nShader(Plugs[0].node(), &Status);if(!Status){break;}
Coeff = nShader.diffuseCoeff();
Diffuse = nShader.color() * Coeff;
Emissive = nShader.incandescence() * nShader.glowIntensity();
Specular = Diffuse;
Transparency = nShader.transparency();
Mesh->m_Materials[ID].Shininess = 0.0f;
break;
}

case MFn::kBlinn:
{
MFnBlinnShader nShader(Plugs[0].node(), &Status);if(!Status){break;}
Coeff = nShader.diffuseCoeff();
Diffuse = nShader.color() * Coeff;
Emissive = nShader.incandescence() * nShader.glowIntensity();
Specular = nShader.specularColor();
Transparency = nShader.transparency();
Mesh->m_Materials[ID].Shininess = nShader.reflectivity();
break;
}

case MFn::kPhong:
{
MFnPhongShader nShader(Plugs[0].node(), &Status);if(!Status){break;}
Coeff = nShader.diffuseCoeff();
Diffuse = nShader.color() * Coeff;
Emissive = nShader.incandescence() * nShader.glowIntensity();
Specular = nShader.specularColor();
Transparency = nShader.transparency();
Mesh->m_Materials[ID].Shininess = nShader.reflectivity();
break;
}

default:
{
MFnDependencyNode nNode(Plugs[0].node(), &Status);if(!Status){break;}
MPlug pDiffuse = nNode.findPlug("outColor", &Status);
if(Status && pDiffuse.numElements() >= 3)
{
pDiffuse[0].getValue(Diffuse.r);
pDiffuse[1].getValue(Diffuse.g);
pDiffuse[2].getValue(Diffuse.b);
Specular = Diffuse;
}

MPlug pEmissive = nNode.findPlug("outGlowColor", &Status);
if(Status && pEmissive.numElements() >= 3)
{
pEmissive[0].getValue(Diffuse.r);
pEmissive[1].getValue(Diffuse.g);
pEmissive[2].getValue(Diffuse.b);
}

MPlug pTransparency = nNode.findPlug("outTransparency", &Status);
if(Status && pTransparency.numElements() >= 3)
{
pTransparency[0].getValue(Diffuse.r);
pTransparency[1].getValue(Diffuse.g);
pTransparency[2].getValue(Diffuse.b);
}
break;
}
}
Mesh->m_Materials[ID].Diffuse[0] = Diffuse.r;
Mesh->m_Materials[ID].Diffuse[1] = Diffuse.g;
Mesh->m_Materials[ID].Diffuse[2] = Diffuse.b;
Mesh->m_Materials[ID].Specular[0] = Specular.r;
Mesh->m_Materials[ID].Specular[1] = Specular.g;
Mesh->m_Materials[ID].Specular[2] = Specular.b;
Mesh->m_Materials[ID].Emissive[0] = Emissive.r;
Mesh->m_Materials[ID].Emissive[1] = Emissive.g;
Mesh->m_Materials[ID].Emissive[2] = Emissive.b;
Transparency *= Transparency;
Mesh->m_Materials[ID].Transparency = (float)sqrt((Transparency.r + Transparency.g + Transparency.b) / 3);

MPlug Color = MFnDependencyNode(Plugs[0].node()).findPlug("color", &Status); if(!Status){continue;}
MItDependencyGraph IT(Color, MFn::kFileTexture, MItDependencyGraph::kUpstream, MItDependencyGraph::kBreadthFirst, MItDependencyGraph::kNodeLevel, &Status); if(!Status){continue;}
IT.disablePruningOnFilter();
if(IT.isDone()){continue;}

MString TextureFile;
MFnDependencyNode(IT.thisNode()).findPlug("fileTextureName").getValue(TextureFile);
if(Mesh->m_Materials[ID].TextureFile == NULL)
{
cout << "[ERROR] Not enough memory to store data.\n";
goto UXMERROR;
}

MString FileTitle;
int TitlePosition = TextureFile.rindex('/');
if(TitlePosition == -1)
{
FileTitle = TextureFile;
}
else
{
FileTitle = TextureFile.substring(TitlePosition + 1, TitlePosition + 51);
}
strcpy(Mesh->m_Materials[ID].TextureFile, FileTitle.asChar());

Mesh->m_Materials[ID].Diffuse[0] = Coeff;
Mesh->m_Materials[ID].Diffuse[1] = Coeff;
Mesh->m_Materials[ID].Diffuse[2] = Coeff;
}
}
ExitMaterials:

if(Mesh->m_NumMaterials == 0 && Mesh->m_NumUVs < 0)
{
delete[] Mesh->m_UVs;
Mesh->m_UVs = NULL;
Mesh->m_NumUVs = 0;

Mesh->m_NumMaterials = 1;
if((Mesh->m_Materials = new UXMMATERIAL[Mesh->m_NumMaterials]))
{
cout << "[ERROR] Not enough memory to store data.\n";
goto UXMERROR;
}
}

Status = nMesh.getPoints(Vertices);
if(!Status)
{
cout << "[ERROR] Vertex data could not be read.\n";
goto UXMERROR;
}

if(Vertices.length() != Mesh->m_NumVertices)
{
cout << "[ERROR] Vertex count mismatch.\n";
goto UXMERROR;
}

for(ID = 0; ID < Mesh->m_NumVertices; ID++)
{
Mesh->m_Vertices[ID][0] = Vertices[ID][0];
Mesh->m_Vertices[ID][1] = Vertices[ID][1];
Mesh->m_Vertices[ID][2] = Vertices[ID][2];
}

if(Mesh->m_NumNormals == 0){goto ExitNormals;}
Status = nMesh.getNormals(Normals);
if(!Status)
{
cout << "[ERROR] Normal data could not be read.\n";
goto UXMERROR;
}

if(Normals.length() != Mesh->m_NumNormals)
{
cout << "[ERROR] Normal count mismatch.\n";
goto UXMERROR;
}

for(ID = 0; ID < Mesh->m_NumNormals; ID++)
{
Mesh->m_Normals[ID][0] = Normals[ID][0];
Mesh->m_Normals[ID][1] = Normals[ID][1];
Mesh->m_Normals[ID][2] = Normals[ID][2];
}
ExitNormals:

if(Mesh->m_NumUVs == 0){goto ExitUVs;}
Status = nMesh.getUVs(Us, Vs);
if(!Status)
{
cout << "[ERROR] UV data could not be read.\n";
goto UXMERROR;
}

if(Us.length() != Mesh->m_NumUVs || Vs.length() != Mesh->m_NumUVs)
{
cout << "[ERROR] UV count mismatch.\n";
goto UXMERROR;
}

for(ID = 0; ID < Mesh->m_NumUVs; ID++)
{
Mesh->m_UVs[ID][0] = Us[ID];
Mesh->m_UVs[ID][1] = Vs[ID];
}
ExitUVs:

Mesh->m_NumFaces = (DWORD)nMesh.numPolygons();
if(Mesh->m_NumFaces == 0)
{
cout << "[ERROR] Face data could not be read.\n";
goto UXMERROR;
}

if((Mesh->m_Faces = new UXMFACE[Mesh->m_NumFaces]) == NULL)
{
cout << "[ERROR] Not enough memory to store data.\n";
goto UXMERROR;
}

Status = POLYGON.reset(nMesh.object());
if(!Status)
{
cout << "[ERROR] Polygon iterator could not be initialized.\n";
goto UXMERROR;
}

for(ID = 0; !POLYGON.isDone(); ID++, POLYGON.next())
{
if(Mesh->m_NumMaterials == 1)
{
Mesh->m_Faces[ID].UVID = 0;
}else{
Mesh->m_Faces[ID].UVID = ShaderMap[ID];
}

if(POLYGON.polygonVertexCount() == 0){goto UXMERROR;}
Mesh->m_Faces[ID].NumIndices = POLYGON.polygonVertexCount();
if((Mesh->m_Faces[ID].Indices = new DWORD[Mesh->m_Faces[ID].NumIndices]) == NULL)
{
cout << "[ERROR] Not enough memory to store data.\n";
goto UXMERROR;
}

for(IndexID = 0; IndexID < Mesh->m_Faces[ID].NumIndices; IndexID++)
{
VertexID = POLYGON.vertexIndex(IndexID, &Status);
if(!Status)
{
cout << "[ERROR] Could not load face data.\n";
goto UXMERROR;
}
Mesh->m_Faces[ID].Indices[IndexID] = VertexID;
}
Mesh->m_NumIndices += Mesh->m_Faces[ID].NumIndices;
}

if((DWORD)nMesh.numPolygons() != ID)
{
cout << "[ERROR] Polygon count mismatch.\n";
goto UXMERROR;
}

Header.NumUVs = Mesh->m_NumUVs;
Header.NumFaces = Mesh->m_NumFaces;
Header.NumNormals = Mesh->m_NumNormals;
Header.NumIndices = Mesh->m_NumIndices;
Header.NumVertices = Mesh->m_NumVertices;
Header.NumMaterials = Mesh->m_NumMaterials;

File = fopen(Filename.asChar(), "w+b");
fwrite(CopyData, 49, 1, File);
fwrite(&Header, sizeof(UXMHEADER), 1, File);

for(ID = 0; ID < Mesh->m_NumVertices; ID++)
{
fwrite(&Mesh->m_Vertices[ID][0], sizeof(FLOAT3), 1, File);
fwrite(&Mesh->m_Vertices[ID][1], sizeof(FLOAT3), 1, File);
fwrite(&Mesh->m_Vertices[ID][2], sizeof(FLOAT3), 1, File);
}

for(ID = 0; ID < Mesh->m_NumNormals; ID++)
{
fwrite(&Mesh->m_Normals[ID][0], sizeof(FLOAT3), 1, File);
fwrite(&Mesh->m_Normals[ID][1], sizeof(FLOAT3), 1, File);
fwrite(&Mesh->m_Normals[ID][2], sizeof(FLOAT3), 1, File);
}

for(ID = 0; ID < Mesh->m_NumUVs; ID++)
{
fwrite(&Mesh->m_UVs[ID][0], sizeof(FLOAT2), 1, File);
fwrite(&Mesh->m_UVs[ID][1], sizeof(FLOAT2), 1, File);
}

for(ID = 0; ID < Mesh->m_NumFaces; ID++)
{
for(IndexID = 0; IndexID < Mesh->m_Faces[ID].NumIndices; IndexID++)
{
fwrite(&Mesh->m_Faces[ID].Indices[IndexID + 0], sizeof(DWORD), 1, File);
fwrite(&Mesh->m_Faces[ID].Indices[IndexID + 1], sizeof(DWORD), 1, File);
fwrite(&Mesh->m_Faces[ID].Indices[IndexID + 2], sizeof(DWORD), 1, File);
IndexID += 3;
}
}

for(ID = 0; ID < Mesh->m_NumMaterials; ID++)
{
fwrite(Mesh->m_Materials[ID].Name, 256, 1, File);
if(Mesh->m_Materials[ID].TextureFile == NULL)
{
fwrite(TexFile, 256, 1, File);
}else{
fwrite(Mesh->m_Materials[ID].TextureFile, 256, 1, File);
}

FLOAT ALPHA = 1.0f;
fwrite(&Mesh->m_Materials[ID].Ambient[0], sizeof(FLOAT3), 1, File);
fwrite(&Mesh->m_Materials[ID].Ambient[1], sizeof(FLOAT3), 1, File);
fwrite(&Mesh->m_Materials[ID].Ambient[2], sizeof(FLOAT3), 1, File); fwrite(&ALPHA, sizeof(FLOAT), 1, File);
fwrite(&Mesh->m_Materials[ID].Diffuse[0], sizeof(FLOAT3), 1, File);
fwrite(&Mesh->m_Materials[ID].Diffuse[1], sizeof(FLOAT3), 1, File);
fwrite(&Mesh->m_Materials[ID].Diffuse[2], sizeof(FLOAT3), 1, File); fwrite(&ALPHA, sizeof(FLOAT), 1, File);
fwrite(&Mesh->m_Materials[ID].Emissive[0], sizeof(FLOAT3), 1, File);
fwrite(&Mesh->m_Materials[ID].Emissive[1], sizeof(FLOAT3), 1, File);
fwrite(&Mesh->m_Materials[ID].Emissive[2], sizeof(FLOAT3), 1, File); fwrite(&ALPHA, sizeof(FLOAT), 1, File);
fwrite(&Mesh->m_Materials[ID].Specular[0], sizeof(FLOAT3), 1, File);
fwrite(&Mesh->m_Materials[ID].Specular[1], sizeof(FLOAT3), 1, File);
fwrite(&Mesh->m_Materials[ID].Specular[2], sizeof(FLOAT3), 1, File); fwrite(&ALPHA, sizeof(FLOAT), 1, File);
fwrite(&Mesh->m_Materials[ID].Shininess, sizeof(FLOAT), 1, File);
fwrite(&Mesh->m_Materials[ID].Transparency, sizeof(FLOAT), 1, File);
}
fclose(File);

cout << "\t" << Mesh->m_NumVertices << " Vertices\n"
<< "\t" << Mesh->m_NumNormals << " Normals\n"
<< "\t" << Mesh->m_NumUVs << " UVs\n"
<< "\t" << Mesh->m_NumMaterials << " Materials\n"
<< "\t" << Mesh->m_NumFaces << " Faces\n" << endl;

UXMERROR:
return 0;
}

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!