TrinityCore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
VMAP::TileAssembler Class Reference

#include <TileAssembler.h>

Public Member Functions

 TileAssembler (const std::string &pSrcDirName, const std::string &pDestDirName)
 
virtual ~TileAssembler ()
 
bool convertWorld2 ()
 
bool readMapSpawns ()
 
bool calculateTransformedBound (ModelSpawn &spawn)
 
void exportGameobjectModels ()
 
bool convertRawFile (const std::string &pModelFilename)
 
void setModelNameFilterMethod (bool(*pFilterMethod)(char *pName))
 
std::string getDirEntryNameFromModName (unsigned int pMapId, const std::string &pModPosName)
 

Private Attributes

std::string iDestDir
 
std::string iSrcDir
 
bool(* iFilterMethod )(char *pName)
 
G3D::Table< std::string,
unsigned int > 
iUniqueNameIds
 
unsigned int iCurrentUniqueNameId
 
MapData mapData
 
std::set< std::string > spawnedModelFiles
 

Constructor & Destructor Documentation

VMAP::TileAssembler::TileAssembler ( const std::string &  pSrcDirName,
const std::string &  pDestDirName 
)
56  : iDestDir(pDestDirName), iSrcDir(pSrcDirName), iFilterMethod(NULL), iCurrentUniqueNameId(0)
57  {
58  //mkdir(iDestDir);
59  //init();
60  }
unsigned int iCurrentUniqueNameId
Definition: TileAssembler.h:100
arena_t NULL
Definition: jemalloc_internal.h:624
std::string iDestDir
Definition: TileAssembler.h:96
bool(* iFilterMethod)(char *pName)
Definition: TileAssembler.h:98
std::string iSrcDir
Definition: TileAssembler.h:97
VMAP::TileAssembler::~TileAssembler ( )
virtual
63  {
64  //delete iCoordModelMapping;
65  }

Member Function Documentation

