M2MeshFile loader 0.2
-Texturing (one layer only) -alpha transparency and backface culling flags handled -various fixes
This commit is contained in:
parent
b4ece10cb1
commit
1a79b45b99
@ -1,12 +1,14 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "CM2MeshFileLoader.h"
|
#include "CM2MeshFileLoader.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace irr
|
namespace irr
|
||||||
{
|
{
|
||||||
namespace scene
|
namespace scene
|
||||||
{
|
{
|
||||||
|
|
||||||
CM2MeshFileLoader::CM2MeshFileLoader(IrrlichtDevice* device):Device(device)
|
CM2MeshFileLoader::CM2MeshFileLoader(IrrlichtDevice* device, c8* basedir):Device(device), Basedir(basedir)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -42,13 +44,15 @@ namespace irr
|
|||||||
else logger->log(L"header okay",ELL_INFORMATION);
|
else logger->log(L"header okay",ELL_INFORMATION);
|
||||||
//Name -> not very important I think, but save it nontheless;
|
//Name -> not very important I think, but save it nontheless;
|
||||||
std::cout << "Name offset:" << header.nameOfs << "Name length:" << header.nameLength << "\n";
|
std::cout << "Name offset:" << header.nameOfs << "Name length:" << header.nameLength << "\n";
|
||||||
|
//M2MeshName.clear();
|
||||||
|
//M2MeshName.reserve(header.nameLength);
|
||||||
file->seek(header.nameOfs);
|
file->seek(header.nameOfs);
|
||||||
file->read(&M2MeshName[0],header.nameLength);
|
// file->read(&M2MeshName[0],header.nameLength);
|
||||||
std::cout << "Read name:"<<M2MeshName.c_str()<<"\n";
|
//std::cout << "Read name:"<<M2MeshName.c_str()<<"Size: "<< M2MeshName.size() <<"|"<<M2MeshName[0]<< "\n";
|
||||||
//logger->log("Mesh Name",M2MeshName.c_str(),ELL_INFORMATION);
|
//logger->log("Mesh Name",M2MeshName.c_str(),ELL_INFORMATION);
|
||||||
//Now we load all kinds of data from the file
|
//Now we load all kinds of data from the file
|
||||||
|
|
||||||
//Vertices
|
//Vertices. Global data
|
||||||
if(!M2MVertices.empty())
|
if(!M2MVertices.empty())
|
||||||
M2MVertices.clear();
|
M2MVertices.clear();
|
||||||
|
|
||||||
@ -62,7 +66,7 @@ namespace irr
|
|||||||
}
|
}
|
||||||
std::cout << "Read "<<M2MVertices.size()<<"/"<<header.nVertices<<" Vertices\n";
|
std::cout << "Read "<<M2MVertices.size()<<"/"<<header.nVertices<<" Vertices\n";
|
||||||
|
|
||||||
//Views == Sets of vertices. Usage yet unknown
|
//Views == Sets of vertices. Usage yet unknown. Global data
|
||||||
if(M2MViews.size()>0)
|
if(M2MViews.size()>0)
|
||||||
M2MViews.clear();
|
M2MViews.clear();
|
||||||
ModelView tempM2MView;
|
ModelView tempM2MView;
|
||||||
@ -75,8 +79,9 @@ namespace irr
|
|||||||
std::cout << "Read "<<M2MViews.size()<<"/"<<header.nViews<<" Views\n";
|
std::cout << "Read "<<M2MViews.size()<<"/"<<header.nViews<<" Views\n";
|
||||||
|
|
||||||
logger->log("Using View 0 for all further operations",ELL_INFORMATION);
|
logger->log("Using View 0 for all further operations",ELL_INFORMATION);
|
||||||
|
std::cout<<"This View has "<<M2MViews[0].nSub<<" Submeshes\n";
|
||||||
|
|
||||||
//Vertex indices of a specific view.
|
//Vertex indices of a specific view.Local to View 0
|
||||||
if(M2MIndices.size()>0)
|
if(M2MIndices.size()>0)
|
||||||
M2MIndices.clear();
|
M2MIndices.clear();
|
||||||
|
|
||||||
@ -90,7 +95,7 @@ namespace irr
|
|||||||
std::cout << "Read "<<M2MIndices.size()<<"/"<<M2MViews[0].nIndex<<" Indices\n";
|
std::cout << "Read "<<M2MIndices.size()<<"/"<<M2MViews[0].nIndex<<" Indices\n";
|
||||||
|
|
||||||
|
|
||||||
//Triangles. Data Points point to the Vertex Indices, not the vertices themself. 3 Points = 1 Triangle
|
//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();
|
||||||
|
|
||||||
@ -103,15 +108,101 @@ namespace irr
|
|||||||
}
|
}
|
||||||
std::cout << "Read "<<M2MTriangles.size()<<"/"<<M2MViews[0].nTris<<" Triangle Indices\n";
|
std::cout << "Read "<<M2MTriangles.size()<<"/"<<M2MViews[0].nTris<<" Triangle Indices\n";
|
||||||
|
|
||||||
//Texture Lookup table.
|
//Submeshes, Local to View 0
|
||||||
|
if(M2MSubmeshes.size()>0)
|
||||||
|
M2MSubmeshes.clear();
|
||||||
|
|
||||||
|
ModelViewSubmesh tempM2Submesh;
|
||||||
|
file->seek(M2MViews[0].ofsSub);
|
||||||
|
for(u32 i =0;i<M2MViews[0].nSub;i++)
|
||||||
|
{
|
||||||
|
file->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";
|
||||||
|
}
|
||||||
|
std::cout << "Read "<<M2MSubmeshes.size()<<"/"<<M2MViews[0].nSub<<" Submeshes\n";
|
||||||
|
|
||||||
|
//Texture units. Local to view 0
|
||||||
|
TextureUnit tempM2TexUnit;
|
||||||
|
if(!M2MTextureUnit.empty())
|
||||||
|
{
|
||||||
|
M2MTextureUnit.clear();
|
||||||
|
}
|
||||||
|
file->seek(M2MViews[0].ofsTex);
|
||||||
|
for(u32 i=0;i<M2MViews[0].nTex;i++)
|
||||||
|
{
|
||||||
|
file->read(&tempM2TexUnit,sizeof(TextureUnit));
|
||||||
|
M2MTextureUnit.push_back(tempM2TexUnit);
|
||||||
|
}
|
||||||
|
std::cout << "Read "<<M2MTextureUnit.size()<<" Texture Unit entries for View 0\n";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//Texture Lookup table. This is global data
|
||||||
|
u16 tempM2TexLookup;
|
||||||
|
if(!M2MTextureLookup.empty())
|
||||||
|
{
|
||||||
|
M2MTextureLookup.clear();
|
||||||
|
}
|
||||||
file->seek(header.ofsTexLookup);
|
file->seek(header.ofsTexLookup);
|
||||||
for(u32 i=0;i<header.nTexLookup;i++)
|
for(u32 i=0;i<header.nTexLookup;i++)
|
||||||
{
|
{
|
||||||
|
file->read(&tempM2TexLookup,sizeof(u16));
|
||||||
|
M2MTextureLookup.push_back(tempM2TexLookup);
|
||||||
}
|
}
|
||||||
|
std::cout << "Read "<<M2MTextureLookup.size()<<" Texture lookup entries\n";
|
||||||
|
|
||||||
|
//Texture Definitions table. This is global data
|
||||||
|
TextureDefinition tempM2TexDef;
|
||||||
|
if(!M2MTextureDef.empty())
|
||||||
|
{
|
||||||
|
M2MTextureDef.clear();
|
||||||
|
}
|
||||||
|
file->seek(header.ofsTextures);
|
||||||
|
for(u32 i=0;i<header.nTextures;i++)
|
||||||
|
{
|
||||||
|
file->read(&tempM2TexDef,sizeof(TextureDefinition));
|
||||||
|
M2MTextureDef.push_back(tempM2TexDef);
|
||||||
|
}
|
||||||
|
std::cout << "Read "<<M2MTextureDef.size()<<" Texture Definition entries\n";
|
||||||
|
|
||||||
|
//Render Flags table. This is global data
|
||||||
|
RenderFlags tempM2RF;
|
||||||
|
if(!M2MRenderFlags.empty())
|
||||||
|
{
|
||||||
|
M2MRenderFlags.clear();
|
||||||
|
}
|
||||||
|
file->seek(header.ofsTexFlags);
|
||||||
|
for(u32 i=0;i<header.nTexFlags;i++)
|
||||||
|
{
|
||||||
|
file->read(&tempM2RF,sizeof(RenderFlags));
|
||||||
|
M2MRenderFlags.push_back(tempM2RF);
|
||||||
|
}
|
||||||
|
std::cout << "Read "<<M2MRenderFlags.size()<<" Render Flags\n";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//std::cout << M2MTextureUnit[0].submeshIndex1 <<","<<M2MTextureUnit[0].submeshIndex1 <<","<<M2MTextureUnit[0].textureIndex<<";\n";
|
||||||
|
|
||||||
|
if(!M2MTextureFiles.empty())
|
||||||
|
M2MTextureFiles.clear();
|
||||||
|
|
||||||
|
std::string tempTexFileName="";
|
||||||
|
M2MTextureFiles.reallocate(M2MTextureDef.size());
|
||||||
|
for(u32 i=0; i<M2MTextureDef.size(); i++)
|
||||||
|
{
|
||||||
|
file->seek(M2MTextureDef[i].texFileOfs);
|
||||||
|
file->read(&tempTexFileName[0],M2MTextureDef[i].texFileLen);
|
||||||
|
M2MTextureFiles.push_back(tempTexFileName.c_str());
|
||||||
|
std::cout<<M2MTextureFiles.size()<<"-"<<M2MTextureFiles[i].c_str()<<"\n";
|
||||||
|
}
|
||||||
|
// std::cout << "Read "<<M2MTextureFiles.size()<<"/"<<M2MTextureDef.size()<<" Texture file names\n";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//Now, M2MTriangles refers to M2MIndices and not to M2MVertices.
|
|
||||||
//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)
|
||||||
M2Vertices.clear();
|
M2Vertices.clear();
|
||||||
|
|
||||||
@ -119,38 +210,76 @@ namespace irr
|
|||||||
{
|
{
|
||||||
M2Vertices.push_back(video::S3DVertex(M2MVertices[i].pos,M2MVertices[i].normal, video::SColor(255,100,100,100),M2MVertices[i].texcoords));
|
M2Vertices.push_back(video::S3DVertex(M2MVertices[i].pos,M2MVertices[i].normal, video::SColor(255,100,100,100),M2MVertices[i].texcoords));
|
||||||
}
|
}
|
||||||
if(M2Indices.size()>0)
|
|
||||||
M2Indices.clear();
|
|
||||||
|
|
||||||
for(u32 i=0;i<M2MTriangles.size();i++)
|
|
||||||
{
|
|
||||||
M2Indices.push_back(M2MIndices[M2MTriangles[i]]);
|
if (Mesh)
|
||||||
}
|
Mesh->drop();
|
||||||
|
|
||||||
Mesh=new SMesh();
|
Mesh=new SMesh();
|
||||||
|
|
||||||
|
|
||||||
SMeshBuffer* IMB = new SMeshBuffer;
|
|
||||||
while(Mesh->getMeshBufferCount()>0)
|
while(Mesh->getMeshBufferCount()>0)
|
||||||
{
|
{
|
||||||
Mesh->MeshBuffers.erase(0);
|
Mesh->MeshBuffers.erase(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "Sending "<<M2Vertices.size() <<" Vertices and " << M2Indices.size() <<" Indices to the MeshBuffer\n";
|
|
||||||
IMB->append(M2Vertices.const_pointer(),M2Vertices.size(),M2Indices.const_pointer(),M2Indices.size());
|
|
||||||
|
|
||||||
|
for(u32 i=0; i < M2MViews[0].nSub;i++)//
|
||||||
|
{
|
||||||
|
//std::cout << "Proceeding with Submesh "<<i<<"/"<<M2MViews[0].nSub<<"\n";
|
||||||
|
//Now, M2MTriangles refers to M2MIndices and not to M2MVertices.
|
||||||
|
|
||||||
|
if(M2Indices.size()>0)
|
||||||
|
M2Indices.clear();
|
||||||
|
|
||||||
|
for(u32 j=M2MSubmeshes[i].ofsTris;j<M2MSubmeshes[i].ofsTris+M2MSubmeshes[i].nTris;j++)
|
||||||
|
{
|
||||||
|
M2Indices.push_back(M2MIndices[M2MTriangles[j]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//std::cout << "Sending "<<M2Vertices.size() <<" Vertices and " << M2Indices.size() <<" Indices to the MeshBuffer\n";
|
||||||
|
|
||||||
|
IMB = new SMeshBuffer;
|
||||||
|
IMB->append(M2Vertices.const_pointer(),M2Vertices.size(),M2Indices.const_pointer(),M2Indices.size());
|
||||||
IMB->recalculateBoundingBox();
|
IMB->recalculateBoundingBox();
|
||||||
|
|
||||||
|
//IMB->getMaterial().DiffuseColor.set(255,255-(u32)(255/(M2MSubmeshes.size()))*i,(u32)(255/(M2MSubmeshes.size()))*i,0);
|
||||||
|
//IMB->getMaterial().DiffuseColor.set(255,(M2MSubmeshes[i].meshpartId==0?0:255),(M2MSubmeshes[i].meshpartId==0?255:0),0);
|
||||||
|
|
||||||
|
|
||||||
|
std::string TexName=Basedir.c_str();
|
||||||
|
TexName+="/";
|
||||||
|
TexName+=M2MTextureFiles[M2MTextureUnit[i].textureIndex].c_str();
|
||||||
|
|
||||||
|
while(TexName.find('\\')<TexName.size())//Replace \ by /
|
||||||
|
{
|
||||||
|
TexName.replace(TexName.find('\\'),1,"/");
|
||||||
|
}
|
||||||
|
while(TexName.find(' ')<TexName.size())//Replace space by _
|
||||||
|
{
|
||||||
|
TexName.replace(TexName.find(' '),1,"_");
|
||||||
|
}
|
||||||
|
std::transform(TexName.begin(), TexName.end(), TexName.begin(), tolower);
|
||||||
|
|
||||||
|
IMB->getMaterial().setTexture(0,Device->getVideoDriver()->getTexture(TexName.c_str()));
|
||||||
|
std::cout<<M2MRenderFlags[i].flags<<"--"<<M2MRenderFlags[i].blending<<"\n";
|
||||||
|
IMB->getMaterial().BackfaceCulling=(M2MRenderFlags[i].flags & 0x04)?false:true;
|
||||||
|
if(M2MRenderFlags[i].blending==1)
|
||||||
|
IMB->getMaterial().MaterialType=video::EMT_TRANSPARENT_ALPHA_CHANNEL;
|
||||||
Mesh->addMeshBuffer(IMB);
|
Mesh->addMeshBuffer(IMB);
|
||||||
IMB->drop();
|
IMB->drop();
|
||||||
|
//std::cout << "Mesh now has "<<Mesh->getMeshBufferCount()<<" Buffers\n";
|
||||||
|
}
|
||||||
|
|
||||||
aniMesh= new SAnimatedMesh();
|
aniMesh= new SAnimatedMesh();
|
||||||
|
|
||||||
|
|
||||||
aniMesh->addMesh(Mesh);
|
aniMesh->addMesh(Mesh);
|
||||||
Mesh->drop();
|
Mesh->drop();
|
||||||
Mesh = 0;
|
Mesh = 0;
|
||||||
|
|
||||||
aniMesh->recalculateBoundingBox();
|
aniMesh->recalculateBoundingBox();
|
||||||
|
|
||||||
|
|
||||||
return aniMesh;
|
return aniMesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
#include "irrlicht/irrlicht.h"
|
#include "irrlicht/irrlicht.h"
|
||||||
#include "irrlicht/IMeshLoader.h"
|
#include "irrlicht/IMeshLoader.h"
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace irr
|
namespace irr
|
||||||
{
|
{
|
||||||
@ -12,10 +13,10 @@ namespace irr
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
//! Constructor
|
//! Constructor
|
||||||
CM2MeshFileLoader(IrrlichtDevice* device);
|
CM2MeshFileLoader(IrrlichtDevice* device, c8* basedir);
|
||||||
|
|
||||||
//! destructor
|
//! destructor
|
||||||
~CM2MeshFileLoader();
|
virtual ~CM2MeshFileLoader();
|
||||||
|
|
||||||
//! returns true if the file maybe is able to be loaded by this class
|
//! returns true if the file maybe is able to be loaded by this class
|
||||||
//! based on the file extension (e.g. ".cob")
|
//! based on the file extension (e.g. ".cob")
|
||||||
@ -131,17 +132,64 @@ namespace irr
|
|||||||
s32 lod; // LOD bias?
|
s32 lod; // LOD bias?
|
||||||
};
|
};
|
||||||
|
|
||||||
// io::IFileSystem* FileSystem;
|
struct ModelViewSubmesh {
|
||||||
|
u32 meshpartId;
|
||||||
|
u16 ofsVertex;//Starting vertex number for this submesh
|
||||||
|
u16 nVertex;
|
||||||
|
u16 ofsTris;//Starting Triangle index
|
||||||
|
u16 nTris;
|
||||||
|
u16 unk1, unk2, unk3, unk4;
|
||||||
|
core::vector3df v;
|
||||||
|
float unkf[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TextureDefinition {
|
||||||
|
u32 texType;
|
||||||
|
u16 unk;
|
||||||
|
u16 texFlags;
|
||||||
|
u32 texFileLen;
|
||||||
|
u32 texFileOfs;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TextureUnit{
|
||||||
|
u16 Flags;
|
||||||
|
s16 renderOrder;
|
||||||
|
u16 submeshIndex1, submeshIndex2;
|
||||||
|
s16 colorIndex;
|
||||||
|
u16 renderFlagsIndex;
|
||||||
|
u16 TextureUnitNumber;
|
||||||
|
u16 unk1;
|
||||||
|
u16 textureIndex;
|
||||||
|
u16 TextureUnitNumber2;
|
||||||
|
u16 transparencyIndex;
|
||||||
|
u16 texAnimIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RenderFlags{
|
||||||
|
u16 flags;
|
||||||
|
u16 blending;
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
io::IFileSystem* FileSystem;
|
||||||
IrrlichtDevice* Device;
|
IrrlichtDevice* Device;
|
||||||
// scene::IMeshManipulator* Manipulator;
|
// scene::IMeshManipulator* Manipulator;
|
||||||
core::stringc M2MeshName;
|
core::stringc M2MeshName;
|
||||||
|
core::stringc Basedir;
|
||||||
SAnimatedMesh* aniMesh;
|
SAnimatedMesh* aniMesh;
|
||||||
SMesh* Mesh;
|
SMesh* Mesh;
|
||||||
|
SMeshBuffer* IMB;
|
||||||
//Taken from the Model file, thus m2M*
|
//Taken from the Model file, thus m2M*
|
||||||
core::array<ModelVertex> M2MVertices;
|
core::array<ModelVertex> M2MVertices;
|
||||||
core::array<ModelView> M2MViews;
|
core::array<ModelView> M2MViews;
|
||||||
core::array<u16> M2MIndices;
|
core::array<u16> M2MIndices;
|
||||||
core::array<u16> M2MTriangles;
|
core::array<u16> M2MTriangles;
|
||||||
|
core::array<ModelViewSubmesh> M2MSubmeshes;
|
||||||
|
core::array<u16> M2MTextureLookup;
|
||||||
|
core::array<TextureDefinition> M2MTextureDef;
|
||||||
|
core::array<std::string> M2MTextureFiles;
|
||||||
|
core::array<TextureUnit> M2MTextureUnit;
|
||||||
|
core::array<RenderFlags> M2MRenderFlags;
|
||||||
//Used for the Mesh, thus m2_noM_*
|
//Used for the Mesh, thus m2_noM_*
|
||||||
core::array<video::S3DVertex> M2Vertices;
|
core::array<video::S3DVertex> M2Vertices;
|
||||||
core::array<u16> M2Indices;
|
core::array<u16> M2Indices;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user