Core/Vmaps: Reduce memory used by vmaps (and their size, slightly)
This commit is contained in:
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace ADT
|
||||
|
||||
struct ADTOutputCache
|
||||
{
|
||||
uint32 Flags;
|
||||
uint8 Flags;
|
||||
std::vector<uint8> Data;
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in new issue
Block a user