* 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:
parent
1a79b45b99
commit
9d330665f3
Binary file not shown.
@ -214,7 +214,7 @@ for(u32 i=0;i<M2MVertices.size();i++)
|
||||
|
||||
|
||||
if (Mesh)
|
||||
Mesh->drop();
|
||||
Mesh->drop(); // crash on vc9
|
||||
|
||||
Mesh=new SMesh();
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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>&);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user