More refactoring of code.
This commit is contained in:
@@ -27,10 +27,10 @@ namespace Game.Collision
|
||||
{
|
||||
public BIH()
|
||||
{
|
||||
init_empty();
|
||||
InitEmpty();
|
||||
}
|
||||
|
||||
void init_empty()
|
||||
void InitEmpty()
|
||||
{
|
||||
tree= new uint[3];
|
||||
objects = new uint[0];
|
||||
@@ -38,7 +38,7 @@ namespace Game.Collision
|
||||
tree[0] = (3u << 30); // dummy leaf
|
||||
}
|
||||
|
||||
void buildHierarchy(List<uint> tempTree, buildData dat, BuildStats stats)
|
||||
void BuildHierarchy(List<uint> tempTree, buildData dat, BuildStats stats)
|
||||
{
|
||||
// create space for the first node
|
||||
tempTree.Add(3u << 30); // dummy leaf
|
||||
@@ -51,16 +51,16 @@ namespace Game.Collision
|
||||
gridBox.hi = bounds.Hi;
|
||||
AABound nodeBox = gridBox;
|
||||
// seed subdivide function
|
||||
subdivide(0, (int)(dat.numPrims - 1), tempTree, dat, gridBox, nodeBox, 0, 1, stats);
|
||||
Subdivide(0, (int)(dat.numPrims - 1), tempTree, dat, gridBox, nodeBox, 0, 1, stats);
|
||||
}
|
||||
|
||||
void subdivide(int left, int right, List<uint> tempTree, buildData dat, AABound gridBox, AABound nodeBox, int nodeIndex, int depth, BuildStats stats)
|
||||
void Subdivide(int left, int right, List<uint> tempTree, buildData dat, AABound gridBox, AABound nodeBox, int nodeIndex, int depth, BuildStats stats)
|
||||
{
|
||||
if ((right - left + 1) <= dat.maxPrims || depth >= 64)
|
||||
{
|
||||
// write leaf node
|
||||
stats.updateLeaf(depth, right - left + 1);
|
||||
createNode(tempTree, nodeIndex, left, right);
|
||||
stats.UpdateLeaf(depth, right - left + 1);
|
||||
CreateNode(tempTree, nodeIndex, left, right);
|
||||
return;
|
||||
}
|
||||
// calculate extents
|
||||
@@ -122,21 +122,21 @@ namespace Game.Collision
|
||||
// node box is too big compare to space occupied by primitives?
|
||||
if (1.3f * nodeNewW < nodeBoxW)
|
||||
{
|
||||
stats.updateBVH2();
|
||||
stats.UpdateBVH2();
|
||||
int nextIndex1 = tempTree.Count;
|
||||
// allocate child
|
||||
tempTree.Add(0);
|
||||
tempTree.Add(0);
|
||||
tempTree.Add(0);
|
||||
// write bvh2 clip node
|
||||
stats.updateInner();
|
||||
stats.UpdateInner();
|
||||
tempTree[nodeIndex + 0] = (uint)((axis << 30) | (1 << 29) | nextIndex1);
|
||||
tempTree[nodeIndex + 1] = floatToRawIntBits(nodeL);
|
||||
tempTree[nodeIndex + 2] = floatToRawIntBits(nodeR);
|
||||
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, nextIndex1, depth + 1, stats);
|
||||
Subdivide(left, rightOrig, tempTree, dat, gridBox, nodeBox, nextIndex1, depth + 1, stats);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -147,8 +147,8 @@ namespace Game.Collision
|
||||
if (prevAxis == axis && MathFunctions.fuzzyEq(prevSplit, split))
|
||||
{
|
||||
// we are stuck here - create a leaf
|
||||
stats.updateLeaf(depth, right - left + 1);
|
||||
createNode(tempTree, nodeIndex, left, right);
|
||||
stats.UpdateLeaf(depth, right - left + 1);
|
||||
CreateNode(tempTree, nodeIndex, left, right);
|
||||
return;
|
||||
}
|
||||
if (clipL <= split)
|
||||
@@ -169,8 +169,8 @@ namespace Game.Collision
|
||||
if (prevAxis == axis && MathFunctions.fuzzyEq(prevSplit, split))
|
||||
{
|
||||
// we are stuck here - create a leaf
|
||||
stats.updateLeaf(depth, right - left + 1);
|
||||
createNode(tempTree, nodeIndex, left, right);
|
||||
stats.UpdateLeaf(depth, right - left + 1);
|
||||
CreateNode(tempTree, nodeIndex, left, right);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -201,23 +201,23 @@ namespace Game.Collision
|
||||
{
|
||||
// create a node with a left child
|
||||
// write leaf node
|
||||
stats.updateInner();
|
||||
stats.UpdateInner();
|
||||
tempTree[nodeIndex + 0] = (uint)((prevAxis << 30) | nextIndex0);
|
||||
tempTree[nodeIndex + 1] = floatToRawIntBits(prevClip);
|
||||
tempTree[nodeIndex + 2] = floatToRawIntBits(float.PositiveInfinity);
|
||||
tempTree[nodeIndex + 1] = FloatToRawIntBits(prevClip);
|
||||
tempTree[nodeIndex + 2] = FloatToRawIntBits(float.PositiveInfinity);
|
||||
}
|
||||
else
|
||||
{
|
||||
// create a node with a right child
|
||||
// write leaf node
|
||||
stats.updateInner();
|
||||
stats.UpdateInner();
|
||||
tempTree[nodeIndex + 0] = (uint)((prevAxis << 30) | (nextIndex0 - 3));
|
||||
tempTree[nodeIndex + 1] = floatToRawIntBits(float.NegativeInfinity);
|
||||
tempTree[nodeIndex + 2] = floatToRawIntBits(prevClip);
|
||||
tempTree[nodeIndex + 1] = FloatToRawIntBits(float.NegativeInfinity);
|
||||
tempTree[nodeIndex + 2] = FloatToRawIntBits(prevClip);
|
||||
}
|
||||
// count stats for the unused leaf
|
||||
depth++;
|
||||
stats.updateLeaf(depth, 0);
|
||||
stats.UpdateLeaf(depth, 0);
|
||||
// now we keep going as we are, with a new nodeIndex:
|
||||
nodeIndex = nextIndex0;
|
||||
}
|
||||
@@ -245,10 +245,10 @@ namespace Game.Collision
|
||||
tempTree.Add(0);
|
||||
}
|
||||
// write leaf node
|
||||
stats.updateInner();
|
||||
stats.UpdateInner();
|
||||
tempTree[nodeIndex + 0] = (uint)((axis << 30) | nextIndex);
|
||||
tempTree[nodeIndex + 1] = floatToRawIntBits(clipL);
|
||||
tempTree[nodeIndex + 2] = floatToRawIntBits(clipR);
|
||||
tempTree[nodeIndex + 1] = FloatToRawIntBits(clipL);
|
||||
tempTree[nodeIndex + 2] = FloatToRawIntBits(clipR);
|
||||
// prepare L/R child boxes
|
||||
AABound gridBoxL = gridBox;
|
||||
AABound gridBoxR = gridBox;
|
||||
@@ -259,16 +259,16 @@ namespace Game.Collision
|
||||
nodeBoxR.lo[axis] = clipR;
|
||||
// recurse
|
||||
if (nl > 0)
|
||||
subdivide(left, right, tempTree, dat, gridBoxL, nodeBoxL, nextIndex, depth + 1, stats);
|
||||
Subdivide(left, right, tempTree, dat, gridBoxL, nodeBoxL, nextIndex, depth + 1, stats);
|
||||
else
|
||||
stats.updateLeaf(depth + 1, 0);
|
||||
stats.UpdateLeaf(depth + 1, 0);
|
||||
if (nr > 0)
|
||||
subdivide(right + 1, rightOrig, tempTree, dat, gridBoxR, nodeBoxR, nextIndex + 3, depth + 1, stats);
|
||||
Subdivide(right + 1, rightOrig, tempTree, dat, gridBoxR, nodeBoxR, nextIndex + 3, depth + 1, stats);
|
||||
else
|
||||
stats.updateLeaf(depth + 1, 0);
|
||||
stats.UpdateLeaf(depth + 1, 0);
|
||||
}
|
||||
|
||||
public bool readFromFile(BinaryReader reader)
|
||||
public bool ReadFromFile(BinaryReader reader)
|
||||
{
|
||||
var lo = reader.Read<Vector3>();
|
||||
var hi = reader.Read<Vector3>();
|
||||
@@ -283,11 +283,11 @@ namespace Game.Collision
|
||||
return true;
|
||||
}
|
||||
|
||||
public void build<T>(List<T> primitives, uint leafSize = 3, bool printStats = false) where T : IModel
|
||||
public void Build<T>(List<T> primitives, uint leafSize = 3, bool printStats = false) where T : IModel
|
||||
{
|
||||
if (primitives.Count == 0)
|
||||
{
|
||||
init_empty();
|
||||
InitEmpty();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -296,16 +296,16 @@ namespace Game.Collision
|
||||
dat.numPrims = (uint)primitives.Count;
|
||||
dat.indices = new uint[dat.numPrims];
|
||||
dat.primBound = new AxisAlignedBox[dat.numPrims];
|
||||
bounds = primitives[0].getBounds();
|
||||
bounds = primitives[0].GetBounds();
|
||||
for (int i = 0; i < dat.numPrims; ++i)
|
||||
{
|
||||
dat.indices[i] = (uint)i;
|
||||
dat.primBound[i] = primitives[i].getBounds();
|
||||
dat.primBound[i] = primitives[i].GetBounds();
|
||||
bounds.merge(dat.primBound[i]);
|
||||
}
|
||||
List<uint> tempTree = new List<uint>();
|
||||
BuildStats stats = new BuildStats();
|
||||
buildHierarchy(tempTree, dat, stats);
|
||||
BuildHierarchy(tempTree, dat, stats);
|
||||
|
||||
objects = new uint[dat.numPrims];
|
||||
for (int i = 0; i < dat.numPrims; ++i)
|
||||
@@ -314,9 +314,9 @@ namespace Game.Collision
|
||||
tree = tempTree.ToArray();
|
||||
}
|
||||
|
||||
public uint primCount() { return (uint)objects.Length; }
|
||||
public uint PrimCount() { return (uint)objects.Length; }
|
||||
|
||||
public void intersectRay(Ray r, WorkerCallback intersectCallback, ref float maxDist, bool stopAtFirst = false)
|
||||
public void IntersectRay(Ray r, WorkerCallback intersectCallback, ref float maxDist, bool stopAtFirst = false)
|
||||
{
|
||||
float intervalMin = -1.0f;
|
||||
float intervalMax = -1.0f;
|
||||
@@ -356,7 +356,7 @@ namespace Game.Collision
|
||||
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
offsetFront[i] = floatToRawIntBits(dir[i]) >> 31;
|
||||
offsetFront[i] = FloatToRawIntBits(dir[i]) >> 31;
|
||||
offsetBack[i] = offsetFront[i] ^ 1;
|
||||
offsetFront3[i] = offsetFront[i] * 3;
|
||||
offsetBack3[i] = offsetBack[i] * 3;
|
||||
@@ -383,8 +383,8 @@ namespace Game.Collision
|
||||
if (axis < 3)
|
||||
{
|
||||
// "normal" interior node
|
||||
float tf = (intBitsToFloat(tree[(int)(node + offsetFront[axis])]) - org[axis]) * invDir[axis];
|
||||
float tb = (intBitsToFloat(tree[(int)(node + offsetBack[axis])]) - org[axis]) * invDir[axis];
|
||||
float tf = (IntBitsToFloat(tree[(int)(node + offsetFront[axis])]) - org[axis]) * invDir[axis];
|
||||
float tb = (IntBitsToFloat(tree[(int)(node + offsetBack[axis])]) - org[axis]) * invDir[axis];
|
||||
// ray passes between clip zones
|
||||
if (tf < intervalMin && tb > intervalMax)
|
||||
break;
|
||||
@@ -432,8 +432,8 @@ namespace Game.Collision
|
||||
{
|
||||
if (axis > 2)
|
||||
return; // should not happen
|
||||
float tf = (intBitsToFloat(tree[(int)(node + offsetFront[axis])]) - org[axis]) * invDir[axis];
|
||||
float tb = (intBitsToFloat(tree[(int)(node + offsetBack[axis])]) - org[axis]) * invDir[axis];
|
||||
float tf = (IntBitsToFloat(tree[(int)(node + offsetFront[axis])]) - org[axis]) * invDir[axis];
|
||||
float tb = (IntBitsToFloat(tree[(int)(node + offsetBack[axis])]) - org[axis]) * invDir[axis];
|
||||
node = offset;
|
||||
intervalMin = (tf >= intervalMin) ? tf : intervalMin;
|
||||
intervalMax = (tb <= intervalMax) ? tb : intervalMax;
|
||||
@@ -459,7 +459,7 @@ namespace Game.Collision
|
||||
}
|
||||
}
|
||||
|
||||
public void intersectPoint(Vector3 p, WorkerCallback intersectCallback)
|
||||
public void IntersectPoint(Vector3 p, WorkerCallback intersectCallback)
|
||||
{
|
||||
if (!bounds.contains(p))
|
||||
return;
|
||||
@@ -481,8 +481,8 @@ namespace Game.Collision
|
||||
if (axis < 3)
|
||||
{
|
||||
// "normal" interior node
|
||||
float tl = intBitsToFloat(tree[node + 1]);
|
||||
float tr = intBitsToFloat(tree[node + 2]);
|
||||
float tl = IntBitsToFloat(tree[node + 1]);
|
||||
float tr = IntBitsToFloat(tree[node + 2]);
|
||||
// point is between clip zones
|
||||
if (tl < p[(int)axis] && tr > p[axis])
|
||||
break;
|
||||
@@ -522,8 +522,8 @@ namespace Game.Collision
|
||||
{
|
||||
if (axis > 2)
|
||||
return; // should not happen
|
||||
float tl = intBitsToFloat(tree[node + 1]);
|
||||
float tr = intBitsToFloat(tree[node + 2]);
|
||||
float tl = IntBitsToFloat(tree[node + 1]);
|
||||
float tr = IntBitsToFloat(tree[node + 2]);
|
||||
node = offset;
|
||||
if (tl > p[axis] || tr < p[axis])
|
||||
break;
|
||||
@@ -540,7 +540,7 @@ namespace Game.Collision
|
||||
}
|
||||
}
|
||||
|
||||
void createNode(List<uint> tempTree, int nodeIndex, int left, int right)
|
||||
void CreateNode(List<uint> tempTree, int nodeIndex, int left, int right)
|
||||
{
|
||||
// write leaf node
|
||||
tempTree[nodeIndex + 0] = (uint)((3 << 30) | left);
|
||||
@@ -589,9 +589,9 @@ namespace Game.Collision
|
||||
numLeavesN[i] = 0;
|
||||
}
|
||||
|
||||
public void updateInner() { numNodes++; }
|
||||
public void updateBVH2() { numBVH2++; }
|
||||
public void updateLeaf(int depth, int n)
|
||||
public void UpdateInner() { numNodes++; }
|
||||
public void UpdateBVH2() { numBVH2++; }
|
||||
public void UpdateLeaf(int depth, int n)
|
||||
{
|
||||
numLeaves++;
|
||||
minDepth = Math.Min(depth, minDepth);
|
||||
@@ -619,13 +619,13 @@ namespace Game.Collision
|
||||
public float FloatValue;
|
||||
}
|
||||
|
||||
uint floatToRawIntBits(float f)
|
||||
uint FloatToRawIntBits(float f)
|
||||
{
|
||||
FloatToIntConverter converter = new FloatToIntConverter();
|
||||
converter.FloatValue = f;
|
||||
return converter.IntValue;
|
||||
}
|
||||
float intBitsToFloat(uint i)
|
||||
float IntBitsToFloat(uint i)
|
||||
{
|
||||
FloatToIntConverter converter = new FloatToIntConverter();
|
||||
converter.IntValue = i;
|
||||
|
||||
@@ -22,12 +22,12 @@ namespace Game.Collision
|
||||
{
|
||||
public class BIHWrap<T> where T : IModel
|
||||
{
|
||||
public void insert(T obj)
|
||||
public void Insert(T obj)
|
||||
{
|
||||
++unbalanced_times;
|
||||
m_objects_to_push.Add(obj);
|
||||
}
|
||||
public void remove(T obj)
|
||||
public void Remove(T obj)
|
||||
{
|
||||
++unbalanced_times;
|
||||
uint Idx = 0;
|
||||
@@ -37,7 +37,7 @@ namespace Game.Collision
|
||||
m_objects_to_push.Remove(obj);
|
||||
}
|
||||
|
||||
public void balance()
|
||||
public void Balance()
|
||||
{
|
||||
if (unbalanced_times == 0)
|
||||
return;
|
||||
@@ -47,21 +47,21 @@ namespace Game.Collision
|
||||
m_objects.AddRange(m_obj2Idx.Keys);
|
||||
m_objects.AddRange(m_objects_to_push);
|
||||
|
||||
m_tree.build(m_objects);
|
||||
m_tree.Build(m_objects);
|
||||
}
|
||||
|
||||
public void intersectRay(Ray ray, WorkerCallback intersectCallback, ref float maxDist)
|
||||
public void IntersectRay(Ray ray, WorkerCallback intersectCallback, ref float maxDist)
|
||||
{
|
||||
balance();
|
||||
Balance();
|
||||
MDLCallback temp_cb = new MDLCallback(intersectCallback, m_objects.ToArray(), (uint)m_objects.Count);
|
||||
m_tree.intersectRay(ray, temp_cb, ref maxDist, true);
|
||||
m_tree.IntersectRay(ray, temp_cb, ref maxDist, true);
|
||||
}
|
||||
|
||||
public void intersectPoint(Vector3 point, WorkerCallback intersectCallback)
|
||||
public void IntersectPoint(Vector3 point, WorkerCallback intersectCallback)
|
||||
{
|
||||
balance();
|
||||
Balance();
|
||||
MDLCallback callback = new MDLCallback(intersectCallback, m_objects.ToArray(), (uint)m_objects.Count);
|
||||
m_tree.intersectPoint(point, callback);
|
||||
m_tree.IntersectPoint(point, callback);
|
||||
}
|
||||
|
||||
BIH m_tree = new BIH();
|
||||
|
||||
@@ -15,10 +15,10 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using Framework.Constants;
|
||||
using Framework.GameMath;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Framework.Constants;
|
||||
|
||||
namespace Game.Collision
|
||||
{
|
||||
@@ -178,12 +178,12 @@ namespace Game.Collision
|
||||
{
|
||||
if (prims[entry] == null)
|
||||
return false;
|
||||
bool result = prims[entry].intersectRay(ray, ref distance, pStopAtFirstHit, flags);
|
||||
bool result = prims[entry].IntersectRay(ray, ref distance, pStopAtFirstHit, flags);
|
||||
if (result)
|
||||
hit = true;
|
||||
return result;
|
||||
}
|
||||
public bool didHit() { return hit; }
|
||||
public bool DidHit() { return hit; }
|
||||
|
||||
ModelInstance[] prims;
|
||||
bool hit;
|
||||
@@ -201,7 +201,7 @@ namespace Game.Collision
|
||||
if (prims[entry] == null)
|
||||
return;
|
||||
|
||||
prims[entry].intersectPoint(point, aInfo);
|
||||
prims[entry].IntersectPoint(point, aInfo);
|
||||
}
|
||||
|
||||
ModelInstance[] prims;
|
||||
@@ -242,7 +242,7 @@ namespace Game.Collision
|
||||
return _didHit;
|
||||
}
|
||||
|
||||
public bool didHit() { return _didHit; }
|
||||
public bool DidHit() { return _didHit; }
|
||||
|
||||
bool _didHit;
|
||||
PhaseShift _phaseShift;
|
||||
|
||||
@@ -26,42 +26,42 @@ namespace Game.Collision
|
||||
impl = new DynTreeImpl();
|
||||
}
|
||||
|
||||
public void insert(GameObjectModel mdl)
|
||||
public void Insert(GameObjectModel mdl)
|
||||
{
|
||||
impl.insert(mdl);
|
||||
impl.Insert(mdl);
|
||||
}
|
||||
|
||||
public void remove(GameObjectModel mdl)
|
||||
public void Remove(GameObjectModel mdl)
|
||||
{
|
||||
impl.remove(mdl);
|
||||
impl.Remove(mdl);
|
||||
}
|
||||
|
||||
public bool contains(GameObjectModel mdl)
|
||||
public bool Contains(GameObjectModel mdl)
|
||||
{
|
||||
return impl.contains(mdl);
|
||||
return impl.Contains(mdl);
|
||||
}
|
||||
|
||||
public void balance()
|
||||
public void Balance()
|
||||
{
|
||||
impl.balance();
|
||||
impl.Balance();
|
||||
}
|
||||
|
||||
public void update(uint diff)
|
||||
public void Update(uint diff)
|
||||
{
|
||||
impl.update(diff);
|
||||
impl.Update(diff);
|
||||
}
|
||||
|
||||
public bool getIntersectionTime(Ray ray, Vector3 endPos, PhaseShift phaseShift, float maxDist)
|
||||
public bool GetIntersectionTime(Ray ray, Vector3 endPos, PhaseShift phaseShift, float maxDist)
|
||||
{
|
||||
float distance = maxDist;
|
||||
DynamicTreeIntersectionCallback callback = new DynamicTreeIntersectionCallback(phaseShift);
|
||||
impl.intersectRay(ray, callback, ref distance, endPos);
|
||||
if (callback.didHit())
|
||||
impl.IntersectRay(ray, callback, ref distance, endPos);
|
||||
if (callback.DidHit())
|
||||
maxDist = distance;
|
||||
return callback.didHit();
|
||||
return callback.DidHit();
|
||||
}
|
||||
|
||||
public bool getObjectHitPos(Vector3 startPos, Vector3 endPos, ref Vector3 resultHitPos, float modifyDist, PhaseShift phaseShift)
|
||||
public bool GetObjectHitPos(Vector3 startPos, Vector3 endPos, ref Vector3 resultHitPos, float modifyDist, PhaseShift phaseShift)
|
||||
{
|
||||
bool result = false;
|
||||
float maxDist = (endPos - startPos).magnitude();
|
||||
@@ -76,7 +76,7 @@ namespace Game.Collision
|
||||
Vector3 dir = (endPos - startPos) / maxDist; // direction with length of 1
|
||||
Ray ray = new Ray(startPos, dir);
|
||||
float dist = maxDist;
|
||||
if (getIntersectionTime(ray, endPos, phaseShift, dist))
|
||||
if (GetIntersectionTime(ray, endPos, phaseShift, dist))
|
||||
{
|
||||
resultHitPos = startPos + dir * dist;
|
||||
if (modifyDist < 0)
|
||||
@@ -99,7 +99,7 @@ namespace Game.Collision
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool isInLineOfSight(Vector3 startPos, Vector3 endPos, PhaseShift phaseShift)
|
||||
public bool IsInLineOfSight(Vector3 startPos, Vector3 endPos, PhaseShift phaseShift)
|
||||
{
|
||||
float maxDist = (endPos - startPos).magnitude();
|
||||
|
||||
@@ -108,25 +108,25 @@ namespace Game.Collision
|
||||
|
||||
Ray r = new Ray(startPos, (endPos - startPos) / maxDist);
|
||||
DynamicTreeIntersectionCallback callback = new DynamicTreeIntersectionCallback(phaseShift);
|
||||
impl.intersectRay(r, callback, ref maxDist, endPos);
|
||||
impl.IntersectRay(r, callback, ref maxDist, endPos);
|
||||
|
||||
return !callback.didHit();
|
||||
return !callback.DidHit();
|
||||
}
|
||||
|
||||
public float getHeight(float x, float y, float z, float maxSearchDist, PhaseShift phaseShift)
|
||||
public float GetHeight(float x, float y, float z, float maxSearchDist, PhaseShift phaseShift)
|
||||
{
|
||||
Vector3 v = new Vector3(x, y, z + 0.5f);
|
||||
Ray r = new Ray(v, new Vector3(0, 0, -1));
|
||||
DynamicTreeIntersectionCallback callback = new DynamicTreeIntersectionCallback(phaseShift);
|
||||
impl.intersectZAllignedRay(r, callback, ref maxSearchDist);
|
||||
impl.IntersectZAllignedRay(r, callback, ref maxSearchDist);
|
||||
|
||||
if (callback.didHit())
|
||||
if (callback.DidHit())
|
||||
return v.Z - maxSearchDist;
|
||||
else
|
||||
return float.NegativeInfinity;
|
||||
}
|
||||
|
||||
public bool getAreaInfo(float x, float y, ref float z, PhaseShift phaseShift, out uint flags, out int adtId, out int rootId, out int groupId)
|
||||
public bool GetAreaInfo(float x, float y, ref float z, PhaseShift phaseShift, out uint flags, out int adtId, out int rootId, out int groupId)
|
||||
{
|
||||
flags = 0;
|
||||
adtId = 0;
|
||||
@@ -135,7 +135,7 @@ namespace Game.Collision
|
||||
|
||||
Vector3 v = new Vector3(x, y, z + 0.5f);
|
||||
DynamicTreeAreaInfoCallback intersectionCallBack = new DynamicTreeAreaInfoCallback(phaseShift);
|
||||
impl.intersectPoint(v, intersectionCallBack);
|
||||
impl.IntersectPoint(v, intersectionCallBack);
|
||||
if (intersectionCallBack.GetAreaInfo().result)
|
||||
{
|
||||
flags = intersectionCallBack.GetAreaInfo().flags;
|
||||
@@ -159,27 +159,27 @@ namespace Game.Collision
|
||||
unbalanced_times = 0;
|
||||
}
|
||||
|
||||
public override void insert(GameObjectModel mdl)
|
||||
public override void Insert(GameObjectModel mdl)
|
||||
{
|
||||
base.insert(mdl);
|
||||
base.Insert(mdl);
|
||||
++unbalanced_times;
|
||||
}
|
||||
|
||||
public override void remove(GameObjectModel mdl)
|
||||
public override void Remove(GameObjectModel mdl)
|
||||
{
|
||||
base.remove(mdl);
|
||||
base.Remove(mdl);
|
||||
++unbalanced_times;
|
||||
}
|
||||
|
||||
public override void balance()
|
||||
public override void Balance()
|
||||
{
|
||||
base.balance();
|
||||
base.Balance();
|
||||
unbalanced_times = 0;
|
||||
}
|
||||
|
||||
public void update(uint difftime)
|
||||
public void Update(uint difftime)
|
||||
{
|
||||
if (empty())
|
||||
if (Empty())
|
||||
return;
|
||||
|
||||
rebalance_timer.Update((int)difftime);
|
||||
@@ -187,7 +187,7 @@ namespace Game.Collision
|
||||
{
|
||||
rebalance_timer.Reset(200);
|
||||
if (unbalanced_times > 0)
|
||||
balance();
|
||||
Balance();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -49,17 +49,17 @@ namespace Game.Collision
|
||||
iParentMapData[pair.Value] = pair.Key;
|
||||
}
|
||||
|
||||
public VMAPLoadResult loadMap(uint mapId, uint x, uint y)
|
||||
public VMAPLoadResult LoadMap(uint mapId, uint x, uint y)
|
||||
{
|
||||
var result = VMAPLoadResult.Ignored;
|
||||
if (isMapLoadingEnabled())
|
||||
if (IsMapLoadingEnabled())
|
||||
{
|
||||
if (loadSingleMap(mapId, x, y))
|
||||
if (LoadSingleMap(mapId, x, y))
|
||||
{
|
||||
result = VMAPLoadResult.OK;
|
||||
var childMaps = iChildMapData.LookupByKey(mapId);
|
||||
foreach (uint childMapId in childMaps)
|
||||
if (!loadSingleMap(childMapId, x, y))
|
||||
if (!LoadSingleMap(childMapId, x, y))
|
||||
result = VMAPLoadResult.Error;
|
||||
}
|
||||
else
|
||||
@@ -69,12 +69,12 @@ namespace Game.Collision
|
||||
return result;
|
||||
}
|
||||
|
||||
bool loadSingleMap(uint mapId, uint tileX, uint tileY)
|
||||
bool LoadSingleMap(uint mapId, uint tileX, uint tileY)
|
||||
{
|
||||
var instanceTree = iInstanceMapTrees.LookupByKey(mapId);
|
||||
if (instanceTree == null)
|
||||
{
|
||||
string filename = VMapPath + getMapFileName(mapId);
|
||||
string filename = VMapPath + GetMapFileName(mapId);
|
||||
StaticMapTree newTree = new StaticMapTree(mapId);
|
||||
if (!newTree.InitMap(filename))
|
||||
return false;
|
||||
@@ -87,79 +87,79 @@ namespace Game.Collision
|
||||
return instanceTree.LoadMapTile(tileX, tileY, this);
|
||||
}
|
||||
|
||||
public void unloadMap(uint mapId, uint x, uint y)
|
||||
public void UnloadMap(uint mapId, uint x, uint y)
|
||||
{
|
||||
var childMaps = iChildMapData.LookupByKey(mapId);
|
||||
foreach (uint childMapId in childMaps)
|
||||
unloadSingleMap(childMapId, x, y);
|
||||
UnloadSingleMap(childMapId, x, y);
|
||||
|
||||
unloadSingleMap(mapId, x, y);
|
||||
UnloadSingleMap(mapId, x, y);
|
||||
}
|
||||
|
||||
void unloadSingleMap(uint mapId, uint x, uint y)
|
||||
void UnloadSingleMap(uint mapId, uint x, uint y)
|
||||
{
|
||||
var instanceTree = iInstanceMapTrees.LookupByKey(mapId);
|
||||
if (instanceTree != null)
|
||||
{
|
||||
instanceTree.UnloadMapTile(x, y, this);
|
||||
if (instanceTree.numLoadedTiles() == 0)
|
||||
if (instanceTree.NumLoadedTiles() == 0)
|
||||
{
|
||||
iInstanceMapTrees.Remove(mapId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void unloadMap(uint mapId)
|
||||
public void UnloadMap(uint mapId)
|
||||
{
|
||||
var childMaps = iChildMapData.LookupByKey(mapId);
|
||||
foreach (uint childMapId in childMaps)
|
||||
unloadSingleMap(childMapId);
|
||||
UnloadSingleMap(childMapId);
|
||||
|
||||
unloadSingleMap(mapId);
|
||||
UnloadSingleMap(mapId);
|
||||
}
|
||||
|
||||
void unloadSingleMap(uint mapId)
|
||||
void UnloadSingleMap(uint mapId)
|
||||
{
|
||||
var instanceTree = iInstanceMapTrees.LookupByKey(mapId);
|
||||
if (instanceTree != null)
|
||||
{
|
||||
instanceTree.UnloadMap(this);
|
||||
if (instanceTree.numLoadedTiles() == 0)
|
||||
if (instanceTree.NumLoadedTiles() == 0)
|
||||
{
|
||||
iInstanceMapTrees.Remove(mapId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool isInLineOfSight(uint mapId, float x1, float y1, float z1, float x2, float y2, float z2, ModelIgnoreFlags ignoreFlags)
|
||||
public bool IsInLineOfSight(uint mapId, float x1, float y1, float z1, float x2, float y2, float z2, ModelIgnoreFlags ignoreFlags)
|
||||
{
|
||||
if (!isLineOfSightCalcEnabled() || Global.DisableMgr.IsDisabledFor(DisableType.VMAP, mapId, null, DisableFlags.VmapLOS))
|
||||
if (!IsLineOfSightCalcEnabled() || Global.DisableMgr.IsDisabledFor(DisableType.VMAP, mapId, null, DisableFlags.VmapLOS))
|
||||
return true;
|
||||
|
||||
var instanceTree = iInstanceMapTrees.LookupByKey(mapId);
|
||||
if (instanceTree != null)
|
||||
{
|
||||
Vector3 pos1 = convertPositionToInternalRep(x1, y1, z1);
|
||||
Vector3 pos2 = convertPositionToInternalRep(x2, y2, z2);
|
||||
Vector3 pos1 = ConvertPositionToInternalRep(x1, y1, z1);
|
||||
Vector3 pos2 = ConvertPositionToInternalRep(x2, y2, z2);
|
||||
if (pos1 != pos2)
|
||||
return instanceTree.isInLineOfSight(pos1, pos2, ignoreFlags);
|
||||
return instanceTree.IsInLineOfSight(pos1, pos2, ignoreFlags);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool getObjectHitPos(uint mapId, float x1, float y1, float z1, float x2, float y2, float z2, out float rx, out float ry, out float rz, float modifyDist)
|
||||
public bool GetObjectHitPos(uint mapId, float x1, float y1, float z1, float x2, float y2, float z2, out float rx, out float ry, out float rz, float modifyDist)
|
||||
{
|
||||
if (isLineOfSightCalcEnabled() && !Global.DisableMgr.IsDisabledFor(DisableType.VMAP, mapId, null, DisableFlags.VmapLOS))
|
||||
if (IsLineOfSightCalcEnabled() && !Global.DisableMgr.IsDisabledFor(DisableType.VMAP, mapId, null, DisableFlags.VmapLOS))
|
||||
{
|
||||
var instanceTree = iInstanceMapTrees.LookupByKey(mapId);
|
||||
if (instanceTree != null)
|
||||
{
|
||||
Vector3 resultPos;
|
||||
Vector3 pos1 = convertPositionToInternalRep(x1, y1, z1);
|
||||
Vector3 pos2 = convertPositionToInternalRep(x2, y2, z2);
|
||||
bool result = instanceTree.getObjectHitPos(pos1, pos2, out resultPos, modifyDist);
|
||||
resultPos = convertPositionToInternalRep(resultPos.X, resultPos.Y, resultPos.Z);
|
||||
Vector3 pos1 = ConvertPositionToInternalRep(x1, y1, z1);
|
||||
Vector3 pos2 = ConvertPositionToInternalRep(x2, y2, z2);
|
||||
bool result = instanceTree.GetObjectHitPos(pos1, pos2, out resultPos, modifyDist);
|
||||
resultPos = ConvertPositionToInternalRep(resultPos.X, resultPos.Y, resultPos.Z);
|
||||
rx = resultPos.X;
|
||||
ry = resultPos.Y;
|
||||
rz = resultPos.Z;
|
||||
@@ -174,15 +174,15 @@ namespace Game.Collision
|
||||
return false;
|
||||
}
|
||||
|
||||
public float getHeight(uint mapId, float x, float y, float z, float maxSearchDist)
|
||||
public float GetHeight(uint mapId, float x, float y, float z, float maxSearchDist)
|
||||
{
|
||||
if (isHeightCalcEnabled() && !Global.DisableMgr.IsDisabledFor(DisableType.VMAP, mapId, null, DisableFlags.VmapHeight))
|
||||
if (IsHeightCalcEnabled() && !Global.DisableMgr.IsDisabledFor(DisableType.VMAP, mapId, null, DisableFlags.VmapHeight))
|
||||
{
|
||||
var instanceTree = iInstanceMapTrees.LookupByKey(mapId);
|
||||
if (instanceTree != null)
|
||||
{
|
||||
Vector3 pos = convertPositionToInternalRep(x, y, z);
|
||||
float height = instanceTree.getHeight(pos, maxSearchDist);
|
||||
Vector3 pos = ConvertPositionToInternalRep(x, y, z);
|
||||
float height = instanceTree.GetHeight(pos, maxSearchDist);
|
||||
if (float.IsInfinity(height))
|
||||
height = MapConst.VMAPInvalidHeightValue; // No height
|
||||
|
||||
@@ -193,7 +193,7 @@ namespace Game.Collision
|
||||
return MapConst.VMAPInvalidHeightValue;
|
||||
}
|
||||
|
||||
public bool getAreaInfo(uint mapId, float x, float y, ref float z, out uint flags, out int adtId, out int rootId, out int groupId)
|
||||
public bool GetAreaInfo(uint mapId, float x, float y, ref float z, out uint flags, out int adtId, out int rootId, out int groupId)
|
||||
{
|
||||
flags = 0;
|
||||
adtId = 0;
|
||||
@@ -204,8 +204,8 @@ namespace Game.Collision
|
||||
var instanceTree = iInstanceMapTrees.LookupByKey(mapId);
|
||||
if (instanceTree != null)
|
||||
{
|
||||
Vector3 pos = convertPositionToInternalRep(x, y, z);
|
||||
bool result = instanceTree.getAreaInfo(ref pos, out flags, out adtId, out rootId, out groupId);
|
||||
Vector3 pos = ConvertPositionToInternalRep(x, y, z);
|
||||
bool result = instanceTree.GetAreaInfo(ref pos, out flags, out adtId, out rootId, out groupId);
|
||||
// z is not touched by convertPositionToInternalRep(), so just copy
|
||||
z = pos.Z;
|
||||
return result;
|
||||
@@ -223,7 +223,7 @@ namespace Game.Collision
|
||||
if (instanceTree != null)
|
||||
{
|
||||
LocationInfo info = new LocationInfo();
|
||||
Vector3 pos = convertPositionToInternalRep(x, y, z);
|
||||
Vector3 pos = ConvertPositionToInternalRep(x, y, z);
|
||||
if (instanceTree.GetLocationInfo(pos, info))
|
||||
{
|
||||
floor = info.ground_Z;
|
||||
@@ -239,7 +239,7 @@ namespace Game.Collision
|
||||
return false;
|
||||
}
|
||||
|
||||
public WorldModel acquireModelInstance(string filename, uint flags = 0)
|
||||
public WorldModel AcquireModelInstance(string filename, uint flags = 0)
|
||||
{
|
||||
lock (LoadedModelFilesLock)
|
||||
{
|
||||
@@ -248,7 +248,7 @@ namespace Game.Collision
|
||||
if (model == null)
|
||||
{
|
||||
WorldModel worldmodel = new WorldModel();
|
||||
if (!worldmodel.readFile(VMapPath + filename))
|
||||
if (!worldmodel.ReadFile(VMapPath + filename))
|
||||
{
|
||||
Log.outError(LogFilter.Server, "VMapManager: could not load '{0}'", filename);
|
||||
return null;
|
||||
@@ -259,16 +259,16 @@ namespace Game.Collision
|
||||
worldmodel.Flags = flags;
|
||||
|
||||
model = new ManagedModel();
|
||||
model.setModel(worldmodel);
|
||||
model.SetModel(worldmodel);
|
||||
|
||||
iLoadedModelFiles.Add(filename, model);
|
||||
}
|
||||
model.incRefCount();
|
||||
return model.getModel();
|
||||
model.IncRefCount();
|
||||
return model.GetModel();
|
||||
}
|
||||
}
|
||||
|
||||
public void releaseModelInstance(string filename)
|
||||
public void ReleaseModelInstance(string filename)
|
||||
{
|
||||
lock (LoadedModelFilesLock)
|
||||
{
|
||||
@@ -279,7 +279,7 @@ namespace Game.Collision
|
||||
Log.outError(LogFilter.Server, "VMapManager: trying to unload non-loaded file '{0}'", filename);
|
||||
return;
|
||||
}
|
||||
if (model.decRefCount() == 0)
|
||||
if (model.DecRefCount() == 0)
|
||||
{
|
||||
Log.outDebug(LogFilter.Maps, "VMapManager: unloading file '{0}'", filename);
|
||||
iLoadedModelFiles.Remove(filename);
|
||||
@@ -287,12 +287,12 @@ namespace Game.Collision
|
||||
}
|
||||
}
|
||||
|
||||
public LoadResult existsMap(uint mapId, uint x, uint y)
|
||||
public LoadResult ExistsMap(uint mapId, uint x, uint y)
|
||||
{
|
||||
return StaticMapTree.CanLoadMap(VMapPath, mapId, x, y, this);
|
||||
}
|
||||
|
||||
public int getParentMapId(uint mapId)
|
||||
public int GetParentMapId(uint mapId)
|
||||
{
|
||||
if (iParentMapData.ContainsKey(mapId))
|
||||
return (int)iParentMapData[mapId];
|
||||
@@ -300,7 +300,7 @@ namespace Game.Collision
|
||||
return -1;
|
||||
}
|
||||
|
||||
Vector3 convertPositionToInternalRep(float x, float y, float z)
|
||||
Vector3 ConvertPositionToInternalRep(float x, float y, float z)
|
||||
{
|
||||
Vector3 pos = new Vector3();
|
||||
float mid = 0.5f * 64.0f * 533.33333333f;
|
||||
@@ -311,17 +311,17 @@ namespace Game.Collision
|
||||
return pos;
|
||||
}
|
||||
|
||||
public static string getMapFileName(uint mapId)
|
||||
public static string GetMapFileName(uint mapId)
|
||||
{
|
||||
return $"{mapId:D4}.vmtree";
|
||||
}
|
||||
|
||||
public void setEnableLineOfSightCalc(bool pVal) { _enableLineOfSightCalc = pVal; }
|
||||
public void setEnableHeightCalc(bool pVal) { _enableHeightCalc = pVal; }
|
||||
public void SetEnableLineOfSightCalc(bool pVal) { _enableLineOfSightCalc = pVal; }
|
||||
public void SetEnableHeightCalc(bool pVal) { _enableHeightCalc = pVal; }
|
||||
|
||||
public bool isLineOfSightCalcEnabled() { return _enableLineOfSightCalc; }
|
||||
public bool isHeightCalcEnabled() { return _enableHeightCalc; }
|
||||
public bool isMapLoadingEnabled() { return _enableLineOfSightCalc || _enableHeightCalc; }
|
||||
public bool IsLineOfSightCalcEnabled() { return _enableLineOfSightCalc; }
|
||||
public bool IsHeightCalcEnabled() { return _enableHeightCalc; }
|
||||
public bool IsMapLoadingEnabled() { return _enableLineOfSightCalc || _enableHeightCalc; }
|
||||
|
||||
Dictionary<string, ManagedModel> iLoadedModelFiles = new Dictionary<string, ManagedModel>();
|
||||
Dictionary<uint, StaticMapTree> iInstanceMapTrees = new Dictionary<uint, StaticMapTree>();
|
||||
@@ -341,10 +341,10 @@ namespace Game.Collision
|
||||
iRefCount = 0;
|
||||
}
|
||||
|
||||
public void setModel(WorldModel model) { iModel = model; }
|
||||
public WorldModel getModel() { return iModel; }
|
||||
public void incRefCount() { ++iRefCount; }
|
||||
public int decRefCount() { return --iRefCount; }
|
||||
public void SetModel(WorldModel model) { iModel = model; }
|
||||
public WorldModel GetModel() { return iModel; }
|
||||
public void IncRefCount() { ++iRefCount; }
|
||||
public int DecRefCount() { return --iRefCount; }
|
||||
|
||||
WorldModel iModel;
|
||||
int iRefCount;
|
||||
|
||||
@@ -69,9 +69,9 @@ namespace Game.Collision
|
||||
var magic = reader.ReadStringFromChars(8);
|
||||
var node = reader.ReadStringFromChars(4);
|
||||
|
||||
if (magic == MapConst.VMapMagic && node == "NODE" && iTree.readFromFile(reader))
|
||||
if (magic == MapConst.VMapMagic && node == "NODE" && iTree.ReadFromFile(reader))
|
||||
{
|
||||
iNTreeValues = iTree.primCount();
|
||||
iNTreeValues = iTree.PrimCount();
|
||||
iTreeValues = new ModelInstance[iNTreeValues];
|
||||
success = true;
|
||||
}
|
||||
@@ -98,9 +98,9 @@ namespace Game.Collision
|
||||
{
|
||||
foreach (var id in iLoadedSpawns)
|
||||
{
|
||||
iTreeValues[id.Key].setUnloaded();
|
||||
iTreeValues[id.Key].SetUnloaded();
|
||||
for (uint refCount = 0; refCount < id.Key; ++refCount)
|
||||
vm.releaseModelInstance(iTreeValues[id.Key].name);
|
||||
vm.ReleaseModelInstance(iTreeValues[id.Key].name);
|
||||
}
|
||||
iLoadedSpawns.Clear();
|
||||
iLoadedTiles.Clear();
|
||||
@@ -118,7 +118,7 @@ namespace Game.Collision
|
||||
FileStream stream = OpenMapTileFile(VMapManager.VMapPath, iMapID, tileX, tileY, vm);
|
||||
if (stream == null)
|
||||
{
|
||||
iLoadedTiles[packTileID(tileX, tileY)] = false;
|
||||
iLoadedTiles[PackTileID(tileX, tileY)] = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -133,11 +133,11 @@ namespace Game.Collision
|
||||
{
|
||||
// read model spawns
|
||||
ModelSpawn spawn;
|
||||
result = ModelSpawn.readFromFile(reader, out spawn);
|
||||
result = ModelSpawn.ReadFromFile(reader, out spawn);
|
||||
if (result)
|
||||
{
|
||||
// acquire model instance
|
||||
WorldModel model = vm.acquireModelInstance(spawn.name, spawn.flags);
|
||||
WorldModel model = vm.AcquireModelInstance(spawn.name, spawn.flags);
|
||||
if (model == null)
|
||||
Log.outError(LogFilter.Server, "StaticMapTree.LoadMapTile() : could not acquire WorldModel [{0}, {1}]", tileX, tileY);
|
||||
|
||||
@@ -165,14 +165,14 @@ namespace Game.Collision
|
||||
}
|
||||
}
|
||||
}
|
||||
iLoadedTiles[packTileID(tileX, tileY)] = true;
|
||||
iLoadedTiles[PackTileID(tileX, tileY)] = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void UnloadMapTile(uint tileX, uint tileY, VMapManager vm)
|
||||
{
|
||||
uint tileID = packTileID(tileX, tileY);
|
||||
uint tileID = PackTileID(tileX, tileY);
|
||||
var tile = iLoadedTiles.LookupByKey(tileID);
|
||||
if (!iLoadedTiles.ContainsKey(tileID))
|
||||
{
|
||||
@@ -195,11 +195,11 @@ namespace Game.Collision
|
||||
{
|
||||
// read model spawns
|
||||
ModelSpawn spawn;
|
||||
result = ModelSpawn.readFromFile(reader, out spawn);
|
||||
result = ModelSpawn.ReadFromFile(reader, out spawn);
|
||||
if (result)
|
||||
{
|
||||
// release model instance
|
||||
vm.releaseModelInstance(spawn.name);
|
||||
vm.ReleaseModelInstance(spawn.name);
|
||||
|
||||
// update tree
|
||||
if (!iSpawnIndices.ContainsKey(spawn.ID))
|
||||
@@ -211,7 +211,7 @@ namespace Game.Collision
|
||||
Log.outError(LogFilter.Server, "StaticMapTree.UnloadMapTile() : trying to unload non-referenced model '{0}' (ID:{1})", spawn.name, spawn.ID);
|
||||
else if (--iLoadedSpawns[referencedNode] == 0)
|
||||
{
|
||||
iTreeValues[referencedNode].setUnloaded();
|
||||
iTreeValues[referencedNode].SetUnloaded();
|
||||
iLoadedSpawns.Remove(referencedNode);
|
||||
}
|
||||
}
|
||||
@@ -224,17 +224,17 @@ namespace Game.Collision
|
||||
iLoadedTiles.Remove(tileID);
|
||||
}
|
||||
|
||||
static uint packTileID(uint tileX, uint tileY) { return tileX << 16 | tileY; }
|
||||
static void unpackTileID(uint ID, ref uint tileX, ref uint tileY) { tileX = ID >> 16; tileY = ID & 0xFF; }
|
||||
static uint PackTileID(uint tileX, uint tileY) { return tileX << 16 | tileY; }
|
||||
static void UnpackTileID(uint ID, ref uint tileX, ref uint tileY) { tileX = ID >> 16; tileY = ID & 0xFF; }
|
||||
|
||||
static FileStream OpenMapTileFile(string vmapPath, uint mapID, uint tileX, uint tileY, VMapManager vm)
|
||||
{
|
||||
string tilefile = vmapPath + getTileFileName(mapID, tileX, tileY);
|
||||
string tilefile = vmapPath + GetTileFileName(mapID, tileX, tileY);
|
||||
if (!File.Exists(tilefile))
|
||||
{
|
||||
int parentMapId = vm.getParentMapId(mapID);
|
||||
int parentMapId = vm.GetParentMapId(mapID);
|
||||
if (parentMapId != -1)
|
||||
tilefile = vmapPath + getTileFileName((uint)parentMapId, tileX, tileY);
|
||||
tilefile = vmapPath + GetTileFileName((uint)parentMapId, tileX, tileY);
|
||||
}
|
||||
|
||||
if (!File.Exists(tilefile))
|
||||
@@ -245,7 +245,7 @@ namespace Game.Collision
|
||||
|
||||
public static LoadResult CanLoadMap(string vmapPath, uint mapID, uint tileX, uint tileY, VMapManager vm)
|
||||
{
|
||||
string fullname = vmapPath + VMapManager.getMapFileName(mapID);
|
||||
string fullname = vmapPath + VMapManager.GetMapFileName(mapID);
|
||||
if (!File.Exists(fullname))
|
||||
return LoadResult.FileNotFound;
|
||||
|
||||
@@ -268,12 +268,12 @@ namespace Game.Collision
|
||||
return LoadResult.Success;
|
||||
}
|
||||
|
||||
public static string getTileFileName(uint mapID, uint tileX, uint tileY)
|
||||
public static string GetTileFileName(uint mapID, uint tileX, uint tileY)
|
||||
{
|
||||
return $"{mapID:D4}_{tileY:D2}_{tileX:D2}.vmtile";
|
||||
}
|
||||
|
||||
public bool getAreaInfo(ref Vector3 pos, out uint flags, out int adtId, out int rootId, out int groupId)
|
||||
public bool GetAreaInfo(ref Vector3 pos, out uint flags, out int adtId, out int rootId, out int groupId)
|
||||
{
|
||||
flags = 0;
|
||||
adtId = 0;
|
||||
@@ -281,7 +281,7 @@ namespace Game.Collision
|
||||
groupId = 0;
|
||||
|
||||
AreaInfoCallback intersectionCallBack = new AreaInfoCallback(iTreeValues);
|
||||
iTree.intersectPoint(pos, intersectionCallBack);
|
||||
iTree.IntersectPoint(pos, intersectionCallBack);
|
||||
if (intersectionCallBack.aInfo.result)
|
||||
{
|
||||
flags = intersectionCallBack.aInfo.flags;
|
||||
@@ -297,32 +297,32 @@ namespace Game.Collision
|
||||
public bool GetLocationInfo(Vector3 pos, LocationInfo info)
|
||||
{
|
||||
LocationInfoCallback intersectionCallBack = new LocationInfoCallback(iTreeValues, info);
|
||||
iTree.intersectPoint(pos, intersectionCallBack);
|
||||
iTree.IntersectPoint(pos, intersectionCallBack);
|
||||
return intersectionCallBack.result;
|
||||
}
|
||||
|
||||
public float getHeight(Vector3 pPos, float maxSearchDist)
|
||||
public float GetHeight(Vector3 pPos, float maxSearchDist)
|
||||
{
|
||||
float height = float.PositiveInfinity;
|
||||
Vector3 dir = new Vector3(0, 0, -1);
|
||||
Ray ray = new Ray(pPos, dir); // direction with length of 1
|
||||
float maxDist = maxSearchDist;
|
||||
if (getIntersectionTime(ray, ref maxDist, false, ModelIgnoreFlags.Nothing))
|
||||
if (GetIntersectionTime(ray, ref maxDist, false, ModelIgnoreFlags.Nothing))
|
||||
height = pPos.Z - maxDist;
|
||||
|
||||
return height;
|
||||
}
|
||||
bool getIntersectionTime(Ray pRay, ref float pMaxDist, bool pStopAtFirstHit, ModelIgnoreFlags ignoreFlags)
|
||||
bool GetIntersectionTime(Ray pRay, ref float pMaxDist, bool pStopAtFirstHit, ModelIgnoreFlags ignoreFlags)
|
||||
{
|
||||
float distance = pMaxDist;
|
||||
MapRayCallback intersectionCallBack = new MapRayCallback(iTreeValues, ignoreFlags);
|
||||
iTree.intersectRay(pRay, intersectionCallBack, ref distance, pStopAtFirstHit);
|
||||
if (intersectionCallBack.didHit())
|
||||
iTree.IntersectRay(pRay, intersectionCallBack, ref distance, pStopAtFirstHit);
|
||||
if (intersectionCallBack.DidHit())
|
||||
pMaxDist = distance;
|
||||
return intersectionCallBack.didHit();
|
||||
return intersectionCallBack.DidHit();
|
||||
}
|
||||
|
||||
public bool getObjectHitPos(Vector3 pPos1, Vector3 pPos2, out Vector3 pResultHitPos, float pModifyDist)
|
||||
public bool GetObjectHitPos(Vector3 pPos1, Vector3 pPos2, out Vector3 pResultHitPos, float pModifyDist)
|
||||
{
|
||||
bool result = false;
|
||||
float maxDist = (pPos2 - pPos1).magnitude();
|
||||
@@ -337,7 +337,7 @@ namespace Game.Collision
|
||||
Vector3 dir = (pPos2 - pPos1) / maxDist; // direction with length of 1
|
||||
Ray ray = new Ray(pPos1, dir);
|
||||
float dist = maxDist;
|
||||
if (getIntersectionTime(ray, ref dist, false, ModelIgnoreFlags.Nothing))
|
||||
if (GetIntersectionTime(ray, ref dist, false, ModelIgnoreFlags.Nothing))
|
||||
{
|
||||
pResultHitPos = pPos1 + dir * dist;
|
||||
if (pModifyDist < 0)
|
||||
@@ -365,7 +365,7 @@ namespace Game.Collision
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool isInLineOfSight(Vector3 pos1, Vector3 pos2, ModelIgnoreFlags ignoreFlags)
|
||||
public bool IsInLineOfSight(Vector3 pos1, Vector3 pos2, ModelIgnoreFlags ignoreFlags)
|
||||
{
|
||||
float maxDist = (pos2 - pos1).magnitude();
|
||||
// return false if distance is over max float, in case of cheater teleporting to the end of the universe
|
||||
@@ -380,13 +380,13 @@ namespace Game.Collision
|
||||
return true;
|
||||
// direction with length of 1
|
||||
Ray ray = new Ray(pos1, (pos2 - pos1) / maxDist);
|
||||
if (getIntersectionTime(ray, ref maxDist, true, ignoreFlags))
|
||||
if (GetIntersectionTime(ray, ref maxDist, true, ignoreFlags))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public int numLoadedTiles() { return iLoadedTiles.Count; }
|
||||
public int NumLoadedTiles() { return iLoadedTiles.Count; }
|
||||
|
||||
uint iMapID;
|
||||
BIH iTree = new BIH();
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace Game.Collision
|
||||
|
||||
public class GameObjectModel : IModel
|
||||
{
|
||||
bool initialize(GameObjectModelOwnerBase modelOwner)
|
||||
bool Initialize(GameObjectModelOwnerBase modelOwner)
|
||||
{
|
||||
var modelData = StaticModelList.models.LookupByKey(modelOwner.GetDisplayId());
|
||||
if (modelData == null)
|
||||
@@ -55,7 +55,7 @@ namespace Game.Collision
|
||||
return false;
|
||||
}
|
||||
|
||||
iModel = Global.VMapMgr.acquireModelInstance(modelData.name);
|
||||
iModel = Global.VMapMgr.AcquireModelInstance(modelData.name);
|
||||
|
||||
if (iModel == null)
|
||||
return false;
|
||||
@@ -82,7 +82,7 @@ namespace Game.Collision
|
||||
public static GameObjectModel Create(GameObjectModelOwnerBase modelOwner)
|
||||
{
|
||||
GameObjectModel mdl = new GameObjectModel();
|
||||
if (!mdl.initialize(modelOwner))
|
||||
if (!mdl.Initialize(modelOwner))
|
||||
return null;
|
||||
|
||||
return mdl;
|
||||
@@ -90,7 +90,7 @@ namespace Game.Collision
|
||||
|
||||
public override bool IntersectRay(Ray ray, ref float maxDist, bool stopAtFirstHit, PhaseShift phaseShift, ModelIgnoreFlags ignoreFlags)
|
||||
{
|
||||
if (!isCollisionEnabled() || !owner.IsSpawned())
|
||||
if (!IsCollisionEnabled() || !owner.IsSpawned())
|
||||
return false;
|
||||
|
||||
if (!owner.IsInPhase(phaseShift))
|
||||
@@ -115,7 +115,7 @@ namespace Game.Collision
|
||||
|
||||
public override void IntersectPoint(Vector3 point, AreaInfo info, PhaseShift phaseShift)
|
||||
{
|
||||
if (!isCollisionEnabled() || !owner.IsSpawned() || !isMapObject())
|
||||
if (!IsCollisionEnabled() || !owner.IsSpawned() || !IsMapObject())
|
||||
return;
|
||||
|
||||
if (!owner.IsInPhase(phaseShift))
|
||||
@@ -172,12 +172,12 @@ namespace Game.Collision
|
||||
return true;
|
||||
}
|
||||
|
||||
public override Vector3 getPosition() { return iPos; }
|
||||
public override AxisAlignedBox getBounds() { return iBound; }
|
||||
public override Vector3 GetPosition() { return iPos; }
|
||||
public override AxisAlignedBox GetBounds() { return iBound; }
|
||||
|
||||
public void enableCollision(bool enable) { _collisionEnabled = enable; }
|
||||
bool isCollisionEnabled() { return _collisionEnabled; }
|
||||
public bool isMapObject() { return isWmo; }
|
||||
public void EnableCollision(bool enable) { _collisionEnabled = enable; }
|
||||
bool IsCollisionEnabled() { return _collisionEnabled; }
|
||||
public bool IsMapObject() { return isWmo; }
|
||||
|
||||
public static void LoadGameObjectModelList()
|
||||
{
|
||||
|
||||
@@ -22,8 +22,8 @@ namespace Game.Collision
|
||||
{
|
||||
public class IModel
|
||||
{
|
||||
public virtual Vector3 getPosition() { return default; }
|
||||
public virtual AxisAlignedBox getBounds() { return default; }
|
||||
public virtual Vector3 GetPosition() { return default; }
|
||||
public virtual AxisAlignedBox GetBounds() { return default; }
|
||||
|
||||
public virtual bool IntersectRay(Ray ray, ref float maxDist, bool stopAtFirstHit, PhaseShift phaseShift, ModelIgnoreFlags ignoreFlags) { return false; }
|
||||
public virtual bool IntersectRay(Ray ray, ref float distance, bool stopAtFirstHit, ModelIgnoreFlags ignoreFlags) { return false; }
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace Game.Collision
|
||||
name = spawn.name;
|
||||
}
|
||||
|
||||
public static bool readFromFile(BinaryReader reader, out ModelSpawn spawn)
|
||||
public static bool ReadFromFile(BinaryReader reader, out ModelSpawn spawn)
|
||||
{
|
||||
spawn = new ModelSpawn();
|
||||
|
||||
@@ -94,7 +94,7 @@ namespace Game.Collision
|
||||
iInvScale = 1.0f / iScale;
|
||||
}
|
||||
|
||||
public bool intersectRay(Ray pRay, ref float pMaxDist, bool pStopAtFirstHit, ModelIgnoreFlags ignoreFlags)
|
||||
public bool IntersectRay(Ray pRay, ref float pMaxDist, bool pStopAtFirstHit, ModelIgnoreFlags ignoreFlags)
|
||||
{
|
||||
if (iModel == null)
|
||||
return false;
|
||||
@@ -116,7 +116,7 @@ namespace Game.Collision
|
||||
return hit;
|
||||
}
|
||||
|
||||
public void intersectPoint(Vector3 p, AreaInfo info)
|
||||
public void IntersectPoint(Vector3 p, AreaInfo info)
|
||||
{
|
||||
if (iModel == null)
|
||||
return;
|
||||
@@ -192,7 +192,7 @@ namespace Game.Collision
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setUnloaded() { iModel = null; }
|
||||
public void SetUnloaded() { iModel = null; }
|
||||
|
||||
Matrix3 iInvRot;
|
||||
float iInvScale;
|
||||
|
||||
@@ -128,7 +128,7 @@ namespace Game.Collision
|
||||
return true;
|
||||
}
|
||||
|
||||
public static WmoLiquid readFromFile(BinaryReader reader)
|
||||
public static WmoLiquid ReadFromFile(BinaryReader reader)
|
||||
{
|
||||
WmoLiquid liquid = new WmoLiquid();
|
||||
|
||||
@@ -193,13 +193,13 @@ namespace Game.Collision
|
||||
iLiquid = null;
|
||||
}
|
||||
|
||||
void setLiquidData(WmoLiquid liquid)
|
||||
void SetLiquidData(WmoLiquid liquid)
|
||||
{
|
||||
iLiquid = liquid;
|
||||
liquid = null;
|
||||
}
|
||||
|
||||
public bool readFromFile(BinaryReader reader)
|
||||
public bool ReadFromFile(BinaryReader reader)
|
||||
{
|
||||
triangles.Clear();
|
||||
vertices.Clear();
|
||||
@@ -237,7 +237,7 @@ namespace Game.Collision
|
||||
if (reader.ReadStringFromChars(4) != "MBIH")
|
||||
return false;
|
||||
|
||||
meshTree.readFromFile(reader);
|
||||
meshTree.ReadFromFile(reader);
|
||||
|
||||
// write liquid data
|
||||
if (reader.ReadStringFromChars(4) != "LIQU")
|
||||
@@ -245,7 +245,7 @@ namespace Game.Collision
|
||||
|
||||
chunkSize = reader.ReadUInt32();
|
||||
if (chunkSize > 0)
|
||||
iLiquid = WmoLiquid.readFromFile(reader);
|
||||
iLiquid = WmoLiquid.ReadFromFile(reader);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -256,7 +256,7 @@ namespace Game.Collision
|
||||
return false;
|
||||
|
||||
GModelRayCallback callback = new GModelRayCallback(triangles, vertices);
|
||||
meshTree.intersectRay(ray, callback, ref distance, stopAtFirstHit);
|
||||
meshTree.IntersectRay(ray, callback, ref distance, stopAtFirstHit);
|
||||
return callback.hit;
|
||||
}
|
||||
|
||||
@@ -290,7 +290,7 @@ namespace Game.Collision
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override AxisAlignedBox getBounds() { return iBound; }
|
||||
public override AxisAlignedBox GetBounds() { return iBound; }
|
||||
|
||||
public uint GetMogpFlags() { return iMogpFlags; }
|
||||
|
||||
@@ -328,7 +328,7 @@ namespace Game.Collision
|
||||
return groupModels[0].IntersectRay(ray, ref distance, stopAtFirstHit);
|
||||
|
||||
WModelRayCallBack isc = new WModelRayCallBack(groupModels);
|
||||
groupTree.intersectRay(ray, isc, ref distance, stopAtFirstHit);
|
||||
groupTree.IntersectRay(ray, isc, ref distance, stopAtFirstHit);
|
||||
return isc.hit;
|
||||
}
|
||||
|
||||
@@ -339,7 +339,7 @@ namespace Game.Collision
|
||||
return false;
|
||||
|
||||
WModelAreaCallback callback = new WModelAreaCallback(groupModels, down);
|
||||
groupTree.intersectPoint(p, callback);
|
||||
groupTree.IntersectPoint(p, callback);
|
||||
if (callback.hit != null)
|
||||
{
|
||||
info.rootId = (int)RootWMOID;
|
||||
@@ -359,7 +359,7 @@ namespace Game.Collision
|
||||
return false;
|
||||
|
||||
WModelAreaCallback callback = new WModelAreaCallback(groupModels, down);
|
||||
groupTree.intersectPoint(p, callback);
|
||||
groupTree.IntersectPoint(p, callback);
|
||||
if (callback.hit != null)
|
||||
{
|
||||
info.hitModel = callback.hit;
|
||||
@@ -369,7 +369,7 @@ namespace Game.Collision
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool readFile(string filename)
|
||||
public bool ReadFile(string filename)
|
||||
{
|
||||
if (!File.Exists(filename))
|
||||
{
|
||||
@@ -397,7 +397,7 @@ namespace Game.Collision
|
||||
for (var i = 0; i < count; ++i)
|
||||
{
|
||||
GroupModel group = new GroupModel();
|
||||
group.readFromFile(reader);
|
||||
group.ReadFromFile(reader);
|
||||
groupModels.Add(group);
|
||||
}
|
||||
|
||||
@@ -405,7 +405,7 @@ namespace Game.Collision
|
||||
if (reader.ReadStringFromChars(4) != "GBIH")
|
||||
return false;
|
||||
|
||||
return groupTree.readFromFile(reader);
|
||||
return groupTree.ReadFromFile(reader);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,29 +33,29 @@ namespace Game.Collision
|
||||
nodes[x] = new Node[CELL_NUMBER];
|
||||
}
|
||||
|
||||
public virtual void insert(T value)
|
||||
public virtual void Insert(T value)
|
||||
{
|
||||
AxisAlignedBox bounds = value.getBounds();
|
||||
AxisAlignedBox bounds = value.GetBounds();
|
||||
Cell low = Cell.ComputeCell(bounds.Lo.X, bounds.Lo.Y);
|
||||
Cell high = Cell.ComputeCell(bounds.Hi.X, bounds.Hi.Y);
|
||||
for (int x = low.x; x <= high.x; ++x)
|
||||
{
|
||||
for (int y = low.y; y <= high.y; ++y)
|
||||
{
|
||||
Node node = getGrid(x, y);
|
||||
node.insert(value);
|
||||
Node node = GetGrid(x, y);
|
||||
node.Insert(value);
|
||||
memberTable.Add(value, node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void remove(T value)
|
||||
public virtual void Remove(T value)
|
||||
{
|
||||
// Remove the member
|
||||
memberTable.Remove(value);
|
||||
}
|
||||
|
||||
public virtual void balance()
|
||||
public virtual void Balance()
|
||||
{
|
||||
for (int x = 0; x < CELL_NUMBER; ++x)
|
||||
{
|
||||
@@ -63,13 +63,13 @@ namespace Game.Collision
|
||||
{
|
||||
Node n = nodes[x][y];
|
||||
if (n != null)
|
||||
n.balance();
|
||||
n.Balance();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool contains(T value) { return memberTable.ContainsKey(value); }
|
||||
public bool empty() { return memberTable.Empty(); }
|
||||
public bool Contains(T value) { return memberTable.ContainsKey(value); }
|
||||
public bool Empty() { return memberTable.Empty(); }
|
||||
|
||||
public struct Cell
|
||||
{
|
||||
@@ -95,10 +95,10 @@ namespace Game.Collision
|
||||
return c;
|
||||
}
|
||||
|
||||
public bool isValid() { return x >= 0 && x < CELL_NUMBER && y >= 0 && y < CELL_NUMBER; }
|
||||
public bool IsValid() { return x >= 0 && x < CELL_NUMBER && y >= 0 && y < CELL_NUMBER; }
|
||||
}
|
||||
|
||||
Node getGrid(int x, int y)
|
||||
Node GetGrid(int x, int y)
|
||||
{
|
||||
Cypher.Assert(x < CELL_NUMBER && y < CELL_NUMBER);
|
||||
if (nodes[x][y] == null)
|
||||
@@ -106,15 +106,15 @@ namespace Game.Collision
|
||||
return nodes[x][y];
|
||||
}
|
||||
|
||||
public void intersectRay(Ray ray, WorkerCallback intersectCallback, ref float max_dist)
|
||||
public void IntersectRay(Ray ray, WorkerCallback intersectCallback, ref float max_dist)
|
||||
{
|
||||
intersectRay(ray, intersectCallback, ref max_dist, ray.Origin + ray.Direction * max_dist);
|
||||
IntersectRay(ray, intersectCallback, ref max_dist, ray.Origin + ray.Direction * max_dist);
|
||||
}
|
||||
|
||||
public void intersectRay(Ray ray, WorkerCallback intersectCallback, ref float max_dist, Vector3 end)
|
||||
public void IntersectRay(Ray ray, WorkerCallback intersectCallback, ref float max_dist, Vector3 end)
|
||||
{
|
||||
Cell cell = Cell.ComputeCell(ray.Origin.X, ray.Origin.Y);
|
||||
if (!cell.isValid())
|
||||
if (!cell.IsValid())
|
||||
return;
|
||||
|
||||
Cell last_cell = Cell.ComputeCell(end.X, end.Y);
|
||||
@@ -123,7 +123,7 @@ namespace Game.Collision
|
||||
{
|
||||
Node node = nodes[cell.x][cell.y];
|
||||
if (node != null)
|
||||
node.intersectRay(ray, intersectCallback, ref max_dist);
|
||||
node.IntersectRay(ray, intersectCallback, ref max_dist);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -166,7 +166,7 @@ namespace Game.Collision
|
||||
Node node = nodes[cell.x][cell.y];
|
||||
if (node != null)
|
||||
{
|
||||
node.intersectRay(ray, intersectCallback, ref max_dist);
|
||||
node.IntersectRay(ray, intersectCallback, ref max_dist);
|
||||
}
|
||||
if (cell == last_cell)
|
||||
break;
|
||||
@@ -180,30 +180,30 @@ namespace Game.Collision
|
||||
tMaxY += tDeltaY;
|
||||
cell.y += stepY;
|
||||
}
|
||||
} while (cell.isValid());
|
||||
} while (cell.IsValid());
|
||||
}
|
||||
|
||||
public void intersectPoint(Vector3 point, WorkerCallback intersectCallback)
|
||||
public void IntersectPoint(Vector3 point, WorkerCallback intersectCallback)
|
||||
{
|
||||
Cell cell = Cell.ComputeCell(point.X, point.Y);
|
||||
if (!cell.isValid())
|
||||
if (!cell.IsValid())
|
||||
return;
|
||||
|
||||
Node node = nodes[cell.x][cell.y];
|
||||
if (node != null)
|
||||
node.intersectPoint(point, intersectCallback);
|
||||
node.IntersectPoint(point, intersectCallback);
|
||||
}
|
||||
|
||||
// Optimized verson of intersectRay function for rays with vertical directions
|
||||
public void intersectZAllignedRay(Ray ray, WorkerCallback intersectCallback, ref float max_dist)
|
||||
public void IntersectZAllignedRay(Ray ray, WorkerCallback intersectCallback, ref float max_dist)
|
||||
{
|
||||
Cell cell = Cell.ComputeCell(ray.Origin.X, ray.Origin.Y);
|
||||
if (!cell.isValid())
|
||||
if (!cell.IsValid())
|
||||
return;
|
||||
|
||||
Node node = nodes[cell.x][cell.y];
|
||||
if (node != null)
|
||||
node.intersectRay(ray, intersectCallback, ref max_dist);
|
||||
node.IntersectRay(ray, intersectCallback, ref max_dist);
|
||||
}
|
||||
|
||||
MultiMap<T, Node> memberTable = new MultiMap<T, Node>();
|
||||
|
||||
Reference in New Issue
Block a user