bool VMAP::TileAssembler::calculateTransformedBound ( ModelSpawn spawn)
251  {
252  std::string modelFilename(iSrcDir);
253  modelFilename.push_back('/');
254  modelFilename.append(spawn.name);
255 
256  ModelPosition modelPosition;
257  modelPosition.iDir = spawn.iRot;
258  modelPosition.iScale = spawn.iScale;
259  modelPosition.init();
260 
261  WorldModel_Raw raw_model;
262  if (!raw_model.Read(modelFilename.c_str()))
263  return false;
264 
265  uint32 groups = raw_model.groupsArray.size();
266  if (groups != 1)
267  printf("Warning: '%s' does not seem to be a M2 model!\n", modelFilename.c_str());
268 
269  AABox modelBound;
270  bool boundEmpty=true;
271 
272  for (uint32 g=0; g<groups; ++g) // should be only one for M2 files...
273  {
274  std::vector<Vector3>& vertices = raw_model.groupsArray[g].vertexArray;
275 
276  if (vertices.empty())
277  {
278  std::cout << "error: model '" << spawn.name << "' has no geometry!" << std::endl;
279  continue;
280  }
281 
282  uint32 nvectors = vertices.size();
283  for (uint32 i = 0; i < nvectors; ++i)
284  {
285  Vector3 v = modelPosition.transform(vertices[i]);
286 
287  if (boundEmpty)
288  modelBound = AABox(v, v), boundEmpty=false;
289  else
290  modelBound.merge(v);
291  }
292  }
293  spawn.iBound = modelBound + spawn.iPos;
294  spawn.flags |= MOD_HAS_BOUND;
295  return true;
296  }
void merge(const AABox &a)
Definition: AABox.h:106
Definition: Vector3.h:58
uint32_t uint32
Definition: Define.h:150
Definition: ModelInstance.h:39
Definition: AABox.h:32
std::string iSrcDir
Definition: TileAssembler.h:97
void printf(BasicWriter< Char > &w, BasicCStringRef< Char > format, ArgList args)
Definition: format.h:3083

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool VMAP::TileAssembler::convertRawFile ( const std::string &  pModelFilename)
308  {
309  bool success = true;
310  std::string filename = iSrcDir;
311  if (filename.length() >0)
312  filename.push_back('/');
313  filename.append(pModelFilename);
314 
315  WorldModel_Raw raw_model;
316  if (!raw_model.Read(filename.c_str()))
317  return false;
318 
319  // write WorldModel
320  WorldModel model;
321  model.setRootWmoID(raw_model.RootWMOID);
322  if (!raw_model.groupsArray.empty())
323  {
324  std::vector<GroupModel> groupsArray;
325 
326  uint32 groups = raw_model.groupsArray.size();
327  for (uint32 g = 0; g < groups; ++g)
328  {
329  GroupModel_Raw& raw_group = raw_model.groupsArray[g];
330  groupsArray.push_back(GroupModel(raw_group.mogpflags, raw_group.GroupWMOID, raw_group.bounds ));
331  groupsArray.back().setMeshData(raw_group.vertexArray, raw_group.triangles);
332  groupsArray.back().setLiquidData(raw_group.liquid);
333  }
334 
335  model.setGroupModels(groupsArray);
336  }
337 
338  success = model.writeFile(iDestDir + "/" + pModelFilename + ".vmo");
339  //std::cout << "readRawFile2: '" << pModelFilename << "' tris: " << nElements << " nodes: " << nNodes << std::endl;
340  return success;
341  }
std::string iDestDir
Definition: TileAssembler.h:96
uint32_t uint32
Definition: Define.h:150
std::string iSrcDir
Definition: TileAssembler.h:97

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool VMAP::TileAssembler::convertWorld2 ( )
Todo:
remove extractor hack and uncomment below line:
68  {
69  bool success = readMapSpawns();
70  if (!success)
71  return false;
72 
73  // export Map data
74  for (MapData::iterator map_iter = mapData.begin(); map_iter != mapData.end() && success; ++map_iter)
75  {
76  // build global map tree
77  std::vector<ModelSpawn*> mapSpawns;
78  UniqueEntryMap::iterator entry;
79  printf("Calculating model bounds for map %u...\n", map_iter->first);
80  for (entry = map_iter->second->UniqueEntries.begin(); entry != map_iter->second->UniqueEntries.end(); ++entry)
81  {
82  // M2 models don't have a bound set in WDT/ADT placement data, i still think they're not used for LoS at all on retail
83  if (entry->second.flags & MOD_M2)
84  {
85  if (!calculateTransformedBound(entry->second))
86  break;
87  }
88  else if (entry->second.flags & MOD_WORLDSPAWN) // WMO maps and terrain maps use different origin, so we need to adapt :/
89  {
91  //entry->second.iPos += Vector3(533.33333f*32, 533.33333f*32, 0.f);
92  entry->second.iBound = entry->second.iBound + Vector3(533.33333f*32, 533.33333f*32, 0.f);
93  }
94  mapSpawns.push_back(&(entry->second));
95  spawnedModelFiles.insert(entry->second.name);
96  }
97 
98  printf("Creating map tree for map %u...\n", map_iter->first);
99  BIH pTree;
100 
101  try
102  {
103  pTree.build(mapSpawns, BoundsTrait<ModelSpawn*>::getBounds);
104  }
105  catch (std::exception& e)
106  {
107  printf("Exception ""%s"" when calling pTree.build", e.what());
108  return false;
109  }
110 
111  // ===> possibly move this code to StaticMapTree class
112  std::map<uint32, uint32> modelNodeIdx;
113  for (uint32 i=0; i<mapSpawns.size(); ++i)
114  modelNodeIdx.insert(pair<uint32, uint32>(mapSpawns[i]->ID, i));
115 
116  // write map tree file
117  std::stringstream mapfilename;
118  mapfilename << iDestDir << '/' << std::setfill('0') << std::setw(4) << map_iter->first << ".vmtree";
119  FILE* mapfile = fopen(mapfilename.str().c_str(), "wb");
120  if (!mapfile)
121  {
122  success = false;
123  printf("Cannot open %s\n", mapfilename.str().c_str());
124  break;
125  }
126 
127  //general info
128  if (success && fwrite(VMAP_MAGIC, 1, 8, mapfile) != 8) success = false;
129  uint32 globalTileID = StaticMapTree::packTileID(65, 65);
130  pair<TileMap::iterator, TileMap::iterator> globalRange = map_iter->second->TileEntries.equal_range(globalTileID);
131  char isTiled = globalRange.first == globalRange.second; // only maps without terrain (tiles) have global WMO
132  if (success && fwrite(&isTiled, sizeof(char), 1, mapfile) != 1) success = false;
133  // Nodes
134  if (success && fwrite("NODE", 4, 1, mapfile) != 1) success = false;
135  if (success) success = pTree.writeToFile(mapfile);
136  // global map spawns (WDT), if any (most instances)
137  if (success && fwrite("GOBJ", 4, 1, mapfile) != 1) success = false;
138 
139  for (TileMap::iterator glob=globalRange.first; glob != globalRange.second && success; ++glob)
140  {
141  success = ModelSpawn::writeToFile(mapfile, map_iter->second->UniqueEntries[glob->second]);
142  }
143 
144  fclose(mapfile);
145 
146  // <====
147 
148  // write map tile files, similar to ADT files, only with extra BSP tree node info
149  TileMap &tileEntries = map_iter->second->TileEntries;
150  TileMap::iterator tile;
151  for (tile = tileEntries.begin(); tile != tileEntries.end(); ++tile)
152  {
153  const ModelSpawn &spawn = map_iter->second->UniqueEntries[tile->second];
154  if (spawn.flags & MOD_WORLDSPAWN) // WDT spawn, saved as tile 65/65 currently...
155  continue;
156  uint32 nSpawns = tileEntries.count(tile->first);
157  std::stringstream tilefilename;
158  tilefilename.fill('0');
159  tilefilename << iDestDir << '/' << std::setw(4) << map_iter->first << '_';
160  uint32 x, y;
161  StaticMapTree::unpackTileID(tile->first, x, y);
162  tilefilename << std::setw(2) << x << '_' << std::setw(2) << y << ".vmtile";
163  if (FILE* tilefile = fopen(tilefilename.str().c_str(), "wb"))
164  {
165  // file header
166  if (success && fwrite(VMAP_MAGIC, 1, 8, tilefile) != 8) success = false;
167  // write number of tile spawns
168  if (success && fwrite(&nSpawns, sizeof(uint32), 1, tilefile) != 1) success = false;
169  // write tile spawns
170  for (uint32 s=0; s<nSpawns; ++s)
171  {
172  if (s)
173  ++tile;
174  const ModelSpawn &spawn2 = map_iter->second->UniqueEntries[tile->second];
175  success = success && ModelSpawn::writeToFile(tilefile, spawn2);
176  // MapTree nodes to update when loading tile:
177  std::map<uint32, uint32>::iterator nIdx = modelNodeIdx.find(spawn2.ID);
178  if (success && fwrite(&nIdx->second, sizeof(uint32), 1, tilefile) != 1) success = false;
179  }
180  fclose(tilefile);
181  }
182  }
183  // break; //test, extract only first map; TODO: remvoe this line
184  }
185 
186  // add an object models, listed in temp_gameobject_models file
188  // export objects
189  std::cout << "\nConverting Model Files" << std::endl;
190  for (std::set<std::string>::iterator mfile = spawnedModelFiles.begin(); mfile != spawnedModelFiles.end(); ++mfile)
191  {
192  std::cout << "Converting " << *mfile << std::endl;
193  if (!convertRawFile(*mfile))
194  {
195  std::cout << "error converting " << *mfile << std::endl;
196  success = false;
197  break;
198  }
199  }
200 
201  //cleanup:
202  for (MapData::iterator map_iter = mapData.begin(); map_iter != mapData.end(); ++map_iter)
203  {
204  delete map_iter->second;
205  }
206  return success;
207  }
Definition: ModelInstance.h:38
static uint32 packTileID(uint32 tileX, uint32 tileY)
Definition: MapTree.h:64
bool convertRawFile(const std::string &pModelFilename)
Definition: TileAssembler.cpp:307
bool readMapSpawns()
Definition: TileAssembler.cpp:209
std::multimap< uint32, uint32 > TileMap
Definition: TileAssembler.h:56
std::set< std::string > spawnedModelFiles
Definition: TileAssembler.h:102
bool writeToFile(FILE *wf) const
Definition: BoundingIntervalHierarchy.cpp:247
static bool writeToFile(FILE *rw, const ModelSpawn &spawn)
Definition: ModelInstance.cpp:200
void exportGameobjectModels()
Definition: TileAssembler.cpp:343
Definition: Vector3.h:58
Definition: ModelInstance.h:37
std::string iDestDir
Definition: TileAssembler.h:96
MapData mapData
Definition: TileAssembler.h:101
bool calculateTransformedBound(ModelSpawn &spawn)
Definition: TileAssembler.cpp:250
uint32_t uint32
Definition: Define.h:150
G3D::int16 y
Definition: Vector2int16.h:38
Definition: BoundsTrait.h:17
G3D::int16 x
Definition: Vector2int16.h:37
void build(const PrimArray &primitives, BoundsFunc &getBounds, uint32 leafSize=3, bool printStats=false)
Definition: BoundingIntervalHierarchy.h:84
Definition: BoundingIntervalHierarchy.h:70
const char VMAP_MAGIC[]
Definition: VMapDefinitions.h:28
static void unpackTileID(uint32 ID, uint32 &tileX, uint32 &tileY)
Definition: MapTree.h:65
void printf(BasicWriter< Char > &w, BasicCStringRef< Char > format, ArgList args)
Definition: format.h:3083

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void VMAP::TileAssembler::exportGameobjectModels ( )
344  {
345  FILE* model_list = fopen((iSrcDir + "/" + "temp_gameobject_models").c_str(), "rb");
346  if (!model_list)
347  return;
348 
349  FILE* model_list_copy = fopen((iDestDir + "/" + GAMEOBJECT_MODELS).c_str(), "wb");
350  if (!model_list_copy)
351  {
352  fclose(model_list);
353  return;
354  }
355 
356  uint32 name_length, displayId;
357  char buff[500];
358  while (true)
359  {
360  if (fread(&displayId, sizeof(uint32), 1, model_list) != 1)
361  if (feof(model_list)) // EOF flag is only set after failed reading attempt
362  break;
363 
364  if (fread(&name_length, sizeof(uint32), 1, model_list) != 1
365  || name_length >= sizeof(buff)
366  || fread(&buff, sizeof(char), name_length, model_list) != name_length)
367  {
368  std::cout << "\nFile 'temp_gameobject_models' seems to be corrupted" << std::endl;
369  break;
370  }
371 
372  std::string model_name(buff, name_length);
373 
374  WorldModel_Raw raw_model;
375  if (!raw_model.Read((iSrcDir + "/" + model_name).c_str()) )
376  continue;
377 
378  spawnedModelFiles.insert(model_name);
379  AABox bounds;
380  bool boundEmpty = true;
381  for (uint32 g = 0; g < raw_model.groupsArray.size(); ++g)
382  {
383  std::vector<Vector3>& vertices = raw_model.groupsArray[g].vertexArray;
384 
385  uint32 nvectors = vertices.size();
386  for (uint32 i = 0; i < nvectors; ++i)
387  {
388  Vector3& v = vertices[i];
389  if (boundEmpty)
390  bounds = AABox(v, v), boundEmpty = false;
391  else
392  bounds.merge(v);
393  }
394  }
395 
396  if (bounds.isEmpty())
397  {
398  std::cout << "\nModel " << std::string(buff, name_length) << " has empty bounding box" << std::endl;
399  continue;
400  }
401 
402  if (!bounds.isFinite())
403  {
404  std::cout << "\nModel " << std::string(buff, name_length) << " has invalid bounding box" << std::endl;
405  continue;
406  }
407 
408  fwrite(&displayId, sizeof(uint32), 1, model_list_copy);
409  fwrite(&name_length, sizeof(uint32), 1, model_list_copy);
410  fwrite(&buff, sizeof(char), name_length, model_list_copy);
411  fwrite(&bounds.low(), sizeof(Vector3), 1, model_list_copy);
412  fwrite(&bounds.high(), sizeof(Vector3), 1, model_list_copy);
413  }
414 
415  fclose(model_list);
416  fclose(model_list_copy);
417  }
void merge(const AABox &a)
Definition: AABox.h:106
std::set< std::string > spawnedModelFiles
Definition: TileAssembler.h:102
bool isFinite() const
Definition: AABox.h:131
const Point3 & low() const
Definition: AABox.h:136
Definition: Vector3.h:58
ModelList model_list
Definition: GameObjectModel.cpp:41
std::string iDestDir
Definition: TileAssembler.h:96
uint32_t uint32
Definition: Define.h:150
Definition: AABox.h:32
const char GAMEOBJECT_MODELS[]
Definition: VMapDefinitions.h:30
const Point3 & high() const
Definition: AABox.h:141
bool isEmpty() const
Definition: AABox.h:67
std::string iSrcDir
Definition: TileAssembler.h:97

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::string VMAP::TileAssembler::getDirEntryNameFromModName ( unsigned int  pMapId,
const std::string &  pModPosName 
)
bool VMAP::TileAssembler::readMapSpawns ( )
210  {
211  std::string fname = iSrcDir + "/dir_bin";
212  FILE* dirf = fopen(fname.c_str(), "rb");
213  if (!dirf)
214  {
215  printf("Could not read dir_bin file!\n");
216  return false;
217  }
218  printf("Read coordinate mapping...\n");
219  uint32 mapID, tileX, tileY, check=0;
220  G3D::Vector3 v1, v2;
221  ModelSpawn spawn;
222  while (!feof(dirf))
223  {
224  check = 0;
225  // read mapID, tileX, tileY, Flags, adtID, ID, Pos, Rot, Scale, Bound_lo, Bound_hi, name
226  check += fread(&mapID, sizeof(uint32), 1, dirf);
227  if (check == 0) // EoF...
228  break;
229  check += fread(&tileX, sizeof(uint32), 1, dirf);
230  check += fread(&tileY, sizeof(uint32), 1, dirf);
231  if (!ModelSpawn::readFromFile(dirf, spawn))
232  break;
233 
234  MapSpawns *current;
235  MapData::iterator map_iter = mapData.find(mapID);
236  if (map_iter == mapData.end())
237  {
238  printf("spawning Map %u\n", mapID);
239  mapData[mapID] = current = new MapSpawns();
240  }
241  else current = (*map_iter).second;
242  current->UniqueEntries.insert(pair<uint32, ModelSpawn>(spawn.ID, spawn));
243  current->TileEntries.insert(pair<uint32, uint32>(StaticMapTree::packTileID(tileX, tileY), spawn.ID));
244  }
245  bool success = (ferror(dirf) == 0);
246  fclose(dirf);
247  return success;
248  }
static uint32 packTileID(uint32 tileX, uint32 tileY)
Definition: MapTree.h:64
static bool readFromFile(FILE *rf, ModelSpawn &spawn)
Definition: ModelInstance.cpp:154
Definition: Vector3.h:58
MapData mapData
Definition: TileAssembler.h:101
uint32_t uint32
Definition: Define.h:150
T check(T value)
Definition: format.h:305
std::string iSrcDir
Definition: TileAssembler.h:97
void printf(BasicWriter< Char > &w, BasicCStringRef< Char > format, ArgList args)
Definition: format.h:3083

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void VMAP::TileAssembler::setModelNameFilterMethod ( bool(*)(char *pName)  pFilterMethod)
inline
114 { iFilterMethod = pFilterMethod; }
bool(* iFilterMethod)(char *pName)
Definition: TileAssembler.h:98

Member Data Documentation

unsigned int VMAP::TileAssembler::iCurrentUniqueNameId
private
std::string VMAP::TileAssembler::iDestDir
private
bool(* VMAP::TileAssembler::iFilterMethod)(char *pName)
private
std::string VMAP::TileAssembler::iSrcDir
private
G3D::Table<std::string, unsigned int > VMAP::TileAssembler::iUniqueNameIds
private
MapData VMAP::TileAssembler::mapData
private
std::set<std::string> VMAP::TileAssembler::spawnedModelFiles
private

The documentation for this class was generated from the following files: