27template<>
struct BoundsTrait<
VMAP::GroupModel>
36 static const float EPS = 1e-5f;
40 const Vector3 e1 = points[tri.
idx1] - points[tri.
idx0];
41 const Vector3 e2 = points[tri.
idx2] - points[tri.
idx0];
42 const Vector3 p(ray.direction().cross(e2));
43 const float a = e1.dot(p);
45 if (std::fabs(a) < EPS) {
50 const float f = 1.0f / a;
51 const Vector3 s(ray.origin() - points[tri.
idx0]);
52 const float u = f * s.dot(p);
54 if ((u < 0.0f) || (u > 1.0f)) {
59 const Vector3 q(s.cross(e1));
60 const float v = f * ray.direction().dot(q);
62 if ((v < 0.0f) || ((u + v) > 1.0f)) {
67 const float t = f * e2.dot(q);
69 if ((t > 0.0f) && (t < distance))
96 out = G3D::AABox(lo, hi);
99 const std::vector<Vector3>::const_iterator
vertices;
105 iTilesX(width), iTilesY(height), iCorner(corner), iType(type)
109 iHeight =
new float[(width + 1) * (height + 1)];
110 iFlags =
new uint8[width * height];
114 iHeight =
new float[1];
168 if (tx_f < 0.0f || tx >=
iTilesX)
172 if (ty_f < 0.0f || ty >=
iTilesY)
181 float dx = tx_f - (float)tx;
182 float dy = ty_f - (float)ty;
200 float sx =
iHeight[tx+1 + ty * rowOffset] -
iHeight[tx + ty * rowOffset];
201 float sy =
iHeight[tx+1 + (ty+1) * rowOffset] -
iHeight[tx+1 + ty * rowOffset];
202 liqHeight =
iHeight[tx + ty * rowOffset] + dx * sx + dy * sy;
206 float sx =
iHeight[tx+1 + (ty+1) * rowOffset] -
iHeight[tx + (ty+1) * rowOffset];
207 float sy =
iHeight[tx + (ty+1) * rowOffset] -
iHeight[tx + ty * rowOffset];
208 liqHeight =
iHeight[tx + ty * rowOffset] + dx * sx + dy * sy;
215 return 2 *
sizeof(
uint32) +
226 fwrite(&
iCorner,
sizeof(Vector3), 1, wf) == 1 &&
239 result = fwrite(
iHeight,
sizeof(
float), 1, wf) == 1;
252 fread(&liquid->
iCorner,
sizeof(Vector3), 1, rf) == 1 &&
268 liquid->
iHeight =
new float[1];
269 result = fread(liquid->
iHeight,
sizeof(
float), 1, rf) == 1;
291 iBound(other.iBound), iMogpFlags(other.iMogpFlags), iGroupWMOID(other.iGroupWMOID),
292 vertices(other.vertices), triangles(other.triangles), meshTree(other.meshTree), iLiquid(nullptr)
311 if (result && fwrite(&
iBound,
sizeof(G3D::AABox), 1, wf) != 1) result =
false;
312 if (result && fwrite(&
iMogpFlags,
sizeof(
uint32), 1, wf) != 1) result =
false;
316 if (result && fwrite(
"VERT", 1, 4, wf) != 4) result =
false;
318 chunkSize =
sizeof(
uint32) +
sizeof(Vector3) * count;
319 if (result && fwrite(&chunkSize,
sizeof(
uint32), 1, wf) != 1) result =
false;
320 if (result && fwrite(&count,
sizeof(
uint32), 1, wf) != 1) result =
false;
323 if (result && fwrite(&
vertices[0],
sizeof(Vector3), count, wf) != count) result =
false;
326 if (result && fwrite(
"TRIM", 1, 4, wf) != 4) result =
false;
329 if (result && fwrite(&chunkSize,
sizeof(
uint32), 1, wf) != 1) result =
false;
330 if (result && fwrite(&count,
sizeof(
uint32), 1, wf) != 1) result =
false;
334 if (result && fwrite(
"MBIH", 1, 4, wf) != 4) result =
false;
338 if (result && fwrite(
"LIQU", 1, 4, wf) != 4) result =
false;
342 if (result && fwrite(&chunkSize,
sizeof(
uint32), 1, wf) != 1) result =
false;
346 if (result && fwrite(&chunkSize,
sizeof(
uint32), 1, wf) != 1) result =
false;
363 if (result && fread(&
iBound,
sizeof(G3D::AABox), 1, rf) != 1) result =
false;
364 if (result && fread(&
iMogpFlags,
sizeof(
uint32), 1, rf) != 1) result =
false;
368 if (result && !
readChunk(rf, chunk,
"VERT", 4)) result =
false;
369 if (result && fread(&chunkSize,
sizeof(
uint32), 1, rf) != 1) result =
false;
370 if (result && fread(&count,
sizeof(
uint32), 1, rf) != 1) result =
false;
374 if (result && fread(&
vertices[0],
sizeof(Vector3), count, rf) != count) result =
false;
377 if (result && !
readChunk(rf, chunk,
"TRIM", 4)) result =
false;
378 if (result && fread(&chunkSize,
sizeof(
uint32), 1, rf) != 1) result =
false;
379 if (result && fread(&count,
sizeof(
uint32), 1, rf) != 1) result =
false;
384 if (result && !
readChunk(rf, chunk,
"MBIH", 4)) result =
false;
388 if (result && !
readChunk(rf, chunk,
"LIQU", 4)) result =
false;
389 if (result && fread(&chunkSize,
sizeof(
uint32), 1, rf) != 1) result =
false;
390 if (result && chunkSize > 0)
423 Vector3 rPos = pos - 0.1f * down;
424 float dist = G3D::finf();
425 G3D::Ray ray(rPos, down);
428 z_dist = dist - 0.1f;
459 bool result =
models[entry].IntersectRay(ray, distance, pStopAtFirstHit);
464 std::vector<GroupModel>::const_iterator
models;
481 return groupModels[0].IntersectRay(ray, distance, stopAtFirstHit);
492 std::vector<GroupModel>::const_iterator
prims;
493 std::vector<GroupModel>::const_iterator
hit;
504 if (
prims[entry].IsInsideObject(point,
zVec, group_Z))
515 printf(
"%10u %8X %7.3f, %7.3f, %7.3f | %7.3f, %7.3f, %7.3f | z=%f, p_z=%f\n", gm.
GetWmoID(), gm.
GetMogpFlags(),
536 dist = callback.
zDist;
544 FILE* wf = fopen(filename.c_str(),
"wb");
549 bool result = fwrite(
VMAP_MAGIC, 1, 8, wf) == 8;
550 if (result && fwrite(
"WMOD", 1, 4, wf) != 4) result =
false;
552 if (result && fwrite(&chunkSize,
sizeof(
uint32), 1, wf) != 1) result =
false;
556 if (fwrite(&
flags,
sizeof(
uint32), 1, wf) != 1) result =
false;
558 if (result && fwrite(&
RootWMOID,
sizeof(
uint32), 1, wf) != 1) result =
false;
564 if (result && fwrite(
"GMOD", 1, 4, wf) != 4) result =
false;
567 if (result && fwrite(&count,
sizeof(
uint32), 1, wf) != 1) result =
false;
572 if (result && fwrite(
"GBIH", 1, 4, wf) != 4) result =
false;
582 FILE* rf = fopen(filename.c_str(),
"rb");
592 if (result && !
readChunk(rf, chunk,
"WMOD", 4)) result =
false;
593 if (result && fread(&chunkSize,
sizeof(
uint32), 1, rf) != 1) result =
false;
602 if (result && fread(&
RootWMOID,
sizeof(
uint32), 1, rf) != 1) result =
false;
605 if (result &&
readChunk(rf, chunk,
"GMOD", 4))
609 if (result && fread(&count,
sizeof(
uint32), 1, rf) != 1) result =
false;
612 for (
uint32 i = 0; i < count && result; ++i)
616 if (result && !
readChunk(rf, chunk,
"GBIH", 4)) result =
false;
void build(PrimArray const &primitives, BoundsFunc &getBounds, uint32 leafSize=3, bool printStats=false)
bool writeToFile(FILE *wf) const
bool readFromFile(FILE *rf)
void intersectPoint(const G3D::Vector3 &p, IsectCallback &intersectCallback) const
void intersectRay(const G3D::Ray &r, RayCallback &intersectCallback, float &maxDist, bool stopAtFirst=false) const
constexpr std::underlying_type_t< T > AsUnderlyingType() const
std::vector< G3D::Vector3 > vertices
uint32 GetLiquidType() const
bool readFromFile(FILE *rf)
uint32 GetMogpFlags() const
std::vector< MeshTriangle > triangles
bool GetLiquidLevel(const G3D::Vector3 &pos, float &liqHeight) const
bool IntersectRay(const G3D::Ray &ray, float &distance, bool stopAtFirstHit) const
bool writeToFile(FILE *wf)
const G3D::AABox & GetBound() const
void setMeshData(std::vector< G3D::Vector3 > &vert, std::vector< MeshTriangle > &tri)
pass mesh data to object and create BIH. Passed vectors get get swapped with old geometry!
bool IsInsideObject(const G3D::Vector3 &pos, const G3D::Vector3 &down, float &z_dist) const
void operator()(MeshTriangle const &tri, G3D::AABox &out) const
const std::vector< Vector3 >::const_iterator vertices
TriBoundFunc(std::vector< Vector3 > &vert)
std::vector< GroupModel >::const_iterator hit
WModelAreaCallback(std::vector< GroupModel > const &vals, Vector3 const &down)
std::vector< GroupModel >::const_iterator prims
void operator()(Vector3 const &point, uint32 entry)
G3D::Vector3 iCorner
the lower corner
void getPosInfo(uint32 &tilesX, uint32 &tilesY, G3D::Vector3 &corner) const
float * iHeight
(tilesX + 1)*(tilesY + 1) height values
uint32 iTilesX
number of tiles in x direction, each
bool GetLiquidHeight(G3D::Vector3 const &pos, float &liqHeight) const
uint8 * iFlags
info if liquid tile is used
static bool readFromFile(FILE *rf, WmoLiquid *&liquid)
WmoLiquid & operator=(WmoLiquid const &other)
bool writeToFile(FILE *wf)
EnumFlag< ModelFlags > Flags
bool IntersectRay(const G3D::Ray &ray, float &distance, bool stopAtFirstHit, ModelIgnoreFlags ignoreFlags) const
bool readFile(const std::string &filename)
bool GetLocationInfo(const G3D::Vector3 &p, const G3D::Vector3 &down, float &dist, GroupLocationInfo &info) const
void setGroupModels(std::vector< GroupModel > &models)
pass group models to WorldModel and create BIH. Passed vector is swapped with old geometry!
bool writeFile(const std::string &filename)
std::vector< GroupModel > groupModels
constexpr std::size_t size()
bool readChunk(FILE *rf, char *dest, const char *compare, uint32 len)
bool IntersectTriangle(MeshTriangle const &tri, std::vector< Vector3 >::const_iterator points, G3D::Ray const &ray, float &distance)
static void getBounds(const VMAP::GroupModel &obj, G3D::AABox &out)
std::vector< MeshTriangle >::const_iterator triangles
bool operator()(G3D::Ray const &ray, uint32 entry, float &distance, bool)
GModelRayCallback(std::vector< MeshTriangle > const &tris, const std::vector< Vector3 > &vert)
std::vector< Vector3 >::const_iterator vertices
const GroupModel * hitModel
bool operator()(G3D::Ray const &ray, uint32 entry, float &distance, bool pStopAtFirstHit)
std::vector< GroupModel >::const_iterator models
WModelRayCallBack(std::vector< GroupModel > const &mod)