Core/Vmaps: Reduce memory used by vmaps (and their size, slightly)

This commit is contained in:
Shauren authored and Ovahlord committed 2021-04-25 07:27:37 +02:00
1 parent eda56e744c
commit e86ae8987b
12 files changed
+89 -79

No files matched your search

@@ -45,9 +45,21 @@ namespace VMAP
delete i->second;
for (auto i = iLoadedModelFiles.begin(); i != iLoadedModelFiles.end(); ++i)
delete i->second.getModel();
delete i->second;
}
class ManagedModel
{
public:
ManagedModel() : iRefCount(0) { }
WorldModel* getModel() { return &iModel; }
void incRefCount() { ++iRefCount; }
int decRefCount() { return --iRefCount; }
protected:
WorldModel iModel;
int iRefCount;
};
InstanceTreeMap::const_iterator VMapManager2::GetMapTree(uint32 mapId) const
{
// return the iterator if found or end() if not found/NULL
@@ -347,8 +359,8 @@ namespace VMAP
auto model = iLoadedModelFiles.find(filename);
if (model == iLoadedModelFiles.end())
{
WorldModel* worldmodel = new WorldModel();
if (!worldmodel->readFile(basepath + filename + ".vmo"))
ManagedModel* worldmodel = new ManagedModel();
if (!worldmodel->getModel()->readFile(basepath + filename + ".vmo"))
{
VMAP_ERROR_LOG("misc", "VMapManager2: could not load '%s%s.vmo'", basepath.c_str(), filename.c_str());
delete worldmodel;
@@ -356,13 +368,13 @@ namespace VMAP
}
VMAP_DEBUG_LOG("maps", "VMapManager2: loading file '%s%s'", basepath.c_str(), filename.c_str());
worldmodel->Flags = flags;
worldmodel->getModel()->SetName(filename);
worldmodel->getModel()->Flags = flags;
model = iLoadedModelFiles.insert(std::pair<std::string, ManagedModel>(filename, ManagedModel())).first;
model->second.setModel(worldmodel);
model = iLoadedModelFiles.insert(std::pair<std::string, ManagedModel*>(filename, worldmodel)).first;
}
model->second.incRefCount();
return model->second.getModel();
model->second->incRefCount();
return model->second->getModel();
}
void VMapManager2::releaseModelInstance(const std::string &filename)
@@ -376,10 +388,10 @@ namespace VMAP
VMAP_ERROR_LOG("misc", "VMapManager2: trying to unload non-loaded file '%s'", filename.c_str());
return;
}
if (model->second.decRefCount() == 0)
if (model->second->decRefCount() == 0)
{
VMAP_DEBUG_LOG("maps", "VMapManager2: unloading file '%s'", filename.c_str());
delete model->second.getModel();
delete model->second;
iLoadedModelFiles.erase(model);
}
}
+2 -14
View File
@@ -47,24 +47,12 @@ namespace G3D
namespace VMAP
{
class ManagedModel;
class StaticMapTree;
class WorldModel;
class TC_COMMON_API ManagedModel
{
public:
ManagedModel() : iModel(nullptr), iRefCount(0) { }
void setModel(WorldModel* model) { iModel = model; }
WorldModel* getModel() { return iModel; }
void incRefCount() { ++iRefCount; }
int decRefCount() { return --iRefCount; }
protected:
WorldModel* iModel;
int iRefCount;
};
typedef std::unordered_map<uint32, StaticMapTree*> InstanceTreeMap;
typedef std::unordered_map<std::string, ManagedModel> ModelFileMap;
typedef std::unordered_map<std::string, ManagedModel*> ModelFileMap;
enum DisableTypes
{
+8 -7
View File
@@ -16,17 +16,18 @@
*/
#include "MapTree.h"
#include "ModelInstance.h"
#include "VMapManager2.h"
#include "VMapDefinitions.h"
#include "Log.h"
#include "Errors.h"
#include "Log.h"
#include "Metric.h"
#include "ModelInstance.h"
#include "VMapDefinitions.h"
#include "VMapManager2.h"
#include "WorldModel.h"
#include <string>
#include <sstream>
#include <iomanip>
#include <limits>
#include <sstream>
#include <string>
using G3D::Vector3;
@@ -349,7 +350,7 @@ namespace VMAP
{
iTreeValues[i->first].setUnloaded();
for (uint32 refCount = 0; refCount < i->second; ++refCount)
vm->releaseModelInstance(iTreeValues[i->first].name);
vm->releaseModelInstance(iTreeValues[i->first].getWorldModel()->GetName());
}
iLoadedSpawns.clear();
iLoadedTiles.clear();
@@ -99,7 +99,7 @@ void LoadGameObjectModelList(std::string const& dataPath)
GameObjectModel::~GameObjectModel()
{
if (iModel)
VMAP::VMapFactory::createOrGetVMapManager()->releaseModelInstance(name);
VMAP::VMapFactory::createOrGetVMapManager()->releaseModelInstance(iModel->GetName());
}
bool GameObjectModel::initialize(std::unique_ptr<GameObjectModelOwnerBase> modelOwner, std::string const& dataPath)
@@ -121,7 +121,6 @@ bool GameObjectModel::initialize(std::unique_ptr<GameObjectModelOwnerBase> model
if (!iModel)
return false;
name = it->second.name;
iPos = modelOwner->GetPosition();
iScale = modelOwner->GetScale();
iInvScale = 1.f / iScale;
@@ -54,8 +54,6 @@ class TC_COMMON_API GameObjectModel /*, public Intersectable*/
{
GameObjectModel() : _collisionEnabled(false), iInvScale(0), iScale(0), iModel(nullptr) { }
public:
std::string name;
const G3D::AABox& getBounds() const { return iBound; }
~GameObjectModel();
@@ -24,9 +24,9 @@ using G3D::Ray;
namespace VMAP
{
ModelInstance::ModelInstance(const ModelSpawn& spawn, WorldModel* model) : ModelSpawn(spawn), iModel(model)
ModelInstance::ModelInstance(const ModelSpawn& spawn, WorldModel* model) : ModelMinimalData(spawn), iModel(model)
{
iInvRot = G3D::Matrix3::fromEulerAnglesZYX(G3D::pif() * iRot.y / 180.f, G3D::pif() * iRot.x / 180.f, G3D::pif() * iRot.z / 180.f).inverse();
iInvRot = G3D::Matrix3::fromEulerAnglesZYX(G3D::pif() * spawn.iRot.y / 180.f, G3D::pif() * spawn.iRot.x / 180.f, G3D::pif() * spawn.iRot.z / 180.f).inverse();
iInvScale = 1.f / iScale;
}
@@ -152,7 +152,7 @@ namespace VMAP
bool ModelSpawn::readFromFile(FILE* rf, ModelSpawn& spawn)
{
uint32 check = 0, nameLen;
check += fread(&spawn.flags, sizeof(uint32), 1, rf);
check += fread(&spawn.flags, sizeof(uint8), 1, rf);
// EoF?
if (!check)
{
@@ -160,7 +160,7 @@ namespace VMAP
std::cout << "Error reading ModelSpawn!\n";
return false;
}
check += fread(&spawn.adtId, sizeof(uint16), 1, rf);
check += fread(&spawn.adtId, sizeof(uint8), 1, rf);
check += fread(&spawn.ID, sizeof(uint32), 1, rf);
check += fread(&spawn.iPos, sizeof(float), 3, rf);
check += fread(&spawn.iRot, sizeof(float), 3, rf);
@@ -198,8 +198,8 @@ namespace VMAP
bool ModelSpawn::writeToFile(FILE* wf, const ModelSpawn& spawn)
{
uint32 check = 0;
check += fwrite(&spawn.flags, sizeof(uint32), 1, wf);
check += fwrite(&spawn.adtId, sizeof(uint16), 1, wf);
check += fwrite(&spawn.flags, sizeof(uint8), 1, wf);
check += fwrite(&spawn.adtId, sizeof(uint8), 1, wf);
check += fwrite(&spawn.ID, sizeof(uint32), 1, wf);
check += fwrite(&spawn.iPos, sizeof(float), 3, wf);
check += fwrite(&spawn.iRot, sizeof(float), 3, wf);
+26 -18
View File
@@ -39,28 +39,35 @@ namespace VMAP
MOD_PARENT_SPAWN = 1 << 2
};
class TC_COMMON_API ModelSpawn
struct ModelMinimalData
{
public:
//mapID, tileX, tileY, Flags, ID, Pos, Rot, Scale, Bound_lo, Bound_hi, name
uint32 flags;
uint16 adtId;
uint32 ID;
G3D::Vector3 iPos;
G3D::Vector3 iRot;
float iScale;
G3D::AABox iBound;
std::string name;
bool operator==(const ModelSpawn &other) const { return ID == other.ID; }
//uint32 hashCode() const { return ID; }
// temp?
const G3D::AABox& getBounds() const { return iBound; }
//Flags, ID, Pos, Rot, Scale, Bound_lo, Bound_hi
uint8 flags;
uint8 adtId;
uint32 ID;
G3D::Vector3 iPos;
G3D::Vector3 iRot;
float iScale;
G3D::AABox iBound;
#ifdef VMAP_DEBUG
std::string name;
#endif
static bool readFromFile(FILE* rf, ModelSpawn &spawn);
static bool writeToFile(FILE* rw, const ModelSpawn &spawn);
bool operator==(ModelMinimalData const& other) const { return ID == other.ID; }
G3D::AABox const& getBounds() const { return iBound; }
};
class TC_COMMON_API ModelInstance: public ModelSpawn
struct TC_COMMON_API ModelSpawn : public ModelMinimalData
{
#ifndef VMAP_DEBUG
std::string name;
#endif
static bool readFromFile(FILE* rf, ModelSpawn& spawn);
static bool writeToFile(FILE* rw, ModelSpawn const& spawn);
};
class TC_COMMON_API ModelInstance: public ModelMinimalData
{
public:
ModelInstance(): iInvScale(0.0f), iModel(nullptr) { }
@@ -70,6 +77,7 @@ namespace VMAP
void intersectPoint(const G3D::Vector3& p, AreaInfo &info) const;
bool GetLocationInfo(const G3D::Vector3& p, LocationInfo &info) const;
bool GetLiquidLevel(const G3D::Vector3& p, LocationInfo &info, float &liqHeight) const;
G3D::Matrix3 const& GetInvRot() { return iInvRot; }
WorldModel* getWorldModel() { return iModel; }
protected:
G3D::Matrix3 iInvRot;
+3
View File
@@ -117,11 +117,14 @@ namespace VMAP
bool writeFile(const std::string &filename);
bool readFile(const std::string &filename);
void getGroupModels(std::vector<GroupModel>& outGroupModels);
std::string const& GetName() const { return name; }
void SetName(std::string newName) { name = std::move(newName); }
uint32 Flags;
protected:
uint32 RootWMOID;
std::vector<GroupModel> groupModels;
BIH groupTree;
std::string name;
};
} // namespace VMAP
+2 -2
View File
@@ -224,10 +224,10 @@ bool ADTFile::initFromCache(uint32 map_num, uint32 originalMapId)
for (ADTOutputCache const& cached : *dirfileCache)
{
fwrite(&map_num, sizeof(uint32), 1, dirfile);
uint32 flags = cached.Flags;
uint8 flags = cached.Flags;
if (map_num != originalMapId)
flags |= MOD_PARENT_SPAWN;
fwrite(&flags, sizeof(uint32), 1, dirfile);
fwrite(&flags, sizeof(uint8), 1, dirfile);
fwrite(cached.Data.data(), cached.Data.size(), 1, dirfile);
}
+1 -1
View File
@@ -52,7 +52,7 @@ namespace ADT
struct ADTOutputCache
{
uint32 Flags;
uint8 Flags;
std::vector<uint8> Data;
};
+12 -12
View File
@@ -163,16 +163,16 @@ void Doodad::Extract(ADT::MDDF const& doodadDef, char const* ModelInstName, uint
Vec3D position = fixCoords(doodadDef.Position);
uint16 nameSet = 0;// not used for models
uint8 nameSet = 0;// not used for models
uint32 uniqueId = GenerateUniqueObjectId(doodadDef.UniqueId, 0);
uint32 flags = MOD_M2;
uint8 flags = MOD_M2;
if (mapID != originalMapId)
flags |= MOD_PARENT_SPAWN;
//write mapID, Flags, NameSet, UniqueId, Pos, Rot, Scale, name
fwrite(&mapID, sizeof(uint32), 1, pDirfile);
fwrite(&flags, sizeof(uint32), 1, pDirfile);
fwrite(&nameSet, sizeof(uint16), 1, pDirfile);
fwrite(&flags, sizeof(uint8), 1, pDirfile);
fwrite(&nameSet, sizeof(uint8), 1, pDirfile);
fwrite(&uniqueId, sizeof(uint32), 1, pDirfile);
fwrite(&position, sizeof(Vec3D), 1, pDirfile);
fwrite(&doodadDef.Rotation, sizeof(Vec3D), 1, pDirfile);
@@ -187,7 +187,7 @@ void Doodad::Extract(ADT::MDDF const& doodadDef, char const* ModelInstName, uint
ADTOutputCache& cacheModelData = dirfileCache->back();
cacheModelData.Flags = flags & ~MOD_PARENT_SPAWN;
cacheModelData.Data.resize(
sizeof(uint16) + // nameSet
sizeof(uint8) + // nameSet
sizeof(uint32) + // uniqueId
sizeof(Vec3D) + // position
sizeof(Vec3D) + // doodadDef.Rotation
@@ -198,7 +198,7 @@ void Doodad::Extract(ADT::MDDF const& doodadDef, char const* ModelInstName, uint
uint8* cacheData = cacheModelData.Data.data();
#define CACHE_WRITE(value, size, cnt, dest) memcpy(dest, value, size * cnt); dest += size * cnt;
CACHE_WRITE(&nameSet, sizeof(uint16), 1, cacheData);
CACHE_WRITE(&nameSet, sizeof(uint8), 1, cacheData);
CACHE_WRITE(&uniqueId, sizeof(uint32), 1, cacheData);
CACHE_WRITE(&position, sizeof(Vec3D), 1, cacheData);
CACHE_WRITE(&doodadDef.Rotation, sizeof(Vec3D), 1, cacheData);
@@ -273,16 +273,16 @@ void Doodad::ExtractSet(WMODoodadData const& doodadData, ADT::MODF const& wmo, b
rotation.x = G3D::toDegrees(rotation.x);
rotation.y = G3D::toDegrees(rotation.y);
uint16 nameSet = 0; // not used for models
uint8 nameSet = 0; // not used for models
uint32 uniqueId = GenerateUniqueObjectId(wmo.UniqueId, doodadId);
uint32 tcflags = MOD_M2;
uint8 tcflags = MOD_M2;
if (mapID != originalMapId)
tcflags |= MOD_PARENT_SPAWN;
//write mapID, Flags, NameSet, UniqueId, Pos, Rot, Scale, name
fwrite(&mapID, sizeof(uint32), 1, pDirfile);
fwrite(&tcflags, sizeof(uint32), 1, pDirfile);
fwrite(&nameSet, sizeof(uint16), 1, pDirfile);
fwrite(&tcflags, sizeof(uint8), 1, pDirfile);
fwrite(&nameSet, sizeof(uint8), 1, pDirfile);
fwrite(&uniqueId, sizeof(uint32), 1, pDirfile);
fwrite(&position, sizeof(Vec3D), 1, pDirfile);
fwrite(&rotation, sizeof(Vec3D), 1, pDirfile);
@@ -296,7 +296,7 @@ void Doodad::ExtractSet(WMODoodadData const& doodadData, ADT::MODF const& wmo, b
ADTOutputCache& cacheModelData = dirfileCache->back();
cacheModelData.Flags = tcflags & ~MOD_PARENT_SPAWN;
cacheModelData.Data.resize(
sizeof(uint16) + // nameSet
sizeof(uint8) + // nameSet
sizeof(uint32) + // uniqueId
sizeof(Vec3D) + // position
sizeof(Vec3D) + // rotation
@@ -305,7 +305,7 @@ void Doodad::ExtractSet(WMODoodadData const& doodadData, ADT::MODF const& wmo, b
nlen); // ModelInstName
uint8* cacheData = cacheModelData.Data.data();
CACHE_WRITE(&nameSet, sizeof(uint16), 1, cacheData);
CACHE_WRITE(&nameSet, sizeof(uint8), 1, cacheData);
CACHE_WRITE(&uniqueId, sizeof(uint32), 1, cacheData);
CACHE_WRITE(&position, sizeof(Vec3D), 1, cacheData);
CACHE_WRITE(&rotation, sizeof(Vec3D), 1, cacheData);
+6 -5
View File
@@ -563,14 +563,15 @@ void MapObject::Extract(ADT::MODF const& mapObjDef, char const* WmoInstName, boo
if (mapObjDef.Flags & 0x4)
scale = mapObjDef.Scale / 1024.0f;
uint32 uniqueId = GenerateUniqueObjectId(mapObjDef.UniqueId, 0);
uint32 flags = MOD_HAS_BOUND;
uint8 flags = MOD_HAS_BOUND;
uint8 nameSet = mapObjDef.NameSet;
if (mapID != originalMapId)
flags |= MOD_PARENT_SPAWN;
//write mapID, Flags, NameSet, UniqueId, Pos, Rot, Scale, Bound_lo, Bound_hi, name
fwrite(&mapID, sizeof(uint32), 1, pDirfile);
fwrite(&flags, sizeof(uint32), 1, pDirfile);
fwrite(&mapObjDef.NameSet, sizeof(uint16), 1, pDirfile);
fwrite(&flags, sizeof(uint8), 1, pDirfile);
fwrite(&nameSet, sizeof(uint8), 1, pDirfile);
fwrite(&uniqueId, sizeof(uint32), 1, pDirfile);
fwrite(&position, sizeof(Vec3D), 1, pDirfile);
fwrite(&mapObjDef.Rotation, sizeof(Vec3D), 1, pDirfile);
@@ -586,7 +587,7 @@ void MapObject::Extract(ADT::MODF const& mapObjDef, char const* WmoInstName, boo
ADTOutputCache& cacheModelData = dirfileCache->back();
cacheModelData.Flags = flags & ~MOD_PARENT_SPAWN;
cacheModelData.Data.resize(
sizeof(uint16) + // mapObjDef.NameSet
sizeof(uint8) + // nameSet
sizeof(uint32) + // uniqueId
sizeof(Vec3D) + // position
sizeof(Vec3D) + // mapObjDef.Rotation
@@ -598,7 +599,7 @@ void MapObject::Extract(ADT::MODF const& mapObjDef, char const* WmoInstName, boo
uint8* cacheData = cacheModelData.Data.data();
#define CACHE_WRITE(value, size, count, dest) memcpy(dest, value, size * count); dest += size * count;
CACHE_WRITE(&mapObjDef.NameSet, sizeof(uint16), 1, cacheData);
CACHE_WRITE(&mapObjDef.NameSet, sizeof(uint8), 1, cacheData);
CACHE_WRITE(&uniqueId, sizeof(uint32), 1, cacheData);
CACHE_WRITE(&position, sizeof(Vec3D), 1, cacheData);
CACHE_WRITE(&mapObjDef.Rotation, sizeof(Vec3D), 1, cacheData);