Core/Vmaps: Fix getting area id from gameobject models
This commit is contained in:
@@ -262,19 +262,19 @@ bool DynamicMapTree::getAreaAndLiquidData(float x, float y, float z, PhaseShift
|
||||
G3D::Vector3 v(x, y, z + 0.5f);
|
||||
DynamicTreeLocationInfoCallback intersectionCallBack(phaseShift);
|
||||
impl->intersectPoint(v, intersectionCallBack);
|
||||
if (intersectionCallBack.GetLocationInfo().hitModel)
|
||||
if (VMAP::GroupModel const* hitModel = intersectionCallBack.GetLocationInfo().hitModel)
|
||||
{
|
||||
data.floorZ = intersectionCallBack.GetLocationInfo().ground_Z;
|
||||
uint32 liquidType = intersectionCallBack.GetLocationInfo().hitModel->GetLiquidType();
|
||||
uint32 liquidType = hitModel->GetLiquidType();
|
||||
float liquidLevel;
|
||||
if (!reqLiquidType || VMAP::VMapFactory::createOrGetVMapManager()->GetLiquidFlagsPtr(liquidType) & *reqLiquidType)
|
||||
if (intersectionCallBack.GetHitModel()->GetLiquidLevel(v, intersectionCallBack.GetLocationInfo(), liquidLevel))
|
||||
if (intersectionCallBack.GetHitModel()->GetLiquidLevel(v, hitModel, liquidLevel))
|
||||
data.liquidInfo.emplace(liquidType, liquidLevel);
|
||||
|
||||
data.areaInfo.emplace(intersectionCallBack.GetLocationInfo().hitModel->GetWmoID(),
|
||||
data.areaInfo.emplace(hitModel->GetWmoID(),
|
||||
intersectionCallBack.GetHitModel()->GetNameSetId(),
|
||||
intersectionCallBack.GetLocationInfo().rootId,
|
||||
intersectionCallBack.GetLocationInfo().hitModel->GetMogpFlags(),
|
||||
hitModel->GetMogpFlags(),
|
||||
0);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -244,7 +244,7 @@ namespace VMAP
|
||||
InstanceTreeMap::const_iterator instanceTree = GetMapTree(mapId);
|
||||
if (instanceTree != iInstanceMapTrees.end())
|
||||
{
|
||||
LocationInfo info;
|
||||
StaticMapTreeLocationInfo info;
|
||||
G3D::Vector3 pos = convertPositionToInternalRep(x, y, z);
|
||||
if (instanceTree->second->GetLocationInfo(pos, info))
|
||||
{
|
||||
@@ -254,7 +254,7 @@ namespace VMAP
|
||||
uint32 liquidType = info.hitModel->GetLiquidType(); // entry from LiquidType.dbc
|
||||
float liquidLevel;
|
||||
if (!reqLiquidType || (GetLiquidFlagsPtr(liquidType) & *reqLiquidType))
|
||||
if (info.hitInstance->GetLiquidLevel(pos, info, liquidLevel))
|
||||
if (info.hitInstance->GetLiquidLevel(pos, info.hitModel, liquidLevel))
|
||||
data.liquidInfo.emplace(liquidType, liquidLevel);
|
||||
}
|
||||
|
||||
|
||||
@@ -52,28 +52,27 @@ namespace VMAP
|
||||
class LocationInfoCallback
|
||||
{
|
||||
public:
|
||||
LocationInfoCallback(ModelInstance const* val, LocationInfo& info) : prims(val), locInfo(info), result(false) { }
|
||||
LocationInfoCallback(ModelInstance const* val, StaticMapTreeLocationInfo& info) : prims(val), locInfo(info) { }
|
||||
void operator()(Vector3 const& point, uint32 entry)
|
||||
{
|
||||
#ifdef VMAP_DEBUG
|
||||
TC_LOG_DEBUG("maps", "LocationInfoCallback: trying to intersect '{}'", prims[entry].name);
|
||||
#endif
|
||||
if (prims[entry].GetLocationInfo(point, locInfo))
|
||||
result = true;
|
||||
locInfo.hitInstance = &prims[entry];
|
||||
}
|
||||
|
||||
ModelInstance const* prims;
|
||||
LocationInfo& locInfo;
|
||||
bool result;
|
||||
StaticMapTreeLocationInfo& locInfo;
|
||||
};
|
||||
|
||||
//=========================================================
|
||||
|
||||
bool StaticMapTree::GetLocationInfo(Vector3 const& pos, LocationInfo& info) const
|
||||
bool StaticMapTree::GetLocationInfo(Vector3 const& pos, StaticMapTreeLocationInfo& info) const
|
||||
{
|
||||
LocationInfoCallback intersectionCallBack(iTreeValues.data(), info);
|
||||
iTree.intersectPoint(pos, intersectionCallBack);
|
||||
return intersectionCallBack.result;
|
||||
return intersectionCallBack.locInfo.hitInstance != nullptr;
|
||||
}
|
||||
|
||||
StaticMapTree::StaticMapTree(uint32 mapID, std::string const& basePath)
|
||||
|
||||
@@ -31,19 +31,16 @@ namespace VMAP
|
||||
enum class LoadResult : uint8;
|
||||
enum class ModelIgnoreFlags : uint32;
|
||||
|
||||
struct GroupLocationInfo
|
||||
struct LocationInfo
|
||||
{
|
||||
const GroupModel* hitModel = nullptr;
|
||||
GroupModel const* hitModel = nullptr;
|
||||
int32 rootId = -1;
|
||||
float ground_Z = -G3D::finf();
|
||||
};
|
||||
|
||||
struct TC_COMMON_API LocationInfo
|
||||
struct StaticMapTreeLocationInfo : LocationInfo
|
||||
{
|
||||
LocationInfo(): rootId(-1), hitInstance(nullptr), hitModel(nullptr), ground_Z(-G3D::finf()) { }
|
||||
int32 rootId;
|
||||
ModelInstance const* hitInstance;
|
||||
GroupModel const* hitModel;
|
||||
float ground_Z;
|
||||
ModelInstance const* hitInstance = nullptr;
|
||||
};
|
||||
|
||||
class TC_COMMON_API StaticMapTree
|
||||
@@ -74,7 +71,7 @@ namespace VMAP
|
||||
bool isInLineOfSight(G3D::Vector3 const& pos1, G3D::Vector3 const& pos2, ModelIgnoreFlags ignoreFlags) const;
|
||||
bool getObjectHitPos(G3D::Vector3 const& pos1, G3D::Vector3 const& pos2, G3D::Vector3& pResultHitPos, float pModifyDist) const;
|
||||
float getHeight(G3D::Vector3 const& pPos, float maxSearchDist) const;
|
||||
bool GetLocationInfo(G3D::Vector3 const& pos, LocationInfo& info) const;
|
||||
bool GetLocationInfo(G3D::Vector3 const& pos, StaticMapTreeLocationInfo& info) const;
|
||||
|
||||
LoadResult InitMap(std::string const& fname);
|
||||
void UnloadMap();
|
||||
|
||||
@@ -15,15 +15,15 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "VMapFactory.h"
|
||||
#include "VMapManager.h"
|
||||
#include "VMapDefinitions.h"
|
||||
#include "WorldModel.h"
|
||||
#include "GameObjectModel.h"
|
||||
#include "Log.h"
|
||||
#include "MapTree.h"
|
||||
#include "Memory.h"
|
||||
#include "Timer.h"
|
||||
#include "VMapDefinitions.h"
|
||||
#include "VMapFactory.h"
|
||||
#include "VMapManager.h"
|
||||
#include "WorldModel.h"
|
||||
#include <G3D/Quat.h>
|
||||
|
||||
using G3D::Vector3;
|
||||
@@ -193,15 +193,16 @@ bool GameObjectModel::GetLocationInfo(G3D::Vector3 const& point, VMAP::LocationI
|
||||
// child bounds are defined in object space:
|
||||
Vector3 pModel = iInvRot * (point - iPos) * iInvScale;
|
||||
Vector3 zDirModel = iInvRot * Vector3(0.f, 0.f, -1.f);
|
||||
float zDist;
|
||||
|
||||
VMAP::GroupLocationInfo groupInfo;
|
||||
if (iModel->GetLocationInfo(pModel, zDirModel, zDist, groupInfo))
|
||||
VMAP::WorldModelLocationInfoQueryResult locationQueryResult;
|
||||
if (iModel->GetLocationInfo(pModel, zDirModel, locationQueryResult))
|
||||
{
|
||||
Vector3 modelGround = pModel + zDist * zDirModel;
|
||||
Vector3 modelGround = pModel + locationQueryResult.distanceToModel * zDirModel;
|
||||
float world_Z = ((modelGround * iInvRot) * iScale + iPos).z;
|
||||
if (info.ground_Z < world_Z)
|
||||
{
|
||||
info.rootId = locationQueryResult.rootId;
|
||||
info.hitModel = locationQueryResult.hitModel;
|
||||
info.ground_Z = world_Z;
|
||||
return true;
|
||||
}
|
||||
@@ -210,13 +211,13 @@ bool GameObjectModel::GetLocationInfo(G3D::Vector3 const& point, VMAP::LocationI
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GameObjectModel::GetLiquidLevel(G3D::Vector3 const& point, VMAP::LocationInfo& info, float& liqHeight) const
|
||||
bool GameObjectModel::GetLiquidLevel(G3D::Vector3 const& point, VMAP::GroupModel const* model, float& liqHeight) const
|
||||
{
|
||||
// child bounds are defined in object space:
|
||||
Vector3 pModel = iInvRot * (point - iPos) * iInvScale;
|
||||
//Vector3 zDirModel = iInvRot * Vector3(0.f, 0.f, -1.f);
|
||||
float zDist;
|
||||
if (info.hitModel->GetLiquidLevel(pModel, zDist))
|
||||
if (model->GetLiquidLevel(pModel, zDist))
|
||||
{
|
||||
// calculate world height (zDist in model coords):
|
||||
liqHeight = (Vector3(pModel.x, pModel.y, zDist) * iInvRot * iScale + iPos).z;
|
||||
|
||||
@@ -28,8 +28,8 @@
|
||||
|
||||
namespace VMAP
|
||||
{
|
||||
class GroupModel;
|
||||
class WorldModel;
|
||||
struct AreaInfo;
|
||||
struct LocationInfo;
|
||||
enum class ModelIgnoreFlags : uint32;
|
||||
}
|
||||
@@ -41,6 +41,11 @@ struct GameObjectDisplayInfoEntry;
|
||||
class TC_COMMON_API GameObjectModelOwnerBase
|
||||
{
|
||||
public:
|
||||
GameObjectModelOwnerBase() = default;
|
||||
GameObjectModelOwnerBase(GameObjectModelOwnerBase const& other) = delete;
|
||||
GameObjectModelOwnerBase(GameObjectModelOwnerBase&& other) noexcept = delete;
|
||||
GameObjectModelOwnerBase& operator=(GameObjectModelOwnerBase const& other) = delete;
|
||||
GameObjectModelOwnerBase& operator=(GameObjectModelOwnerBase&& other) noexcept = delete;
|
||||
virtual ~GameObjectModelOwnerBase() = default;
|
||||
|
||||
virtual bool IsSpawned() const = 0;
|
||||
@@ -81,7 +86,7 @@ public:
|
||||
|
||||
bool IntersectRay(G3D::Ray const& ray, float& maxDist, bool stopAtFirstHit, PhaseShift const& phaseShift, VMAP::ModelIgnoreFlags ignoreFlags) const;
|
||||
bool GetLocationInfo(G3D::Vector3 const& point, VMAP::LocationInfo& info, PhaseShift const& phaseShift) const;
|
||||
bool GetLiquidLevel(G3D::Vector3 const& point, VMAP::LocationInfo& info, float& liqHeight) const;
|
||||
bool GetLiquidLevel(G3D::Vector3 const& point, VMAP::GroupModel const* model, float& liqHeight) const;
|
||||
|
||||
static std::unique_ptr<GameObjectModel> Create(std::unique_ptr<GameObjectModelOwnerBase> modelOwner, std::string const& dataPath);
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace VMAP
|
||||
return hit;
|
||||
}
|
||||
|
||||
bool ModelInstance::GetLocationInfo(const G3D::Vector3& p, LocationInfo& info) const
|
||||
bool ModelInstance::GetLocationInfo(G3D::Vector3 const& p, LocationInfo& info) const
|
||||
{
|
||||
if (!iModel)
|
||||
{
|
||||
@@ -81,35 +81,33 @@ namespace VMAP
|
||||
// child bounds are defined in object space:
|
||||
Vector3 pModel = iInvRot * (p - iPos) * iInvScale;
|
||||
Vector3 zDirModel = iInvRot * Vector3(0.f, 0.f, -1.f);
|
||||
float zDist;
|
||||
|
||||
GroupLocationInfo groupInfo;
|
||||
if (iModel->GetLocationInfo(pModel, zDirModel, zDist, groupInfo))
|
||||
WorldModelLocationInfoQueryResult locationQueryResult;
|
||||
if (iModel->GetLocationInfo(pModel, zDirModel, locationQueryResult))
|
||||
{
|
||||
Vector3 modelGround = pModel + zDist * zDirModel;
|
||||
Vector3 modelGround = pModel + locationQueryResult.distanceToModel * zDirModel;
|
||||
// Transform back to world space. Note that:
|
||||
// Mat * vec == vec * Mat.transpose()
|
||||
// and for rotation matrices: Mat.inverse() == Mat.transpose()
|
||||
float world_Z = ((modelGround * iInvRot) * iScale + iPos).z;
|
||||
if (info.ground_Z < world_Z) // hm...could it be handled automatically with zDist at intersection?
|
||||
{
|
||||
info.rootId = groupInfo.rootId;
|
||||
info.hitModel = groupInfo.hitModel;
|
||||
info.rootId = locationQueryResult.rootId;
|
||||
info.hitModel = locationQueryResult.hitModel;
|
||||
info.ground_Z = world_Z;
|
||||
info.hitInstance = this;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ModelInstance::GetLiquidLevel(const G3D::Vector3& p, LocationInfo& info, float& liqHeight) const
|
||||
bool ModelInstance::GetLiquidLevel(G3D::Vector3 const& p, GroupModel const* model, float& liqHeight) const
|
||||
{
|
||||
// child bounds are defined in object space:
|
||||
Vector3 pModel = iInvRot * (p - iPos) * iInvScale;
|
||||
//Vector3 zDirModel = iInvRot * Vector3(0.f, 0.f, -1.f);
|
||||
float zDist;
|
||||
if (info.hitModel->GetLiquidLevel(pModel, zDist))
|
||||
if (model->GetLiquidLevel(pModel, zDist))
|
||||
{
|
||||
// calculate world height (zDist in model coords):
|
||||
liqHeight = (Vector3(pModel.x, pModel.y, zDist) * iInvRot * iScale + iPos).z;
|
||||
|
||||
@@ -27,8 +27,8 @@
|
||||
|
||||
namespace VMAP
|
||||
{
|
||||
class GroupModel;
|
||||
class WorldModel;
|
||||
struct AreaInfo;
|
||||
struct LocationInfo;
|
||||
enum class ModelIgnoreFlags : uint32;
|
||||
|
||||
@@ -75,7 +75,7 @@ namespace VMAP
|
||||
void setUnloaded() { iModel = nullptr; }
|
||||
bool intersectRay(G3D::Ray const& pRay, float& pMaxDist, bool pStopAtFirstHit, ModelIgnoreFlags ignoreFlags) const;
|
||||
bool GetLocationInfo(G3D::Vector3 const& p, LocationInfo& info) const;
|
||||
bool GetLiquidLevel(G3D::Vector3 const& p, LocationInfo& info, float& liqHeight) const;
|
||||
bool GetLiquidLevel(G3D::Vector3 const& p, GroupModel const* model, float& liqHeight) const;
|
||||
G3D::Matrix3 const& GetInvRot() const { return iInvRot; }
|
||||
WorldModel const* getWorldModel() const { return iModel.get(); }
|
||||
void AddTileReference() { ++referencingTiles; }
|
||||
|
||||
@@ -16,9 +16,8 @@
|
||||
*/
|
||||
|
||||
#include "WorldModel.h"
|
||||
#include "VMapDefinitions.h"
|
||||
#include "MapTree.h"
|
||||
#include "ModelIgnoreFlags.h"
|
||||
#include "VMapDefinitions.h"
|
||||
#include <array>
|
||||
#include <cstring>
|
||||
|
||||
@@ -32,7 +31,7 @@ template<> struct BoundsTrait<VMAP::GroupModel>
|
||||
|
||||
namespace VMAP
|
||||
{
|
||||
bool IntersectTriangle(MeshTriangle const& tri, std::vector<Vector3>::const_iterator points, G3D::Ray const& ray, float& distance)
|
||||
bool IntersectTriangle(MeshTriangle const& tri, G3D::Vector3 const* points, G3D::Ray const& ray, float& distance)
|
||||
{
|
||||
static const float EPS = 1e-5f;
|
||||
|
||||
@@ -85,19 +84,14 @@ namespace VMAP
|
||||
class TriBoundFunc
|
||||
{
|
||||
public:
|
||||
TriBoundFunc(std::vector<Vector3>& vert): vertices(vert.begin()) { }
|
||||
TriBoundFunc(std::vector<G3D::Vector3> const& vert): vertices(vert.data()) { }
|
||||
void operator()(MeshTriangle const& tri, G3D::AABox& out) const
|
||||
{
|
||||
G3D::Vector3 lo = vertices[tri.idx0];
|
||||
G3D::Vector3 hi = lo;
|
||||
|
||||
lo = (lo.min(vertices[tri.idx1])).min(vertices[tri.idx2]);
|
||||
hi = (hi.max(vertices[tri.idx1])).max(vertices[tri.idx2]);
|
||||
|
||||
out = G3D::AABox(lo, hi);
|
||||
G3D::Vector3 const& p1 = vertices[tri.idx0], & p2 = vertices[tri.idx1], & p3 = vertices[tri.idx2];
|
||||
out = { p1.min(p2).min(p3), p1.max(p2).max(p3) };
|
||||
}
|
||||
protected:
|
||||
const std::vector<Vector3>::const_iterator vertices;
|
||||
G3D::Vector3 const* vertices;
|
||||
};
|
||||
|
||||
// ===================== WmoLiquid ==================================
|
||||
@@ -395,15 +389,14 @@ namespace VMAP
|
||||
|
||||
struct GModelRayCallback
|
||||
{
|
||||
GModelRayCallback(std::vector<MeshTriangle> const& tris, const std::vector<Vector3> &vert):
|
||||
vertices(vert.begin()), triangles(tris.begin()), hit(false) { }
|
||||
GModelRayCallback(std::vector<MeshTriangle> const& tris, std::vector<G3D::Vector3> const& vert) :
|
||||
vertices(vert.data()), triangles(tris.data()), hit(false) { }
|
||||
bool operator()(G3D::Ray const& ray, uint32 entry, float& distance, bool /*pStopAtFirstHit*/)
|
||||
{
|
||||
hit = IntersectTriangle(triangles[entry], vertices, ray, distance) || hit;
|
||||
return hit;
|
||||
return hit |= IntersectTriangle(triangles[entry], vertices, ray, distance);
|
||||
}
|
||||
std::vector<Vector3>::const_iterator vertices;
|
||||
std::vector<MeshTriangle>::const_iterator triangles;
|
||||
G3D::Vector3 const* vertices;
|
||||
MeshTriangle const* triangles;
|
||||
bool hit;
|
||||
};
|
||||
|
||||
@@ -417,7 +410,7 @@ namespace VMAP
|
||||
return callback.hit;
|
||||
}
|
||||
|
||||
inline bool IsInsideOrAboveBound(G3D::AABox const& bounds, const G3D::Point3& point)
|
||||
inline bool IsInsideOrAboveBound(G3D::AABox const& bounds, G3D::Point3 const& point)
|
||||
{
|
||||
return point.x >= bounds.low().x
|
||||
&& point.y >= bounds.low().y
|
||||
@@ -483,15 +476,12 @@ namespace VMAP
|
||||
|
||||
struct WModelRayCallBack
|
||||
{
|
||||
WModelRayCallBack(std::vector<GroupModel> const& mod): models(mod.begin()), hit(false) { }
|
||||
WModelRayCallBack(std::vector<GroupModel> const& mod) : models(mod.data()), hit(false) { }
|
||||
bool operator()(G3D::Ray const& ray, uint32 entry, float& distance, bool pStopAtFirstHit)
|
||||
{
|
||||
bool result = models[entry].IntersectRay(ray, distance, pStopAtFirstHit);
|
||||
if (result)
|
||||
hit = true;
|
||||
return hit;
|
||||
return hit |= models[entry].IntersectRay(ray, distance, pStopAtFirstHit);
|
||||
}
|
||||
std::vector<GroupModel>::const_iterator models;
|
||||
GroupModel const* models;
|
||||
bool hit;
|
||||
};
|
||||
|
||||
@@ -544,7 +534,7 @@ namespace VMAP
|
||||
}
|
||||
};
|
||||
|
||||
bool WorldModel::GetLocationInfo(const G3D::Vector3& p, const G3D::Vector3& down, float& dist, GroupLocationInfo& info) const
|
||||
bool WorldModel::GetLocationInfo(G3D::Vector3 const& p, G3D::Vector3 const& down, WorldModelLocationInfoQueryResult& info) const
|
||||
{
|
||||
if (groupModels.empty())
|
||||
return false;
|
||||
@@ -555,9 +545,9 @@ namespace VMAP
|
||||
groupTree.intersectRay(r, callback, zDist, false);
|
||||
if (callback.hit[GroupModel::INSIDE])
|
||||
{
|
||||
info.rootId = RootWMOID;
|
||||
info.hitModel = callback.hit[GroupModel::INSIDE];
|
||||
dist = zDist;
|
||||
info.distanceToModel = zDist;
|
||||
info.rootId = RootWMOID;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -566,9 +556,9 @@ namespace VMAP
|
||||
// then find back where we originated from (GroupModel::MAYBE_INSIDE)
|
||||
if (callback.hit[GroupModel::MAYBE_INSIDE] && callback.hit[GroupModel::ABOVE])
|
||||
{
|
||||
info.rootId = RootWMOID;
|
||||
info.hitModel = callback.hit[GroupModel::MAYBE_INSIDE];
|
||||
dist = zDist;
|
||||
info.distanceToModel = zDist;
|
||||
info.rootId = RootWMOID;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -18,22 +18,16 @@
|
||||
#ifndef _WORLDMODEL_H
|
||||
#define _WORLDMODEL_H
|
||||
|
||||
#include <G3D/Vector3.h>
|
||||
#include <G3D/AABox.h>
|
||||
#include <G3D/Ray.h>
|
||||
#include "BoundingIntervalHierarchy.h"
|
||||
|
||||
#include "Define.h"
|
||||
#include "EnumFlag.h"
|
||||
#include "ModelIgnoreFlags.h"
|
||||
#include <G3D/AABox.h>
|
||||
#include <G3D/Ray.h>
|
||||
#include <G3D/Vector3.h>
|
||||
|
||||
namespace VMAP
|
||||
{
|
||||
class TreeNode;
|
||||
struct AreaInfo;
|
||||
struct LocationInfo;
|
||||
struct GroupLocationInfo;
|
||||
enum class ModelIgnoreFlags : uint32;
|
||||
|
||||
enum class ModelFlags : uint32
|
||||
{
|
||||
None = 0x0,
|
||||
@@ -113,6 +107,13 @@ namespace VMAP
|
||||
WmoLiquid* iLiquid;
|
||||
};
|
||||
|
||||
struct WorldModelLocationInfoQueryResult
|
||||
{
|
||||
GroupModel const* hitModel = nullptr;
|
||||
float distanceToModel = 0.0f;
|
||||
int32 rootId = -1;
|
||||
};
|
||||
|
||||
/*! Holds a model (converted M2 or WMO) in its original coordinate space */
|
||||
class TC_COMMON_API WorldModel
|
||||
{
|
||||
@@ -124,7 +125,7 @@ namespace VMAP
|
||||
void setFlags(ModelFlags flags) { Flags = flags; }
|
||||
void setRootWmoID(uint32 id) { RootWMOID = id; }
|
||||
bool IntersectRay(const G3D::Ray &ray, float &distance, bool stopAtFirstHit, ModelIgnoreFlags ignoreFlags) const;
|
||||
bool GetLocationInfo(const G3D::Vector3 &p, const G3D::Vector3 &down, float &dist, GroupLocationInfo& info) const;
|
||||
bool GetLocationInfo(G3D::Vector3 const& p, G3D::Vector3 const& down, WorldModelLocationInfoQueryResult& info) const;
|
||||
bool writeFile(const std::string &filename);
|
||||
bool readFile(const std::string &filename);
|
||||
bool IsM2() const { return Flags.HasFlag(ModelFlags::IsM2); }
|
||||
|
||||
Reference in New Issue
Block a user