AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
VMAP::StaticMapTree Class Reference

#include "MapTree.h"

Public Member Functions

 StaticMapTree (uint32 mapID, const std::string &basePath)
 
 ~StaticMapTree ()
 Make sure to call unloadMap() to unregister acquired model references before destroying.
 
bool isInLineOfSight (const G3D::Vector3 &pos1, const G3D::Vector3 &pos2, ModelIgnoreFlags ignoreFlags) const
 
bool GetObjectHitPos (const G3D::Vector3 &pos1, const G3D::Vector3 &pos2, G3D::Vector3 &pResultHitPos, float pModifyDist) const
 
float getHeight (const G3D::Vector3 &pPos, float maxSearchDist) const
 
bool GetLocationInfo (const G3D::Vector3 &pos, LocationInfo &info) const
 
bool InitMap (const std::string &fname, VMapMgr2 *vm)
 
void UnloadMap (VMapMgr2 *vm)
 
bool LoadMapTile (uint32 tileX, uint32 tileY, VMapMgr2 *vm)
 
void UnloadMapTile (uint32 tileX, uint32 tileY, VMapMgr2 *vm)
 
bool isTiled () const
 
uint32 numLoadedTiles () const
 
void GetModelInstances (ModelInstance *&models, uint32 &count)
 

Static Public Member Functions

static std::string getTileFileName (uint32 mapID, uint32 tileX, uint32 tileY)
 
static uint32 packTileID (uint32 tileX, uint32 tileY)
 
static void unpackTileID (uint32 ID, uint32 &tileX, uint32 &tileY)
 
static LoadResult CanLoadMap (const std::string &basePath, uint32 mapID, uint32 tileX, uint32 tileY)
 

Private Types

typedef std::unordered_map< uint32, bool > loadedTileMap
 
typedef std::unordered_map< uint32, uint32loadedSpawnMap
 

Private Member Functions

bool GetIntersectionTime (const G3D::Ray &pRay, float &pMaxDist, bool StopAtFirstHit, ModelIgnoreFlags ignoreFlags) const
 

Private Attributes

uint32 iMapID
 
bool iIsTiled
 
BIH iTree
 
ModelInstanceiTreeValues
 
uint32 iNTreeValues
 
loadedTileMap iLoadedTiles
 
loadedSpawnMap iLoadedSpawns
 
std::string iBasePath
 

Detailed Description

Member Typedef Documentation

◆ loadedSpawnMap

typedef std::unordered_map<uint32, uint32> VMAP::StaticMapTree::loadedSpawnMap
private

◆ loadedTileMap

typedef std::unordered_map<uint32, bool> VMAP::StaticMapTree::loadedTileMap
private

Constructor & Destructor Documentation

◆ StaticMapTree()

VMAP::StaticMapTree::StaticMapTree ( uint32  mapID,
const std::string &  basePath 
)
94 : iMapID(mapID), iIsTiled(false), iTreeValues(0), iBasePath(basePath)
95 {
96 if (iBasePath.length() > 0 && iBasePath[iBasePath.length() - 1] != '/' && iBasePath[iBasePath.length() - 1] != '\\')
97 {
98 iBasePath.push_back('/');
99 }
100 }
uint32 iMapID
Definition MapTree.h:53
bool iIsTiled
Definition MapTree.h:54
std::string iBasePath
Definition MapTree.h:65
ModelInstance * iTreeValues
Definition MapTree.h:56

References iBasePath.

◆ ~StaticMapTree()

VMAP::StaticMapTree::~StaticMapTree ( )

Make sure to call unloadMap() to unregister acquired model references before destroying.

105 {
106 delete[] iTreeValues;
107 }

References iTreeValues.

Member Function Documentation

◆ CanLoadMap()

