📄 moddata.cpp
字号:
// ModData.cpp: implementation of the CModData class.
//
//////////////////////////////////////////////////////////////////////
#include "Max.h"
#include "resource.h"
#include "istdplug.h"
#include "iparamb2.h"
#include "iparamm2.h"
#include <assert.h>
#include <io.h>
#include <commdlg.h>
#include "stdmat.h"
#include "ModData.h"
#include "SceneReader.h"
#include "MaxMesh.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CMesh::CMesh()
{
m_vertexnum = 0;
m_texcoordnum = 0;
m_submeshCount = 0;
}
CMesh::~CMesh()
{
}
BOOL CMesh::GenerateFromScene(IScene *pScene, Interface *itr, BOOL bExportSelected)
{
ReleaseData();
CSceneReader scnReader(pScene, itr);
CMaxMesh maxMesh;
scnReader.SetMaxMesh(&maxMesh);
scnReader.ParseScene(bExportSelected);
maxMesh.ConvertToOurMesh(this);
// maxMesh.ExportMaxMesh("Test.glmod");
return TRUE;
}
void writeshort(short i,ofstream &fout)
{
unsigned char a;
a = i&0xff;
fout.put(a);
a = i >> 8;
fout.put(a);
}
void writeString(string str,ofstream &fout)
{
fout.put(str.length());
for (int i=0; i<str.length(); i++)
fout.put(str.at(i));
}
Vertex TransformVertex(const Matrix3 &mat, const Vertex & ver)
{
Vertex re;
Point3 temppoint3;
temppoint3.x = ver.x;
temppoint3.y = ver.y;
temppoint3.z = ver.z;
temppoint3 = mat.PointTransform(temppoint3);
re.x = temppoint3.x;
re.y = temppoint3.y;
re.z = temppoint3.z;
return re;
}
BOOL CMesh::SaveToFile(const char *fileName, ExportOptions *pOptions)
{
ofstream fout;
int i, j;
char flag = 0;//flag for the figure attribute
if (m_ptexcoordlist.size() != -1)
flag |= 0x80;// if have the texture
if(pOptions->bHaveVertexNormal)
flag |= 0x20;// we have the normal
if(pOptions->bHaveAnimation)
flag |= 0x10;// we have the animation
if(pOptions->iAnimationType == VERTEX_ANIMATION)
flag |= 0x01;// we USE the VERTEX animation
if(pOptions->iMaxBoneCount == MAX_TWO_BONES)
flag |= 0x02;// we have the Maximam TWO BONES for one vertex to do animation.
if(pOptions->unit == UNIT_DIV16)
flag |= 0x04;// we have the Maximam TWO BONES for one vertex to do animation.
//generate bonding box for every submesh per frame
BBox box;
vector<Vertex> tempList;
int l, m;
Point3 temppoint3;
if (!pOptions->bHaveAnimation) //static mesh
{
m_FrameCount = 0;
for(j=0; j<m_pSubMeshs.size(); j++)
{
box.vmin = m_pvertexlist[m_pSubMeshs[j].m_pfacelist[0].ver1];
box.vmax = box.vmin;
for (m=0; m<m_pSubMeshs[j].m_pfacelist.size(); m++)
{
box.vmin = Vertex::VMin(m_pvertexlist[m_pSubMeshs[j].m_pfacelist[m].ver1], box.vmin);
box.vmin = Vertex::VMin(m_pvertexlist[m_pSubMeshs[j].m_pfacelist[m].ver2], box.vmin);
box.vmin = Vertex::VMin(m_pvertexlist[m_pSubMeshs[j].m_pfacelist[m].ver3], box.vmin);
box.vmax = Vertex::VMax(m_pvertexlist[m_pSubMeshs[j].m_pfacelist[m].ver1], box.vmax);
box.vmax = Vertex::VMax(m_pvertexlist[m_pSubMeshs[j].m_pfacelist[m].ver2], box.vmax);
box.vmax = Vertex::VMax(m_pvertexlist[m_pSubMeshs[j].m_pfacelist[m].ver3], box.vmax);
}
if (pOptions->unit == UNIT_NORMAL)
{
box.vmax.x /= 16;
box.vmax.y /= 16;
box.vmax.z /= 16;
box.vmin.x /= 16;
box.vmin.y /= 16;
box.vmin.z /= 16;
}
m_pSubMeshs[j].bbox.push_back(box);
}
}
else
{
for (i=0; i<m_FrameCount; i++)
{ //transform use bones
tempList.clear();
GetFrameVertex(i, tempList, flag);
for(j=0; j<m_pSubMeshs.size(); j++)
{
box.vmin = tempList[m_pSubMeshs[j].m_pfacelist[0].ver1];
box.vmax = box.vmin;
for (m=0; m<m_pSubMeshs[j].m_pfacelist.size(); m++)
{
box.vmin = Vertex::VMin(tempList[m_pSubMeshs[j].m_pfacelist[m].ver1], box.vmin);
box.vmin = Vertex::VMin(tempList[m_pSubMeshs[j].m_pfacelist[m].ver2], box.vmin);
box.vmin = Vertex::VMin(tempList[m_pSubMeshs[j].m_pfacelist[m].ver3], box.vmin);
box.vmax = Vertex::VMax(tempList[m_pSubMeshs[j].m_pfacelist[m].ver1], box.vmax);
box.vmax = Vertex::VMax(tempList[m_pSubMeshs[j].m_pfacelist[m].ver2], box.vmax);
box.vmax = Vertex::VMax(tempList[m_pSubMeshs[j].m_pfacelist[m].ver3], box.vmax);
}
if (pOptions->unit == UNIT_NORMAL)
{
box.vmax.x /= 16;
box.vmax.y /= 16;
box.vmax.z /= 16;
box.vmin.x /= 16;
box.vmin.y /= 16;
box.vmin.z /= 16;
}
m_pSubMeshs[j].bbox.push_back(box);
}
}
}
if (pOptions->format == 0)//binary
{
fout.open(fileName, ios::binary);
fout.put(flag); //flag;
//file head: vertex count, texture coordinate count, submesh count
writeshort(m_pvertexlist.size(),fout);//pnt
writeshort(m_ptexcoordlist.size(),fout);
writeshort(m_pSubMeshs.size(),fout);
for(i=0;i<m_pvertexlist.size();i++)
{
if (pOptions->unit == UNIT_NORMAL)
{
writeshort(m_pvertexlist[i].x/16,fout);
writeshort(m_pvertexlist[i].y/16,fout);
writeshort(m_pvertexlist[i].z/16,fout);
}
else
{
writeshort(m_pvertexlist[i].x,fout);
writeshort(m_pvertexlist[i].y,fout);
writeshort(m_pvertexlist[i].z,fout);
}
if (pOptions->bHaveVertexNormal)
{
writeshort(m_pvertexlist[i].normal_x,fout);
writeshort(m_pvertexlist[i].normal_y,fout);
writeshort(m_pvertexlist[i].normal_z,fout);
}
}
for(i=0; i<m_ptexcoordlist.size(); i++)
{
writeshort(m_ptexcoordlist[i].u,fout);
writeshort(m_ptexcoordlist[i].v,fout);
}
for(j=0;j<m_pSubMeshs.size(); j++)
{
//write material info: texture name;
writeString(m_pSubMeshs[j].material.texFileName,fout);
writeshort(m_pSubMeshs[j].m_pfacelist.size(), fout);
for(i=0;i<m_pSubMeshs[j].m_pfacelist.size();i++)
{
writeshort(m_pSubMeshs[j].m_pfacelist[i].ver1,fout);
writeshort(m_pSubMeshs[j].m_pfacelist[i].ver2,fout);
writeshort(m_pSubMeshs[j].m_pfacelist[i].ver3,fout);
/* writeshort(m_pSubMeshs[j].m_pfacelist[i].nx,fout);
writeshort(m_pSubMeshs[j].m_pfacelist[i].ny,fout);
writeshort(m_pSubMeshs[j].m_pfacelist[i].nz,fout);*/
if (m_ptexcoordlist.size()>0)
{
writeshort(m_pSubMeshs[j].m_pfacelist[i].tex1,fout);
writeshort(m_pSubMeshs[j].m_pfacelist[i].tex2,fout);
writeshort(m_pSubMeshs[j].m_pfacelist[i].tex3,fout);
}
}
}
//EXPORT BONE DATA: frame count BONE COUNT, bone matrix data for every key frame
if (pOptions->bHaveAnimation)
{
writeshort(m_FrameCount, fout);
writeshort(m_Bones.size(), fout);
if (pOptions->iMaxBoneCount == MAX_TWO_BONES)
{
//export one bone vertex and two bone vertex
writeshort(m_oneBoneVertex.size(), fout);
writeshort(m_twoBoneVertex.size(), fout);
for (j=0; j<m_oneBoneVertex.size(); j++)
{
writeshort(m_oneBoneVertex[j].vertexIndex, fout);
fout.put(m_oneBoneVertex[j].boneIndex);
}
for (j=0; j<m_twoBoneVertex.size(); j++)
{
writeshort(m_twoBoneVertex[j].vertexIndex, fout);
fout.put(m_twoBoneVertex[j].boneIndex1);
fout.put(m_twoBoneVertex[j].boneWeight1);
fout.put(m_twoBoneVertex[j].boneIndex2);
fout.put(m_twoBoneVertex[j].boneWeight2);
}
}
Matrix3 mat;
for (i=0; i<m_Bones.size(); i++)
{
if (pOptions->iMaxBoneCount == MAX_ONE_BONE)
{
//export contorl vertics
writeshort(m_Bones[i].vertexIndics.size(), fout);
for (j=0; j<m_Bones[i].vertexIndics.size(); j++)
{
writeshort(m_Bones[i].vertexIndics[j], fout);
}
}
//export tranformation matrix
for (j=0; j<m_FrameCount; j++)
{
mat = m_Bones[i].trans[j];
int m;
Point3 point3;
for (m=0; m<4; m++)
{
const Point3 point3 = mat.GetRow(m);
if (pOptions->unit == UNIT_DIV16)
{
writeshort(short(point3.x*(m==3?1:1024)), fout);
writeshort(short(point3.y*(m==3?1:1024)), fout);
writeshort(short(point3.z*(m==3?1:1024)), fout);
}
else
{
writeshort(short((m==3?point3.x/16:point3.x*1024)), fout);
writeshort(short((m==3?point3.y/16:point3.y*1024)), fout);
writeshort(short((m==3?point3.z/16:point3.z*1024)), fout);
}
}
}
}
}
//write bounding box info
for(j=0;j<m_pSubMeshs.size(); j++)
{
for (l=0; l<((m_FrameCount==0)?1:m_FrameCount); l++)
{
writeshort(m_pSubMeshs[j].bbox[l].vmin.x, fout);
writeshort(m_pSubMeshs[j].bbox[l].vmin.y, fout);
writeshort(m_pSubMeshs[j].bbox[l].vmin.z, fout);
writeshort(m_pSubMeshs[j].bbox[l].vmax.x, fout);
writeshort(m_pSubMeshs[j].bbox[l].vmax.y, fout);
writeshort(m_pSubMeshs[j].bbox[l].vmax.z, fout);
}
}
}
else
{
fout.open(fileName);
fout << "vertex count: "<<m_pvertexlist.size()<<"\n";
for(i=0;i<m_pvertexlist.size();i++)
{
if (pOptions->unit == UNIT_NORMAL)
{
fout << m_pvertexlist[i].x/16<< ","<<m_pvertexlist[i].y/16<<","<<m_pvertexlist[i].z/16<<"\n";
}
else
{
fout << m_pvertexlist[i].x<< ","<<m_pvertexlist[i].y <<","<<m_pvertexlist[i].z<<"\n";
}
if (pOptions->bHaveVertexNormal)
{
fout << "n:"<<m_pvertexlist[i].normal_x<< ","<<m_pvertexlist[i].normal_y
<<","<<m_pvertexlist[i].normal_z<<"\n";
}
}
fout << "texcoord count: "<<m_ptexcoordlist.size()<<"\n";
for(i=0; i<m_ptexcoordlist.size(); i++)
{
fout << m_ptexcoordlist[i].u<< ","<< m_ptexcoordlist[i].v<< "\n";
}
fout << "submesh count: "<<m_pSubMeshs.size()<<"\n";
for(j=0;j<m_pSubMeshs.size(); j++)
{
//write material info: texture name;
fout <<"texture Name: "<<m_pSubMeshs[j].material.texFileName<<"\n";
fout << "face count: "<<m_pSubMeshs[j].m_pfacelist.size()<<"\n";
for(i=0;i<m_pSubMeshs[j].m_pfacelist.size();i++)
{
fout << m_pSubMeshs[j].m_pfacelist[i].ver1<< ","<<m_pSubMeshs[j].m_pfacelist[i].ver2
<<","<<m_pSubMeshs[j].m_pfacelist[i].ver3<< ",";
if (m_ptexcoordlist.size()>0)
fout<<m_pSubMeshs[j].m_pfacelist[i].tex1<< ","
<<m_pSubMeshs[j].m_pfacelist[i].tex2
<<","<<m_pSubMeshs[j].m_pfacelist[i].tex3<<"\n";
}
}
if (pOptions->bHaveAnimation)
{
fout<<"Frame count: "<<m_FrameCount<<"\n";
fout<<"Bones count: "<<m_Bones.size()<<"\n";
Matrix3 mat;
for (i=0; i<m_Bones.size(); i++)
{
//export contorl vertics
fout<<"Bone "<<m_Bones[i].name<<" Vertex count:" <<m_Bones[i].vertexIndics.size()<<"\n";
fout<<"Vertics:";
for (j=0; j<m_Bones[i].vertexIndics.size(); j++)
{
fout<<m_Bones[i].vertexIndics[j]<<", ";
}
fout<<"\n";
fout<<"Matrix:";
//export tranformation matrix
for (j=0; j<m_FrameCount; j++)
{
mat = m_Bones[i].trans[j];
int m;
Point3 point3;
for (m=0; m<4; m++)
{
const Point3 point3 = mat.GetRow(m);
if (pOptions->unit == UNIT_NORMAL)
{
fout<<short(point3.x*(m==3?1:1024))<<", ";
fout<<short(point3.y*(m==3?1:1024))<<", ";
fout<<short(point3.z*(m==3?1:1024))<<", ";
}
else
{
fout<<short(m==3?point3.x/16:point3.x*1024)<<", ";
fout<<short(m==3?point3.y/16:point3.y*1024)<<", ";
fout<<short(m==3?point3.z/16:point3.z*1024)<<", ";
}
}
fout<<"\n";
}
}
}
}
return TRUE;
}
void CMesh::ReleaseData()
{
m_pvertexlist.clear();
m_vertexnum = 0;
m_ptexcoordlist.clear();
m_texcoordnum = 0;
for (int i=0; i<m_submeshCount; i++)
{
m_pSubMeshs[i].m_pfacelist.clear();
}
m_pSubMeshs.clear();
m_submeshCount = 0;
}
void CMesh::GetFrameVertex(int i, vector<Vertex> &tempList, int flag)
{
Vertex temp1, temp2;
float weight1, weight2;
int j;
for (j=0; j<m_pvertexlist.size(); j++)
{
tempList.push_back(m_pvertexlist[j]);
}
if ((flag&0x02) != 0) //two bones
{
for (j=0; j<m_oneBoneVertex.size(); j++)
{
tempList[m_oneBoneVertex[j].vertexIndex] = TransformVertex(m_Bones[m_oneBoneVertex[j].boneIndex].trans[i],
m_pvertexlist[m_oneBoneVertex[j].vertexIndex]);
}
for (j=0; j<m_twoBoneVertex.size(); j++)
{
temp1 = TransformVertex(m_Bones[m_twoBoneVertex[j].boneIndex1].trans[i],
m_pvertexlist[m_twoBoneVertex[j].vertexIndex]);
temp2 = TransformVertex(m_Bones[m_twoBoneVertex[j].boneIndex2].trans[i],
m_pvertexlist[m_twoBoneVertex[j].vertexIndex]);
weight1 = m_twoBoneVertex[j].boneWeight1;
weight2 = m_twoBoneVertex[j].boneWeight2;
tempList[m_twoBoneVertex[j].vertexIndex].x = (weight1*temp1.x + weight2*temp2.x)/128.0f;
tempList[m_twoBoneVertex[j].vertexIndex].y = (weight1*temp1.y + weight2*temp2.y)/128.0f;
tempList[m_twoBoneVertex[j].vertexIndex].z = (weight1*temp1.z + weight2*temp2.z)/128.0f;
}
}
else // one bone
{
//remove used bones
vector<Bone>::iterator bitr = m_Bones.begin();
while (bitr != m_Bones.end())
{
if (bitr->vertexIndics.size() == 0)
bitr = m_Bones.erase(bitr);
else
bitr++;
}
for (j=0; j<m_Bones.size(); j++)
{
for (int l=0; l<m_Bones[j].vertexIndics.size(); l++)
{
tempList[m_Bones[j].vertexIndics[l]] = TransformVertex(m_Bones[j].trans[i],
m_pvertexlist[m_Bones[j].vertexIndics[l]]);
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -