14template<>
struct BoundsTrait<
VMAP::GroupModel>
23 static const float EPS = 1e-5f;
27 const Vector3 e1 = points[tri.
idx1] - points[tri.
idx0];
28 const Vector3 e2 = points[tri.
idx2] - points[tri.
idx0];
29 const Vector3 p(ray.direction().cross(e2));
30 const float a = e1.dot(p);
37 const float f = 1.0f / a;
38 const Vector3 s(ray.origin() - points[tri.
idx0]);
39 const float u = f * s.dot(p);
41 if ((u < 0.0f) || (u > 1.0f)) {
46 const Vector3 q(s.cross(e1));
47 const float v = f * ray.direction().dot(q);
49 if ((v < 0.0f) || ((u + v) > 1.0f)) {
54 const float t = f * e2.dot(q);
56 if ((t > 0.0f) && (t < distance))
83 out = G3D::AABox(lo, hi);
86 const std::vector<Vector3>::const_iterator
vertices;
92 iTilesX(width), iTilesY(height), iCorner(corner), iType(type)
94 iHeight =
new float[(width+1)*(height+1)];
95 iFlags =
new uint8[width*height];
140 if (tx_f < 0.0f || tx >=
iTilesX)
144 if (ty_f < 0.0f || ty >=
iTilesY)
153 float dx = tx_f - (float)tx;
154 float dy = ty_f - (float)ty;
172 float sx =
iHeight[tx+1 + ty * rowOffset] -
iHeight[tx + ty * rowOffset];
173 float sy =
iHeight[tx+1 + (ty+1) * rowOffset] -
iHeight[tx+1 + ty * rowOffset];
174 liqHeight =
iHeight[tx + ty * rowOffset] + dx * sx + dy * sy;
178 float sx =
iHeight[tx+1 + (ty+1) * rowOffset] -
iHeight[tx + (ty+1) * rowOffset];
179 float sy =
iHeight[tx + (ty+1) * rowOffset] -
iHeight[tx + ty * rowOffset];
180 liqHeight =
iHeight[tx + ty * rowOffset] + dx * sx + dy * sy;
187 return 2 *
sizeof(
uint32) +
198 fwrite(&
iCorner,
sizeof(Vector3), 1, wf) == 1 &&
202 if (fwrite(
iHeight,
sizeof(
float), size, wf) == size)
205 result = fwrite(
iFlags,
sizeof(
uint8), size, wf) == size;
219 fread(&liquid->
iCorner,
sizeof(Vector3), 1, rf) == 1 &&
223 liquid->
iHeight =
new float[size];
224 if (fread(liquid->
iHeight,
sizeof(
float), size, rf) == size)
228 result = fread(liquid->
iFlags,
sizeof(
uint8), size, rf) == size;
263 if (result && fwrite(&
iBound,
sizeof(G3D::AABox), 1, wf) != 1) result =
false;
264 if (result && fwrite(&
iMogpFlags,
sizeof(
uint32), 1, wf) != 1) result =
false;
268 if (result && fwrite(
"VERT", 1, 4, wf) != 4) result =
false;
270 chunkSize =
sizeof(
uint32)+
sizeof(Vector3)*count;
271 if (result && fwrite(&chunkSize,
sizeof(
uint32), 1, wf) != 1) result =
false;
272 if (result && fwrite(&count,
sizeof(
uint32), 1, wf) != 1) result =
false;
275 if (result && fwrite(&
vertices[0],
sizeof(Vector3), count, wf) != count) result =
false;
278 if (result && fwrite(
"TRIM", 1, 4, wf) != 4) result =
false;
281 if (result && fwrite(&chunkSize,
sizeof(
uint32), 1, wf) != 1) result =
false;
282 if (result && fwrite(&count,
sizeof(
uint32), 1, wf) != 1) result =
false;
286 if (result && fwrite(
"MBIH", 1, 4, wf) != 4) result =
false;
287 if (result) result =
meshTree.writeToFile(wf);
290 if (result && fwrite(
"LIQU", 1, 4, wf) != 4) result =
false;
294 if (result && fwrite(&chunkSize,
sizeof(
uint32), 1, wf) != 1) result =
false;
297 chunkSize =
iLiquid->GetFileSize();
298 if (result && fwrite(&chunkSize,
sizeof(
uint32), 1, wf) != 1) result =
false;
299 if (result) result =
iLiquid->writeToFile(wf);
315 if (result && fread(&
iBound,
sizeof(G3D::AABox), 1, rf) != 1) result =
false;
316 if (result && fread(&
iMogpFlags,
sizeof(
uint32), 1, rf) != 1) result =
false;
321 if (result && fread(&chunkSize,
sizeof(
uint32), 1, rf) != 1) result =
false;
322 if (result && fread(&count,
sizeof(
uint32), 1, rf) != 1) result =
false;
326 if (result && fread(&
vertices[0],
sizeof(Vector3), count, rf) != count) result =
false;
330 if (result && fread(&chunkSize,
sizeof(
uint32), 1, rf) != 1) result =
false;
331 if (result && fread(&count,
sizeof(
uint32), 1, rf) != 1) result =
false;
337 if (result) result =
meshTree.readFromFile(rf);
341 if (result && fread(&chunkSize,
sizeof(
uint32), 1, rf) != 1) result =
false;
342 if (result && chunkSize > 0)
354 if (result)
hit=
true;
368 meshTree.intersectRay(ray, callback, distance, stopAtFirstHit);
377 Vector3 rPos = pos - 0.1f * down;
378 float dist = G3D::inf();
379 G3D::Ray ray(rPos, down);
382 z_dist = dist - 0.1f;
389 return iLiquid->GetLiquidHeight(pos, liqHeight);
413 bool result =
models[entry].IntersectRay(ray, distance, pStopAtFirstHit);
414 if (result)
hit=
true;
417 std::vector<GroupModel>::const_iterator
models;
426 return groupModels[0].IntersectRay(ray, distance, stopAtFirstHit);
429 groupTree.intersectRay(ray, isc, distance, stopAtFirstHit);
437 std::vector<GroupModel>::const_iterator
prims;
438 std::vector<GroupModel>::const_iterator
hit;
449 if (
prims[entry].IsInsideObject(point,
zVec, group_Z))
460 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(),
481 info.
flags = callback.
hit->GetMogpFlags();
483 dist = callback.
zDist;
499 dist = callback.
zDist;
507 FILE* wf = fopen(filename.c_str(),
"wb");
512 bool result = fwrite(
VMAP_MAGIC, 1, 8, wf) == 8;
513 if (result && fwrite(
"WMOD", 1, 4, wf) != 4) result =
false;
515 if (result && fwrite(&chunkSize,
sizeof(
uint32), 1, wf) != 1) result =
false;
516 if (result && fwrite(&
RootWMOID,
sizeof(
uint32), 1, wf) != 1) result =
false;
522 if (result && fwrite(
"GMOD", 1, 4, wf) != 4) result =
false;
525 if (result && fwrite(&count,
sizeof(
uint32), 1, wf) != 1) result =
false;
530 if (result && fwrite(
"GBIH", 1, 4, wf) != 4) result =
false;
531 if (result) result =
groupTree.writeToFile(wf);
540 FILE* rf = fopen(filename.c_str(),
"rb");
551 if (result && fread(&chunkSize,
sizeof(
uint32), 1, rf) != 1) result =
false;
552 if (result && fread(&
RootWMOID,
sizeof(
uint32), 1, rf) != 1) result =
false;
559 if (result && fread(&count,
sizeof(
uint32), 1, rf) != 1) result =
false;
562 for (
uint32 i=0; i<count && result; ++i)
567 if (result) result =
groupTree.readFromFile(rf);
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()(const MeshTriangle &tri, G3D::AABox &out) const
const std::vector< Vector3 >::const_iterator vertices
TriBoundFunc(std::vector< Vector3 > &vert)
std::vector< GroupModel >::const_iterator hit
void operator()(const Vector3 &point, uint32 entry)
std::vector< GroupModel >::const_iterator prims
WModelAreaCallback(const std::vector< GroupModel > &vals, const Vector3 &down)
WmoLiquid(uint32 width, uint32 height, const G3D::Vector3 &corner, uint32 type)
bool GetLiquidHeight(const G3D::Vector3 &pos, float &liqHeight) const
G3D::Vector3 iCorner
the lower corner
float * iHeight
(tilesX + 1)*(tilesY + 1) height values
uint32 iTilesX
number of tiles in x direction, each
uint8 * iFlags
info if liquid tile is used
WmoLiquid & operator=(const WmoLiquid &other)
static bool readFromFile(FILE *rf, WmoLiquid *&liquid)
bool writeToFile(FILE *wf)
bool GetLocationInfo(const G3D::Vector3 &p, const G3D::Vector3 &down, float &dist, LocationInfo &info) const
bool IntersectRay(const G3D::Ray &ray, float &distance, bool stopAtFirstHit) const
bool readFile(const std::string &filename)
void setGroupModels(std::vector< GroupModel > &models)
pass group models to WorldModel and create BIH. Passed vector is swapped with old geometry!
bool IntersectPoint(const G3D::Vector3 &p, const G3D::Vector3 &down, float &dist, AreaInfo &info) const
bool writeFile(const std::string &filename)
std::vector< GroupModel > groupModels
bool readChunk(FILE *rf, char *dest, const char *compare, uint32 len)
bool IntersectTriangle(const MeshTriangle &tri, std::vector< Vector3 >::const_iterator points, const G3D::Ray &ray, float &distance)
static void getBounds(const VMAP::GroupModel &obj, G3D::AABox &out)
std::vector< MeshTriangle >::const_iterator triangles
GModelRayCallback(const std::vector< MeshTriangle > &tris, const std::vector< Vector3 > &vert)
bool operator()(const G3D::Ray &ray, uint32 entry, float &distance, bool)
std::vector< Vector3 >::const_iterator vertices
const GroupModel * hitModel
bool operator()(const G3D::Ray &ray, uint32 entry, float &distance, bool pStopAtFirstHit)
std::vector< GroupModel >::const_iterator models
WModelRayCallBack(const std::vector< GroupModel > &mod)