LoadResult VMAP::StaticMapTree::CanLoadMap ( const std::string &  basePath,
uint32  mapID,
uint32  tileX,
uint32  tileY 
)
static
216 {
217 std::string basePath = vmapPath;
218 if (basePath.length() > 0 && basePath[basePath.length() - 1] != '/' && basePath[basePath.length() - 1] != '\\')
219 {
220 basePath.push_back('/');
221 }
222 std::string fullname = basePath + VMapMgr2::getMapFileName(mapID);
223
225
226 FILE* rf = fopen(fullname.c_str(), "rb");
227 if (!rf)
228 {
230 }
231
232 char tiled;
233 char chunk[8];
234 if (!readChunk(rf, chunk, VMAP_MAGIC, 8) || fread(&tiled, sizeof(char), 1, rf) != 1)
235 {
236 fclose(rf);
238 }
239 if (tiled)
240 {
241 std::string tilefile = basePath + getTileFileName(mapID, tileX, tileY);
242 FILE* tf = fopen(tilefile.c_str(), "rb");
243 if (!tf)
244 {
246 }
247 else
248 {
249 if (!readChunk(tf, chunk, VMAP_MAGIC, 8))
250 {
252 }
253 fclose(tf);
254 }
255 }
256 fclose(rf);
257 return result;
258 }
static std::string getTileFileName(uint32 mapID, uint32 tileX, uint32 tileY)
Definition MapTree.cpp:76
static std::string getMapFileName(unsigned int mapId)
Definition VMapMgr2.cpp:89
bool readChunk(FILE *rf, char *dest, const char *compare, uint32 len)
Definition TileAssembler.cpp:40
LoadResult
Definition IVMapMgr.h:42
const char VMAP_MAGIC[]
Definition VMapDefinitions.h:25

References VMAP::FileNotFound, VMAP::VMapMgr2::getMapFileName(), getTileFileName(), VMAP::readChunk(), VMAP::Success, VMAP::VersionMismatch, and VMAP::VMAP_MAGIC.

Referenced by VMAP::VMapMgr2::existsMap().

◆ getHeight()

float VMAP::StaticMapTree::getHeight ( const G3D::Vector3 &  pPos,
float  maxSearchDist 
) const
201 {
202 float height = G3D::finf();
203 Vector3 dir = Vector3(0, 0, -1);
204 G3D::Ray ray(pPos, dir); // direction with length of 1
205 float maxDist = maxSearchDist;
206 if (GetIntersectionTime(ray, maxDist, false, ModelIgnoreFlags::Nothing))
207 {
208 height = pPos.z - maxDist;
209 }
210 return (height);
211 }
bool GetIntersectionTime(const G3D::Ray &pRay, float &pMaxDist, bool StopAtFirstHit, ModelIgnoreFlags ignoreFlags) const
Definition MapTree.cpp:115

References GetIntersectionTime(), and VMAP::Nothing.

◆ GetIntersectionTime()

bool VMAP::StaticMapTree::GetIntersectionTime ( const G3D::Ray &  pRay,
float &  pMaxDist,
bool  StopAtFirstHit,
ModelIgnoreFlags  ignoreFlags 
) const
private

If intersection is found within pMaxDist, sets pMaxDist to intersection distance and returns true. Else, pMaxDist is not modified and returns false;

116 {
117 float distance = pMaxDist;
118 MapRayCallback intersectionCallBack(iTreeValues, ignoreFlags);
119 iTree.intersectRay(pRay, intersectionCallBack, distance, StopAtFirstHit);
120 if (intersectionCallBack.didHit())
121 {
122 pMaxDist = distance;
123 }
124 return intersectionCallBack.didHit();
125 }
void intersectRay(const G3D::Ray &r, RayCallback &intersectCallback, float &maxDist, bool stopAtFirstHit) const
Definition BoundingIntervalHierarchy.h:123
BIH iTree
Definition MapTree.h:55

References VMAP::MapRayCallback::didHit(), BIH::intersectRay(), iTree, and iTreeValues.

Referenced by getHeight(), GetObjectHitPos(), and isInLineOfSight().

◆ GetLocationInfo()

bool VMAP::StaticMapTree::GetLocationInfo ( const G3D::Vector3 &  pos,
LocationInfo info 
) const
87 {
88 LocationInfoCallback intersectionCallBack(iTreeValues, info);
89 iTree.intersectPoint(pos, intersectionCallBack);
90 return intersectionCallBack.result;
91 }
void intersectPoint(const G3D::Vector3 &p, IsectCallback &intersectCallback) const
Definition BoundingIntervalHierarchy.h:286

References BIH::intersectPoint(), iTree, iTreeValues, and VMAP::LocationInfoCallback::result.

◆ GetModelInstances()

