* Fixed compile on VC9

* Updated stuffextract to extract textures from M2 models to correct directories (lowercased, spaces replaces with underline), models still in one directory
** Crash with new M2Mesh loader NOT fixed!
This commit is contained in:
bluma4862 2008-04-06 11:53:39 +00:00
parent 1a79b45b99
commit 9d330665f3
6 changed files with 135 additions and 75 deletions

Binary file not shown.

View File

@ -214,7 +214,7 @@ for(u32 i=0;i<M2MVertices.size();i++)
if (Mesh)
Mesh->drop();
Mesh->drop(); // crash on vc9
Mesh=new SMesh();

View File

@ -2,34 +2,13 @@
#include "irrlicht/IMeshLoader.h"
#include <string>
#include <vector>
#include <algorithm>
namespace irr
{
namespace scene
{
class CM2MeshFileLoader : public IMeshLoader
{
public:
//! Constructor
CM2MeshFileLoader(IrrlichtDevice* device, c8* basedir);
//! destructor
virtual ~CM2MeshFileLoader();
//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".cob")
virtual bool isALoadableFileExtension(const c8* fileName)const;
//! creates/loads an animated mesh from the file.
//! \return Pointer to the created mesh. Returns 0 if loading failed.
//! If you no longer need the mesh, you should call IAnimatedMesh::drop().
//! See IUnknown::drop() for more information.
virtual scene::IAnimatedMesh* createMesh(irr::io::IReadFile* file);
private:
struct ModelHeader {
c8 id[4];
u8 version[4];
@ -111,8 +90,37 @@ struct ModelHeader {
u32 nParticleEmitters; // V
u32 ofsParticleEmitters;
} header;
};
struct TextureDefinition {
u32 texType;
u16 unk;
u16 texFlags;
u32 texFileLen;
u32 texFileOfs;
};
class CM2MeshFileLoader : public IMeshLoader
{
public:
//! Constructor
CM2MeshFileLoader(IrrlichtDevice* device, c8* basedir);
//! destructor
virtual ~CM2MeshFileLoader();
//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".cob")
virtual bool isALoadableFileExtension(const c8* fileName)const;
//! creates/loads an animated mesh from the file.
//! \return Pointer to the created mesh. Returns 0 if loading failed.
//! If you no longer need the mesh, you should call IAnimatedMesh::drop().
//! See IUnknown::drop() for more information.
virtual scene::IAnimatedMesh* createMesh(irr::io::IReadFile* file);
private:
ModelHeader header;
struct ModelVertex {
core::vector3df pos;//Use Irrlicht Vector here!
@ -143,14 +151,6 @@ struct ModelViewSubmesh {
float unkf[4];
};
struct TextureDefinition {
u32 texType;
u16 unk;
u16 texFlags;
u32 texFileLen;
u32 texFileOfs;
};
struct TextureUnit{
u16 Flags;
s16 renderOrder;

View File

@ -121,7 +121,7 @@ void PseuGUI::_Init(void)
//...
// register external loaders for not supported filetypes
scene::CM2MeshFileLoader* m2loader = new scene::CM2MeshFileLoader(_device);
scene::CM2MeshFileLoader* m2loader = new scene::CM2MeshFileLoader(_device, "data");
_smgr->addExternalMeshLoader(m2loader);
_initialized = true;

View File

@ -12,7 +12,9 @@
#include "DBCFieldData.h"
#include "Locale.h"
#include "ProgressBar.h"
#include "../../Client/Gui/CM2MeshFileLoader.h"
int replaceSpaces (int i) { return i==(int)' ' ? (int)'_' : i; }
std::map<uint32,std::string> mapNames;
@ -637,47 +639,6 @@ void ExtractMapDependencies(void)
CreateDir(pathwmo.c_str());
uint32 wmosdone=0,texdone=0,mdone=0;
if(doTextures)
{
printf("Extracting textures...\n");
bar = new barGoLink(texNames.size(), true);
for(std::set<NameAndAlt>::iterator i = texNames.begin(); i != texNames.end(); i++)
{
bar->step();
mpqfn = i->name;
altfn = i->alt;
if(altfn.empty())
altfn = mpqfn;
if(!mpqtex.FileExists((char*)mpqfn.c_str()))
continue;
realfn = pathtex + "/" + _PathToFileName(altfn);
std::fstream fh;
fh.open(realfn.c_str(),std::ios_base::out | std::ios_base::binary);
if(fh.is_open())
{
ByteBuffer& bb = mpqtex.ExtractFile((char*)mpqfn.c_str());
fh.write((const char*)bb.contents(),bb.size());
if(doMd5)
{
MD5Hash h;
h.Update((uint8*)bb.contents(), bb.size());
h.Finalize();
uint8 *md5ptr = new uint8[MD5_DIGEST_LENGTH];
md5Tex[_PathToFileName(realfn)] = md5ptr;
memcpy(md5ptr, h.GetDigest(), MD5_DIGEST_LENGTH);
}
texdone++;
}
else
printf("Could not write texture %s\n",realfn.c_str());
fh.close();
}
printf("\n");
if(texNames.size())
OutMD5((char*)pathtex.c_str(),md5Tex);
delete bar;
}
if(doModels)
{
printf("Extracting models...\n");
@ -712,6 +673,9 @@ void ExtractMapDependencies(void)
{
ByteBuffer& bb = mpqmodel.ExtractFile((char*)mpqfn.c_str());
fh.write((const char*)bb.contents(),bb.size());
if (doTextures)
FetchTexturesFromModel(bb);
if(doMd5)
{
MD5Hash h;
@ -733,9 +697,69 @@ void ExtractMapDependencies(void)
delete bar;
}
if(doWmos)
if(doTextures)
{
printf("Extracting textures...\n");
bar = new barGoLink(texNames.size(), true);
for(std::set<NameAndAlt>::iterator i = texNames.begin(); i != texNames.end(); i++)
{
bar->step();
mpqfn = i->name;
altfn = i->alt;
if(altfn.empty())
altfn = mpqfn;
if(!mpqtex.FileExists((char*)mpqfn.c_str()))
continue;
// prepare lowercased and "underlined" path for file
std::string copy = mpqfn;
std::transform(copy.begin(), copy.end(), copy.begin(), ::tolower);
std::transform(copy.begin(), copy.end(), copy.begin(), replaceSpaces);
if (copy.find_first_of("/\\") != std::string::npos)
{
std::string copy2 = copy;
char* tok = strtok((char*)copy2.c_str(),"/\\");
std::string fullpath = pathtex;
while (tok && !strstr(tok, "."))
{
fullpath += "/";
fullpath += tok;
CreateDir(fullpath.c_str());
tok = strtok(NULL, "/\\");
}
}
realfn = pathtex + "/" + copy; //_PathToFileName(altfn);
std::fstream fh;
fh.open(realfn.c_str(),std::ios_base::out | std::ios_base::binary);
if(fh.is_open())
{
ByteBuffer& bb = mpqtex.ExtractFile((char*)mpqfn.c_str());
fh.write((const char*)bb.contents(),bb.size());
if(doMd5)
{
MD5Hash h;
h.Update((uint8*)bb.contents(), bb.size());
h.Finalize();
uint8 *md5ptr = new uint8[MD5_DIGEST_LENGTH];
md5Tex[_PathToFileName(realfn)] = md5ptr;
memcpy(md5ptr, h.GetDigest(), MD5_DIGEST_LENGTH);
}
texdone++;
}
else
printf("Could not write texture %s\n",realfn.c_str());
fh.close();
}
printf("\n");
if(texNames.size())
OutMD5((char*)pathtex.c_str(),md5Tex);
delete bar;
}
if(doWmos)
{
printf("Extracting WMOS...\n");
bar = new barGoLink(wmoNames.size(),true);
for(std::set<NameAndAlt>::iterator i = wmoNames.begin(); i != wmoNames.end(); i++)
{
@ -866,4 +890,39 @@ void ADT_FillModelData(const uint8* data,std::set<NameAndAlt>& st)
ADT_ExportStringSetByOffset(data,OFFSET_MODELS,st,"DIMM");
}
void FetchTexturesFromModel(ByteBuffer& bb)
{
bb.rpos(0);
irr::scene::ModelHeader header;
bb.read((uint8*)&header, sizeof(header));
if (header.version[0] != 4 && header.version[1] != 1 && header.version[2] != 0 && header.version[3] != 0) {
printf("Not model file!");
return;
}
irr::core::array<irr::scene::TextureDefinition> M2MTextureDef;
M2MTextureDef.clear();
irr::scene::TextureDefinition tempM2TexDef;
bb.rpos(header.ofsTextures);
for(irr::u32 i=0;i<header.nTextures;i++)
{
bb.read((uint8*)&tempM2TexDef,sizeof(irr::scene::TextureDefinition));
M2MTextureDef.push_back(tempM2TexDef);
}
std::string tempTexFileName="";
for(irr::u32 i=0; i<M2MTextureDef.size(); i++)
{
bb.rpos(M2MTextureDef[i].texFileOfs);
tempTexFileName.resize(M2MTextureDef[i].texFileLen+1);
bb.read((uint8*)&tempTexFileName[0],M2MTextureDef[i].texFileLen);
if (tempTexFileName.empty())
continue;
// printf(tempTexFileName.c_str()); // for debug
texNames.insert(NameAndAlt(tempTexFileName));
}
}

View File

@ -39,6 +39,7 @@ void ExtractMaps(void);
void ExtractMapDependencies(void);
void ExtractSoundFiles(void);
void FetchTexturesFromModel(ByteBuffer&);
void ADT_ExportStringSetByOffset(const uint8*, uint32, std::set<NameAndAlt>&, char*);
void ADT_FillTextureData(const uint8*,std::set<NameAndAlt>&);