* 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:
parent
3845d3b51c
commit
f8adc3311a
@ -1,3 +1,4 @@
|
|||||||
|
// #define _DEBUG 1
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "MemoryDataHolder.h"
|
#include "MemoryDataHolder.h"
|
||||||
#include "MemoryInterface.h"
|
#include "MemoryInterface.h"
|
||||||
@ -51,39 +52,18 @@ IAnimatedMesh* CM2MeshFileLoader::createMesh(io::IReadFile* file)
|
|||||||
|
|
||||||
return AnimatedMesh;
|
return AnimatedMesh;
|
||||||
}
|
}
|
||||||
bool CM2MeshFileLoader::load()
|
void CM2MeshFileLoader::ReadVertices()
|
||||||
{
|
{
|
||||||
DEBUG(logdebug("Trying to open file %s",MeshFile->getFileName()));
|
//Vertices. Global data
|
||||||
|
if(!M2MVertices.empty())
|
||||||
|
|
||||||
MeshFile->read(&header,sizeof(ModelHeader));
|
|
||||||
if (header.version[0] != 8 || header.version[1] != 1 || header.version[2] != 0 || header.version[3] != 0) {
|
|
||||||
logerror("M2: [%s] Wrong header! File version doesn't match or file is not a M2 file.",MeshFile->getFileName());
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DEBUG(logdebug("header okay"));
|
|
||||||
}
|
|
||||||
//Name -> not very important I think, but save it nontheless;
|
|
||||||
//M2MeshName.clear();
|
|
||||||
//M2MeshName.reserve(header.nameLength);
|
|
||||||
//file->seek(header.nameOfs);
|
|
||||||
//file->read(&M2MeshName[0],header.nameLength);
|
|
||||||
//std::cout << "Read name:"<<M2MeshName.c_str()<<"Size: "<< M2MeshName.size() <<"|"<<M2MeshName[0]<< "\n";
|
|
||||||
//logger->log("Mesh Name",M2MeshName.c_str(),ELL_INFORMATION);
|
|
||||||
//Now we load all kinds of data from the file
|
|
||||||
|
|
||||||
//Vertices. Global data
|
|
||||||
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;
|
||||||
@ -93,146 +73,270 @@ for(u32 i =0;i<header.nVertices;i++)
|
|||||||
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
|
void CM2MeshFileLoader::ReadViewData(io::IReadFile* file)
|
||||||
|
|
||||||
std::string SkinName = MeshFile->getFileName();
|
|
||||||
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());
|
|
||||||
if (!SkinFile)
|
|
||||||
{
|
{
|
||||||
logerror("Error! Skin file not found: %s", SkinName.c_str());
|
//Vertex indices of a specific view.Local to View 0
|
||||||
return 0;
|
if(M2MIndices.size()>0)
|
||||||
}
|
|
||||||
|
|
||||||
ModelView currentView;
|
|
||||||
SkinFile->read(¤tView, sizeof(ModelView));
|
|
||||||
|
|
||||||
//std::cout << "Skins "<<header.nViews<<" (views)\n";
|
|
||||||
|
|
||||||
DEBUG(logdebug("Using View 0 for all further operations"));
|
|
||||||
DEBUG(logdebug("This View has %u Submeshes",currentView.nSub));
|
|
||||||
|
|
||||||
//Vertex indices of a specific view.Local to View 0
|
|
||||||
if(M2MIndices.size()>0)
|
|
||||||
M2MIndices.clear();
|
M2MIndices.clear();
|
||||||
|
|
||||||
u16 tempM2Index;
|
u16 tempM2Index;
|
||||||
SkinFile->seek(currentView.ofsIndex);
|
file->seek(currentView.ofsIndex);
|
||||||
for(u32 i =0;i<currentView.nIndex;i++)
|
for(u32 i =0;i<currentView.nIndex;i++)
|
||||||
{
|
{
|
||||||
SkinFile->read(&tempM2Index,sizeof(u16));
|
file->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);
|
file->seek(currentView.ofsTris);
|
||||||
for(u32 i =0;i<currentView.nTris;i++)
|
for(u32 i =0;i<currentView.nTris;i++)
|
||||||
{
|
{
|
||||||
SkinFile->read(&tempM2Triangle,sizeof(u16));
|
file->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);
|
file->seek(currentView.ofsSub);
|
||||||
for(u32 i =0;i<currentView.nSub;i++)
|
for(u32 i =0;i<currentView.nSub;i++)
|
||||||
{
|
{
|
||||||
SkinFile->read(&tempM2Submesh,sizeof(ModelViewSubmesh));
|
file->read(&tempM2Submesh,sizeof(ModelViewSubmesh)-(header.version==0x100?16:0));
|
||||||
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);
|
file->seek(currentView.ofsTex);
|
||||||
for(u32 i=0;i<currentView.nTex;i++)
|
for(u32 i=0;i<currentView.nTex;i++)
|
||||||
{
|
{
|
||||||
SkinFile->read(&tempM2TexUnit,sizeof(TextureUnit));
|
file->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()));
|
|
||||||
|
|
||||||
|
void CM2MeshFileLoader::ReadTextureDefinitions()
|
||||||
|
|
||||||
|
|
||||||
//Texture Lookup table. This is global data
|
|
||||||
u16 tempM2TexLookup;
|
|
||||||
if(!M2MTextureLookup.empty())
|
|
||||||
{
|
{
|
||||||
|
//Texture Lookup table. This is global data
|
||||||
|
u16 tempM2TexLookup;
|
||||||
|
if(!M2MTextureLookup.empty())
|
||||||
|
{
|
||||||
M2MTextureLookup.clear();
|
M2MTextureLookup.clear();
|
||||||
}
|
}
|
||||||
MeshFile->seek(header.ofsTexLookup);
|
MeshFile->seek(header.ofsTexLookup);
|
||||||
for(u32 i=0;i<header.nTexLookup;i++)
|
for(u32 i=0;i<header.nTexLookup;i++)
|
||||||
{
|
{
|
||||||
MeshFile->read(&tempM2TexLookup,sizeof(u16));
|
MeshFile->read(&tempM2TexLookup,sizeof(u16));
|
||||||
M2MTextureLookup.push_back(tempM2TexLookup);
|
M2MTextureLookup.push_back(tempM2TexLookup);
|
||||||
DEBUG(logdebug("Texture %u Type %u\n",i,tempM2TexLookup));
|
DEBUG(logdebug("Texture %u Type %u",i,tempM2TexLookup));
|
||||||
}
|
}
|
||||||
DEBUG(logdebug("Read %u Texture lookup entries",M2MTextureLookup.size()));
|
DEBUG(logdebug("Read %u Texture lookup entries",M2MTextureLookup.size()));
|
||||||
|
|
||||||
//Texture Definitions table. This is global data
|
//Texture Definitions table. This is global data
|
||||||
TextureDefinition tempM2TexDef;
|
TextureDefinition tempM2TexDef;
|
||||||
if(!M2MTextureDef.empty())
|
if(!M2MTextureDef.empty())
|
||||||
{
|
{
|
||||||
M2MTextureDef.clear();
|
M2MTextureDef.clear();
|
||||||
}
|
}
|
||||||
MeshFile->seek(header.ofsTextures);
|
MeshFile->seek(header.ofsTextures);
|
||||||
for(u32 i=0;i<header.nTextures;i++)
|
for(u32 i=0;i<header.nTextures;i++)
|
||||||
{
|
{
|
||||||
MeshFile->read(&tempM2TexDef,sizeof(TextureDefinition));
|
MeshFile->read(&tempM2TexDef,sizeof(TextureDefinition));
|
||||||
M2MTextureDef.push_back(tempM2TexDef);
|
M2MTextureDef.push_back(tempM2TexDef);
|
||||||
DEBUG(logdebug("Texture %u Type %u\n",i,tempM2TexDef.texType));
|
DEBUG(logdebug("Texture %u Type %u",i,tempM2TexDef.texType));
|
||||||
}
|
}
|
||||||
DEBUG(logdebug("Read %u Texture Definition entries",M2MTextureDef.size()));
|
DEBUG(logdebug("Read %u Texture Definition entries",M2MTextureDef.size()));
|
||||||
|
|
||||||
//Render Flags table. This is global data
|
//Render Flags table. This is global data
|
||||||
RenderFlags tempM2RF;
|
RenderFlags tempM2RF;
|
||||||
if(!M2MRenderFlags.empty())
|
if(!M2MRenderFlags.empty())
|
||||||
{
|
{
|
||||||
M2MRenderFlags.clear();
|
M2MRenderFlags.clear();
|
||||||
}
|
}
|
||||||
MeshFile->seek(header.ofsTexFlags);
|
MeshFile->seek(header.ofsTexFlags);
|
||||||
for(u32 i=0;i<header.nTexFlags;i++)
|
for(u32 i=0;i<header.nTexFlags;i++)
|
||||||
{
|
{
|
||||||
MeshFile->read(&tempM2RF,sizeof(RenderFlags));
|
MeshFile->read(&tempM2RF,sizeof(RenderFlags));
|
||||||
M2MRenderFlags.push_back(tempM2RF);
|
M2MRenderFlags.push_back(tempM2RF);
|
||||||
DEBUG(logdebug("Flag %u: (%u, %u)",i,tempM2RF.blending,tempM2RF.flags));
|
DEBUG(logdebug("Flag %u: (%u, %u)",i,tempM2RF.blending,tempM2RF.flags));
|
||||||
}
|
}
|
||||||
DEBUG(logdebug("Read %u Renderflags",M2MRenderFlags.size()));
|
DEBUG(logdebug("Read %u Renderflags",M2MRenderFlags.size()));
|
||||||
|
|
||||||
if(!M2MTextureFiles.empty())
|
if(!M2MTextureFiles.empty())
|
||||||
M2MTextureFiles.clear();
|
M2MTextureFiles.clear();
|
||||||
|
|
||||||
std::string tempTexFileName="";
|
std::string tempTexFileName="";
|
||||||
M2MTextureFiles.reallocate(M2MTextureDef.size());
|
M2MTextureFiles.reallocate(M2MTextureDef.size());
|
||||||
for(u32 i=0; i<M2MTextureDef.size(); i++)
|
for(u32 i=0; i<M2MTextureDef.size(); i++)
|
||||||
{
|
{
|
||||||
tempTexFileName.resize(M2MTextureDef[i].texFileLen + 1);
|
tempTexFileName.resize(M2MTextureDef[i].texFileLen + 1);
|
||||||
MeshFile->seek(M2MTextureDef[i].texFileOfs);
|
MeshFile->seek(M2MTextureDef[i].texFileOfs);
|
||||||
MeshFile->read((void*)tempTexFileName.data(),M2MTextureDef[i].texFileLen);
|
MeshFile->read((void*)tempTexFileName.data(),M2MTextureDef[i].texFileLen);
|
||||||
M2MTextureFiles.push_back("");
|
M2MTextureFiles.push_back("");
|
||||||
M2MTextureFiles[i]=tempTexFileName.c_str();
|
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));
|
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()
|
||||||
|
{
|
||||||
|
DEBUG(logdebug("Trying to open file %s",MeshFile->getFileName()));
|
||||||
|
|
||||||
|
|
||||||
|
MeshFile->read(&header,20);
|
||||||
|
switch(header.version)
|
||||||
|
{
|
||||||
|
case 0x100:
|
||||||
|
{
|
||||||
|
DEBUG(logdebug("M2 Version 1.00"));
|
||||||
|
MeshFile->read((u8*)&header+20,sizeof(ModelHeader)-20);
|
||||||
|
ReadVertices();
|
||||||
|
MeshFile->seek(header.ofsViews);
|
||||||
|
MeshFile->read(¤tView,sizeof(ModelView));
|
||||||
|
ReadViewData(MeshFile);
|
||||||
|
ReadTextureDefinitions();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x104:
|
||||||
|
{
|
||||||
|
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
|
||||||
|
// 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));
|
||||||
|
|
||||||
|
//Views (skins) == Sets of vertices. Usage yet unknown. Global data
|
||||||
|
|
||||||
|
// std::string SkinName = MeshFile->getFileName();
|
||||||
|
// 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());
|
||||||
|
// if (!SkinFile)
|
||||||
|
// {
|
||||||
|
// logerror("Error! Skin file not found: %s", SkinName.c_str());
|
||||||
|
// return 0;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// SkinFile->read(¤tView, sizeof(ModelView));
|
||||||
|
//
|
||||||
|
// //std::cout << "Skins "<<header.nViews<<" (views)\n";
|
||||||
|
//
|
||||||
|
// DEBUG(logdebug("Using View 0 for all further operations"));
|
||||||
|
// DEBUG(logdebug("This View has %u Submeshes",currentView.nSub));
|
||||||
|
//
|
||||||
|
// //Vertex indices of a specific view.Local to View 0
|
||||||
|
// if(M2MIndices.size()>0)
|
||||||
|
// M2MIndices.clear();
|
||||||
|
//
|
||||||
|
// u16 tempM2Index;
|
||||||
|
// SkinFile->seek(currentView.ofsIndex);
|
||||||
|
// for(u32 i =0;i<currentView.nIndex;i++)
|
||||||
|
// {
|
||||||
|
// SkinFile->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;
|
||||||
|
// SkinFile->seek(currentView.ofsTris);
|
||||||
|
// for(u32 i =0;i<currentView.nTris;i++)
|
||||||
|
// {
|
||||||
|
// SkinFile->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;
|
||||||
|
// SkinFile->seek(currentView.ofsSub);
|
||||||
|
// for(u32 i =0;i<currentView.nSub;i++)
|
||||||
|
// {
|
||||||
|
// SkinFile->read(&tempM2Submesh,sizeof(ModelViewSubmesh));
|
||||||
|
// 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();
|
||||||
|
// }
|
||||||
|
// SkinFile->seek(currentView.ofsTex);
|
||||||
|
// for(u32 i=0;i<currentView.nTex;i++)
|
||||||
|
// {
|
||||||
|
// SkinFile->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()));
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
// 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";
|
||||||
@ -494,7 +611,7 @@ for(u32 i=0; i < currentView.nSub;i++)//
|
|||||||
{
|
{
|
||||||
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,15 +626,21 @@ 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());
|
||||||
|
video::ITexture* tex = Device->getVideoDriver()->findTexture(buf);
|
||||||
|
if(!tex)
|
||||||
|
{
|
||||||
io::IReadFile* TexFile = io::IrrCreateIReadFileBasic(Device, buf);
|
io::IReadFile* TexFile = io::IrrCreateIReadFileBasic(Device, buf);
|
||||||
// logdebug("Texture %s loading",M2MTextureFiles[M2MTextureLookup[M2MTextureUnit[j].textureIndex]].c_str());
|
// logdebug("Texture %s loading",M2MTextureFiles[M2MTextureLookup[M2MTextureUnit[j].textureIndex]].c_str());
|
||||||
if (!TexFile)
|
if (!TexFile)
|
||||||
{
|
{
|
||||||
logerror("CM2MeshFileLoader: Texture file not found: %s", buf);
|
logerror("CM2MeshFileLoader: Texture file not found: %s", buf);
|
||||||
continue;
|
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;
|
||||||
@ -527,8 +650,9 @@ for(u32 i=0; i < currentView.nSub;i++)//
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user