void VMAP::StaticMapTree::GetModelInstances ( ModelInstance *&  models,
uint32 count 
)
497 {
498 models = iTreeValues;
499 count = iNTreeValues;
500 }
uint32 iNTreeValues
Definition MapTree.h:57

References iNTreeValues, and iTreeValues.

◆ GetObjectHitPos()

bool VMAP::StaticMapTree::GetObjectHitPos ( const G3D::Vector3 &  pos1,
const G3D::Vector3 &  pos2,
G3D::Vector3 &  pResultHitPos,
float  pModifyDist 
) const

When moving from pos1 to pos2 check if we hit an object. Return true and the position if we hit one Return the hit pos or the original dest pos

156 {
157 bool result = false;
158 float maxDist = (pPos2 - pPos1).magnitude();
159 // valid map coords should *never ever* produce float overflow, but this would produce NaNs too
160 ASSERT(maxDist < std::numeric_limits<float>::max());
161 // prevent NaN values which can cause BIH intersection to enter infinite loop
162 if (maxDist < 1e-10f)
163 {
164 pResultHitPos = pPos2;
165 return false;
166 }
167 Vector3 dir = (pPos2 - pPos1) / maxDist; // direction with length of 1
168 G3D::Ray ray(pPos1, dir);
169 float dist = maxDist;
170 if (GetIntersectionTime(ray, dist, false, ModelIgnoreFlags::Nothing))
171 {
172 pResultHitPos = pPos1 + dir * dist;
173 if (pModifyDist < 0)
174 {
175 if ((pResultHitPos - pPos1).magnitude() > -pModifyDist)
176 {
177 pResultHitPos = pResultHitPos + dir * pModifyDist;
178 }
179 else
180 {
181 pResultHitPos = pPos1;
182 }
183 }
184 else
185 {
186 pResultHitPos = pResultHitPos + dir * pModifyDist;
187 }
188 result = true;
189 }
190 else
191 {
192 pResultHitPos = pPos2;
193 result = false;
194 }
195 return result;
196 }
#define ASSERT
Definition Errors.h:68

References ASSERT, GetIntersectionTime(), and VMAP::Nothing.

◆ getTileFileName()

std::string VMAP::StaticMapTree::getTileFileName ( uint32  mapID,
uint32  tileX,
uint32  tileY 
)
static
77 {
78 std::stringstream tilefilename;
79 tilefilename.fill('0');
80 tilefilename << std::setw(3) << mapID << '_';
81 //tilefilename << std::setw(2) << tileX << '_' << std::setw(2) << tileY << ".vmtile";
82 tilefilename << std::setw(2) << tileY << '_' << std::setw(2) << tileX << ".vmtile";
83 return tilefilename.str();
84 }

Referenced by CanLoadMap(), LoadMapTile(), and UnloadMapTile().

◆ InitMap()

bool VMAP::StaticMapTree::InitMap ( const std::string &  fname,
VMapMgr2 vm 
)
263 {
264 //VMAP_DEBUG_LOG(LOG_FILTER_MAPS, "StaticMapTree::InitMap() : initializing StaticMapTree '{}'", fname);
265 bool success = false;
266 std::string fullname = iBasePath + fname;
267 FILE* rf = fopen(fullname.c_str(), "rb");
268 if (!rf)
269 {
270 return false;
271 }
272
273 char chunk[8];
274 char tiled = '\0';
275
276 if (readChunk(rf, chunk, VMAP_MAGIC, 8) && fread(&tiled, sizeof(char), 1, rf) == 1 &&
277 readChunk(rf, chunk, "NODE", 4) && iTree.readFromFile(rf))
278 {
280 iTreeValues = new ModelInstance[iNTreeValues];
281 success = readChunk(rf, chunk, "GOBJ", 4);
282 }
283
284 iIsTiled = bool(tiled);
285
286 // global model spawns
287 // only non-tiled maps have them, and if so exactly one (so far at least...)
288 ModelSpawn spawn;
289#ifdef VMAP_DEBUG
290 //LOG_DEBUG(LOG_FILTER_MAPS, "StaticMapTree::InitMap() : map isTiled: {}", static_cast<uint32>(iIsTiled));
291#endif
292 if (!iIsTiled && ModelSpawn::readFromFile(rf, spawn))
293 {
294 WorldModel* model = vm->acquireModelInstance(iBasePath, spawn.name, spawn.flags);
295 //VMAP_DEBUG_LOG(LOG_FILTER_MAPS, "StaticMapTree::InitMap() : loading {}", spawn.name);
296 if (model)
297 {
298 // assume that global model always is the first and only tree value (could be improved...)
299 iTreeValues[0] = ModelInstance(spawn, model);
300 iLoadedSpawns[0] = 1;
301 }
302 else
303 {
304 success = false;
305 //VMAP_ERROR_LOG(LOG_FILTER_GENERAL, "StaticMapTree::InitMap() : could not acquire WorldModel pointer for '{}'", spawn.name);
306 }
307 }
308
309 fclose(rf);
310 return success;
311 }
uint32 primCount() const
Definition BoundingIntervalHierarchy.h:119
bool readFromFile(FILE *rf)
Definition BoundingIntervalHierarchy.cpp:287
static bool readFromFile(FILE *rf, ModelSpawn &spawn)
Definition ModelInstance.cpp:125
loadedSpawnMap iLoadedSpawns
Definition MapTree.h:64

