* Read 1.12.x M2 files

NOTE: Reading any other version of M2 is broken right now - needs readding later
This commit is contained in:
shlainn 2011-09-16 22:41:22 +02:00
parent 3845d3b51c
commit f8adc3311a
2 changed files with 360 additions and 226 deletions

View File

@ -1,3 +1,4 @@
// #define _DEBUG 1
#include <iostream> #include <iostream>
#include "MemoryDataHolder.h" #include "MemoryDataHolder.h"
#include "MemoryInterface.h" #include "MemoryInterface.h"
@ -51,187 +52,290 @@ IAnimatedMesh* CM2MeshFileLoader::createMesh(io::IReadFile* file)
return AnimatedMesh; return AnimatedMesh;
} }
void CM2MeshFileLoader::ReadVertices()
{
//Vertices. Global data
if(!M2MVertices.empty())
M2MVertices.clear();
ModelVertex tempM2MVert;
f32 tempYZ;
MeshFile->seek(header.ofsVertices);
for(u32 i =0;i<header.nVertices;i++)
{
MeshFile->read(&tempM2MVert,sizeof(ModelVertex));
tempYZ = tempM2MVert.pos.Y;
tempM2MVert.pos.Y=tempM2MVert.pos.Z;
tempM2MVert.pos.Z=tempYZ;
tempYZ = tempM2MVert.normal.Y;
tempM2MVert.normal.Y=tempM2MVert.normal.Z;
tempM2MVert.normal.Z=tempYZ;
M2MVertices.push_back(tempM2MVert);
}
DEBUG(logdebug("Read %u/%u Vertices",M2MVertices.size(),header.nVertices));
}
void CM2MeshFileLoader::ReadViewData(io::IReadFile* file)
{
//Vertex indices of a specific view.Local to View 0
if(M2MIndices.size()>0)
M2MIndices.clear();
u16 tempM2Index;
file->seek(currentView.ofsIndex);
for(u32 i =0;i<currentView.nIndex;i++)
{
file->read(&tempM2Index,sizeof(u16));
M2MIndices.push_back(tempM2Index);
}
DEBUG(logdebug("Read %u/%u Indices",M2MIndices.size(),currentView.nIndex));
//Triangles. Data Points point to the Vertex Indices, not the vertices themself. 3 Points = 1 Triangle, Local to View 0
if(M2MTriangles.size()>0)
M2MTriangles.clear();
u16 tempM2Triangle;
file->seek(currentView.ofsTris);
for(u32 i =0;i<currentView.nTris;i++)
{
file->read(&tempM2Triangle,sizeof(u16));
M2MTriangles.push_back(tempM2Triangle);
}
DEBUG(logdebug("Read %u/%u Triangles",M2MTriangles.size(),currentView.nTris));
//Submeshes, Local to View 0
if(M2MSubmeshes.size()>0)
M2MSubmeshes.clear();
ModelViewSubmesh tempM2Submesh;
file->seek(currentView.ofsSub);
for(u32 i =0;i<currentView.nSub;i++)
{
file->read(&tempM2Submesh,sizeof(ModelViewSubmesh)-(header.version==0x100?16:0));
M2MSubmeshes.push_back(tempM2Submesh);
// std::cout<< "Submesh " <<i<<" ID "<<tempM2Submesh.meshpartId<<" starts at V/T "<<tempM2Submesh.ofsVertex<<"/"<<tempM2Submesh.ofsTris<<" and has "<<tempM2Submesh.nVertex<<"/"<<tempM2Submesh.nTris<<" V/T\n";
}
DEBUG(logdebug("Read %u/%u Submeshes",M2MSubmeshes.size(),currentView.nSub));
//Texture units. Local to view 0
TextureUnit tempM2TexUnit;
if(!M2MTextureUnit.empty())
{
M2MTextureUnit.clear();
}
file->seek(currentView.ofsTex);
for(u32 i=0;i<currentView.nTex;i++)
{
file->read(&tempM2TexUnit,sizeof(TextureUnit));
M2MTextureUnit.push_back(tempM2TexUnit);
DEBUG(logdebug(" TexUnit %u: Submesh: %u %u Render Flag: %u TextureUnitNumber: %u %u TTU: %u",i,tempM2TexUnit.submeshIndex1,tempM2TexUnit.submeshIndex2, tempM2TexUnit.renderFlagsIndex, tempM2TexUnit.TextureUnitNumber, tempM2TexUnit.TextureUnitNumber2 ,tempM2TexUnit.textureIndex));
}
DEBUG(logdebug("Read %u Texture Unit entries for View 0",M2MTextureUnit.size()));
}
void CM2MeshFileLoader::ReadTextureDefinitions()
{
//Texture Lookup table. This is global data
u16 tempM2TexLookup;
if(!M2MTextureLookup.empty())
{
M2MTextureLookup.clear();
}
MeshFile->seek(header.ofsTexLookup);
for(u32 i=0;i<header.nTexLookup;i++)
{
MeshFile->read(&tempM2TexLookup,sizeof(u16));
M2MTextureLookup.push_back(tempM2TexLookup);
DEBUG(logdebug("Texture %u Type %u",i,tempM2TexLookup));
}
DEBUG(logdebug("Read %u Texture lookup entries",M2MTextureLookup.size()));
//Texture Definitions table. This is global data
TextureDefinition tempM2TexDef;
if(!M2MTextureDef.empty())
{
M2MTextureDef.clear();
}
MeshFile->seek(header.ofsTextures);
for(u32 i=0;i<header.nTextures;i++)
{
MeshFile->read(&tempM2TexDef,sizeof(TextureDefinition));
M2MTextureDef.push_back(tempM2TexDef);
DEBUG(logdebug("Texture %u Type %u",i,tempM2TexDef.texType));
}
DEBUG(logdebug("Read %u Texture Definition entries",M2MTextureDef.size()));
//Render Flags table. This is global data
RenderFlags tempM2RF;
if(!M2MRenderFlags.empty())
{
M2MRenderFlags.clear();
}
MeshFile->seek(header.ofsTexFlags);
for(u32 i=0;i<header.nTexFlags;i++)
{
MeshFile->read(&tempM2RF,sizeof(RenderFlags));
M2MRenderFlags.push_back(tempM2RF);
DEBUG(logdebug("Flag %u: (%u, %u)",i,tempM2RF.blending,tempM2RF.flags));
}
DEBUG(logdebug("Read %u Renderflags",M2MRenderFlags.size()));
if(!M2MTextureFiles.empty())
M2MTextureFiles.clear();
std::string tempTexFileName="";
M2MTextureFiles.reallocate(M2MTextureDef.size());
for(u32 i=0; i<M2MTextureDef.size(); i++)
{
tempTexFileName.resize(M2MTextureDef[i].texFileLen + 1);
MeshFile->seek(M2MTextureDef[i].texFileOfs);
MeshFile->read((void*)tempTexFileName.data(),M2MTextureDef[i].texFileLen);
M2MTextureFiles.push_back("");
M2MTextureFiles[i]=tempTexFileName.c_str();
DEBUG(logdebug("Texture: %u %u (%s/%s) @ %u(%u)",i,M2MTextureFiles.size(),M2MTextureFiles[i].c_str(),tempTexFileName.c_str(),M2MTextureDef[i].texFileOfs,M2MTextureDef[i].texFileLen));
}
}
bool CM2MeshFileLoader::load() bool CM2MeshFileLoader::load()
{ {
DEBUG(logdebug("Trying to open file %s",MeshFile->getFileName())); DEBUG(logdebug("Trying to open file %s",MeshFile->getFileName()));
MeshFile->read(&header,sizeof(ModelHeader)); MeshFile->read(&header,20);
if (header.version[0] != 8 || header.version[1] != 1 || header.version[2] != 0 || header.version[3] != 0) { switch(header.version)
logerror("M2: [%s] Wrong header! File version doesn't match or file is not a M2 file.",MeshFile->getFileName()); {
return 0; case 0x100:
} {
else DEBUG(logdebug("M2 Version 1.00"));
{ MeshFile->read((u8*)&header+20,sizeof(ModelHeader)-20);
DEBUG(logdebug("header okay")); ReadVertices();
} MeshFile->seek(header.ofsViews);
//Name -> not very important I think, but save it nontheless; MeshFile->read(&currentView,sizeof(ModelView));
//M2MeshName.clear(); ReadViewData(MeshFile);
//M2MeshName.reserve(header.nameLength); ReadTextureDefinitions();
//file->seek(header.nameOfs); break;
//file->read(&M2MeshName[0],header.nameLength); }
//std::cout << "Read name:"<<M2MeshName.c_str()<<"Size: "<< M2MeshName.size() <<"|"<<M2MeshName[0]<< "\n"; case 0x104:
//logger->log("Mesh Name",M2MeshName.c_str(),ELL_INFORMATION); {
//Now we load all kinds of data from the file DEBUG(logdebug("M2 Version 1.04"));
return 0;
break;
}
case 0x108:
{
DEBUG(logdebug("M2 Version 1.08"));
return 0;
break;
}
default:
{
logerror("M2: [%s] Wrong header %0X! File version doesn't match or file is not a M2 file.",MeshFile->getFileName(),header.version);
return 0;
}
}
//Vertices. Global data //Vertices. Global data
if(!M2MVertices.empty()) // if(!M2MVertices.empty())
M2MVertices.clear(); // M2MVertices.clear();
//
ModelVertex tempM2MVert; // ModelVertex tempM2MVert;
f32 tempYZ; // f32 tempYZ;
MeshFile->seek(header.ofsVertices); // MeshFile->seek(header.ofsVertices);
//
for(u32 i =0;i<header.nVertices;i++) // for(u32 i =0;i<header.nVertices;i++)
{ // {
MeshFile->read(&tempM2MVert,sizeof(ModelVertex)); // MeshFile->read(&tempM2MVert,sizeof(ModelVertex));
tempYZ = tempM2MVert.pos.Y; // tempYZ = tempM2MVert.pos.Y;
tempM2MVert.pos.Y=tempM2MVert.pos.Z; // tempM2MVert.pos.Y=tempM2MVert.pos.Z;
tempM2MVert.pos.Z=tempYZ; // tempM2MVert.pos.Z=tempYZ;
tempYZ = tempM2MVert.normal.Y; // tempYZ = tempM2MVert.normal.Y;
tempM2MVert.normal.Y=tempM2MVert.normal.Z; // tempM2MVert.normal.Y=tempM2MVert.normal.Z;
tempM2MVert.normal.Z=tempYZ; // tempM2MVert.normal.Z=tempYZ;
//
M2MVertices.push_back(tempM2MVert); // M2MVertices.push_back(tempM2MVert);
} // }
DEBUG(logdebug("Read %u/%u Vertices",M2MVertices.size(),header.nVertices)); // DEBUG(logdebug("Read %u/%u Vertices",M2MVertices.size(),header.nVertices));
//Views (skins) == Sets of vertices. Usage yet unknown. Global data //Views (skins) == Sets of vertices. Usage yet unknown. Global data
std::string SkinName = MeshFile->getFileName(); // std::string SkinName = MeshFile->getFileName();
SkinName = SkinName.substr(0, SkinName.length()-3) + "00.skin"; // FIX ME (and stuffextract) ! as we need more skins // SkinName = SkinName.substr(0, SkinName.length()-3) + "00.skin"; // FIX ME (and stuffextract) ! as we need more skins
io::IReadFile* SkinFile = io::IrrCreateIReadFileBasic(Device, SkinName.c_str()); // io::IReadFile* SkinFile = io::IrrCreateIReadFileBasic(Device, SkinName.c_str());
if (!SkinFile) // if (!SkinFile)
{ // {
logerror("Error! Skin file not found: %s", SkinName.c_str()); // logerror("Error! Skin file not found: %s", SkinName.c_str());
return 0; // return 0;
} // }
//
ModelView currentView; // SkinFile->read(&currentView, sizeof(ModelView));
SkinFile->read(&currentView, sizeof(ModelView)); //
// //std::cout << "Skins "<<header.nViews<<" (views)\n";
//std::cout << "Skins "<<header.nViews<<" (views)\n"; //
// DEBUG(logdebug("Using View 0 for all further operations"));
DEBUG(logdebug("Using View 0 for all further operations")); // DEBUG(logdebug("This View has %u Submeshes",currentView.nSub));
DEBUG(logdebug("This View has %u Submeshes",currentView.nSub)); //
// //Vertex indices of a specific view.Local to View 0
//Vertex indices of a specific view.Local to View 0 // if(M2MIndices.size()>0)
if(M2MIndices.size()>0) // M2MIndices.clear();
M2MIndices.clear(); //
// u16 tempM2Index;
u16 tempM2Index; // SkinFile->seek(currentView.ofsIndex);
SkinFile->seek(currentView.ofsIndex); // for(u32 i =0;i<currentView.nIndex;i++)
for(u32 i =0;i<currentView.nIndex;i++) // {
{ // SkinFile->read(&tempM2Index,sizeof(u16));
SkinFile->read(&tempM2Index,sizeof(u16)); // M2MIndices.push_back(tempM2Index);
M2MIndices.push_back(tempM2Index); // }
} // DEBUG(logdebug("Read %u/%u Indices",M2MIndices.size(),currentView.nIndex));
DEBUG(logdebug("Read %u/%u Indices",M2MIndices.size(),currentView.nIndex)); //
//
// //Triangles. Data Points point to the Vertex Indices, not the vertices themself. 3 Points = 1 Triangle, Local to View 0
//Triangles. Data Points point to the Vertex Indices, not the vertices themself. 3 Points = 1 Triangle, Local to View 0 // if(M2MTriangles.size()>0)
if(M2MTriangles.size()>0) // M2MTriangles.clear();
M2MTriangles.clear(); //
// u16 tempM2Triangle;
u16 tempM2Triangle; // SkinFile->seek(currentView.ofsTris);
SkinFile->seek(currentView.ofsTris); // for(u32 i =0;i<currentView.nTris;i++)
for(u32 i =0;i<currentView.nTris;i++) // {
{ // SkinFile->read(&tempM2Triangle,sizeof(u16));
SkinFile->read(&tempM2Triangle,sizeof(u16)); // M2MTriangles.push_back(tempM2Triangle);
M2MTriangles.push_back(tempM2Triangle); // }
} // DEBUG(logdebug("Read %u/%u Triangles",M2MTriangles.size(),currentView.nTris));
DEBUG(logdebug("Read %u/%u Triangles",M2MTriangles.size(),currentView.nTris)); // //Submeshes, Local to View 0
//Submeshes, Local to View 0 // if(M2MSubmeshes.size()>0)
if(M2MSubmeshes.size()>0) // M2MSubmeshes.clear();
M2MSubmeshes.clear(); //
// ModelViewSubmesh tempM2Submesh;
ModelViewSubmesh tempM2Submesh; // SkinFile->seek(currentView.ofsSub);
SkinFile->seek(currentView.ofsSub); // for(u32 i =0;i<currentView.nSub;i++)
for(u32 i =0;i<currentView.nSub;i++) // {
{ // SkinFile->read(&tempM2Submesh,sizeof(ModelViewSubmesh));
SkinFile->read(&tempM2Submesh,sizeof(ModelViewSubmesh)); // M2MSubmeshes.push_back(tempM2Submesh);
M2MSubmeshes.push_back(tempM2Submesh); // // std::cout<< "Submesh " <<i<<" ID "<<tempM2Submesh.meshpartId<<" starts at V/T "<<tempM2Submesh.ofsVertex<<"/"<<tempM2Submesh.ofsTris<<" and has "<<tempM2Submesh.nVertex<<"/"<<tempM2Submesh.nTris<<" V/T\n";
// std::cout<< "Submesh " <<i<<" ID "<<tempM2Submesh.meshpartId<<" starts at V/T "<<tempM2Submesh.ofsVertex<<"/"<<tempM2Submesh.ofsTris<<" and has "<<tempM2Submesh.nVertex<<"/"<<tempM2Submesh.nTris<<" V/T\n"; // }
} // DEBUG(logdebug("Read %u/%u Submeshes",M2MSubmeshes.size(),currentView.nSub));
DEBUG(logdebug("Read %u/%u Submeshes",M2MSubmeshes.size(),currentView.nSub)); //
// //Texture units. Local to view 0
//Texture units. Local to view 0 // TextureUnit tempM2TexUnit;
TextureUnit tempM2TexUnit; // if(!M2MTextureUnit.empty())
if(!M2MTextureUnit.empty()) // {
{ // M2MTextureUnit.clear();
M2MTextureUnit.clear(); // }
} // SkinFile->seek(currentView.ofsTex);
SkinFile->seek(currentView.ofsTex); // for(u32 i=0;i<currentView.nTex;i++)
for(u32 i=0;i<currentView.nTex;i++) // {
{ // SkinFile->read(&tempM2TexUnit,sizeof(TextureUnit));
SkinFile->read(&tempM2TexUnit,sizeof(TextureUnit)); // M2MTextureUnit.push_back(tempM2TexUnit);
M2MTextureUnit.push_back(tempM2TexUnit); // DEBUG(logdebug(" TexUnit %u: Submesh: %u %u Render Flag: %u TextureUnitNumber: %u %u TTU: %u",i,tempM2TexUnit.submeshIndex1,tempM2TexUnit.submeshIndex2, tempM2TexUnit.renderFlagsIndex, tempM2TexUnit.TextureUnitNumber, tempM2TexUnit.TextureUnitNumber2 ,tempM2TexUnit.textureIndex));
DEBUG(logdebug(" TexUnit %u: Submesh: %u %u Render Flag: %u TextureUnitNumber: %u %u TTU: %u",i,tempM2TexUnit.submeshIndex1,tempM2TexUnit.submeshIndex2, tempM2TexUnit.renderFlagsIndex, tempM2TexUnit.TextureUnitNumber, tempM2TexUnit.TextureUnitNumber2 ,tempM2TexUnit.textureIndex)); // }
} // DEBUG(logdebug("Read %u Texture Unit entries for View 0",M2MTextureUnit.size()));
DEBUG(logdebug("Read %u Texture Unit entries for View 0",M2MTextureUnit.size())); //
//Texture Lookup table. This is global data
u16 tempM2TexLookup;
if(!M2MTextureLookup.empty())
{
M2MTextureLookup.clear();
}
MeshFile->seek(header.ofsTexLookup);
for(u32 i=0;i<header.nTexLookup;i++)
{
MeshFile->read(&tempM2TexLookup,sizeof(u16));
M2MTextureLookup.push_back(tempM2TexLookup);
DEBUG(logdebug("Texture %u Type %u\n",i,tempM2TexLookup));
}
DEBUG(logdebug("Read %u Texture lookup entries",M2MTextureLookup.size()));
//Texture Definitions table. This is global data
TextureDefinition tempM2TexDef;
if(!M2MTextureDef.empty())
{
M2MTextureDef.clear();
}
MeshFile->seek(header.ofsTextures);
for(u32 i=0;i<header.nTextures;i++)
{
MeshFile->read(&tempM2TexDef,sizeof(TextureDefinition));
M2MTextureDef.push_back(tempM2TexDef);
DEBUG(logdebug("Texture %u Type %u\n",i,tempM2TexDef.texType));
}
DEBUG(logdebug("Read %u Texture Definition entries",M2MTextureDef.size()));
//Render Flags table. This is global data
RenderFlags tempM2RF;
if(!M2MRenderFlags.empty())
{
M2MRenderFlags.clear();
}
MeshFile->seek(header.ofsTexFlags);
for(u32 i=0;i<header.nTexFlags;i++)
{
MeshFile->read(&tempM2RF,sizeof(RenderFlags));
M2MRenderFlags.push_back(tempM2RF);
DEBUG(logdebug("Flag %u: (%u, %u)",i,tempM2RF.blending,tempM2RF.flags));
}
DEBUG(logdebug("Read %u Renderflags",M2MRenderFlags.size()));
if(!M2MTextureFiles.empty())
M2MTextureFiles.clear();
std::string tempTexFileName="";
M2MTextureFiles.reallocate(M2MTextureDef.size());
for(u32 i=0; i<M2MTextureDef.size(); i++)
{
tempTexFileName.resize(M2MTextureDef[i].texFileLen + 1);
MeshFile->seek(M2MTextureDef[i].texFileOfs);
MeshFile->read((void*)tempTexFileName.data(),M2MTextureDef[i].texFileLen);
M2MTextureFiles.push_back("");
M2MTextureFiles[i]=tempTexFileName.c_str();
DEBUG(logdebug("Texture: %u %u (%s/%s) @ %u(%u)",i,M2MTextureFiles.size(),M2MTextureFiles[i].c_str(),tempTexFileName.c_str(),M2MTextureDef[i].texFileOfs,M2MTextureDef[i].texFileLen));
}
/////////////////////////////////////// ///////////////////////////////////////
// Animation related stuff // // Animation related stuff //
@ -440,6 +544,19 @@ if(M2MBones[i].scaling.header.nValues>0){
} }
*/ */
//std::cout<<AnimatedMesh->getAllJoints()[1]->Children.size()<<" Children\n"; //std::cout<<AnimatedMesh->getAllJoints()[1]->Children.size()<<" Children\n";
///////////////////////////
// EVERYTHING IS READ
///////////////////////////
//And M2MVertices are not usable like this. Thus we transform //And M2MVertices are not usable like this. Thus we transform
if(M2Vertices.size()>0) if(M2Vertices.size()>0)
@ -468,8 +585,8 @@ for(u32 i=0; i < currentView.nSub;i++)//
for(u32 j=M2MSubmeshes[i].ofsVertex;j<M2MSubmeshes[i].ofsVertex+M2MSubmeshes[i].nVertex;j++) for(u32 j=M2MSubmeshes[i].ofsVertex;j<M2MSubmeshes[i].ofsVertex+M2MSubmeshes[i].nVertex;j++)
{ {
MeshBuffer->Vertices_Standard.push_back(M2Vertices[j]); MeshBuffer->Vertices_Standard.push_back(M2Vertices[j]);
for(u32 k=0; k<4; k++) // for(u32 k=0; k<4; k++)
{ // {
//std::cout << (u32)M2MVertices[j].bones[k] << " "; //std::cout << (u32)M2MVertices[j].bones[k] << " ";
/* ANIMATION NEED FIX !!! /* ANIMATION NEED FIX !!!
if((M2MVertices[j].weights[k]/255.0f)>0.0f) if((M2MVertices[j].weights[k]/255.0f)>0.0f)
@ -481,7 +598,7 @@ for(u32 i=0; i < currentView.nSub;i++)//
} }
*/ */
//std::cout<<weight->buffer_id << " " << weight->vertex_id << " " << weight->strength <<"|"; //std::cout<<weight->buffer_id << " " << weight->vertex_id << " " << weight->strength <<"|";
} // }
// std::cout<<'\n'; // std::cout<<'\n';
} }
//std::cout << i << ": " << MeshBuffer->Vertices_Standard.size() <<" "<<M2MSubmeshes[i].ofsVertex<<" "<<M2MSubmeshes[i].nVertex<< "\n"; //std::cout << i << ": " << MeshBuffer->Vertices_Standard.size() <<" "<<M2MSubmeshes[i].ofsVertex<<" "<<M2MSubmeshes[i].nVertex<< "\n";
@ -491,10 +608,10 @@ for(u32 i=0; i < currentView.nSub;i++)//
//MeshBuffer->getMaterial().DiffuseColor.set(255,255-(u32)(255/(M2MSubmeshes.size()))*i,(u32)(255/(M2MSubmeshes.size()))*i,0); //MeshBuffer->getMaterial().DiffuseColor.set(255,255-(u32)(255/(M2MSubmeshes.size()))*i,(u32)(255/(M2MSubmeshes.size()))*i,0);
//MeshBuffer->getMaterial().DiffuseColor.set(255,(M2MSubmeshes[i].meshpartId==0?0:255),(M2MSubmeshes[i].meshpartId==0?255:0),0); //MeshBuffer->getMaterial().DiffuseColor.set(255,(M2MSubmeshes[i].meshpartId==0?0:255),(M2MSubmeshes[i].meshpartId==0?255:0),0);
for(u32 j=0;j<M2MTextureUnit.size();j++)//Loop through texture units for(u32 j=0;j<M2MTextureUnit.size();j++)//Loop through texture units
{ {
if(M2MTextureUnit[j].submeshIndex1==i && !M2MTextureFiles[M2MTextureLookup[M2MTextureUnit[j].textureIndex]].empty())//if a texture unit belongs to this submesh if(M2MTextureUnit[j].submeshIndex1==i && !M2MTextureFiles[M2MTextureLookup[M2MTextureUnit[j].textureIndex]].empty())//if a texture unit belongs to this submesh
{ {
// std::string TexName=Texdir.c_str(); // std::string TexName=Texdir.c_str();
// TexName+="/"; // TexName+="/";
// if(i<M2MTextureUnit.size()) // if(i<M2MTextureUnit.size())
// TexName+=M2MTextureFiles[M2MTextureLookup[M2MTextureUnit[j].textureIndex]].c_str(); // TexName+=M2MTextureFiles[M2MTextureLookup[M2MTextureUnit[j].textureIndex]].c_str();
@ -509,26 +626,33 @@ for(u32 i=0; i < currentView.nSub;i++)//
std::transform(TexName.begin(), TexName.end(), TexName.begin(), tolower);*/ std::transform(TexName.begin(), TexName.end(), TexName.begin(), tolower);*/
char buf[1000]; char buf[1000];
MemoryDataHolder::MakeTextureFilename(buf,M2MTextureFiles[M2MTextureLookup[M2MTextureUnit[j].textureIndex]].c_str()); MemoryDataHolder::MakeTextureFilename(buf,M2MTextureFiles[M2MTextureLookup[M2MTextureUnit[j].textureIndex]].c_str());
io::IReadFile* TexFile = io::IrrCreateIReadFileBasic(Device, buf); video::ITexture* tex = Device->getVideoDriver()->findTexture(buf);
// logdebug("Texture %s loading",M2MTextureFiles[M2MTextureLookup[M2MTextureUnit[j].textureIndex]].c_str()); if(!tex)
if (!TexFile)
{ {
logerror("CM2MeshFileLoader: Texture file not found: %s", buf); io::IReadFile* TexFile = io::IrrCreateIReadFileBasic(Device, buf);
continue; // logdebug("Texture %s loading",M2MTextureFiles[M2MTextureLookup[M2MTextureUnit[j].textureIndex]].c_str());
} if (!TexFile)
{
logerror("CM2MeshFileLoader: Texture file not found: %s", buf);
continue;
}
// logdebug("Texture %s loaded",M2MTextureFiles[M2MTextureLookup[M2MTextureUnit[j].textureIndex]].c_str()); // logdebug("Texture %s loaded",M2MTextureFiles[M2MTextureLookup[M2MTextureUnit[j].textureIndex]].c_str());
MeshBuffer->getMaterial().setTexture(M2MTextureUnit[j].TextureUnitNumber,Device->getVideoDriver()->getTexture(TexFile)); tex = Device->getVideoDriver()->getTexture(TexFile);
TexFile->drop();
}
MeshBuffer->getMaterial().setTexture(M2MTextureUnit[j].TextureUnitNumber,tex);
DEBUG(logdebug("Render Flags: %u %u",M2MRenderFlags[M2MTextureUnit[j].renderFlagsIndex].flags,M2MRenderFlags[M2MTextureUnit[j].renderFlagsIndex].blending)); DEBUG(logdebug("Render Flags: %u %u",M2MRenderFlags[M2MTextureUnit[j].renderFlagsIndex].flags,M2MRenderFlags[M2MTextureUnit[j].renderFlagsIndex].blending));
MeshBuffer->getMaterial().BackfaceCulling=(M2MRenderFlags[M2MTextureUnit[j].renderFlagsIndex].flags & 0x04)?false:true; MeshBuffer->getMaterial().BackfaceCulling=(M2MRenderFlags[M2MTextureUnit[j].renderFlagsIndex].flags & 0x04)?false:true;
if(M2MRenderFlags[M2MTextureUnit[j].renderFlagsIndex].blending==1) if(M2MRenderFlags[M2MTextureUnit[j].renderFlagsIndex].blending==1)
MeshBuffer->getMaterial().MaterialType=video::EMT_TRANSPARENT_ALPHA_CHANNEL; MeshBuffer->getMaterial().MaterialType=video::EMT_TRANSPARENT_ALPHA_CHANNEL;
}
} }
}
MeshBuffer->recalculateBoundingBox();
MeshBuffer->setHardwareMappingHint(EHM_STATIC);
//MeshBuffer->recalculateBoundingBox();
// Mesh->addMeshBuffer(MeshBuffer); // Mesh->addMeshBuffer(MeshBuffer);
// Mesh->recalculateBoundingBox(); // Mesh->recalculateBoundingBox();
//MeshBuffer->drop(); //MeshBuffer->drop();
@ -546,7 +670,7 @@ Device->getSceneManager()->getMeshManipulator()->flipSurfaces(AnimatedMesh); //F
AnimatedMesh->setInterpolationMode(scene::EIM_LINEAR); AnimatedMesh->setInterpolationMode(scene::EIM_LINEAR);
SkinFile->drop(); // SkinFile->drop();
M2MTriangles.clear(); M2MTriangles.clear();
M2Vertices.clear(); M2Vertices.clear();
M2Indices.clear(); M2Indices.clear();

View File

@ -11,80 +11,86 @@ namespace scene
{ {
struct ModelHeader { struct ModelHeader {
c8 id[4]; c8 id[4]; //0x00
u8 version[4]; u32 version;
u32 nameLength; u32 nameLength;
u32 nameOfs; u32 nameOfs;
u32 type; u32 type; //0x10
//Anim Block @ 0x14
u32 nGlobalSequences; u32 nGlobalSequences;
u32 ofsGlobalSequences; u32 ofsGlobalSequences;
u32 nAnimations; u32 nAnimations;
u32 ofsAnimations; u32 ofsAnimations; //0x20
u32 nC; u32 nAnimationLookup;
u32 ofsC; u32 ofsAnimationLookup;
u32 nD;
u32 ofsD; //0x30
u32 nBones; u32 nBones;
u32 ofsBones; u32 ofsBones;
u32 nF; u32 nSkelBoneLookup;
u32 ofsF; u32 ofsSkelBoneLookup; //0x40
u32 nVertices; u32 nVertices; //0x44
u32 ofsVertices; u32 ofsVertices;
u32 nViews; // number of skins ? u32 nViews; // number of skins ?
u32 ofsViews; //0x50
u32 nColors; u32 nColors;
u32 ofsColors; u32 ofsColors;
u32 nTextures; u32 nTextures;
u32 ofsTextures; u32 ofsTextures; //0x60
u32 nTransparency; // H u32 nTransparency;
u32 ofsTransparency; u32 ofsTransparency;
u32 nTexAnims; // J u32 nI;
u32 ofsI; //0x70
u32 nTexAnims;
u32 ofsTexAnims; u32 ofsTexAnims;
u32 nTexReplace; u32 nTexReplace;
u32 ofsTexReplace; u32 ofsTexReplace; //0x80
u32 nTexFlags; u32 nTexFlags;
u32 ofsTexFlags; u32 ofsTexFlags;
u32 nY; u32 nY;
u32 ofsY; u32 ofsY; //0x90
u32 nTexLookup; u32 nTexLookup;
u32 ofsTexLookup; u32 ofsTexLookup;
u32 nTexUnitLookup; // L u32 nTexUnitLookup;
u32 ofsTexUnitLookup; u32 ofsTexUnitLookup; //0xa0
u32 nTransparencyLookup; // M u32 nTransparencyLookup;
u32 ofsTransparencyLookup; u32 ofsTransparencyLookup;
u32 nTexAnimLookup; u32 nTexAnimLookup;
u32 ofsTexAnimLookup; u32 ofsTexAnimLookup; //0xb0
f32 floats[14]; f32 floats[14];
u32 nBoundingTriangles; u32 nBoundingTriangles;
u32 ofsBoundingTriangles; u32 ofsBoundingTriangles; //0xf0
u32 nBoundingVertices; u32 nBoundingVertices;
u32 ofsBoundingVertices; u32 ofsBoundingVertices;
u32 nBoundingNormals; u32 nBoundingNormals;
u32 ofsBoundingNormals; u32 ofsBoundingNormals; //0x100
u32 nAttachments; // O u32 nAttachments;
u32 ofsAttachments; u32 ofsAttachments;
u32 nAttachLookup; // P u32 nAttachLookup;
u32 ofsAttachLookup; u32 ofsAttachLookup; //0x110
u32 nQ; // Q u32 nAttachments_2;
u32 ofsQ; u32 ofsAttachments_2;
u32 nLights; // R u32 nLights;
u32 ofsLights; u32 ofsLights; //0x120
u32 nCameras; // S u32 nCameras;
u32 ofsCameras; u32 ofsCameras;
u32 nT; u32 nCameraLookup;
u32 ofsT; u32 ofsnCameraLookup; //0x130
u32 nRibbonEmitters; // U u32 nRibbonEmitters;
u32 ofsRibbonEmitters; u32 ofsRibbonEmitters;
u32 nParticleEmitters; // V u32 nParticleEmitters;
u32 ofsParticleEmitters; u32 ofsParticleEmitters;//0x140
}; };
@ -106,13 +112,13 @@ struct ModelVertex {
}; };
struct ModelView { struct ModelView {
c8 id[4]; // always "SKIN" // c8 id[4]; // always "SKIN"
u32 nIndex, ofsIndex; // Vertices in this model (index into vertices[]) u32 nIndex, ofsIndex; // Vertices in this model (index into vertices[])
u32 nTris, ofsTris; // indices u32 nTris, ofsTris; // indices
u32 nProps, ofsProps; // additional vtx properties u32 nProps, ofsProps; // additional vtx properties
u32 nSub, ofsSub; // materials/renderops/submeshes u32 nSub, ofsSub; // materials/renderops/submeshes
u32 nTex, ofsTex; // material properties/textures u32 nTex, ofsTex; // material properties/textures
s32 lod; // LOD bias? u32 lod; // LOD bias?
}; };
struct ModelViewSubmesh { struct ModelViewSubmesh {
@ -212,17 +218,21 @@ public:
private: private:
bool load(); bool load();
void ReadVertices();
void ReadTextureDefinitions();
void ReadViewData(io::IReadFile* file);
IrrlichtDevice* Device; IrrlichtDevice *Device;
core::stringc Texdir; core::stringc Texdir;
io::IReadFile* MeshFile; io::IReadFile *MeshFile, *SkinFile;
CSkinnedMesh* AnimatedMesh; CSkinnedMesh *AnimatedMesh;
scene::CSkinnedMesh::SJoint* ParentJoint; scene::CSkinnedMesh::SJoint *ParentJoint;
ModelHeader header; ModelHeader header;
ModelView currentView;
core::stringc M2MeshName; core::stringc M2MeshName;
SMesh* Mesh; SMesh* Mesh;
//SSkinMeshBuffer* MeshBuffer; //SSkinMeshBuffer* MeshBuffer;