Tools/MeshExtractor: More progress on extracting GameObject models
This commit is contained in:
@@ -170,13 +170,62 @@ void ExtractGameobjectModels()
|
|||||||
fclose(output);
|
fclose(output);
|
||||||
delete[] indices;
|
delete[] indices;
|
||||||
delete[] vertices;
|
delete[] vertices;
|
||||||
|
|
||||||
|
uint32 displayId = (*itr)->Values[0];
|
||||||
|
uint32 pathLength = fileName.size();
|
||||||
|
fwrite(&displayId, sizeof(uint32), 1, modelList);
|
||||||
|
fwrite(&pathLength, sizeof(uint32), 1, modelList);
|
||||||
|
fwrite(fileName.c_str(), sizeof(char), pathLength, modelList);
|
||||||
}
|
}
|
||||||
else if (extension == "wmo")
|
else if (extension == "wmo")
|
||||||
{
|
{
|
||||||
//WorldModelRoot model(path);
|
WorldModelRoot model(path);
|
||||||
|
|
||||||
|
FILE* output = fopen((baseBuildingsPath + fileName).c_str(), "wb");
|
||||||
|
if (!output)
|
||||||
|
{
|
||||||
|
printf("Could not create file %s, please check that you have write permissions\n", (baseBuildingsPath + fileName).c_str());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
fwrite(Constants::VMAPMagic, 1, 8, output);
|
||||||
|
uint32 numVertices = 0;
|
||||||
|
fwrite(&numVertices, sizeof(uint32), 1, output); // will be filled later
|
||||||
|
fwrite(&model.Header.CountGroups, sizeof(uint32), 1, output);
|
||||||
|
fwrite(&model.Header.WmoId, sizeof(uint32), 1, output);
|
||||||
|
|
||||||
|
uint32 i = 0;
|
||||||
|
for (std::vector<WorldModelGroup>::iterator itr2 = model.Groups.begin(); itr2 != model.Groups.end(); ++itr2)
|
||||||
|
{
|
||||||
|
fwrite(&itr2->Header.Flags, sizeof(uint32), 1, output);
|
||||||
|
fwrite(&itr2->Header.WmoId, sizeof(uint32), 1, output);
|
||||||
|
fwrite(&itr2->Header.BoundingBox[0], sizeof(uint32), 1, output);
|
||||||
|
fwrite(&itr2->Header.BoundingBox[1], sizeof(uint32), 1, output);
|
||||||
|
uint32 LiquidFlags = itr2->HasLiquidData ? 1 : 0;
|
||||||
|
fwrite(&LiquidFlags, sizeof(uint32), 1, output);
|
||||||
|
|
||||||
|
fwrite("GRP ", sizeof(char), 4, output);
|
||||||
|
uint32 k = 0;
|
||||||
|
uint32 mobaBatch = itr2->MOBALength / 12;
|
||||||
|
uint32* MobaEx = new uint32[mobaBatch*4];
|
||||||
|
|
||||||
|
for(uint32 i = 8; i < itr2->MOBALength; i += 12)
|
||||||
|
MobaEx[k++] = itr2->MOBA[i];
|
||||||
|
|
||||||
|
int mobaSizeGrp = mobaBatch * 4 + 4;
|
||||||
|
fwrite(&mobaSizeGrp, 4, 1, output);
|
||||||
|
fwrite(&mobaBatch, 4, 1, output);
|
||||||
|
fwrite(MobaEx, 4, k, output);
|
||||||
|
delete[] MobaEx;
|
||||||
|
|
||||||
|
// Note: still not finished
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fclose(modelList);
|
||||||
printf("GameObject models extraction finished!");
|
printf("GameObject models extraction finished!");
|
||||||
Constants::ToWoWCoords = false;
|
Constants::ToWoWCoords = false;
|
||||||
}
|
}
|
||||||
@@ -252,7 +301,7 @@ void PrintUsage()
|
|||||||
printf("- %u to extract DBCs\n", Constants::EXTRACT_FLAG_DBC);
|
printf("- %u to extract DBCs\n", Constants::EXTRACT_FLAG_DBC);
|
||||||
printf("- %u to extract Maps (Not yet implemented)\n", Constants::EXTRACT_FLAG_MAPS);
|
printf("- %u to extract Maps (Not yet implemented)\n", Constants::EXTRACT_FLAG_MAPS);
|
||||||
printf("- %u to extract VMaps (Not yet implemented)\n", Constants::EXTRACT_FLAG_VMAPS);
|
printf("- %u to extract VMaps (Not yet implemented)\n", Constants::EXTRACT_FLAG_VMAPS);
|
||||||
printf("- %u to extract GameObject models (Not yet finished)\n", Constants::EXTRACT_FLAG_GOB_MODELS);
|
printf("- %u to extract GameObject models (Not yet finished, you need to run VMapAssembler on the extracted files)\n", Constants::EXTRACT_FLAG_GOB_MODELS);
|
||||||
printf("- %u to extract MMaps (Not yet finished)\n", Constants::EXTRACT_FLAG_MMAPS);
|
printf("- %u to extract MMaps (Not yet finished)\n", Constants::EXTRACT_FLAG_MMAPS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -484,3 +484,21 @@ char* Utils::GetPlainName(const char* FileName)
|
|||||||
FileName = temp + 1;
|
FileName = temp + 1;
|
||||||
return (char*)FileName;
|
return (char*)FileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WMOGroupHeader WMOGroupHeader::Read( FILE* stream )
|
||||||
|
{
|
||||||
|
WMOGroupHeader ret;
|
||||||
|
fread(&ret.OffsetGroupName, sizeof(uint32), 1, stream);
|
||||||
|
fread(&ret.OffsetDescriptiveName, sizeof(uint32), 1, stream);
|
||||||
|
fread(&ret.Flags, sizeof(uint32), 1, stream);
|
||||||
|
ret.BoundingBox[0] = Vector3::Read(stream);
|
||||||
|
ret.BoundingBox[1] = Vector3::Read(stream);
|
||||||
|
fread(&ret.OffsetPortals, sizeof(uint32), 1, stream);
|
||||||
|
fread(&ret.CountPortals, sizeof(uint32), 1, stream);
|
||||||
|
fread(&ret.CountBatches, sizeof(uint16), 4, stream);
|
||||||
|
fread(&ret.Fogs, sizeof(uint8), 4, stream);
|
||||||
|
fread(&ret.LiquidTypeRelated, sizeof(uint32), 1, stream);
|
||||||
|
fread(&ret.WmoId, sizeof(uint32), 1, stream);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|||||||
@@ -289,6 +289,25 @@ public:
|
|||||||
static H2OInformation Read(FILE* stream);
|
static H2OInformation Read(FILE* stream);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class WMOGroupHeader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WMOGroupHeader() {}
|
||||||
|
|
||||||
|
uint32 OffsetGroupName;
|
||||||
|
uint32 OffsetDescriptiveName;
|
||||||
|
uint32 Flags;
|
||||||
|
Vector3 BoundingBox[2];
|
||||||
|
uint32 OffsetPortals;
|
||||||
|
uint32 CountPortals;
|
||||||
|
uint16 CountBatches[4];
|
||||||
|
uint8 Fogs[4];
|
||||||
|
uint32 LiquidTypeRelated;
|
||||||
|
uint32 WmoId;
|
||||||
|
|
||||||
|
static WMOGroupHeader Read(FILE* stream);
|
||||||
|
};
|
||||||
|
|
||||||
// Dummy class to act as an interface.
|
// Dummy class to act as an interface.
|
||||||
class IDefinition
|
class IDefinition
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
#include "WorldModelGroup.h"
|
#include "WorldModelGroup.h"
|
||||||
#include "ChunkedData.h"
|
#include "ChunkedData.h"
|
||||||
#include "Chunk.h"
|
#include "Chunk.h"
|
||||||
|
#include "Utils.h"
|
||||||
|
|
||||||
WorldModelGroup::WorldModelGroup( std::string path, int groupIndex ) : GroupIndex(groupIndex), IsBad(false)
|
WorldModelGroup::WorldModelGroup( std::string path, int groupIndex ) : GroupIndex(groupIndex), IsBad(false), MOBA(NULL)
|
||||||
{
|
{
|
||||||
Data = new ChunkedData(path);
|
Data = new ChunkedData(path);
|
||||||
if (!Data->Stream)
|
if (!Data->Stream)
|
||||||
@@ -14,16 +15,20 @@ WorldModelGroup::WorldModelGroup( std::string path, int groupIndex ) : GroupInde
|
|||||||
int32 firstSub = mainChunk->FindSubChunkOffset("MOPY");
|
int32 firstSub = mainChunk->FindSubChunkOffset("MOPY");
|
||||||
if (firstSub == -1)
|
if (firstSub == -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
Name = Utils::GetPlainName(path.c_str());
|
||||||
|
|
||||||
FILE* stream = mainChunk->GetStream();
|
FILE* stream = mainChunk->GetStream();
|
||||||
fseek(stream, firstSub, SEEK_SET);
|
fseek(stream, firstSub, SEEK_SET);
|
||||||
SubData = new ChunkedData(stream, mainChunk->Length - firstSub);
|
SubData = new ChunkedData(stream, mainChunk->Length - firstSub);
|
||||||
|
|
||||||
ReadBoundingBox();
|
ReadHeader();
|
||||||
ReadMaterials();
|
ReadMaterials();
|
||||||
ReadTriangles();
|
ReadTriangles();
|
||||||
ReadVertices();
|
ReadVertices();
|
||||||
ReadNormals();
|
ReadNormals();
|
||||||
ReadLiquid();
|
ReadLiquid();
|
||||||
|
ReadBatches();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldModelGroup::ReadNormals()
|
void WorldModelGroup::ReadNormals()
|
||||||
@@ -108,15 +113,23 @@ void WorldModelGroup::ReadMaterials()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldModelGroup::ReadBoundingBox()
|
void WorldModelGroup::ReadHeader()
|
||||||
{
|
{
|
||||||
Chunk* chunk = Data->GetChunkByName("MOGP");
|
Chunk* chunk = Data->GetChunkByName("MOGP");
|
||||||
if (!chunk)
|
if (!chunk)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
FILE* stream = chunk->GetStream();
|
FILE* stream = chunk->GetStream();
|
||||||
fseek(stream, 8, SEEK_CUR);
|
Header = WMOGroupHeader::Read(stream);
|
||||||
fread(&Flags, sizeof(uint32), 1, stream);
|
}
|
||||||
BoundingBox[0] = Vector3::Read(stream);
|
|
||||||
BoundingBox[1] = Vector3::Read(stream);
|
void WorldModelGroup::ReadBatches()
|
||||||
|
{
|
||||||
|
Chunk* chunk = Data->GetChunkByName("MOBA");
|
||||||
|
if (!chunk)
|
||||||
|
return;
|
||||||
|
|
||||||
|
MOBALength = chunk->Length / 2;
|
||||||
|
MOBA = new uint16[MOBALength];
|
||||||
|
fread(MOBA, sizeof(uint16), MOBALength, chunk->GetStream());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,13 +10,17 @@ public:
|
|||||||
ChunkedData* Data;
|
ChunkedData* Data;
|
||||||
ChunkedData* SubData;
|
ChunkedData* SubData;
|
||||||
int GroupIndex;
|
int GroupIndex;
|
||||||
Vector3 BoundingBox[2];
|
std::string Name;
|
||||||
uint32 Flags;
|
WMOGroupHeader Header;
|
||||||
|
|
||||||
std::vector<uint8> TriangleFlags;
|
std::vector<uint8> TriangleFlags;
|
||||||
std::vector<uint8> TriangleMaterials;
|
std::vector<uint8> TriangleMaterials;
|
||||||
std::vector<Triangle<uint16> > Triangles;
|
std::vector<Triangle<uint16> > Triangles;
|
||||||
std::vector<Vector3> Vertices;
|
std::vector<Vector3> Vertices;
|
||||||
std::vector<Vector3> Normals;
|
std::vector<Vector3> Normals;
|
||||||
|
// @ToDo: Research.
|
||||||
|
uint16* MOBA;
|
||||||
|
uint32 MOBALength;
|
||||||
|
|
||||||
bool HasLiquidData;
|
bool HasLiquidData;
|
||||||
bool IsBad;
|
bool IsBad;
|
||||||
@@ -28,6 +32,7 @@ private:
|
|||||||
void ReadVertices();
|
void ReadVertices();
|
||||||
void ReadTriangles();
|
void ReadTriangles();
|
||||||
void ReadMaterials();
|
void ReadMaterials();
|
||||||
void ReadBoundingBox();
|
void ReadHeader();
|
||||||
|
void ReadBatches();
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
Reference in New Issue
Block a user