References VMAP::VMapMgr2::acquireModelInstance(), VMAP::ModelSpawn::flags, iBasePath, iIsTiled, iLoadedSpawns, iNTreeValues, iTree, iTreeValues, VMAP::ModelSpawn::name, BIH::primCount(), VMAP::readChunk(), BIH::readFromFile(), VMAP::ModelSpawn::readFromFile(), and VMAP::VMAP_MAGIC.

Referenced by VMAP::VMapMgr2::_loadMap().

◆ isInLineOfSight()

bool VMAP::StaticMapTree::isInLineOfSight ( const G3D::Vector3 &  pos1,
const G3D::Vector3 &  pos2,
ModelIgnoreFlags  ignoreFlags 
) const
129 {
130 float maxDist = (pos2 - pos1).magnitude();
131 // return false if distance is over max float, in case of cheater teleporting to the end of the universe
132 if (maxDist == std::numeric_limits<float>::max() || !std::isfinite(maxDist))
133 {
134 return false;
135 }
136
137 // valid map coords should *never ever* produce float overflow, but this would produce NaNs too
138 ASSERT(maxDist < std::numeric_limits<float>::max());
139 // prevent NaN values which can cause BIH intersection to enter infinite loop
140 if (maxDist < 1e-10f)
141 {
142 return true;
143 }
144 // direction with length of 1
145 G3D::Ray ray = G3D::Ray::fromOriginAndDirection(pos1, (pos2 - pos1) / maxDist);
146
147 return !GetIntersectionTime(ray, maxDist, true, ignoreFlags);
148 }

References ASSERT, and GetIntersectionTime().

◆ isTiled()

bool VMAP::StaticMapTree::isTiled ( ) const
inline
88{ return iIsTiled; }

References iIsTiled.

◆ LoadMapTile()

