aboutsummaryrefslogtreecommitdiff
path: root/src/server/shared
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/shared')
-rw-r--r--src/server/shared/vmap/BIH.cpp304
-rw-r--r--src/server/shared/vmap/BIH.h391
-rw-r--r--src/server/shared/vmap/CMakeLists.txt30
-rw-r--r--src/server/shared/vmap/IVMapManager.h106
-rw-r--r--src/server/shared/vmap/MapTree.cpp450
-rw-r--r--src/server/shared/vmap/MapTree.h97
-rw-r--r--src/server/shared/vmap/ModelInstance.cpp219
-rw-r--r--src/server/shared/vmap/ModelInstance.h81
-rw-r--r--src/server/shared/vmap/TileAssembler.cpp494
-rw-r--r--src/server/shared/vmap/TileAssembler.h89
-rw-r--r--src/server/shared/vmap/VMapDefinitions.h42
-rw-r--r--src/server/shared/vmap/VMapFactory.cpp136
-rw-r--r--src/server/shared/vmap/VMapFactory.h43
-rw-r--r--src/server/shared/vmap/VMapManager2.cpp336
-rw-r--r--src/server/shared/vmap/VMapManager2.h114
-rw-r--r--src/server/shared/vmap/VMapTools.h150
-rw-r--r--src/server/shared/vmap/WorldModel.cpp535
-rw-r--r--src/server/shared/vmap/WorldModel.h123
18 files changed, 0 insertions, 3740 deletions
diff --git a/src/server/shared/vmap/BIH.cpp b/src/server/shared/vmap/BIH.cpp
deleted file mode 100644
index 4bd6b3c701e..00000000000
--- a/src/server/shared/vmap/BIH.cpp
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
- * Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "BIH.h"
-
-void BIH::buildHierarchy(std::vector<uint32> &tempTree, buildData &dat, BuildStats &stats)
-{
- // create space for the first node
- tempTree.push_back(3 << 30); // dummy leaf
- tempTree.insert(tempTree.end(), 2, 0);
- //tempTree.add(0);
-
- // seed bbox
- AABound gridBox = { bounds.low(), bounds.high() };
- AABound nodeBox = gridBox;
- // seed subdivide function
- subdivide(0, dat.numPrims - 1, tempTree, dat, gridBox, nodeBox, 0, 1, stats);
-}
-
-void BIH::subdivide(int left, int right, std::vector<uint32> &tempTree, buildData &dat, AABound &gridBox, AABound &nodeBox, int nodeIndex, int depth, BuildStats &stats)
-{
- if ((right - left + 1) <= dat.maxPrims || depth >= MAX_STACK_SIZE)
- {
- // write leaf node
- stats.updateLeaf(depth, right - left + 1);
- createNode(tempTree, nodeIndex, left, right);
- return;
- }
- // calculate extents
- int axis = -1, prevAxis, rightOrig;
- float clipL = G3D::fnan(), clipR = G3D::fnan(), prevClip = G3D::fnan();
- float split = G3D::fnan(), prevSplit;
- bool wasLeft = true;
- while (true)
- {
- prevAxis = axis;
- prevSplit = split;
- // perform quick consistency checks
- Vector3 d( gridBox.hi - gridBox.lo );
- if (d.x < 0 || d.y < 0 || d.z < 0)
- throw std::logic_error("negative node extents");
- for (int i = 0; i < 3; i++)
- {
- if (nodeBox.hi[i] < gridBox.lo[i] || nodeBox.lo[i] > gridBox.hi[i])
- {
- //UI.printError(Module.ACCEL, "Reached tree area in error - discarding node with: %d objects", right - left + 1);
- throw std::logic_error("invalid node overlap");
- }
- }
- // find longest axis
- axis = d.primaryAxis();
- split = 0.5f * (gridBox.lo[axis] + gridBox.hi[axis]);
- // partition L/R subsets
- clipL = -G3D::inf();
- clipR = G3D::inf();
- rightOrig = right; // save this for later
- float nodeL = G3D::inf();
- float nodeR = -G3D::inf();
- for (int i = left; i <= right;)
- {
- int obj = dat.indices[i];
- float minb = dat.primBound[obj].low()[axis];
- float maxb = dat.primBound[obj].high()[axis];
- float center = (minb + maxb) * 0.5f;
- if (center <= split)
- {
- // stay left
- i++;
- if (clipL < maxb)
- clipL = maxb;
- }
- else
- {
- // move to the right most
- int t = dat.indices[i];
- dat.indices[i] = dat.indices[right];
- dat.indices[right] = t;
- right--;
- if (clipR > minb)
- clipR = minb;
- }
- nodeL = std::min(nodeL, minb);
- nodeR = std::max(nodeR, maxb);
- }
- // check for empty space
- if (nodeL > nodeBox.lo[axis] && nodeR < nodeBox.hi[axis])
- {
- float nodeBoxW = nodeBox.hi[axis] - nodeBox.lo[axis];
- float nodeNewW = nodeR - nodeL;
- // node box is too big compare to space occupied by primitives?
- if (1.3f * nodeNewW < nodeBoxW)
- {
- stats.updateBVH2();
- int nextIndex = tempTree.size();
- // allocate child
- tempTree.push_back(0);
- tempTree.push_back(0);
- tempTree.push_back(0);
- // write bvh2 clip node
- stats.updateInner();
- tempTree[nodeIndex + 0] = (axis << 30) | (1 << 29) | nextIndex;
- tempTree[nodeIndex + 1] = floatToRawIntBits(nodeL);
- tempTree[nodeIndex + 2] = floatToRawIntBits(nodeR);
- // update nodebox and recurse
- nodeBox.lo[axis] = nodeL;
- nodeBox.hi[axis] = nodeR;
- subdivide(left, rightOrig, tempTree, dat, gridBox, nodeBox, nextIndex, depth + 1, stats);
- return;
- }
- }
- // ensure we are making progress in the subdivision
- if (right == rightOrig)
- {
- // all left
- if (prevAxis == axis && prevSplit == split) {
- // we are stuck here - create a leaf
- stats.updateLeaf(depth, right - left + 1);
- createNode(tempTree, nodeIndex, left, right);
- return;
- }
- if (clipL <= split) {
- // keep looping on left half
- gridBox.hi[axis] = split;
- prevClip = clipL;
- wasLeft = true;
- continue;
- }
- gridBox.hi[axis] = split;
- prevClip = G3D::fnan();
- }
- else if (left > right)
- {
- // all right
- if (prevAxis == axis && prevSplit == split) {
- // we are stuck here - create a leaf
- stats.updateLeaf(depth, right - left + 1);
- createNode(tempTree, nodeIndex, left, right);
- return;
- }
- right = rightOrig;
- if (clipR >= split) {
- // keep looping on right half
- gridBox.lo[axis] = split;
- prevClip = clipR;
- wasLeft = false;
- continue;
- }
- gridBox.lo[axis] = split;
- prevClip = G3D::fnan();
- }
- else
- {
- // we are actually splitting stuff
- if (prevAxis != -1 && !isnan(prevClip))
- {
- // second time through - lets create the previous split
- // since it produced empty space
- int nextIndex = tempTree.size();
- // allocate child node
- tempTree.push_back(0);
- tempTree.push_back(0);
- tempTree.push_back(0);
- if (wasLeft) {
- // create a node with a left child
- // write leaf node
- stats.updateInner();
- tempTree[nodeIndex + 0] = (prevAxis << 30) | nextIndex;
- tempTree[nodeIndex + 1] = floatToRawIntBits(prevClip);
- tempTree[nodeIndex + 2] = floatToRawIntBits(G3D::inf());
- } else {
- // create a node with a right child
- // write leaf node
- stats.updateInner();
- tempTree[nodeIndex + 0] = (prevAxis << 30) | (nextIndex - 3);
- tempTree[nodeIndex + 1] = floatToRawIntBits(-G3D::inf());
- tempTree[nodeIndex + 2] = floatToRawIntBits(prevClip);
- }
- // count stats for the unused leaf
- depth++;
- stats.updateLeaf(depth, 0);
- // now we keep going as we are, with a new nodeIndex:
- nodeIndex = nextIndex;
- }
- break;
- }
- }
- // compute index of child nodes
- int nextIndex = tempTree.size();
- // allocate left node
- int nl = right - left + 1;
- int nr = rightOrig - (right + 1) + 1;
- if (nl > 0) {
- tempTree.push_back(0);
- tempTree.push_back(0);
- tempTree.push_back(0);
- } else
- nextIndex -= 3;
- // allocate right node
- if (nr > 0) {
- tempTree.push_back(0);
- tempTree.push_back(0);
- tempTree.push_back(0);
- }
- // write leaf node
- stats.updateInner();
- tempTree[nodeIndex + 0] = (axis << 30) | nextIndex;
- tempTree[nodeIndex + 1] = floatToRawIntBits(clipL);
- tempTree[nodeIndex + 2] = floatToRawIntBits(clipR);
- // prepare L/R child boxes
- AABound gridBoxL(gridBox), gridBoxR(gridBox);
- AABound nodeBoxL(nodeBox), nodeBoxR(nodeBox);
- gridBoxL.hi[axis] = gridBoxR.lo[axis] = split;
- nodeBoxL.hi[axis] = clipL;
- nodeBoxR.lo[axis] = clipR;
- // recurse
- if (nl > 0)
- subdivide(left, right, tempTree, dat, gridBoxL, nodeBoxL, nextIndex, depth + 1, stats);
- else
- stats.updateLeaf(depth + 1, 0);
- if (nr > 0)
- subdivide(right + 1, rightOrig, tempTree, dat, gridBoxR, nodeBoxR, nextIndex + 3, depth + 1, stats);
- else
- stats.updateLeaf(depth + 1, 0);
-}
-
-bool BIH::writeToFile(FILE *wf) const
-{
- uint32 treeSize = tree.size();
- uint32 check=0, count=0;
- check += fwrite(&bounds.low(), sizeof(float), 3, wf);
- check += fwrite(&bounds.high(), sizeof(float), 3, wf);
- check += fwrite(&treeSize, sizeof(uint32), 1, wf);
- check += fwrite(&tree[0], sizeof(uint32), treeSize, wf);
- count = objects.size();
- check += fwrite(&count, sizeof(uint32), 1, wf);
- check += fwrite(&objects[0], sizeof(uint32), count, wf);
- return check == (3 + 3 + 2 + treeSize + count);
-}
-
-bool BIH::readFromFile(FILE *rf)
-{
- uint32 treeSize;
- Vector3 lo, hi;
- uint32 check=0, count=0;
- check += fread(&lo, sizeof(float), 3, rf);
- check += fread(&hi, sizeof(float), 3, rf);
- bounds = AABox(lo, hi);
- check += fread(&treeSize, sizeof(uint32), 1, rf);
- tree.resize(treeSize);
- check += fread(&tree[0], sizeof(uint32), treeSize, rf);
- check += fread(&count, sizeof(uint32), 1, rf);
- objects.resize(count); // = new uint32[nObjects];
- check += fread(&objects[0], sizeof(uint32), count, rf);
- return check == (3 + 3 + 2 + treeSize + count);
-}
-
-void BIH::BuildStats::updateLeaf(int depth, int n)
-{
- numLeaves++;
- minDepth = std::min(depth, minDepth);
- maxDepth = std::max(depth, maxDepth);
- sumDepth += depth;
- minObjects = std::min(n, minObjects);
- maxObjects = std::max(n, maxObjects);
- sumObjects += n;
- int nl = std::min(n, 5);
- ++numLeavesN[nl];
-}
-
-void BIH::BuildStats::printStats()
-{
- printf("Tree stats:\n");
- printf(" * Nodes: %d\n", numNodes);
- printf(" * Leaves: %d\n", numLeaves);
- printf(" * Objects: min %d\n", minObjects);
- printf(" avg %.2f\n", (float) sumObjects / numLeaves);
- printf(" avg(n>0) %.2f\n", (float) sumObjects / (numLeaves - numLeavesN[0]));
- printf(" max %d\n", maxObjects);
- printf(" * Depth: min %d\n", minDepth);
- printf(" avg %.2f\n", (float) sumDepth / numLeaves);
- printf(" max %d\n", maxDepth);
- printf(" * Leaves w/: N=0 %3d%%\n", 100 * numLeavesN[0] / numLeaves);
- printf(" N=1 %3d%%\n", 100 * numLeavesN[1] / numLeaves);
- printf(" N=2 %3d%%\n", 100 * numLeavesN[2] / numLeaves);
- printf(" N=3 %3d%%\n", 100 * numLeavesN[3] / numLeaves);
- printf(" N=4 %3d%%\n", 100 * numLeavesN[4] / numLeaves);
- printf(" N>4 %3d%%\n", 100 * numLeavesN[5] / numLeaves);
- printf(" * BVH2 nodes: %d (%3d%%)\n", numBVH2, 100 * numBVH2 / (numNodes + numLeaves - 2 * numBVH2));
-}
diff --git a/src/server/shared/vmap/BIH.h b/src/server/shared/vmap/BIH.h
deleted file mode 100644
index 15ae90c23eb..00000000000
--- a/src/server/shared/vmap/BIH.h
+++ /dev/null
@@ -1,391 +0,0 @@
-/*
- * Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef _BIH_H
-#define _BIH_H
-
-#include <G3D/Vector3.h>
-#include <G3D/Ray.h>
-#include <G3D/AABox.h>
-
-#include <Platform/Define.h>
-
-#include <stdexcept>
-#include <vector>
-#include <algorithm>
-#include <limits>
-#include <cmath>
-
-#define MAX_STACK_SIZE 64
-
-#ifdef _MSC_VER
- #define isnan(x) _isnan(x)
-#endif
-
-using G3D::Vector3;
-using G3D::AABox;
-using G3D::Ray;
-
-static inline uint32 floatToRawIntBits(float f)
-{
- union
- {
- uint32 ival;
- float fval;
- } temp;
- temp.fval=f;
- return temp.ival;
-}
-
-static inline float intBitsToFloat(uint32 i)
-{
- union
- {
- uint32 ival;
- float fval;
- } temp;
- temp.ival=i;
- return temp.fval;
-}
-
-struct AABound
-{
- Vector3 lo, hi;
-};
-
-/** Bounding Interval Hierarchy Class.
- Building and Ray-Intersection functions based on BIH from
- Sunflow, a Java Raytracer, released under MIT/X11 License
- http://sunflow.sourceforge.net/
- Copyright (c) 2003-2007 Christopher Kulla
-*/
-
-class BIH
-{
- public:
- BIH() {};
- template< class T, class BoundsFunc >
- void build(const std::vector<T> &primitives, BoundsFunc &getBounds, uint32 leafSize = 3, bool printStats=false)
- {
- if(primitives.size() == 0)
- return;
- buildData dat;
- dat.maxPrims = leafSize;
- dat.numPrims = primitives.size();
- dat.indices = new uint32[dat.numPrims];
- dat.primBound = new AABox[dat.numPrims];
- getBounds(primitives[0], bounds);
- for (uint32 i=0; i<dat.numPrims; ++i)
- {
- dat.indices[i] = i;
- AABox tb;
- getBounds(primitives[i], dat.primBound[i]);
- bounds.merge(dat.primBound[i]);
- }
- std::vector<uint32> tempTree;
- BuildStats stats;
- buildHierarchy(tempTree, dat, stats);
- if (printStats)
- stats.printStats();
-
- objects.resize(dat.numPrims);
- for (uint32 i=0; i<dat.numPrims; ++i)
- objects[i] = dat.indices[i];
- //nObjects = dat.numPrims;
- tree = tempTree;
- delete[] dat.primBound;
- delete[] dat.indices;
- }
- uint32 primCount() { return objects.size(); }
-
- template<typename RayCallback>
- void intersectRay(const Ray &r, RayCallback& intersectCallback, float &maxDist, bool stopAtFirst=false) const
- {
- float intervalMin = 0.f;
- float intervalMax = maxDist;
- Vector3 org = r.origin();
- Vector3 dir = r.direction();
- Vector3 invDir;
- float t1, t2;
- for(int i=0; i<3; ++i)
- {
- invDir[i] = 1.f / dir[i];
- t1 = (bounds.low()[i] - org[i]) * invDir[i];
- t2 = (bounds.high()[i] - org[i]) * invDir[i];
- if (invDir[i] > 0) {
- if (t1 > intervalMin)
- intervalMin = t1;
- if (t2 < intervalMax)
- intervalMax = t2;
- } else {
- if (t2 > intervalMin)
- intervalMin = t2;
- if (t1 < intervalMax)
- intervalMax = t1;
- }
- if (intervalMin > intervalMax)
- return;
- }
-
- uint32 offsetFront[3];
- uint32 offsetBack[3];
- uint32 offsetFront3[3];
- uint32 offsetBack3[3];
- // compute custom offsets from direction sign bit
-
- for(int i=0; i<3; ++i)
- {
- offsetFront[i] = floatToRawIntBits(dir[i]) >> 31;
- offsetBack[i] = offsetFront[i] ^ 1;
- offsetFront3[i] = offsetFront[i] * 3;
- offsetBack3[i] = offsetBack[i] * 3;
-
- // avoid always adding 1 during the inner loop
- ++offsetFront[i];
- ++offsetBack[i];
- }
-
- StackNode stack[MAX_STACK_SIZE];
- int stackPos = 0;
- int node = 0;
-
- while (true) {
- while (true)
- {
- uint32 tn = tree[node];
- uint32 axis = (tn & (3 << 30)) >> 30;
- bool BVH2 = tn & (1 << 29);
- int offset = tn & ~(7 << 29);
- if (!BVH2)
- {
- if (axis < 3)
- {
- // "normal" interior node
- float tf = (intBitsToFloat(tree[node + offsetFront[axis]]) - org[axis]) * invDir[axis];
- float tb = (intBitsToFloat(tree[node + offsetBack[axis]]) - org[axis]) * invDir[axis];
- // ray passes between clip zones
- if (tf < intervalMin && tb > intervalMax)
- break;
- int back = offset + offsetBack3[axis];
- node = back;
- // ray passes through far node only
- if (tf < intervalMin) {
- intervalMin = (tb >= intervalMin) ? tb : intervalMin;
- continue;
- }
- node = offset + offsetFront3[axis]; // front
- // ray passes through near node only
- if (tb > intervalMax) {
- intervalMax = (tf <= intervalMax) ? tf : intervalMax;
- continue;
- }
- // ray passes through both nodes
- // push back node
- stack[stackPos].node = back;
- stack[stackPos].tnear = (tb >= intervalMin) ? tb : intervalMin;
- stack[stackPos].tfar = intervalMax;
- stackPos++;
- // update ray interval for front node
- intervalMax = (tf <= intervalMax) ? tf : intervalMax;
- continue;
- }
- else
- {
- // leaf - test some objects
- int n = tree[node + 1];
- while (n > 0) {
- bool hit = intersectCallback(r, objects[offset], maxDist, stopAtFirst);
- if(stopAtFirst && hit) return;
- --n;
- ++offset;
- }
- break;
- }
- }
- else
- {
- if (axis>2)
- return; // should not happen
- float tf = (intBitsToFloat(tree[node + offsetFront[axis]]) - org[axis]) * invDir[axis];
- float tb = (intBitsToFloat(tree[node + offsetBack[axis]]) - org[axis]) * invDir[axis];
- node = offset;
- intervalMin = (tf >= intervalMin) ? tf : intervalMin;
- intervalMax = (tb <= intervalMax) ? tb : intervalMax;
- if (intervalMin > intervalMax)
- break;
- continue;
- }
- } // traversal loop
- do
- {
- // stack is empty?
- if (stackPos == 0)
- return;
- // move back up the stack
- stackPos--;
- intervalMin = stack[stackPos].tnear;
- if (maxDist < intervalMin)
- continue;
- node = stack[stackPos].node;
- intervalMax = stack[stackPos].tfar;
- break;
- } while (true);
- }
- }
-
- template<typename IsectCallback>
- void intersectPoint(const Vector3 &p, IsectCallback& intersectCallback) const
- {
- if (!bounds.contains(p))
- return;
-
- StackNode stack[MAX_STACK_SIZE];
- int stackPos = 0;
- int node = 0;
-
- while (true) {
- while (true)
- {
- uint32 tn = tree[node];
- uint32 axis = (tn & (3 << 30)) >> 30;
- bool BVH2 = tn & (1 << 29);
- int offset = tn & ~(7 << 29);
- if (!BVH2)
- {
- if (axis < 3)
- {
- // "normal" interior node
- float tl = intBitsToFloat(tree[node + 1]);
- float tr = intBitsToFloat(tree[node + 2]);
- // point is between clip zones
- if (tl < p[axis] && tr > p[axis])
- break;
- int right = offset + 3;
- node = right;
- // point is in right node only
- if (tl < p[axis]) {
- continue;
- }
- node = offset; // left
- // point is in left node only
- if (tr > p[axis]) {
- continue;
- }
- // point is in both nodes
- // push back right node
- stack[stackPos].node = right;
- stackPos++;
- continue;
- }
- else
- {
- // leaf - test some objects
- int n = tree[node + 1];
- while (n > 0) {
- intersectCallback(p, objects[offset]); // !!!
- --n;
- ++offset;
- }
- break;
- }
- }
- else // BVH2 node (empty space cut off left and right)
- {
- if (axis>2)
- return; // should not happen
- float tl = intBitsToFloat(tree[node + 1]);
- float tr = intBitsToFloat(tree[node + 2]);
- node = offset;
- if (tl > p[axis] || tr < p[axis])
- break;
- continue;
- }
- } // traversal loop
-
- // stack is empty?
- if (stackPos == 0)
- return;
- // move back up the stack
- stackPos--;
- node = stack[stackPos].node;
- }
- }
-
- bool writeToFile(FILE *wf) const;
- bool readFromFile(FILE *rf);
-
- protected:
- std::vector<uint32> tree;
- std::vector<uint32> objects;
- AABox bounds;
-
- struct buildData
- {
- uint32 *indices;
- AABox *primBound;
- uint32 numPrims;
- int maxPrims;
- };
- struct StackNode
- {
- uint32 node;
- float tnear;
- float tfar;
- };
-
- class BuildStats
- {
- private:
- int numNodes;
- int numLeaves;
- int sumObjects;
- int minObjects;
- int maxObjects;
- int sumDepth;
- int minDepth;
- int maxDepth;
- int numLeavesN[6];
- int numBVH2;
-
- public:
- BuildStats():
- numNodes(0), numLeaves(0), sumObjects(0), minObjects(0x0FFFFFFF),
- maxObjects(0xFFFFFFFF), sumDepth(0), minDepth(0x0FFFFFFF),
- maxDepth(0xFFFFFFFF), numBVH2(0)
- {
- for(int i=0; i<6; ++i) numLeavesN[i] = 0;
- }
-
- void updateInner() { numNodes++; }
- void updateBVH2() { numBVH2++; }
- void updateLeaf(int depth, int n);
- void printStats();
- };
-
- void buildHierarchy(std::vector<uint32> &tempTree, buildData &dat, BuildStats &stats);
-
- void createNode(std::vector<uint32> &tempTree, int nodeIndex, uint32 left, uint32 right) {
- // write leaf node
- tempTree[nodeIndex + 0] = (3 << 30) | left;
- tempTree[nodeIndex + 1] = right - left + 1;
- }
-
- void subdivide(int left, int right, std::vector<uint32> &tempTree, buildData &dat, AABound &gridBox, AABound &nodeBox, int nodeIndex, int depth, BuildStats &stats);
-};
-
-#endif // _BIH_H
diff --git a/src/server/shared/vmap/CMakeLists.txt b/src/server/shared/vmap/CMakeLists.txt
deleted file mode 100644
index 7d865d354e7..00000000000
--- a/src/server/shared/vmap/CMakeLists.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-
-########### next target ###############
-
-SET(vmaps_STAT_SRCS
- BIH.h
- BIH.cpp
- IVMapManager.h
- MapTree.cpp
- MapTree.h
- ModelInstance.cpp
- ModelInstance.h
- TileAssembler.cpp
- TileAssembler.h
- VMapDefinitions.h
- VMapFactory.cpp
- VMapFactory.h
- VMapManager2.cpp
- VMapManager2.h
- VMapTools.h
- WorldModel.cpp
- WorldModel.h
-)
-
-include_directories(
- ${ACE_INCLUDE_DIR}
- ${CMAKE_SOURCE_DIR}/src/server/framework
- ${CMAKE_SOURCE_DIR}/dep/include/g3dlite
-)
-
-add_library(vmaps STATIC ${vmaps_STAT_SRCS})
diff --git a/src/server/shared/vmap/IVMapManager.h b/src/server/shared/vmap/IVMapManager.h
deleted file mode 100644
index 00629eb122c..00000000000
--- a/src/server/shared/vmap/IVMapManager.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef _IVMAPMANAGER_H
-#define _IVMAPMANAGER_H
-
-#include<string>
-#include <Platform/Define.h>
-
-//===========================================================
-
-/**
-This is the minimum interface to the VMapMamager.
-*/
-
-namespace VMAP
-{
-
- enum VMAP_LOAD_RESULT
- {
- VMAP_LOAD_RESULT_ERROR,
- VMAP_LOAD_RESULT_OK,
- VMAP_LOAD_RESULT_IGNORED,
- };
-
- #define VMAP_INVALID_HEIGHT -100000.0f // for check
- #define VMAP_INVALID_HEIGHT_VALUE -200000.0f // real assigned value in unknown height case
-
- //===========================================================
- class IVMapManager
- {
- private:
- bool iEnableLineOfSightCalc;
- bool iEnableHeightCalc;
-
- public:
- IVMapManager() : iEnableLineOfSightCalc(true), iEnableHeightCalc(true) {}
-
- virtual ~IVMapManager(void) {}
-
- virtual int loadMap(const char* pBasePath, unsigned int pMapId, int x, int y) = 0;
-
- virtual bool existsMap(const char* pBasePath, unsigned int pMapId, int x, int y) = 0;
-
- virtual void unloadMap(unsigned int pMapId, int x, int y) = 0;
- virtual void unloadMap(unsigned int pMapId) = 0;
-
- virtual bool isInLineOfSight(unsigned int pMapId, float x1, float y1, float z1, float x2, float y2, float z2) = 0;
- virtual float getHeight(unsigned int pMapId, float x, float y, float z) = 0;
- /**
- test if we hit an object. return true if we hit one. rx,ry,rz will hold the hit position or the dest position, if no intersection was found
- return a position, that is pReduceDist closer to the origin
- */
- virtual bool getObjectHitPos(unsigned int pMapId, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float &ry, float& rz, float pModifyDist) = 0;
- /**
- send debug commands
- */
- virtual bool processCommand(char *pCommand)= 0;
-
- /**
- Enable/disable LOS calculation
- It is enabled by default. If it is enabled in mid game the maps have to loaded manualy
- */
- void setEnableLineOfSightCalc(bool pVal) { iEnableLineOfSightCalc = pVal; }
- /**
- Enable/disable model height calculation
- It is enabled by default. If it is enabled in mid game the maps have to loaded manualy
- */
- void setEnableHeightCalc(bool pVal) { iEnableHeightCalc = pVal; }
-
- bool isLineOfSightCalcEnabled() const { return(iEnableLineOfSightCalc); }
- bool isHeightCalcEnabled() const { return(iEnableHeightCalc); }
- bool isMapLoadingEnabled() const { return(iEnableLineOfSightCalc || iEnableHeightCalc ); }
-
- virtual std::string getDirFileName(unsigned int pMapId, int x, int y) const =0;
- /**
- Block maps from being used.
- parameter: String of map ids. Delimiter = ","
- e.g.: "0,1,530"
- */
- virtual void preventMapsFromBeingUsed(const char* pMapIdString) =0;
- /**
- Query world model area info.
- \param z gets adjusted to the ground height for which this are info is valid
- */
- virtual bool getAreaInfo(unsigned int pMapId, float x, float y, float &z, uint32 &flags, int32 &adtId, int32 &rootId, int32 &groupId) const=0;
- virtual bool GetLiquidLevel(uint32 pMapId, float x, float y, float z, uint8 ReqLiquidType, float &level, float &floor, uint32 &type) const=0;
- };
-
-}
-#endif
diff --git a/src/server/shared/vmap/MapTree.cpp b/src/server/shared/vmap/MapTree.cpp
deleted file mode 100644
index 8c77ee109f3..00000000000
--- a/src/server/shared/vmap/MapTree.cpp
+++ /dev/null
@@ -1,450 +0,0 @@
-/*
- * Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "MapTree.h"
-#include "ModelInstance.h"
-#include "VMapManager2.h"
-#include "VMapDefinitions.h"
-
-#include <string>
-#include <sstream>
-#include <iomanip>
-
-using G3D::Vector3;
-
-namespace VMAP
-{
-
- class MapRayCallback
- {
- public:
- MapRayCallback(ModelInstance *val): prims(val) {}
- ModelInstance *prims;
- bool operator()(const G3D::Ray& ray, uint32 entry, float& distance, bool pStopAtFirstHit=true)
- {
- return prims[entry].intersectRay(ray, distance, pStopAtFirstHit);
- //std::cout << "trying to intersect '" << entity->name << "'\n";
- }
- };
-
- class AreaInfoCallback
- {
- public:
- AreaInfoCallback(ModelInstance *val): prims(val) {}
- void operator()(const Vector3& point, uint32 entry)
- {
-#ifdef VMAP_DEBUG
- std::cout << "trying to intersect '" << prims[entry].name << "'\n";
-#endif
- prims[entry].intersectPoint(point, aInfo);
- }
-
- ModelInstance *prims;
- AreaInfo aInfo;
- };
-
- class LocationInfoCallback
- {
- public:
- LocationInfoCallback(ModelInstance *val, LocationInfo &info): prims(val), locInfo(info), result(false) {}
- void operator()(const Vector3& point, uint32 entry)
- {
-#ifdef VMAP_DEBUG
- std::cout << "trying to intersect '" << prims[entry].name << "'\n";
-#endif
- if (prims[entry].GetLocationInfo(point, locInfo))
- result = true;
- }
-
- ModelInstance *prims;
- LocationInfo &locInfo;
- bool result;
- };
-
-
- //=========================================================
-
- std::string StaticMapTree::getTileFileName(uint32 mapID, uint32 tileX, uint32 tileY)
- {
- std::stringstream tilefilename;
- tilefilename.fill('0');
- tilefilename << std::setw(3) << mapID << "_";
- //tilefilename << std::setw(2) << tileX << "_" << std::setw(2) << tileY << ".vmtile";
- tilefilename << std::setw(2) << tileY << "_" << std::setw(2) << tileX << ".vmtile";
- return tilefilename.str();
- }
-
- bool StaticMapTree::getAreaInfo(Vector3 &pos, uint32 &flags, int32 &adtId, int32 &rootId, int32 &groupId) const
- {
- AreaInfoCallback intersectionCallBack(iTreeValues);
- iTree.intersectPoint(pos, intersectionCallBack);
- if (intersectionCallBack.aInfo.result)
- {
- flags = intersectionCallBack.aInfo.flags;
- adtId = intersectionCallBack.aInfo.adtId;
- rootId = intersectionCallBack.aInfo.rootId;
- groupId = intersectionCallBack.aInfo.groupId;
- pos.z = intersectionCallBack.aInfo.ground_Z;
- return true;
- }
- return false;
- }
-
- bool StaticMapTree::GetLocationInfo(const Vector3 &pos, LocationInfo &info) const
- {
- LocationInfoCallback intersectionCallBack(iTreeValues, info);
- iTree.intersectPoint(pos, intersectionCallBack);
- return intersectionCallBack.result;
- }
-
- StaticMapTree::StaticMapTree(uint32 mapID, const std::string &basePath):
- iMapID(mapID), /* iTree(0), */ iTreeValues(0), iBasePath(basePath)
- {
- if (iBasePath.length() > 0 && (iBasePath[iBasePath.length()-1] != '/' || iBasePath[iBasePath.length()-1] != '\\'))
- {
- iBasePath.append("/");
- }
- }
-
- //=========================================================
- //! Make sure to call unloadMap() to unregister acquired model references before destroying
- StaticMapTree::~StaticMapTree()
- {
- delete[] iTreeValues;
- }
-
- //=========================================================
- /**
- return dist to hit or inf() if no hit
- */
-
- float StaticMapTree::getIntersectionTime(const G3D::Ray& pRay, float pMaxDist, bool pStopAtFirstHit) const
- {
- float distance = pMaxDist;
- MapRayCallback intersectionCallBack(iTreeValues);
- iTree.intersectRay(pRay, intersectionCallBack, distance, pStopAtFirstHit);
- return distance;
- }
- //=========================================================
-
- bool StaticMapTree::isInLineOfSight(const Vector3& pos1, const Vector3& pos2) const
- {
- bool result = true;
- float maxDist = (pos2 - pos1).magnitude();
- // prevent NaN values which can cause BIH intersection to enter infinite loop
- if (maxDist < 1e-10f)
- return true;
- // direction with length of 1
- G3D::Ray ray = G3D::Ray::fromOriginAndDirection(pos1, (pos2 - pos1)/maxDist);
- float resultDist = getIntersectionTime(ray, maxDist, true);
- if (resultDist < maxDist)
- {
- result = false;
- }
- return result;
- }
- //=========================================================
- /**
- When moving from pos1 to pos2 check if we hit an object. Return true and the position if we hit one
- Return the hit pos or the original dest pos
- */
-
- bool StaticMapTree::getObjectHitPos(const Vector3& pPos1, const Vector3& pPos2, Vector3& pResultHitPos, float pModifyDist) const
- {
- bool result=false;
- float maxDist = (pPos2 - pPos1).magnitude();
- // prevent NaN values which can cause BIH intersection to enter infinite loop
- if (maxDist < 1e-10f)
- {
- pResultHitPos = pPos2;
- return false;
- }
- Vector3 dir = (pPos2 - pPos1)/maxDist; // direction with length of 1
- G3D::Ray ray(pPos1, dir);
- float dist = getIntersectionTime(ray, maxDist, false);
- if (dist < maxDist)
- {
- pResultHitPos = pPos1 + dir * dist;
- if (pModifyDist < 0)
- {
- if ((pResultHitPos - pPos1).magnitude() > -pModifyDist)
- {
- pResultHitPos = pResultHitPos + dir*pModifyDist;
- }
- else
- {
- pResultHitPos = pPos1;
- }
- }
- else
- {
- pResultHitPos = pResultHitPos + dir*pModifyDist;
- }
- result = true;
- }
- else
- {
- pResultHitPos = pPos2;
- result = false;
- }
- return result;
- }
-
- //=========================================================
-
- float StaticMapTree::getHeight(const Vector3& pPos) const
- {
- float height = G3D::inf();
- Vector3 dir = Vector3(0,0,-1);
- G3D::Ray ray(pPos, dir); // direction with length of 1
- float maxDist = VMapDefinitions::getMaxCanFallDistance();
- float dist = getIntersectionTime(ray, maxDist, false);
- if (dist < maxDist)
- {
- height = pPos.z - dist;
- }
- return(height);
- }
-
- //=========================================================
-
- bool StaticMapTree::CanLoadMap(const std::string &vmapPath, uint32 mapID, uint32 tileX, uint32 tileY)
- {
- std::string basePath = vmapPath;
- if (basePath.length() > 0 && (basePath[basePath.length()-1] != '/' || basePath[basePath.length()-1] != '\\'))
- basePath.append("/");
- std::string fullname = basePath + VMapManager2::getMapFileName(mapID);
- bool success = true;
- FILE *rf = fopen(fullname.c_str(), "rb");
- if (!rf)
- return false;
- // TODO: check magic number when implemented...
- char tiled;
- char chunk[8];
- if (!readChunk(rf, chunk, VMAP_MAGIC, 8) || fread(&tiled, sizeof(char), 1, rf) != 1)
- {
- fclose(rf);
- return false;
- }
- if (tiled)
- {
- std::string tilefile = basePath + getTileFileName(mapID, tileX, tileY);
- FILE* tf = fopen(tilefile.c_str(), "rb");
- if (!tf)
- success = false;
- else
- fclose(tf);
- }
- fclose(rf);
- return success;
- }
-
- //=========================================================
-
- bool StaticMapTree::InitMap(const std::string &fname, VMapManager2 *vm)
- {
- std::cout << "Initializing StaticMapTree '" << fname << "'\n";
- bool success = true;
- std::string fullname = iBasePath + fname;
- FILE *rf = fopen(fullname.c_str(), "rb");
- if (!rf)
- return false;
- else
- {
- char chunk[8];
- //general info
- if (!readChunk(rf, chunk, VMAP_MAGIC, 8)) success = false;
- char tiled;
- if (success && fread(&tiled, sizeof(char), 1, rf) != 1) success = false;
- iIsTiled = bool(tiled);
- // Nodes
- if (success && !readChunk(rf, chunk, "NODE", 4)) success = false;
- if (success) success = iTree.readFromFile(rf);
- if (success)
- {
- iNTreeValues = iTree.primCount();
- iTreeValues = new ModelInstance[iNTreeValues];
- }
-
- if (success && !readChunk(rf, chunk, "GOBJ", 4)) success = false;
- // global model spawns
- // only non-tiled maps have them, and if so exactly one (so far at least...)
- ModelSpawn spawn;
-#ifdef VMAP_DEBUG
- std::cout << "Map isTiled:" << bool(iIsTiled) << std::endl;
-#endif
- if (!iIsTiled && ModelSpawn::readFromFile(rf, spawn))
- {
- WorldModel *model = vm->acquireModelInstance(iBasePath, spawn.name);
- std::cout << "StaticMapTree::InitMap(): loading " << spawn.name << std::endl;
- if (model)
- {
- // assume that global model always is the first and only tree value (could be improved...)
- iTreeValues[0] = ModelInstance(spawn, model);
- iLoadedSpawns[0] = 1;
- }
- else
- {
- success = false;
- std::cout << "error: could not acquire WorldModel pointer!\n";
- }
- }
-
- fclose(rf);
- }
- return success;
- }
-
- //=========================================================
-
- void StaticMapTree::UnloadMap(VMapManager2 *vm)
- {
- for (loadedSpawnMap::iterator i = iLoadedSpawns.begin(); i != iLoadedSpawns.end(); ++i)
- {
- iTreeValues[i->first].setUnloaded();
- for (uint32 refCount = 0; refCount < i->second; ++refCount)
- vm->releaseModelInstance(iTreeValues[i->first].name);
- }
- iLoadedSpawns.clear();
- iLoadedTiles.clear();
- }
-
- //=========================================================
-
- bool StaticMapTree::LoadMapTile(uint32 tileX, uint32 tileY, VMapManager2 *vm)
- {
- if (!iIsTiled)
- {
- // currently, core creates grids for all maps, whether it has terrain tiles or not
- // so we need "fake" tile loads to know when we can unload map geometry
- iLoadedTiles[packTileID(tileX, tileY)] = false;
- return true;
- }
- if (!iTreeValues)
- {
- std::cout << "Tree has not been initialized!\n";
- return false;
- }
- bool result = true;
-
- std::string tilefile = iBasePath + getTileFileName(iMapID, tileX, tileY);
- FILE* tf = fopen(tilefile.c_str(), "rb");
- if (tf)
- {
- uint32 numSpawns;
- if (fread(&numSpawns, sizeof(uint32), 1, tf) != 1)
- result = false;
- for (uint32 i=0; i<numSpawns && result; ++i)
- {
- // read model spawns
- ModelSpawn spawn;
- result = ModelSpawn::readFromFile(tf, spawn);
- if (result)
- {
- // acquire model instance
- WorldModel *model = vm->acquireModelInstance(iBasePath, spawn.name);
- if (!model) std::cout << "error: could not acquire WorldModel pointer!\n";
-
- // update tree
- uint32 referencedVal;
-
- fread(&referencedVal, sizeof(uint32), 1, tf);
- if (!iLoadedSpawns.count(referencedVal))
- {
-#ifdef VMAP_DEBUG
- if (referencedVal > iNTreeValues)
- {
- std::cout << "invalid tree element! (" << referencedVal << "/" << iNTreeValues << ")\n";
- continue;
- }
-#endif
- iTreeValues[referencedVal] = ModelInstance(spawn, model);
- iLoadedSpawns[referencedVal] = 1;
- }
- else
- {
- ++iLoadedSpawns[referencedVal];
-#ifdef VMAP_DEBUG
- if (iTreeValues[referencedVal].ID != spawn.ID) std::cout << "error: trying to load wrong spawn in node!\n";
- else if (iTreeValues[referencedVal].name != spawn.name) std::cout << "error: name collision on GUID="<< spawn.ID << "\n";
-#endif
- }
- }
- }
- iLoadedTiles[packTileID(tileX, tileY)] = true;
- fclose(tf);
- }
- else
- iLoadedTiles[packTileID(tileX, tileY)] = false;
- return result;
- }
-
- //=========================================================
-
- void StaticMapTree::UnloadMapTile(uint32 tileX, uint32 tileY, VMapManager2 *vm)
- {
- uint32 tileID = packTileID(tileX, tileY);
- loadedTileMap::iterator tile = iLoadedTiles.find(tileID);
- if (tile == iLoadedTiles.end())
- {
- std::cout << "WARNING: trying to unload non-loaded tile. Map:" << iMapID << " X:" << tileX << " Y:" << tileY << std::endl;
- return;
- }
- if (tile->second) // file associated with tile
- {
- std::string tilefile = iBasePath + getTileFileName(iMapID, tileX, tileY);
- FILE* tf = fopen(tilefile.c_str(), "rb");
- if (tf)
- {
- bool result=true;
- uint32 numSpawns;
- if (fread(&numSpawns, sizeof(uint32), 1, tf) != 1)
- result = false;
- for (uint32 i=0; i<numSpawns && result; ++i)
- {
- // read model spawns
- ModelSpawn spawn;
- result = ModelSpawn::readFromFile(tf, spawn);
- if (result)
- {
- // release model instance
- vm->releaseModelInstance(spawn.name);
-
- // update tree
- uint32 referencedNode;
-
- fread(&referencedNode, sizeof(uint32), 1, tf);
- if (!iLoadedSpawns.count(referencedNode))
- {
- std::cout << "error! trying to unload non-referenced model '" << spawn.name << "' (ID:" << spawn.ID << ")\n";
- }
- else if (--iLoadedSpawns[referencedNode] == 0)
- {
- //std::cout << "MapTree: removing '" << spawn.name << "' from tree\n";
- iTreeValues[referencedNode].setUnloaded();
- iLoadedSpawns.erase(referencedNode);
- }
- }
- }
- fclose(tf);
- }
- }
- iLoadedTiles.erase(tile);
- }
-
-}
diff --git a/src/server/shared/vmap/MapTree.h b/src/server/shared/vmap/MapTree.h
deleted file mode 100644
index 7955cb92d68..00000000000
--- a/src/server/shared/vmap/MapTree.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef _MAPTREE_H
-#define _MAPTREE_H
-
-#include "Platform/Define.h"
-#include "Utilities/UnorderedMap.h"
-#include "BIH.h"
-
-namespace VMAP
-{
- class ModelInstance;
- class GroupModel;
- class VMapManager2;
-
- struct LocationInfo
- {
- LocationInfo(): hitInstance(0), hitModel(0), ground_Z(-G3D::inf()) {};
- const ModelInstance *hitInstance;
- const GroupModel *hitModel;
- float ground_Z;
- };
-
- class StaticMapTree
- {
- typedef UNORDERED_MAP<uint32, bool> loadedTileMap;
- typedef UNORDERED_MAP<uint32, uint32> loadedSpawnMap;
- private:
- uint32 iMapID;
- bool iIsTiled;
- BIH iTree;
- ModelInstance *iTreeValues; // the tree entries
- uint32 iNTreeValues;
-
- // Store all the map tile idents that are loaded for that map
- // some maps are not splitted into tiles and we have to make sure, not removing the map before all tiles are removed
- // empty tiles have no tile file, hence map with bool instead of just a set (consistency check)
- loadedTileMap iLoadedTiles;
- // stores <tree_index, reference_count> to invalidate tree values, unload map, and to be able to report errors
- loadedSpawnMap iLoadedSpawns;
- std::string iBasePath;
-
- private:
- float getIntersectionTime(const G3D::Ray& pRay, float pMaxDist, bool pStopAtFirstHit) const;
- //bool containsLoadedMapTile(unsigned int pTileIdent) const { return(iLoadedMapTiles.containsKey(pTileIdent)); }
- public:
- static std::string getTileFileName(uint32 mapID, uint32 tileX, uint32 tileY);
- static uint32 packTileID(uint32 tileX, uint32 tileY) { return tileX<<16 | tileY; }
- static void unpackTileID(uint32 ID, uint32 &tileX, uint32 &tileY) { tileX = ID>>16; tileY = ID&0xFF; }
- static bool CanLoadMap(const std::string &basePath, uint32 mapID, uint32 tileX, uint32 tileY);
-
- StaticMapTree(uint32 mapID, const std::string &basePath);
- ~StaticMapTree();
-
- bool isInLineOfSight(const G3D::Vector3& pos1, const G3D::Vector3& pos2) const;
- bool getObjectHitPos(const G3D::Vector3& pos1, const G3D::Vector3& pos2, G3D::Vector3& pResultHitPos, float pModifyDist) const;
- float getHeight(const G3D::Vector3& pPos) const;
- bool getAreaInfo(G3D::Vector3 &pos, uint32 &flags, int32 &adtId, int32 &rootId, int32 &groupId) const;
- bool GetLocationInfo(const Vector3 &pos, LocationInfo &info) const;
-
- bool InitMap(const std::string &fname, VMapManager2 *vm);
- void UnloadMap(VMapManager2 *vm);
- bool LoadMapTile(uint32 tileX, uint32 tileY, VMapManager2 *vm);
- void UnloadMapTile(uint32 tileX, uint32 tileY, VMapManager2 *vm);
- bool isTiled() const { return iIsTiled; }
- uint32 numLoadedTiles() const { return iLoadedTiles.size(); }
- };
-
- struct AreaInfo
- {
- AreaInfo(): result(false), ground_Z(-G3D::inf()) {};
- bool result;
- float ground_Z;
- uint32 flags;
- int32 adtId;
- int32 rootId;
- int32 groupId;
- };
-} // VMAP
-
-#endif // _MAPTREE_H
diff --git a/src/server/shared/vmap/ModelInstance.cpp b/src/server/shared/vmap/ModelInstance.cpp
deleted file mode 100644
index 677a08e147a..00000000000
--- a/src/server/shared/vmap/ModelInstance.cpp
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "ModelInstance.h"
-#include "WorldModel.h"
-#include "MapTree.h"
-
-using G3D::Vector3;
-using G3D::Ray;
-
-namespace VMAP
-{
- ModelInstance::ModelInstance(const ModelSpawn &spawn, WorldModel *model): ModelSpawn(spawn), iModel(model)
- {
- iInvRot = G3D::Matrix3::fromEulerAnglesZYX(G3D::pi()*iRot.y/180.f, G3D::pi()*iRot.x/180.f, G3D::pi()*iRot.z/180.f).inverse();
- iInvScale = 1.f/iScale;
- }
-
- bool ModelInstance::intersectRay(const G3D::Ray& pRay, float& pMaxDist, bool pStopAtFirstHit) const
- {
- if (!iModel)
- {
- //std::cout << "<object not loaded>\n";
- return false;
- }
- float time = pRay.intersectionTime(iBound);
- if (time == G3D::inf())
- {
-// std::cout << "Ray does not hit '" << name << "'\n";
-
- return false;
- }
-// std::cout << "Ray crosses bound of '" << name << "'\n";
-/* std::cout << "ray from:" << pRay.origin().x << ", " << pRay.origin().y << ", " << pRay.origin().z
- << " dir:" << pRay.direction().x << ", " << pRay.direction().y << ", " << pRay.direction().z
- << " t/tmax:" << time << "/" << pMaxDist;
- std::cout << "\nBound lo:" << iBound.low().x << ", " << iBound.low().y << ", " << iBound.low().z << " hi: "
- << iBound.high().x << ", " << iBound.high().y << ", " << iBound.high().z << std::endl; */
- // child bounds are defined in object space:
- Vector3 p = iInvRot * (pRay.origin() - iPos) * iInvScale;
- Ray modRay(p, iInvRot * pRay.direction());
- float distance = pMaxDist * iInvScale;
- bool hit = iModel->IntersectRay(modRay, distance, pStopAtFirstHit);
- distance *= iScale;
- pMaxDist = distance;
- return hit;
- }
-
- void ModelInstance::intersectPoint(const G3D::Vector3& p, AreaInfo &info) const
- {
- if (!iModel)
- {
-#ifdef VMAP_DEBUG
- std::cout << "<object not loaded>\n";
-#endif
- return;
- }
-
- // M2 files don't contain area info, only WMO files
- if (flags & MOD_M2)
- return;
- if (!iBound.contains(p))
- return;
- // 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 (iModel->IntersectPoint(pModel, zDirModel, zDist, info))
- {
- Vector3 modelGround = pModel + zDist * 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)
- {
- info.ground_Z = world_Z;
- info.adtId = adtId;
- }
- }
- }
-
- bool ModelInstance::GetLocationInfo(const G3D::Vector3& p, LocationInfo &info) const
- {
- if (!iModel)
- {
-#ifdef VMAP_DEBUG
- std::cout << "<object not loaded>\n";
-#endif
- return false;
- }
-
- // M2 files don't contain area info, only WMO files
- if (flags & MOD_M2)
- return false;
- if (!iBound.contains(p))
- return false;
- // 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 (iModel->GetLocationInfo(pModel, zDirModel, zDist, info))
- {
- Vector3 modelGround = pModel + zDist * 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.ground_Z = world_Z;
- info.hitInstance = this;
- return true;
- }
- }
- return false;
- }
-
- bool ModelInstance::GetLiquidLevel(const G3D::Vector3& p, LocationInfo &info, 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))
- {
- // calculate world height (zDist in model coords):
- // assume WMO not tilted (wouldn't make much sense anyway)
- liqHeight = zDist * iScale + iPos.z;
- return true;
- }
- return false;
- }
-
- bool ModelSpawn::readFromFile(FILE *rf, ModelSpawn &spawn)
- {
- uint32 check=0, nameLen;
- check += fread(&spawn.flags, sizeof(uint32), 1, rf);
- // EoF?
- if (!check)
- {
- if (ferror(rf))
- std::cout << "Error reading ModelSpawn!\n";
- return false;
- }
- check += fread(&spawn.adtId, sizeof(uint16), 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);
- check += fread(&spawn.iScale, sizeof(float), 1, rf);
- bool has_bound = (spawn.flags & MOD_HAS_BOUND);
- if (has_bound) // only WMOs have bound in MPQ, only available after computation
- {
- Vector3 bLow, bHigh;
- check += fread(&bLow, sizeof(float), 3, rf);
- check += fread(&bHigh, sizeof(float), 3, rf);
- spawn.iBound = G3D::AABox(bLow, bHigh);
- }
- check += fread(&nameLen, sizeof(uint32), 1, rf);
- if(check != (has_bound ? 17 : 11))
- {
- std::cout << "Error reading ModelSpawn!\n";
- return false;
- }
- char nameBuff[500];
- if (nameLen>500) // file names should never be that long, must be file error
- {
- std::cout << "Error reading ModelSpawn, file name too long!\n";
- return false;
- }
- check = fread(nameBuff, sizeof(char), nameLen, rf);
- if (check != nameLen)
- {
- std::cout << "Error reading ModelSpawn!\n";
- return false;
- }
- spawn.name = std::string(nameBuff, nameLen);
- return true;
- }
-
- 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.ID, sizeof(uint32), 1, wf);
- check += fwrite(&spawn.iPos, sizeof(float), 3, wf);
- check += fwrite(&spawn.iRot, sizeof(float), 3, wf);
- check += fwrite(&spawn.iScale, sizeof(float), 1, wf);
- bool has_bound = (spawn.flags & MOD_HAS_BOUND);
- if(has_bound) // only WMOs have bound in MPQ, only available after computation
- {
- check += fwrite(&spawn.iBound.low(), sizeof(float), 3, wf);
- check += fwrite(&spawn.iBound.high(), sizeof(float), 3, wf);
- }
- uint32 nameLen = spawn.name.length();
- check += fwrite(&nameLen, sizeof(uint32), 1, wf);
- if(check != (has_bound ? 17 : 11)) return false;
- check = fwrite(spawn.name.c_str(), sizeof(char), nameLen, wf);
- if(check != nameLen) return false;
- return true;
- }
-
-}
diff --git a/src/server/shared/vmap/ModelInstance.h b/src/server/shared/vmap/ModelInstance.h
deleted file mode 100644
index 97b3ab632a1..00000000000
--- a/src/server/shared/vmap/ModelInstance.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef _MODELINSTANCE_H_
-#define _MODELINSTANCE_H_
-
-#include <G3D/Matrix3.h>
-#include <G3D/Vector3.h>
-#include <G3D/AABox.h>
-#include <G3D/Ray.h>
-
-#include "Platform/Define.h"
-
-namespace VMAP
-{
- class WorldModel;
- struct AreaInfo;
- struct LocationInfo;
-
- enum ModelFlags
- {
- MOD_M2 = 1,
- MOD_WORLDSPAWN = 1<<1,
- MOD_HAS_BOUND = 1<<2
- };
-
- class ModelSpawn
- {
- 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; }
-
-
- static bool readFromFile(FILE *rf, ModelSpawn &spawn);
- static bool writeToFile(FILE *rw, const ModelSpawn &spawn);
- };
-
- class ModelInstance: public ModelSpawn
- {
- public:
- ModelInstance(): iModel(0) {}
- ModelInstance(const ModelSpawn &spawn, WorldModel *model);
- void setUnloaded() { iModel = 0; }
- bool intersectRay(const G3D::Ray& pRay, float& pMaxDist, bool pStopAtFirstHit) const;
- 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;
- protected:
- G3D::Matrix3 iInvRot;
- float iInvScale;
- WorldModel *iModel;
- };
-} // namespace VMAP
-
-#endif // _MODELINSTANCE
diff --git a/src/server/shared/vmap/TileAssembler.cpp b/src/server/shared/vmap/TileAssembler.cpp
deleted file mode 100644
index d01b54a7564..00000000000
--- a/src/server/shared/vmap/TileAssembler.cpp
+++ /dev/null
@@ -1,494 +0,0 @@
-/*
- * Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "WorldModel.h"
-#include "TileAssembler.h"
-#include "MapTree.h"
-#include "BIH.h"
-#include "VMapDefinitions.h"
-
-#include <set>
-#include <iomanip>
-#include <sstream>
-#include <iomanip>
-
-using G3D::Vector3;
-using G3D::AABox;
-using G3D::inf;
-using std::pair;
-
-template<> struct BoundsTrait<VMAP::ModelSpawn*>
-{
- static void getBounds(const VMAP::ModelSpawn* const &obj, G3D::AABox& out) { out = obj->getBounds(); }
-};
-
-namespace VMAP
-{
- bool readChunk(FILE *rf, char *dest, const char *compare, uint32 len)
- {
- if (fread(dest, sizeof(char), len, rf) != len) return false;
- return memcmp(dest, compare, len) == 0;
- }
-
- Vector3 ModelPosition::transform(const Vector3& pIn) const
- {
- Vector3 out = pIn * iScale;
- out = iRotation * out;
- return(out);
- }
-
- //=================================================================
-
- TileAssembler::TileAssembler(const std::string& pSrcDirName, const std::string& pDestDirName)
- {
- iCurrentUniqueNameId = 0;
- iFilterMethod = NULL;
- iSrcDir = pSrcDirName;
- iDestDir = pDestDirName;
- //mkdir(iDestDir);
- //init();
- }
-
- TileAssembler::~TileAssembler()
- {
- //delete iCoordModelMapping;
- }
-
- bool TileAssembler::convertWorld2()
- {
- std::set<std::string> spawnedModelFiles;
- bool success = readMapSpawns();
- if (!success)
- return false;
-
- // export Map data
- for (MapData::iterator map_iter = mapData.begin(); map_iter != mapData.end() && success; ++map_iter)
- {
- // build global map tree
- std::vector<ModelSpawn*> mapSpawns;
- UniqueEntryMap::iterator entry;
- for (entry = map_iter->second->UniqueEntries.begin(); entry != map_iter->second->UniqueEntries.end(); ++entry)
- {
- // M2 models don't have a bound set in WDT/ADT placement data, i still think they're not used for LoS at all on retail
- if (entry->second.flags & MOD_M2)
- {
- if (!calculateTransformedBound(entry->second))
- break;
- }
- else if (entry->second.flags & MOD_WORLDSPAWN) // WMO maps and terrain maps use different origin, so we need to adapt :/
- {
- // TODO: remove extractor hack and uncomment below line:
- //entry->second.iPos += Vector3(533.33333f*32, 533.33333f*32, 0.f);
- entry->second.iBound = entry->second.iBound + Vector3(533.33333f*32, 533.33333f*32, 0.f);
- }
- mapSpawns.push_back(&(entry->second));
- spawnedModelFiles.insert(entry->second.name);
- }
-
- BIH pTree;
- pTree.build(mapSpawns, BoundsTrait<ModelSpawn*>::getBounds);
-
- // ===> possibly move this code to StaticMapTree class
- std::map<uint32, uint32> modelNodeIdx;
- for (uint32 i=0; i<mapSpawns.size(); ++i)
- modelNodeIdx.insert(pair<uint32, uint32>(mapSpawns[i]->ID, i));
- if (!modelNodeIdx.empty())
- printf("min GUID: %u, max GUID: %u\n", modelNodeIdx.begin()->first, modelNodeIdx.rbegin()->first);
-
- // write map tree file
- std::stringstream mapfilename;
- mapfilename << iDestDir << "/" << std::setfill('0') << std::setw(3) << map_iter->first << ".vmtree";
- FILE *mapfile = fopen(mapfilename.str().c_str(), "wb");
- if (!mapfile)
- {
- success = false;
- printf("Cannot open %s\n", mapfilename.str().c_str());
- break;
- }
-
- //general info
- if (success && fwrite(VMAP_MAGIC, 1, 8, mapfile) != 8) success = false;
- uint32 globalTileID = StaticMapTree::packTileID(65, 65);
- pair<TileMap::iterator, TileMap::iterator> globalRange = map_iter->second->TileEntries.equal_range(globalTileID);
- char isTiled = globalRange.first == globalRange.second; // only maps without terrain (tiles) have global WMO
- if (success && fwrite(&isTiled, sizeof(char), 1, mapfile) != 1) success = false;
- // Nodes
- if (success && fwrite("NODE", 4, 1, mapfile) != 1) success = false;
- if (success) success = pTree.writeToFile(mapfile);
- // global map spawns (WDT), if any (most instances)
- if (success && fwrite("GOBJ", 4, 1, mapfile) != 1) success = false;
-
- for (TileMap::iterator glob=globalRange.first; glob != globalRange.second && success; ++glob)
- {
- success = ModelSpawn::writeToFile(mapfile, map_iter->second->UniqueEntries[glob->second]);
- }
-
- fclose(mapfile);
-
- // <====
-
- // write map tile files, similar to ADT files, only with extra BSP tree node info
- TileMap &tileEntries = map_iter->second->TileEntries;
- TileMap::iterator tile;
- for (tile = tileEntries.begin(); tile != tileEntries.end(); ++tile)
- {
- const ModelSpawn &spawn = map_iter->second->UniqueEntries[tile->second];
- if (spawn.flags & MOD_WORLDSPAWN) // WDT spawn, saved as tile 65/65 currently...
- continue;
- uint32 nSpawns = tileEntries.count(tile->first);
- std::stringstream tilefilename;
- tilefilename.fill('0');
- tilefilename << iDestDir << "/" << std::setw(3) << map_iter->first << "_";
- uint32 x, y;
- StaticMapTree::unpackTileID(tile->first, x, y);
- tilefilename << std::setw(2) << x << "_" << std::setw(2) << y << ".vmtile";
- FILE *tilefile = fopen(tilefilename.str().c_str(), "wb");
- // write number of tile spawns
- if (success && fwrite(&nSpawns, sizeof(uint32), 1, tilefile) != 1) success = false;
- // write tile spawns
- for (uint32 s=0; s<nSpawns; ++s)
- {
- if (s)
- ++tile;
- const ModelSpawn &spawn2 = map_iter->second->UniqueEntries[tile->second];
- success = success && ModelSpawn::writeToFile(tilefile, spawn2);
- // MapTree nodes to update when loading tile:
- std::map<uint32, uint32>::iterator nIdx = modelNodeIdx.find(spawn2.ID);
- if (success && fwrite(&nIdx->second, sizeof(uint32), 1, tilefile) != 1) success = false;
- }
- fclose(tilefile);
- }
- // break; //test, extract only first map; TODO: remvoe this line
- }
-
- // export objects
- std::cout << "\nConverting Model Files" << std::endl;
- for (std::set<std::string>::iterator mfile = spawnedModelFiles.begin(); mfile != spawnedModelFiles.end(); ++mfile)
- {
- std::cout << "Converting " << *mfile << std::endl;
- if (!convertRawFile(*mfile))
- {
- std::cout << "error converting " << *mfile << std::endl;
- success = false;
- break;
- }
- }
-
- //cleanup:
- for (MapData::iterator map_iter = mapData.begin(); map_iter != mapData.end(); ++map_iter)
- {
- delete map_iter->second;
- }
- return success;
- }
-
- bool TileAssembler::readMapSpawns()
- {
- std::string fname = iSrcDir + "/dir_bin";
- FILE *dirf = fopen(fname.c_str(), "rb");
- if (!dirf)
- {
- printf("Could not read dir_bin file!\n");
- return false;
- }
- printf("Read coordinate mapping...\n");
- uint32 mapID, tileX, tileY, check=0;
- G3D::Vector3 v1, v2;
- ModelSpawn spawn;
- while (!feof(dirf))
- {
- check = 0;
- // read mapID, tileX, tileY, Flags, adtID, ID, Pos, Rot, Scale, Bound_lo, Bound_hi, name
- check += fread(&mapID, sizeof(uint32), 1, dirf);
- if (check == 0) // EoF...
- break;
- check += fread(&tileX, sizeof(uint32), 1, dirf);
- check += fread(&tileY, sizeof(uint32), 1, dirf);
- if (!ModelSpawn::readFromFile(dirf, spawn))
- break;
-
- MapSpawns *current;
- MapData::iterator map_iter = mapData.find(mapID);
- if (map_iter == mapData.end())
- {
- printf("spawning Map %d\n", mapID);
- mapData[mapID] = current = new MapSpawns();
- }
- else current = (*map_iter).second;
- current->UniqueEntries.insert(pair<uint32, ModelSpawn>(spawn.ID, spawn));
- current->TileEntries.insert(pair<uint32, uint32>(StaticMapTree::packTileID(tileX, tileY), spawn.ID));
- }
- bool success = (ferror(dirf) == 0);
- fclose(dirf);
- return success;
- }
-
- bool TileAssembler::calculateTransformedBound(ModelSpawn &spawn)
- {
- std::string modelFilename = iSrcDir + "/" + spawn.name;
- ModelPosition modelPosition;
- modelPosition.iDir = spawn.iRot;
- modelPosition.iScale = spawn.iScale;
- modelPosition.init();
-
- FILE *rf = fopen(modelFilename.c_str(), "rb");
- if (!rf)
- {
- printf("ERROR: Can't open model file: %s\n", modelFilename.c_str());
- return false;
- }
-
- AABox modelBound;
- bool boundEmpty=true;
- char ident[8];
-
- int readOperation = 1;
-
- // temporary use defines to simplify read/check code (close file and return at fail)
- #define READ_OR_RETURN(V,S) if(fread((V), (S), 1, rf) != 1) { \
- fclose(rf); printf("readfail, op = %i\n", readOperation); return(false); }readOperation++;
- #define CMP_OR_RETURN(V,S) if(strcmp((V),(S)) != 0) { \
- fclose(rf); printf("cmpfail, %s!=%s\n", V, S);return(false); }
-
- READ_OR_RETURN(&ident, 8);
- CMP_OR_RETURN(ident, "VMAP003");
-
- // we have to read one int. This is needed during the export and we have to skip it here
- uint32 tempNVectors;
- READ_OR_RETURN(&tempNVectors, sizeof(tempNVectors));
-
- uint32 groups, wmoRootId;
- char blockId[5];
- blockId[4] = 0;
- int blocksize;
- float *vectorarray = 0;
-
- READ_OR_RETURN(&groups, sizeof(uint32));
- READ_OR_RETURN(&wmoRootId, sizeof(uint32));
- if (groups != 1) printf("Warning: '%s' does not seem to be a M2 model!\n", modelFilename.c_str());
-
- for (uint32 g=0; g<groups; ++g) // should be only one for M2 files...
- {
- fseek(rf, 3*sizeof(uint32) + 6*sizeof(float), SEEK_CUR);
-
- READ_OR_RETURN(&blockId, 4);
- CMP_OR_RETURN(blockId, "GRP ");
- READ_OR_RETURN(&blocksize, sizeof(int));
- fseek(rf, blocksize, SEEK_CUR);
-
- // ---- indexes
- READ_OR_RETURN(&blockId, 4);
- CMP_OR_RETURN(blockId, "INDX");
- READ_OR_RETURN(&blocksize, sizeof(int));
- fseek(rf, blocksize, SEEK_CUR);
-
- // ---- vectors
- READ_OR_RETURN(&blockId, 4);
- CMP_OR_RETURN(blockId, "VERT");
- READ_OR_RETURN(&blocksize, sizeof(int));
- uint32 nvectors;
- READ_OR_RETURN(&nvectors, sizeof(uint32));
-
- if (nvectors >0)
- {
- vectorarray = new float[nvectors*3];
- READ_OR_RETURN(vectorarray, nvectors*sizeof(float)*3);
- }
- else
- {
- std::cout << "error: model '" << spawn.name << "' has no geometry!" << std::endl;
- return false;
- }
-
- for (uint32 i=0, indexNo=0; indexNo<nvectors; indexNo++, i+=3)
- {
- Vector3 v = Vector3(vectorarray[i+0], vectorarray[i+1], vectorarray[i+2]);
- v = modelPosition.transform(v);
-
- if (boundEmpty)
- modelBound = AABox(v, v), boundEmpty=false;
- else
- modelBound.merge(v);
- }
- delete[] vectorarray;
- // drop of temporary use defines
- #undef READ_OR_RETURN
- #undef CMP_OR_RETURN
- }
- spawn.iBound = modelBound + spawn.iPos;
- spawn.flags |= MOD_HAS_BOUND;
- fclose(rf);
- return true;
- }
-
- struct WMOLiquidHeader
- {
- int xverts, yverts, xtiles, ytiles;
- float pos_x;
- float pos_y;
- float pos_z;
- short type;
- };
- //=================================================================
- bool TileAssembler::convertRawFile(const std::string& pModelFilename)
- {
- bool success = true;
- std::string filename = iSrcDir;
- if (filename.length() >0)
- filename.append("/");
- filename.append(pModelFilename);
- FILE *rf = fopen(filename.c_str(), "rb");
-
- if (!rf)
- {
- printf("ERROR: Can't open model file in form: %s",pModelFilename.c_str());
- printf("... or form: %s",filename.c_str() );
- return false;
- }
-
- char ident[8];
-
- int readOperation = 1;
-
- // temporary use defines to simplify read/check code (close file and return at fail)
- #define READ_OR_RETURN(V,S) if(fread((V), (S), 1, rf) != 1) { \
- fclose(rf); printf("readfail, op = %i\n", readOperation); return(false); }readOperation++;
- #define CMP_OR_RETURN(V,S) if(strcmp((V),(S)) != 0) { \
- fclose(rf); printf("cmpfail, %s!=%s\n", V, S);return(false); }
-
- READ_OR_RETURN(&ident, 8);
- CMP_OR_RETURN(ident, "VMAP003");
-
- // we have to read one int. This is needed during the export and we have to skip it here
- uint32 tempNVectors;
- READ_OR_RETURN(&tempNVectors, sizeof(tempNVectors));
-
- uint32 groups;
- uint32 RootWMOID;
- char blockId[5];
- blockId[4] = 0;
- int blocksize;
-
- READ_OR_RETURN(&groups, sizeof(uint32));
- READ_OR_RETURN(&RootWMOID, sizeof(uint32));
-
- std::vector<GroupModel> groupsArray;
-
- for (uint32 g=0; g<groups; ++g)
- {
- std::vector<MeshTriangle> triangles;
- std::vector<Vector3> vertexArray;
-
- uint32 mogpflags, GroupWMOID;
- READ_OR_RETURN(&mogpflags, sizeof(uint32));
- READ_OR_RETURN(&GroupWMOID, sizeof(uint32));
-
- float bbox1[3], bbox2[3];
- READ_OR_RETURN(bbox1, sizeof(float)*3);
- READ_OR_RETURN(bbox2, sizeof(float)*3);
-
- uint32 liquidflags;
- READ_OR_RETURN(&liquidflags, sizeof(uint32));
-
- // will this ever be used? what is it good for anyway??
- uint32 branches;
- READ_OR_RETURN(&blockId, 4);
- CMP_OR_RETURN(blockId, "GRP ");
- READ_OR_RETURN(&blocksize, sizeof(int));
- READ_OR_RETURN(&branches, sizeof(uint32));
- for (uint32 b=0; b<branches; ++b)
- {
- uint32 indexes;
- // indexes for each branch (not used jet)
- READ_OR_RETURN(&indexes, sizeof(uint32));
- }
-
- // ---- indexes
- READ_OR_RETURN(&blockId, 4);
- CMP_OR_RETURN(blockId, "INDX");
- READ_OR_RETURN(&blocksize, sizeof(int));
- uint32 nindexes;
- READ_OR_RETURN(&nindexes, sizeof(uint32));
- if (nindexes >0)
- {
- uint16 *indexarray = new uint16[nindexes];
- READ_OR_RETURN(indexarray, nindexes*sizeof(uint16));
- for (uint32 i=0; i<nindexes; i+=3)
- {
- triangles.push_back(MeshTriangle(indexarray[i], indexarray[i+1], indexarray[i+2]));
- }
- delete[] indexarray;
- }
-
- // ---- vectors
- READ_OR_RETURN(&blockId, 4);
- CMP_OR_RETURN(blockId, "VERT");
- READ_OR_RETURN(&blocksize, sizeof(int));
- uint32 nvectors;
- READ_OR_RETURN(&nvectors, sizeof(uint32));
-
- if (nvectors >0)
- {
- float *vectorarray = new float[nvectors*3];
- READ_OR_RETURN(vectorarray, nvectors*sizeof(float)*3);
- for (uint32 i=0; i<nvectors; ++i)
- {
- vertexArray.push_back( Vector3(vectorarray + 3*i) );
- }
- delete[] vectorarray;
- }
- // ----- liquid
- WmoLiquid *liquid = 0;
- if (liquidflags& 1)
- {
- WMOLiquidHeader hlq;
- READ_OR_RETURN(&blockId, 4);
- CMP_OR_RETURN(blockId, "LIQU");
- READ_OR_RETURN(&blocksize, sizeof(int));
- READ_OR_RETURN(&hlq, sizeof(WMOLiquidHeader));
- liquid = new WmoLiquid(hlq.xtiles, hlq.ytiles, Vector3(hlq.pos_x, hlq.pos_y, hlq.pos_z), hlq.type);
- uint32 size = hlq.xverts*hlq.yverts;
- READ_OR_RETURN(liquid->GetHeightStorage(), size*sizeof(float));
- size = hlq.xtiles*hlq.ytiles;
- READ_OR_RETURN(liquid->GetFlagsStorage(), size);
- }
-
- groupsArray.push_back(GroupModel(mogpflags, GroupWMOID, AABox(Vector3(bbox1), Vector3(bbox2))));
- groupsArray.back().setMeshData(vertexArray, triangles);
- groupsArray.back().setLiquidData(liquid);
-
- // drop of temporary use defines
- #undef READ_OR_RETURN
- #undef CMP_OR_RETURN
-
- }
- fclose(rf);
-
- // write WorldModel
- WorldModel model;
- model.setRootWmoID(RootWMOID);
- if (groupsArray.size())
- {
- model.setGroupModels(groupsArray);
- success = model.writeFile(iDestDir + "/" + pModelFilename + ".vmo");
- }
-
- //std::cout << "readRawFile2: '" << pModelFilename << "' tris: " << nElements << " nodes: " << nNodes << std::endl;
- return success;
- }
-}
diff --git a/src/server/shared/vmap/TileAssembler.h b/src/server/shared/vmap/TileAssembler.h
deleted file mode 100644
index b26735708af..00000000000
--- a/src/server/shared/vmap/TileAssembler.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef _TILEASSEMBLER_H_
-#define _TILEASSEMBLER_H_
-
-#include <G3D/Vector3.h>
-#include <G3D/Matrix3.h>
-#include <map>
-
-#include "ModelInstance.h"
-
-namespace VMAP
-{
- /**
- This Class is used to convert raw vector data into balanced BSP-Trees.
- To start the conversion call convertWorld().
- */
- //===============================================
-
- class ModelPosition
- {
- private:
- G3D::Matrix3 iRotation;
- public:
- G3D::Vector3 iPos;
- G3D::Vector3 iDir;
- float iScale;
- void init()
- {
- iRotation = G3D::Matrix3::fromEulerAnglesZYX(G3D::pi()*iDir.y/180.f, G3D::pi()*iDir.x/180.f, G3D::pi()*iDir.z/180.f);
- }
- G3D::Vector3 transform(const G3D::Vector3& pIn) const;
- void moveToBasePos(const G3D::Vector3& pBasePos) { iPos -= pBasePos; }
- };
-
- typedef std::map<uint32, ModelSpawn> UniqueEntryMap;
- typedef std::multimap<uint32, uint32> TileMap;
-
- struct MapSpawns
- {
- UniqueEntryMap UniqueEntries;
- TileMap TileEntries;
- };
-
- typedef std::map<uint32, MapSpawns*> MapData;
- //===============================================
-
- class TileAssembler
- {
- private:
- std::string iDestDir;
- std::string iSrcDir;
- bool (*iFilterMethod)(char *pName);
- G3D::Table<std::string, unsigned int > iUniqueNameIds;
- unsigned int iCurrentUniqueNameId;
- MapData mapData;
-
- public:
- TileAssembler(const std::string& pSrcDirName, const std::string& pDestDirName);
- virtual ~TileAssembler();
-
- bool convertWorld2();
- bool readMapSpawns();
- bool calculateTransformedBound(ModelSpawn &spawn);
-
- bool convertRawFile(const std::string& pModelFilename);
- void setModelNameFilterMethod(bool (*pFilterMethod)(char *pName)) { iFilterMethod = pFilterMethod; }
- std::string getDirEntryNameFromModName(unsigned int pMapId, const std::string& pModPosName);
- unsigned int getUniqueNameId(const std::string pName);
- };
-
-} // VMAP
-#endif /*_TILEASSEMBLER_H_*/
diff --git a/src/server/shared/vmap/VMapDefinitions.h b/src/server/shared/vmap/VMapDefinitions.h
deleted file mode 100644
index e4a34cc1397..00000000000
--- a/src/server/shared/vmap/VMapDefinitions.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef _VMAPDEFINITIONS_H
-#define _VMAPDEFINITIONS_H
-#include <cstring>
-
-#define LIQUID_TILE_SIZE (533.333f / 128.f)
-
-namespace VMAP
-{
- //=====================================
- #define MAX_CAN_FALL_DISTANCE 10.0f
- const char VMAP_MAGIC[] = "VMAP_3.0";
-
- class VMapDefinitions
- {
- public:
- static float getMaxCanFallDistance() { return MAX_CAN_FALL_DISTANCE; }
- };
-
- //======================================
-
- // defined in TileAssembler.cpp currently...
- bool readChunk(FILE *rf, char *dest, const char *compare, uint32 len);
-}
-#endif
diff --git a/src/server/shared/vmap/VMapFactory.cpp b/src/server/shared/vmap/VMapFactory.cpp
deleted file mode 100644
index 331acbace47..00000000000
--- a/src/server/shared/vmap/VMapFactory.cpp
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <sys/types.h>
-#include "VMapFactory.h"
-#include "VMapManager2.h"
-
-using namespace G3D;
-
-namespace VMAP
-{
- void chompAndTrim(std::string& str)
- {
- while(str.length() >0)
- {
- char lc = str[str.length()-1];
- if(lc == '\r' || lc == '\n' || lc == ' ' || lc == '"' || lc == '\'')
- {
- str = str.substr(0,str.length()-1);
- }
- else
- {
- break;
- }
- }
- while(str.length() >0)
- {
- char lc = str[0];
- if(lc == ' ' || lc == '"' || lc == '\'')
- {
- str = str.substr(1,str.length()-1);
- }
- else
- {
- break;
- }
- }
- }
-
- IVMapManager *gVMapManager = 0;
- Table<unsigned int , bool>* iIgnoreSpellIds=0;
-
- //===============================================
- // result false, if no more id are found
-
- bool getNextId(const std::string& pString, unsigned int& pStartPos, unsigned int& pId)
- {
- bool result = false;
- unsigned int i;
- for(i=pStartPos;i<pString.size(); ++i)
- {
- if(pString[i] == ',')
- {
- break;
- }
- }
- if(i>pStartPos)
- {
- std::string idString = pString.substr(pStartPos, i-pStartPos);
- pStartPos = i+1;
- chompAndTrim(idString);
- pId = atoi(idString.c_str());
- result = true;
- }
- return(result);
- }
-
- //===============================================
- /**
- parameter: String of map ids. Delimiter = ","
- */
-
- void VMapFactory::preventSpellsFromBeingTestedForLoS(const char* pSpellIdString)
- {
- if(!iIgnoreSpellIds)
- iIgnoreSpellIds = new Table<unsigned int , bool>();
- if(pSpellIdString != NULL)
- {
- unsigned int pos =0;
- unsigned int id;
- std::string confString(pSpellIdString);
- chompAndTrim(confString);
- while(getNextId(confString, pos, id))
- {
- iIgnoreSpellIds->set(id, true);
- }
- }
- }
-
- //===============================================
-
- bool VMapFactory::checkSpellForLoS(unsigned int pSpellId)
- {
- return(!iIgnoreSpellIds->containsKey(pSpellId));
- }
-
- //===============================================
- // just return the instance
- IVMapManager* VMapFactory::createOrGetVMapManager()
- {
- if(gVMapManager == 0)
- gVMapManager= new VMapManager2(); // should be taken from config ... Please change if you like :-)
- return gVMapManager;
- }
-
- //===============================================
- // delete all internal data structures
- void VMapFactory::clear()
- {
- if(iIgnoreSpellIds)
- {
- delete iIgnoreSpellIds;
- iIgnoreSpellIds = NULL;
- }
- if(gVMapManager)
- {
- delete gVMapManager;
- gVMapManager = NULL;
- }
- }
-}
diff --git a/src/server/shared/vmap/VMapFactory.h b/src/server/shared/vmap/VMapFactory.h
deleted file mode 100644
index 8dc2c01938a..00000000000
--- a/src/server/shared/vmap/VMapFactory.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef _VMAPFACTORY_H
-#define _VMAPFACTORY_H
-
-#include "IVMapManager.h"
-
-/**
-This is the access point to the VMapManager.
-*/
-
-namespace VMAP
-{
- //===========================================================
-
- class VMapFactory
- {
- public:
- static IVMapManager* createOrGetVMapManager();
- static void clear();
-
- static void preventSpellsFromBeingTestedForLoS(const char* pSpellIdString);
- static bool checkSpellForLoS(unsigned int pSpellId);
- };
-
-}
-#endif
diff --git a/src/server/shared/vmap/VMapManager2.cpp b/src/server/shared/vmap/VMapManager2.cpp
deleted file mode 100644
index 1e8a84aee52..00000000000
--- a/src/server/shared/vmap/VMapManager2.cpp
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- * Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <iostream>
-#include <iomanip>
-#include <string>
-#include <sstream>
-#include "VMapManager2.h"
-#include "MapTree.h"
-#include "ModelInstance.h"
-#include "WorldModel.h"
-#include "VMapDefinitions.h"
-
-using G3D::Vector3;
-
-namespace VMAP
-{
-
- //=========================================================
-
- VMapManager2::VMapManager2()
- {
- }
-
- //=========================================================
-
- VMapManager2::~VMapManager2(void)
- {
- for (InstanceTreeMap::iterator i = iInstanceMapTrees.begin(); i != iInstanceMapTrees.end(); ++i)
- {
- delete i->second;
- }
- for (ModelFileMap::iterator i = iLoadedModelFiles.begin(); i != iLoadedModelFiles.end(); ++i)
- {
- delete i->second.getModel();
- }
- }
-
- //=========================================================
-
- Vector3 VMapManager2::convertPositionToInternalRep(float x, float y, float z) const
- {
- Vector3 pos;
- const float mid = 0.5 * 64.0 * 533.33333333f;
- pos.x = mid - x;
- pos.y = mid - y;
- pos.z = z;
-
- return pos;
- }
-
- //=========================================================
-
- Vector3 VMapManager2::convertPositionToMangosRep(float x, float y, float z) const
- {
- Vector3 pos;
- const float mid = 0.5 * 64.0 * 533.33333333f;
- pos.x = mid - x;
- pos.y = mid - y;
- pos.z = z;
-
- return pos;
- }
- //=========================================================
-
- // move to MapTree too?
- std::string VMapManager2::getMapFileName(unsigned int pMapId)
- {
- std::stringstream fname;
- fname.width(3);
- fname << std::setfill('0') << pMapId << std::string(MAP_FILENAME_EXTENSION2);
- return fname.str();
- }
-
- //=========================================================
- /**
- Block maps from being used.
- parameter: String of map ids. Delimiter = ","
- e.g.: "0,1,590"
- */
-
- void VMapManager2::preventMapsFromBeingUsed(const char* pMapIdString)
- {
- iIgnoreMapIds.clear();
- if (pMapIdString != NULL)
- {
- std::string map_str;
- std::stringstream map_ss;
- map_ss.str(std::string(pMapIdString));
- while (std::getline(map_ss, map_str, ','))
- {
- std::stringstream ss2(map_str);
- int map_num = -1;
- ss2 >> map_num;
- if (map_num >= 0)
- {
- std::cout << "ingoring Map " << map_num << " for VMaps\n";
- iIgnoreMapIds[map_num] = true;
- // unload map in case it is loaded
- unloadMap(map_num);
- }
- }
- }
- }
-
- //=========================================================
-
- int VMapManager2::loadMap(const char* pBasePath, unsigned int pMapId, int x, int y)
- {
- int result = VMAP_LOAD_RESULT_IGNORED;
- if (isMapLoadingEnabled() && !iIgnoreMapIds.count(pMapId))
- {
- if (_loadMap(pMapId, pBasePath, x, y))
- result = VMAP_LOAD_RESULT_OK;
- else
- result = VMAP_LOAD_RESULT_ERROR;
- }
- return result;
- }
-
- //=========================================================
- // load one tile (internal use only)
-
- bool VMapManager2::_loadMap(unsigned int pMapId, const std::string &basePath, uint32 tileX, uint32 tileY)
- {
- InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(pMapId);
- if (instanceTree == iInstanceMapTrees.end())
- {
- std::string mapFileName = getMapFileName(pMapId);
- StaticMapTree *newTree = new StaticMapTree(pMapId, basePath);
- if (!newTree->InitMap(mapFileName, this))
- return false;
- instanceTree = iInstanceMapTrees.insert(InstanceTreeMap::value_type(pMapId, newTree)).first;
- }
- return instanceTree->second->LoadMapTile(tileX, tileY, this);
- }
-
- //=========================================================
-
- void VMapManager2::unloadMap(unsigned int pMapId)
- {
- InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(pMapId);
- if (instanceTree != iInstanceMapTrees.end())
- {
- instanceTree->second->UnloadMap(this);
- if (instanceTree->second->numLoadedTiles() == 0)
- {
- delete instanceTree->second;
- iInstanceMapTrees.erase(pMapId);
- }
- }
- }
-
- //=========================================================
-
- void VMapManager2::unloadMap(unsigned int pMapId, int x, int y)
- {
- InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(pMapId);
- if (instanceTree != iInstanceMapTrees.end())
- {
- instanceTree->second->UnloadMapTile(x, y, this);
- if (instanceTree->second->numLoadedTiles() == 0)
- {
- delete instanceTree->second;
- iInstanceMapTrees.erase(pMapId);
- }
- }
- }
-
- //==========================================================
-
- bool VMapManager2::isInLineOfSight(unsigned int pMapId, float x1, float y1, float z1, float x2, float y2, float z2)
- {
- if (!isLineOfSightCalcEnabled()) return true;
- bool result = true;
- InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(pMapId);
- if (instanceTree != iInstanceMapTrees.end())
- {
- Vector3 pos1 = convertPositionToInternalRep(x1,y1,z1);
- Vector3 pos2 = convertPositionToInternalRep(x2,y2,z2);
- if (pos1 != pos2)
- {
- result = instanceTree->second->isInLineOfSight(pos1, pos2);
- }
- }
- return result;
- }
- //=========================================================
- /**
- get the hit position and return true if we hit something
- otherwise the result pos will be the dest pos
- */
- bool VMapManager2::getObjectHitPos(unsigned int pMapId, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float &ry, float& rz, float pModifyDist)
- {
- bool result = false;
- rx=x2;
- ry=y2;
- rz=z2;
- if (isLineOfSightCalcEnabled())
- {
- InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(pMapId);
- if (instanceTree != iInstanceMapTrees.end())
- {
- Vector3 pos1 = convertPositionToInternalRep(x1,y1,z1);
- Vector3 pos2 = convertPositionToInternalRep(x2,y2,z2);
- Vector3 resultPos;
- result = instanceTree->second->getObjectHitPos(pos1, pos2, resultPos, pModifyDist);
- resultPos = convertPositionToMangosRep(resultPos.x,resultPos.y,resultPos.z);
- rx = resultPos.x;
- ry = resultPos.y;
- rz = resultPos.z;
- }
- }
- return result;
- }
-
- //=========================================================
- /**
- get height or INVALID_HEIGHT if no height available
- */
-
- float VMapManager2::getHeight(unsigned int pMapId, float x, float y, float z)
- {
- float height = VMAP_INVALID_HEIGHT_VALUE; //no height
- if (isHeightCalcEnabled())
- {
- InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(pMapId);
- if (instanceTree != iInstanceMapTrees.end())
- {
- Vector3 pos = convertPositionToInternalRep(x,y,z);
- height = instanceTree->second->getHeight(pos);
- if (!(height < G3D::inf()))
- {
- height = VMAP_INVALID_HEIGHT_VALUE; //no height
- }
- }
- }
- return height;
- }
-
- //=========================================================
-
- bool VMapManager2::getAreaInfo(unsigned int pMapId, float x, float y, float &z, uint32 &flags, int32 &adtId, int32 &rootId, int32 &groupId) const
- {
- bool result=false;
- InstanceTreeMap::const_iterator instanceTree = iInstanceMapTrees.find(pMapId);
- if (instanceTree != iInstanceMapTrees.end())
- {
- Vector3 pos = convertPositionToInternalRep(x, y, z);
- result = instanceTree->second->getAreaInfo(pos, flags, adtId, rootId, groupId);
- // z is not touched by convertPositionToMangosRep(), so just copy
- z = pos.z;
- }
- return(result);
- }
-
- bool VMapManager2::GetLiquidLevel(uint32 pMapId, float x, float y, float z, uint8 ReqLiquidType, float &level, float &floor, uint32 &type) const
- {
- InstanceTreeMap::const_iterator instanceTree = iInstanceMapTrees.find(pMapId);
- if (instanceTree != iInstanceMapTrees.end())
- {
- LocationInfo info;
- Vector3 pos = convertPositionToInternalRep(x, y, z);
- if (instanceTree->second->GetLocationInfo(pos, info))
- {
- floor = info.ground_Z;
- type = info.hitModel->GetLiquidType();
- if (ReqLiquidType && !(type & ReqLiquidType))
- return false;
- if (info.hitInstance->GetLiquidLevel(pos, info, level))
- return true;
- }
- }
- return false;
- }
-
- //=========================================================
-
- WorldModel* VMapManager2::acquireModelInstance(const std::string &basepath, const std::string &filename)
- {
- ModelFileMap::iterator model = iLoadedModelFiles.find(filename);
- if (model == iLoadedModelFiles.end())
- {
- WorldModel *worldmodel = new WorldModel();
- if (!worldmodel->readFile(basepath + filename + ".vmo"))
- {
- std::cout << "VMapManager2: could not load '" << basepath << filename << ".vmo'!\n";
- delete worldmodel;
- return NULL;
- }
- std::cout << "VMapManager2: loading file '" << basepath << filename << "'.\n";
- model = iLoadedModelFiles.insert(std::pair<std::string, ManagedModel>(filename, ManagedModel())).first;
- model->second.setModel(worldmodel);
- }
- model->second.incRefCount();
- return model->second.getModel();
- }
-
- void VMapManager2::releaseModelInstance(const std::string &filename)
- {
- ModelFileMap::iterator model = iLoadedModelFiles.find(filename);
- if (model == iLoadedModelFiles.end())
- {
- std::cout << "VMapManager2: trying to unload non-loaded file '" << filename << "'!\n";
- return;
- }
- if( model->second.decRefCount() == 0)
- {
- std::cout << "VMapManager2: unloading file '" << filename << "'.\n";
- delete model->second.getModel();
- iLoadedModelFiles.erase(model);
- }
- }
- //=========================================================
-
- bool VMapManager2::existsMap(const char* pBasePath, unsigned int pMapId, int x, int y)
- {
- return StaticMapTree::CanLoadMap(std::string(pBasePath), pMapId, x, y);
- }
-
-} // namespace VMAP
diff --git a/src/server/shared/vmap/VMapManager2.h b/src/server/shared/vmap/VMapManager2.h
deleted file mode 100644
index 5f03b87b07f..00000000000
--- a/src/server/shared/vmap/VMapManager2.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef _VMAPMANAGER2_H
-#define _VMAPMANAGER2_H
-
-#include "IVMapManager.h"
-#include "Utilities/UnorderedMap.h"
-#include "Platform/Define.h"
-#include <G3D/Vector3.h>
-
-//===========================================================
-
-#define MAP_FILENAME_EXTENSION2 ".vmtree"
-
-#define FILENAMEBUFFER_SIZE 500
-
-/**
-This is the main Class to manage loading and unloading of maps, line of sight, height calculation and so on.
-For each map or map tile to load it reads a directory file that contains the ModelContainer files used by this map or map tile.
-Each global map or instance has its own dynamic BSP-Tree.
-The loaded ModelContainers are included in one of these BSP-Trees.
-Additionally a table to match map ids and map names is used.
-*/
-
-//===========================================================
-
-namespace VMAP
-{
- class StaticMapTree;
- class WorldModel;
-
- class ManagedModel
- {
- public:
- ManagedModel(): iModel(0), 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 UNORDERED_MAP<uint32 , StaticMapTree *> InstanceTreeMap;
- typedef UNORDERED_MAP<std::string, ManagedModel> ModelFileMap;
-
- class VMapManager2 : public IVMapManager
- {
- protected:
- // Tree to check collision
- ModelFileMap iLoadedModelFiles;
- InstanceTreeMap iInstanceMapTrees;
- // UNORDERED_MAP<unsigned int , bool> iMapsSplitIntoTiles;
- UNORDERED_MAP<unsigned int , bool> iIgnoreMapIds;
-
- bool _loadMap(uint32 pMapId, const std::string &basePath, uint32 tileX, uint32 tileY);
- /* void _unloadMap(uint32 pMapId, uint32 x, uint32 y); */
-
- public:
- // public for debug
- G3D::Vector3 convertPositionToInternalRep(float x, float y, float z) const;
- G3D::Vector3 convertPositionToMangosRep(float x, float y, float z) const;
- static std::string getMapFileName(unsigned int pMapId);
-
- VMapManager2();
- ~VMapManager2(void);
-
- int loadMap(const char* pBasePath, unsigned int pMapId, int x, int y);
-
- void unloadMap(unsigned int pMapId, int x, int y);
- void unloadMap(unsigned int pMapId);
-
- bool isInLineOfSight(unsigned int pMapId, float x1, float y1, float z1, float x2, float y2, float z2) ;
- /**
- fill the hit pos and return true, if an object was hit
- */
- bool getObjectHitPos(unsigned int pMapId, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float &ry, float& rz, float pModifyDist);
- float getHeight(unsigned int pMapId, float x, float y, float z);
-
- bool processCommand(char *pCommand) { return false; } // for debug and extensions
-
- void preventMapsFromBeingUsed(const char* pMapIdString);
- bool getAreaInfo(unsigned int pMapId, float x, float y, float &z, uint32 &flags, int32 &adtId, int32 &rootId, int32 &groupId) const;
- bool GetLiquidLevel(uint32 pMapId, float x, float y, float z, uint8 ReqLiquidType, float &level, float &floor, uint32 &type) const;
-
- WorldModel* acquireModelInstance(const std::string &basepath, const std::string &filename);
- void releaseModelInstance(const std::string &filename);
-
- // what's the use of this? o.O
- virtual std::string getDirFileName(unsigned int pMapId, int x, int y) const
- {
- return getMapFileName(pMapId);
- }
- virtual bool existsMap(const char* pBasePath, unsigned int pMapId, int x, int y);
- };
-}
-#endif
diff --git a/src/server/shared/vmap/VMapTools.h b/src/server/shared/vmap/VMapTools.h
deleted file mode 100644
index dbbd9af9271..00000000000
--- a/src/server/shared/vmap/VMapTools.h
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
-* Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-#ifndef _VMAPTOOLS_H
-#define _VMAPTOOLS_H
-
-#include <G3D/CollisionDetection.h>
-#include <G3D/AABox.h>
-
-#include "NodeValueAccess.h"
-
-/**
-The Class is mainly taken from G3D/AABSPTree.h but modified to be able to use our internal data structure.
-This is an iterator that helps us analysing the BSP-Trees.
-The collision detection is modified to return true, if we are inside an object.
-*/
-
-namespace VMAP
-{
- template<class TValue>
- class IntersectionCallBack {
- public:
- TValue* closestEntity;
- G3D::Vector3 hitLocation;
- G3D::Vector3 hitNormal;
-
- void operator()(const G3D::Ray& ray, const TValue* entity, bool pStopAtFirstHit, float& distance) {
- entity->intersect(ray, distance, pStopAtFirstHit, hitLocation, hitNormal);
- }
- };
-
- //==============================================================
- //==============================================================
- //==============================================================
-
- class MyCollisionDetection
- {
- private:
- public:
-
- static bool collisionLocationForMovingPointFixedAABox(
- const G3D::Vector3& origin,
- const G3D::Vector3& dir,
- const G3D::AABox& box,
- G3D::Vector3& location,
- bool& Inside)
- {
-
- // Integer representation of a floating-point value.
-#define IR(x) (reinterpret_cast<G3D::uint32 const&>(x))
-
- Inside = true;
- const G3D::Vector3& MinB = box.low();
- const G3D::Vector3& MaxB = box.high();
- G3D::Vector3 MaxT(-1.0f, -1.0f, -1.0f);
-
- // Find candidate planes.
- for (int i = 0; i < 3; ++i)
- {
- if (origin[i] < MinB[i])
- {
- location[i] = MinB[i];
- Inside = false;
-
- // Calculate T distances to candidate planes
- if (IR(dir[i]))
- {
- MaxT[i] = (MinB[i] - origin[i]) / dir[i];
- }
- }
- else if (origin[i] > MaxB[i])
- {
- location[i] = MaxB[i];
- Inside = false;
-
- // Calculate T distances to candidate planes
- if (IR(dir[i]))
- {
- MaxT[i] = (MaxB[i] - origin[i]) / dir[i];
- }
- }
- }
-
- if (Inside)
- {
- // definite hit
- location = origin;
- return true;
- }
-
- // Get largest of the maxT's for final choice of intersection
- int WhichPlane = 0;
- if (MaxT[1] > MaxT[WhichPlane])
- {
- WhichPlane = 1;
- }
-
- if (MaxT[2] > MaxT[WhichPlane])
- {
- WhichPlane = 2;
- }
-
- // Check final candidate actually inside box
- if (IR(MaxT[WhichPlane]) & 0x80000000)
- {
- // Miss the box
- return false;
- }
-
- for (int i = 0; i < 3; ++i)
- {
- if (i != WhichPlane)
- {
- location[i] = origin[i] + MaxT[WhichPlane] * dir[i];
- if ((location[i] < MinB[i]) ||
- (location[i] > MaxB[i]))
- {
- // On this plane we're outside the box extents, so
- // we miss the box
- return false;
- }
- }
- }
- /*
- // Choose the normal to be the plane normal facing into the ray
- normal = G3D::Vector3::zero();
- normal[WhichPlane] = (dir[WhichPlane] > 0) ? -1.0 : 1.0;
- */
- return true;
-
-#undef IR
- }
- };
-}
-#endif
diff --git a/src/server/shared/vmap/WorldModel.cpp b/src/server/shared/vmap/WorldModel.cpp
deleted file mode 100644
index 690c77577ae..00000000000
--- a/src/server/shared/vmap/WorldModel.cpp
+++ /dev/null
@@ -1,535 +0,0 @@
-/*
- * Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "WorldModel.h"
-#include "VMapDefinitions.h"
-#include "MapTree.h"
-
-using G3D::Vector3;
-using G3D::Ray;
-
-template<> struct BoundsTrait<VMAP::GroupModel>
-{
- static void getBounds(const VMAP::GroupModel& obj, G3D::AABox& out) { out = obj.GetBound(); }
-};
-
-
-namespace VMAP
-{
- bool IntersectTriangle(const MeshTriangle &tri, std::vector<Vector3>::const_iterator points, const G3D::Ray &ray, float &distance)
- {
- static const float EPS = 1e-5f;
-
- // See RTR2 ch. 13.7 for the algorithm.
-
- const Vector3 e1 = points[tri.idx1] - points[tri.idx0];
- const Vector3 e2 = points[tri.idx2] - points[tri.idx0];
- const Vector3 p(ray.direction().cross(e2));
- const float a = e1.dot(p);
-
- if (abs(a) < EPS) {
- // Determinant is ill-conditioned; abort early
- return false;
- }
-
- const float f = 1.0f / a;
- const Vector3 s(ray.origin() - points[tri.idx0]);
- const float u = f * s.dot(p);
-
- if ((u < 0.0f) || (u > 1.0f)) {
- // We hit the plane of the m_geometry, but outside the m_geometry
- return false;
- }
-
- const Vector3 q(s.cross(e1));
- const float v = f * ray.direction().dot(q);
-
- if ((v < 0.0f) || ((u + v) > 1.0f)) {
- // We hit the plane of the triangle, but outside the triangle
- return false;
- }
-
- const float t = f * e2.dot(q);
-
- if ((t > 0.0f) && (t < distance))
- {
- // This is a new hit, closer than the previous one
- distance = t;
-
- /* baryCoord[0] = 1.0 - u - v;
- baryCoord[1] = u;
- baryCoord[2] = v; */
-
- return true;
- }
- // This hit is after the previous hit, so ignore it
- return false;
- }
-
- class TriBoundFunc
- {
- public:
- TriBoundFunc(std::vector<Vector3> &vert): vertices(vert.begin()) {}
- void operator()(const MeshTriangle &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);
- }
- protected:
- const std::vector<Vector3>::const_iterator vertices;
- };
-
- // ===================== WmoLiquid ==================================
-
- WmoLiquid::WmoLiquid(uint32 width, uint32 height, const Vector3 &corner, uint32 type):
- iTilesX(width), iTilesY(height), iCorner(corner), iType(type)
- {
- iHeight = new float[(width+1)*(height+1)];
- iFlags = new uint8[width*height];
- }
-
- WmoLiquid::WmoLiquid(const WmoLiquid &other): iHeight(0), iFlags(0)
- {
- *this = other; // use assignment operator...
- }
-
- WmoLiquid::~WmoLiquid()
- {
- delete[] iHeight;
- delete[] iFlags;
- }
-
- WmoLiquid& WmoLiquid::operator=(const WmoLiquid &other)
- {
- if (this == &other)
- return *this;
- iTilesX = other.iTilesX;
- iTilesY = other.iTilesY;
- iCorner = other.iCorner;
- iType = other.iType;
- delete iHeight;
- delete iFlags;
- if (other.iHeight)
- {
- iHeight = new float[(iTilesX+1)*(iTilesY+1)];
- memcpy(iHeight, other.iHeight, (iTilesX+1)*(iTilesY+1)*sizeof(float));
- }
- else
- iHeight = 0;
- if (other.iFlags)
- {
- iFlags = new uint8[iTilesX * iTilesY];
- memcpy(iFlags, other.iFlags, iTilesX * iTilesY);
- }
- else
- iFlags = 0;
- return *this;
- }
-
- bool WmoLiquid::GetLiquidHeight(const Vector3 &pos, float &liqHeight) const
- {
- uint32 tx = (pos.x - iCorner.x)/LIQUID_TILE_SIZE;
- if (tx<0 || tx >= iTilesX) return false;
- uint32 ty = (pos.y - iCorner.y)/LIQUID_TILE_SIZE;
- if (ty<0 || ty >= iTilesY) return false;
- // checking for 0x08 *might* be enough, but disabled tiles always are 0x?F:
- if ((iFlags[tx + ty*iTilesX] & 0x0F) == 0x0F)
- return false;
- //placeholder...use only lower left corner vertex
- liqHeight = /* iCorner.z + */ iHeight[tx + ty*(iTilesX+1)];
- return true;
- }
-
- uint32 WmoLiquid::GetFileSize()
- {
- return 2 * sizeof(uint32) +
- sizeof(Vector3) +
- (iTilesX + 1)*(iTilesY + 1) * sizeof(float) +
- iTilesX * iTilesY;
- }
-
- bool WmoLiquid::writeToFile(FILE *wf)
- {
- bool result = true;
- if (result && fwrite(&iTilesX, sizeof(uint32), 1, wf) != 1) result = false;
- if (result && fwrite(&iTilesY, sizeof(uint32), 1, wf) != 1) result = false;
- if (result && fwrite(&iCorner, sizeof(Vector3), 1, wf) != 1) result = false;
- if (result && fwrite(&iType, sizeof(uint32), 1, wf) != 1) result = false;
- uint32 size = (iTilesX + 1)*(iTilesY + 1);
- if (result && fwrite(iHeight, sizeof(float), size, wf) != size) result = false;
- size = iTilesX*iTilesY;
- if (result && fwrite(iFlags, sizeof(uint8), size, wf) != size) result = false;
- return result;
- }
-
- bool WmoLiquid::readFromFile(FILE *rf, WmoLiquid *&out)
- {
- bool result = true;
- WmoLiquid *liquid = new WmoLiquid();
- if (result && fread(&liquid->iTilesX, sizeof(uint32), 1, rf) != 1) result = false;
- if (result && fread(&liquid->iTilesY, sizeof(uint32), 1, rf) != 1) result = false;
- if (result && fread(&liquid->iCorner, sizeof(Vector3), 1, rf) != 1) result = false;
- if (result && fread(&liquid->iType, sizeof(uint32), 1, rf) != 1) result = false;
- uint32 size = (liquid->iTilesX + 1)*(liquid->iTilesY + 1);
- liquid->iHeight = new float[size];
- if (result && fread(liquid->iHeight, sizeof(float), size, rf) != size) result = false;
- size = liquid->iTilesX * liquid->iTilesY;
- liquid->iFlags = new uint8[size];
- if (result && fread(liquid->iFlags, sizeof(uint8), size, rf) != size) result = false;
- if (!result)
- delete liquid;
- out = liquid;
- return result;
- }
-
- // ===================== GroupModel ==================================
-
- GroupModel::GroupModel(const GroupModel &other):
- iBound(other.iBound), iMogpFlags(other.iMogpFlags), iGroupWMOID(other.iGroupWMOID),
- vertices(other.vertices), triangles(other.triangles), meshTree(other.meshTree), iLiquid(0)
- {
- if (other.iLiquid)
- iLiquid = new WmoLiquid(*other.iLiquid);
- }
-
- void GroupModel::setMeshData(std::vector<Vector3> &vert, std::vector<MeshTriangle> &tri)
- {
- vertices.swap(vert);
- triangles.swap(tri);
- TriBoundFunc bFunc(vertices);
- meshTree.build(triangles, bFunc);
- }
-
- bool GroupModel::writeToFile(FILE *wf)
- {
- bool result = true;
- uint32 chunkSize, count;
-
- if (result && fwrite(&iBound, sizeof(G3D::AABox), 1, wf) != 1) result = false;
- if (result && fwrite(&iMogpFlags, sizeof(uint32), 1, wf) != 1) result = false;
- if (result && fwrite(&iGroupWMOID, sizeof(uint32), 1, wf) != 1) result = false;
-
- // write vertices
- if (result && fwrite("VERT", 1, 4, wf) != 4) result = false;
- count = vertices.size();
- chunkSize = sizeof(uint32)+ sizeof(Vector3)*count;
- if (result && fwrite(&chunkSize, sizeof(uint32), 1, wf) != 1) result = false;
- if (result && fwrite(&count, sizeof(uint32), 1, wf) != 1) result = false;
- if (!count) // models without (collision) geometry end here, unsure if they are useful
- return result;
- if (result && fwrite(&vertices[0], sizeof(Vector3), count, wf) != count) result = false;
-
- // write triangle mesh
- if (result && fwrite("TRIM", 1, 4, wf) != 4) result = false;
- count = triangles.size();
- chunkSize = sizeof(uint32)+ sizeof(MeshTriangle)*count;
- if (result && fwrite(&chunkSize, sizeof(uint32), 1, wf) != 1) result = false;
- if (result && fwrite(&count, sizeof(uint32), 1, wf) != 1) result = false;
- if (result && fwrite(&triangles[0], sizeof(MeshTriangle), count, wf) != count) result = false;
-
- // write mesh BIH
- if (result && fwrite("MBIH", 1, 4, wf) != 4) result = false;
- if (result) result = meshTree.writeToFile(wf);
-
- // write liquid data
- if (result && fwrite("LIQU", 1, 4, wf) != 4) result = false;
- if (!iLiquid)
- {
- chunkSize = 0;
- if (result && fwrite(&chunkSize, sizeof(uint32), 1, wf) != 1) result = false;
- return result;
- }
- chunkSize = iLiquid->GetFileSize();
- if (result && fwrite(&chunkSize, sizeof(uint32), 1, wf) != 1) result = false;
- if (result) result = iLiquid->writeToFile(wf);
-
- return result;
- }
-
- bool GroupModel::readFromFile(FILE *rf)
- {
- char chunk[8];
- bool result = true;
- uint32 chunkSize, count;
- triangles.clear();
- vertices.clear();
- delete iLiquid;
- iLiquid = 0;
-
- if (result && fread(&iBound, sizeof(G3D::AABox), 1, rf) != 1) result = false;
- if (result && fread(&iMogpFlags, sizeof(uint32), 1, rf) != 1) result = false;
- if (result && fread(&iGroupWMOID, sizeof(uint32), 1, rf) != 1) result = false;
-
- // read vertices
- if (result && !readChunk(rf, chunk, "VERT", 4)) result = false;
- if (result && fread(&chunkSize, sizeof(uint32), 1, rf) != 1) result = false;
- if (result && fread(&count, sizeof(uint32), 1, rf) != 1) result = false;
- if (!count) // models without (collision) geometry end here, unsure if they are useful
- return result;
- if (result) vertices.resize(count);
- if (result && fread(&vertices[0], sizeof(Vector3), count, rf) != count) result = false;
-
- // read triangle mesh
- if (result && !readChunk(rf, chunk, "TRIM", 4)) result = false;
- if (result && fread(&chunkSize, sizeof(uint32), 1, rf) != 1) result = false;
- if (result && fread(&count, sizeof(uint32), 1, rf) != 1) result = false;
- if (result) triangles.resize(count);
- if (result && fread(&triangles[0], sizeof(MeshTriangle), count, rf) != count) result = false;
-
- // read mesh BIH
- if (result && !readChunk(rf, chunk, "MBIH", 4)) result = false;
- if (result) result = meshTree.readFromFile(rf);
-
- // write liquid data
- if (result && !readChunk(rf, chunk, "LIQU", 4)) result = false;
- if (result && fread(&chunkSize, sizeof(uint32), 1, rf) != 1) result = false;
- if (result && chunkSize > 0)
- result = WmoLiquid::readFromFile(rf, iLiquid);
- return result;
- }
-
- struct GModelRayCallback
- {
- GModelRayCallback(const std::vector<MeshTriangle> &tris, const std::vector<Vector3> &vert):
- vertices(vert.begin()), triangles(tris.begin()), hit(false) {}
- bool operator()(const G3D::Ray& ray, uint32 entry, float& distance, bool pStopAtFirstHit)
- {
- bool result = IntersectTriangle(triangles[entry], vertices, ray, distance);
- if (result) hit=true;
- return hit;
- }
- std::vector<Vector3>::const_iterator vertices;
- std::vector<MeshTriangle>::const_iterator triangles;
- bool hit;
- };
-
- bool GroupModel::IntersectRay(const G3D::Ray &ray, float &distance, bool stopAtFirstHit) const
- {
- if (!triangles.size())
- return false;
- GModelRayCallback callback(triangles, vertices);
- meshTree.intersectRay(ray, callback, distance, stopAtFirstHit);
- return callback.hit;
- }
-
- bool GroupModel::IsInsideObject(const Vector3 &pos, const Vector3 &down, float &z_dist) const
- {
- if (!triangles.size() || !iBound.contains(pos))
- return false;
- GModelRayCallback callback(triangles, vertices);
- Vector3 rPos = pos - 0.1f * down;
- float dist = G3D::inf();
- G3D::Ray ray(rPos, down);
- bool hit = IntersectRay(ray, dist, false);
- if (hit)
- z_dist = dist - 0.1f;
- return hit;
- }
-
- bool GroupModel::GetLiquidLevel(const Vector3 &pos, float &liqHeight) const
- {
- if (iLiquid)
- return iLiquid->GetLiquidHeight(pos, liqHeight);
- return false;
- }
-
- uint32 GroupModel::GetLiquidType() const
- {
- // convert to type mask, matching MAP_LIQUID_TYPE_* defines in Map.h
- if (iLiquid)
- return (1 << iLiquid->GetType());
- return 0;
- }
-
- // ===================== WorldModel ==================================
-
- void WorldModel::setGroupModels(std::vector<GroupModel> &models)
- {
- groupModels.swap(models);
- groupTree.build(groupModels, BoundsTrait<GroupModel>::getBounds, 1);
- }
-
- struct WModelRayCallBack
- {
- WModelRayCallBack(const std::vector<GroupModel> &mod): models(mod.begin()), hit(false) {}
- bool operator()(const G3D::Ray& ray, uint32 entry, float& distance, bool pStopAtFirstHit)
- {
- bool result = models[entry].IntersectRay(ray, distance, pStopAtFirstHit);
- if (result) hit=true;
- return hit;
- }
- std::vector<GroupModel>::const_iterator models;
- bool hit;
- };
-
- bool WorldModel::IntersectRay(const G3D::Ray &ray, float &distance, bool stopAtFirstHit) const
- {
- // small M2 workaround, maybe better make separate class with virtual intersection funcs
- // in any case, there's no need to use a bound tree if we only have one submodel
- if (groupModels.size() == 1)
- return groupModels[0].IntersectRay(ray, distance, stopAtFirstHit);
-
- WModelRayCallBack isc(groupModels);
- groupTree.intersectRay(ray, isc, distance, stopAtFirstHit);
- return isc.hit;
- }
-
- class WModelAreaCallback {
- public:
- WModelAreaCallback(const std::vector<GroupModel> &vals, const Vector3 &down):
- prims(vals.begin()), hit(vals.end()), minVol(G3D::inf()), zDist(G3D::inf()), zVec(down) {}
- std::vector<GroupModel>::const_iterator prims;
- std::vector<GroupModel>::const_iterator hit;
- float minVol;
- float zDist;
- Vector3 zVec;
- void operator()(const Vector3& point, uint32 entry)
- {
- float group_Z;
- //float pVol = prims[entry].GetBound().volume();
- //if(pVol < minVol)
- //{
- /* if (prims[entry].iBound.contains(point)) */
- if (prims[entry].IsInsideObject(point, zVec, group_Z))
- {
- //minVol = pVol;
- //hit = prims + entry;
- if (group_Z < zDist)
- {
- zDist = group_Z;
- hit = prims + entry;
- }
-#ifdef VMAP_DEBUG
- const GroupModel &gm = prims[entry];
- 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(),
- gm.GetBound().low().x, gm.GetBound().low().y, gm.GetBound().low().z,
- gm.GetBound().high().x, gm.GetBound().high().y, gm.GetBound().high().z, group_Z, point.z);
-#endif
- }
- //}
- //std::cout << "trying to intersect '" << prims[entry].name << "'\n";
- }
- };
-
- bool WorldModel::IntersectPoint(const G3D::Vector3 &p, const G3D::Vector3 &down, float &dist, AreaInfo &info) const
- {
- if (!groupModels.size())
- return false;
- WModelAreaCallback callback(groupModels, down);
- groupTree.intersectPoint(p, callback);
- if (callback.hit != groupModels.end())
- {
- info.rootId = RootWMOID;
- info.groupId = callback.hit->GetWmoID();
- info.flags = callback.hit->GetMogpFlags();
- info.result = true;
- dist = callback.zDist;
- return true;
- }
- return false;
- }
-
- bool WorldModel::GetLocationInfo(const G3D::Vector3 &p, const G3D::Vector3 &down, float &dist, LocationInfo &info) const
- {
- if (!groupModels.size())
- return false;
- WModelAreaCallback callback(groupModels, down);
- groupTree.intersectPoint(p, callback);
- if (callback.hit != groupModels.end())
- {
- info.hitModel = &(*callback.hit);
- dist = callback.zDist;
- return true;
- }
- return false;
- }
-
- bool WorldModel::writeFile(const std::string &filename)
- {
- FILE *wf = fopen(filename.c_str(), "wb");
- if (!wf)
- return false;
-
- bool result = true;
- uint32 chunkSize, count;
- result = fwrite(VMAP_MAGIC,1,8,wf) == 8;
- if (result && fwrite("WMOD", 1, 4, wf) != 4) result = false;
- chunkSize = sizeof(uint32) + sizeof(uint32);
- if (result && fwrite(&chunkSize, sizeof(uint32), 1, wf) != 1) result = false;
- if (result && fwrite(&RootWMOID, sizeof(uint32), 1, wf) != 1) result = false;
-
- // write group models
- count=groupModels.size();
- if (count)
- {
- if (result && fwrite("GMOD", 1, 4, wf) != 4) result = false;
- //chunkSize = sizeof(uint32)+ sizeof(GroupModel)*count;
- //if (result && fwrite(&chunkSize, sizeof(uint32), 1, wf) != 1) result = false;
- if (result && fwrite(&count, sizeof(uint32), 1, wf) != 1) result = false;
- for (uint32 i=0; i<groupModels.size() && result; ++i)
- result = groupModels[i].writeToFile(wf);
-
- // write group BIH
- if (result && fwrite("GBIH", 1, 4, wf) != 4) result = false;
- if (result) result = groupTree.writeToFile(wf);
- }
-
- fclose(wf);
- return result;
- }
-
- bool WorldModel::readFile(const std::string &filename)
- {
- FILE *rf = fopen(filename.c_str(), "rb");
- if (!rf)
- return false;
-
- bool result = true;
- uint32 chunkSize, count;
- char chunk[8]; // Ignore the added magic header
- if (!readChunk(rf, chunk, VMAP_MAGIC, 8)) result = false;
-
- if (result && !readChunk(rf, chunk, "WMOD", 4)) result = false;
- if (result && fread(&chunkSize, sizeof(uint32), 1, rf) != 1) result = false;
- if (result && fread(&RootWMOID, sizeof(uint32), 1, rf) != 1) result = false;
-
- // read group models
- if (result && readChunk(rf, chunk, "GMOD", 4))
- {
- //if (fread(&chunkSize, sizeof(uint32), 1, rf) != 1) result = false;
-
- if (result && fread(&count, sizeof(uint32), 1, rf) != 1) result = false;
- if (result) groupModels.resize(count);
- //if (result && fread(&groupModels[0], sizeof(GroupModel), count, rf) != count) result = false;
- for (uint32 i=0; i<count && result; ++i)
- result = groupModels[i].readFromFile(rf);
-
- // read group BIH
- if (result && !readChunk(rf, chunk, "GBIH", 4)) result = false;
- if (result) result = groupTree.readFromFile(rf);
- }
-
- fclose(rf);
- return result;
- }
-}
diff --git a/src/server/shared/vmap/WorldModel.h b/src/server/shared/vmap/WorldModel.h
deleted file mode 100644
index f12efed4f5d..00000000000
--- a/src/server/shared/vmap/WorldModel.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef _WORLDMODEL_H
-#define _WORLDMODEL_H
-
-#include <G3D/HashTrait.h>
-#include <G3D/Vector3.h>
-#include <G3D/AABox.h>
-#include <G3D/Ray.h>
-#include "BIH.h"
-
-#include "Platform/Define.h"
-
-namespace VMAP
-{
- class TreeNode;
- struct AreaInfo;
- struct LocationInfo;
-
- class MeshTriangle
- {
- public:
- MeshTriangle(){};
- MeshTriangle(uint32 na, uint32 nb, uint32 nc): idx0(na), idx1(nb), idx2(nc) {};
-
- uint32 idx0;
- uint32 idx1;
- uint32 idx2;
- };
-
- class WmoLiquid
- {
- public:
- WmoLiquid(uint32 width, uint32 height, const Vector3 &corner, uint32 type);
- WmoLiquid(const WmoLiquid &other);
- ~WmoLiquid();
- WmoLiquid& operator=(const WmoLiquid &other);
- bool GetLiquidHeight(const Vector3 &pos, float &liqHeight) const;
- uint32 GetType() const { return iType; }
- float *GetHeightStorage() { return iHeight; }
- uint8 *GetFlagsStorage() { return iFlags; }
- uint32 GetFileSize();
- bool writeToFile(FILE *wf);
- static bool readFromFile(FILE *rf, WmoLiquid *&liquid);
- private:
- WmoLiquid(): iHeight(0), iFlags(0) {};
- uint32 iTilesX; //!< number of tiles in x direction, each
- uint32 iTilesY;
- Vector3 iCorner; //!< the lower corner
- uint32 iType; //!< liquid type
- float *iHeight; //!< (tilesX + 1)*(tilesY + 1) height values
- uint8 *iFlags; //!< info if liquid tile is used
- };
-
- /*! holding additional info for WMO group files */
- class GroupModel
- {
- public:
- GroupModel(): iLiquid(0) {}
- GroupModel(const GroupModel &other);
- GroupModel(uint32 mogpFlags, uint32 groupWMOID, const AABox &bound):
- iBound(bound), iMogpFlags(mogpFlags), iGroupWMOID(groupWMOID), iLiquid(0) {}
- ~GroupModel() { delete iLiquid; }
-
- //! pass mesh data to object and create BIH. Passed vectors get get swapped with old geometry!
- void setMeshData(std::vector<Vector3> &vert, std::vector<MeshTriangle> &tri);
- void setLiquidData(WmoLiquid *liquid) { iLiquid = liquid; }
- bool IntersectRay(const G3D::Ray &ray, float &distance, bool stopAtFirstHit) const;
- bool IsInsideObject(const Vector3 &pos, const Vector3 &down, float &z_dist) const;
- bool GetLiquidLevel(const Vector3 &pos, float &liqHeight) const;
- uint32 GetLiquidType() const;
- bool writeToFile(FILE *wf);
- bool readFromFile(FILE *rf);
- const G3D::AABox& GetBound() const { return iBound; }
- uint32 GetMogpFlags() const { return iMogpFlags; }
- uint32 GetWmoID() const { return iGroupWMOID; }
- protected:
- G3D::AABox iBound;
- uint32 iMogpFlags;// 0x8 outdor; 0x2000 indoor
- uint32 iGroupWMOID;
- std::vector<Vector3> vertices;
- std::vector<MeshTriangle> triangles;
- BIH meshTree;
- WmoLiquid *iLiquid;
- };
- /*! Holds a model (converted M2 or WMO) in its original coordinate space */
- class WorldModel
- {
- public:
- WorldModel(): RootWMOID(0) {}
-
- //! pass group models to WorldModel and create BIH. Passed vector is swapped with old geometry!
- void setGroupModels(std::vector<GroupModel> &models);
- void setRootWmoID(uint32 id) { RootWMOID = id; }
- bool IntersectRay(const G3D::Ray &ray, float &distance, bool stopAtFirstHit) const;
- bool IntersectPoint(const G3D::Vector3 &p, const G3D::Vector3 &down, float &dist, AreaInfo &info) const;
- bool GetLocationInfo(const G3D::Vector3 &p, const G3D::Vector3 &down, float &dist, LocationInfo &info) const;
- bool writeFile(const std::string &filename);
- bool readFile(const std::string &filename);
- protected:
- uint32 RootWMOID;
- std::vector<GroupModel> groupModels;
- BIH groupTree;
- };
-} // namespace VMAP
-
-#endif // _WORLDMODEL_H