bool VMAP::StaticMapTree::LoadMapTile ( uint32  tileX,
uint32  tileY,
VMapMgr2 vm 
)
332 {
333 if (!iIsTiled)
334 {
335 // currently, core creates grids for all maps, whether it has terrain tiles or not
336 // so we need "fake" tile loads to know when we can unload map geometry
337 iLoadedTiles[packTileID(tileX, tileY)] = false;
338 return true;
339 }
340 if (!iTreeValues)
341 {
342 LOG_ERROR("maps", "StaticMapTree::LoadMapTile() : tree has not been initialized [{}, {}]", tileX, tileY);
343 return false;
344 }
345 bool result = true;
346
347 std::string tilefile = iBasePath + getTileFileName(iMapID, tileX, tileY);
348 FILE* tf = fopen(tilefile.c_str(), "rb");
349 if (tf)
350 {
351 char chunk[8];
352
353 if (!readChunk(tf, chunk, VMAP_MAGIC, 8))
354 {
355 result = false;
356 }
357 uint32 numSpawns = 0;
358 if (result && fread(&numSpawns, sizeof(uint32), 1, tf) != 1)
359 {
360 result = false;
361 }
362 for (uint32 i = 0; i < numSpawns && result; ++i)
363 {
364 // read model spawns
365 ModelSpawn spawn;
366 result = ModelSpawn::readFromFile(tf, spawn);
367 if (result)
368 {
369 // acquire model instance
370 WorldModel* model = vm->acquireModelInstance(iBasePath, spawn.name, spawn.flags);
371 if (!model)
372 {
373 LOG_ERROR("maps", "StaticMapTree::LoadMapTile() : could not acquire WorldModel pointer [{}, {}]", tileX, tileY);
374 }
375
376 // update tree
377 uint32 referencedVal;
378
379 if (fread(&referencedVal, sizeof(uint32), 1, tf) == 1)
380 {
381 if (!iLoadedSpawns.count(referencedVal))
382 {
383#if defined(VMAP_DEBUG)
384 if (referencedVal > iNTreeValues)
385 {
386 LOG_DEBUG("maps", "StaticMapTree::LoadMapTile() : invalid tree element ({}/{})", referencedVal, iNTreeValues);
387 continue;
388 }
389#endif
390 iTreeValues[referencedVal] = ModelInstance(spawn, model);
391 iLoadedSpawns[referencedVal] = 1;
392 }
393 else
394 {
395 ++iLoadedSpawns[referencedVal];
396#if defined(VMAP_DEBUG)
397 if (iTreeValues[referencedVal].ID != spawn.ID)
398 {
399 LOG_DEBUG("maps", "StaticMapTree::LoadMapTile() : trying to load wrong spawn in node");
400 }
401 else if (iTreeValues[referencedVal].name != spawn.name)
402 {
403 LOG_DEBUG("maps", "StaticMapTree::LoadMapTile() : name collision on GUID={}", spawn.ID);
404 }
405#endif
406 }
407 }
408 else
409 {
410 result = false;
411 }
412 }
413 }
414 iLoadedTiles[packTileID(tileX, tileY)] = true;
415 fclose(tf);
416 }
417 else
418 {
419 iLoadedTiles[packTileID(tileX, tileY)] = false;
420 }
421
422 METRIC_EVENT("map_events", "LoadMapTile",
423 "Map: " + std::to_string(iMapID) + " TileX: " + std::to_string(tileX) + " TileY: " + std::to_string(tileY));
424
425 return result;
426 }
std::uint32_t uint32
Definition Define.h:107
#define LOG_ERROR(filterType__,...)
Definition Log.h:158
#define LOG_DEBUG(filterType__,...)
Definition Log.h:170
#define METRIC_EVENT(category, title, description)
Definition Metric.h:189
std::string name
Definition ModelInstance.h:52
uint32 ID
Definition ModelInstance.h:47
static uint32 packTileID(uint32 tileX, uint32 tileY)
Definition MapTree.h:72
loadedTileMap iLoadedTiles
Definition MapTree.h:62

References VMAP::VMapMgr2::acquireModelInstance(), VMAP::ModelSpawn::flags, getTileFileName(), iBasePath, VMAP::ModelSpawn::ID, iIsTiled, iLoadedSpawns, iLoadedTiles, iMapID, iNTreeValues, iTreeValues, LOG_DEBUG, LOG_ERROR, METRIC_EVENT, VMAP::ModelSpawn::name, packTileID(), VMAP::readChunk(), VMAP::ModelSpawn::readFromFile(), and VMAP::VMAP_MAGIC.

Referenced by VMAP::VMapMgr2::_loadMap().

◆ numLoadedTiles()

uint32 VMAP::StaticMapTree::numLoadedTiles ( ) const
inline
89{ return iLoadedTiles.size(); }

References iLoadedTiles.

◆ packTileID()

static uint32 VMAP::StaticMapTree::packTileID ( uint32  tileX,
uint32  tileY 
)
inlinestatic

◆ UnloadMap()

void VMAP::StaticMapTree::UnloadMap ( VMapMgr2 vm)
316 {
317 for (loadedSpawnMap::iterator i = iLoadedSpawns.begin(); i != iLoadedSpawns.end(); ++i)
318 {
319 iTreeValues[i->first].setUnloaded();
320 for (uint32 refCount = 0; refCount < i->second; ++refCount)
321 {
322 vm->releaseModelInstance(iTreeValues[i->first].name);
323 }
324 }
325 iLoadedSpawns.clear();
326 iLoadedTiles.clear();
327 }
void setUnloaded()
Definition ModelInstance.h:67

References iLoadedSpawns, iLoadedTiles, iTreeValues, VMAP::ModelSpawn::name, VMAP::VMapMgr2::releaseModelInstance(), and VMAP::ModelInstance::setUnloaded().

◆ UnloadMapTile()

void VMAP::StaticMapTree::UnloadMapTile ( uint32  tileX,
uint32  tileY,
VMapMgr2 vm 
)
431 {
432 uint32 tileID = packTileID(tileX, tileY);
433 loadedTileMap::iterator tile = iLoadedTiles.find(tileID);
434 if (tile == iLoadedTiles.end())
435 {
436 LOG_ERROR("maps", "StaticMapTree::UnloadMapTile() : trying to unload non-loaded tile - Map:{} X:{} Y:{}", iMapID, tileX, tileY);
437 return;
438 }
439 if (tile->second) // file associated with tile
440 {
441 std::string tilefile = iBasePath + getTileFileName(iMapID, tileX, tileY);
442 FILE* tf = fopen(tilefile.c_str(), "rb");
443 if (tf)
444 {
445 bool result = true;
446 char chunk[8];
447 if (!readChunk(tf, chunk, VMAP_MAGIC, 8))
448 {
449 result = false;
450 }
451 uint32 numSpawns;
452 if (fread(&numSpawns, sizeof(uint32), 1, tf) != 1)
453 {
454 result = false;
455 }
456 for (uint32 i = 0; i < numSpawns && result; ++i)
457 {
458 // read model spawns
459 ModelSpawn spawn;
460 result = ModelSpawn::readFromFile(tf, spawn);
461 if (result)
462 {
463 // release model instance
464 vm->releaseModelInstance(spawn.name);
465
466 // update tree
467 uint32 referencedNode;
468
469 if (fread(&referencedNode, sizeof(uint32), 1, tf) != 1)
470 {
471 result = false;
472 }
473 else
474 {
475 if (!iLoadedSpawns.count(referencedNode))
476 {
477 LOG_ERROR("maps", "StaticMapTree::UnloadMapTile() : trying to unload non-referenced model '{}' (ID:{})", spawn.name, spawn.ID);
478 }
479 else if (--iLoadedSpawns[referencedNode] == 0)
480 {
481 iTreeValues[referencedNode].setUnloaded();
482 iLoadedSpawns.erase(referencedNode);
483 }
484 }
485 }
486 }
487 fclose(tf);
488 }
489 }
490 iLoadedTiles.erase(tile);
491
492 METRIC_EVENT("map_events", "UnloadMapTile",
493 "Map: " + std::to_string(iMapID) + " TileX: " + std::to_string(tileX) + " TileY: " + std::to_string(tileY));
494 }

References getTileFileName(), iBasePath, VMAP::ModelSpawn::ID, iLoadedSpawns, iLoadedTiles, iMapID, iTreeValues, LOG_ERROR, METRIC_EVENT, VMAP::ModelSpawn::name, packTileID(), VMAP::readChunk(), VMAP::ModelSpawn::readFromFile(), VMAP::VMapMgr2::releaseModelInstance(), VMAP::ModelInstance::setUnloaded(), and VMAP::VMAP_MAGIC.

◆ unpackTileID()

static void VMAP::StaticMapTree::unpackTileID ( uint32  ID,
uint32 tileX,
uint32 tileY 
)
inlinestatic
73{ tileX = ID >> 16; tileY = ID & 0xFF; }

Referenced by MMAP::MapBuilder::buildMap(), MMAP::MapBuilder::buildNavMesh(), and VMAP::TileAssembler::convertWorld2().

Member Data Documentation

◆ iBasePath

std::string VMAP::StaticMapTree::iBasePath
private

◆ iIsTiled

bool VMAP::StaticMapTree::iIsTiled
private

Referenced by InitMap(), isTiled(), and LoadMapTile().

◆ iLoadedSpawns

loadedSpawnMap VMAP::StaticMapTree::iLoadedSpawns
private

◆ iLoadedTiles

loadedTileMap VMAP::StaticMapTree::iLoadedTiles
private

◆ iMapID

uint32 VMAP::StaticMapTree::iMapID
private

Referenced by LoadMapTile(), and UnloadMapTile().

◆ iNTreeValues

uint32 VMAP::StaticMapTree::iNTreeValues
private

◆ iTree

BIH VMAP::StaticMapTree::iTree
private

◆ iTreeValues


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