Core/BattlePets: Add battle pets to pet journal when learning related spells
This commit is contained in:
@@ -41,281 +41,6 @@ namespace Game.Collision
|
|||||||
tree.Add(0);
|
tree.Add(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void build<T>(List<T> primitives, uint leafSize = 3, bool printStats = false) where T : IModel
|
|
||||||
{
|
|
||||||
if (primitives.Count == 0)
|
|
||||||
{
|
|
||||||
init_empty();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
buildData dat;
|
|
||||||
dat.maxPrims = (int)leafSize;
|
|
||||||
dat.numPrims = (uint)primitives.Count;
|
|
||||||
dat.indices = new uint[dat.numPrims];
|
|
||||||
dat.primBound = new AxisAlignedBox[dat.numPrims];
|
|
||||||
bounds = primitives[0].getBounds();
|
|
||||||
for (int i = 0; i < dat.numPrims; ++i)
|
|
||||||
{
|
|
||||||
dat.indices[i] = (uint)i;
|
|
||||||
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);
|
|
||||||
if (printStats)
|
|
||||||
stats.printStats();
|
|
||||||
|
|
||||||
for (int i = 0; i < dat.numPrims; ++i)
|
|
||||||
objects.Add(dat.indices[i]);
|
|
||||||
tree = tempTree;
|
|
||||||
}
|
|
||||||
public uint primCount() { return (uint)objects.Count; }
|
|
||||||
|
|
||||||
public bool readFromFile(BinaryReader reader)
|
|
||||||
{
|
|
||||||
var lo = reader.ReadStruct<Vector3>();
|
|
||||||
var hi = reader.ReadStruct<Vector3>();
|
|
||||||
bounds = new AxisAlignedBox(lo, hi);
|
|
||||||
|
|
||||||
uint treeSize = reader.ReadUInt32();
|
|
||||||
tree.Clear();
|
|
||||||
for (var i = 0; i < treeSize; i++)
|
|
||||||
tree.Add(reader.ReadUInt32());
|
|
||||||
|
|
||||||
var count = reader.ReadUInt32();
|
|
||||||
objects.Clear();
|
|
||||||
for (var i = 0; i < count; i++)
|
|
||||||
objects.Add(reader.ReadUInt32());
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void intersectRay(Ray r, WorkerCallback intersectCallback, ref float maxDist, bool stopAtFirst = false)
|
|
||||||
{
|
|
||||||
float intervalMin = -1.0f;
|
|
||||||
float intervalMax = -1.0f;
|
|
||||||
Vector3 org = r.Origin;
|
|
||||||
Vector3 dir = r.Direction;
|
|
||||||
Vector3 invDir = new Vector3();
|
|
||||||
for (int i = 0; i < 3; ++i)
|
|
||||||
{
|
|
||||||
invDir[i] = 1.0f / dir[i];
|
|
||||||
if (MathFunctions.fuzzyNe(dir[i], 0.0f))
|
|
||||||
{
|
|
||||||
float t1 = (bounds.Lo[i] - org[i]) * invDir[i];
|
|
||||||
float t2 = (bounds.Hi[i] - org[i]) * invDir[i];
|
|
||||||
if (t1 > t2)
|
|
||||||
MathFunctions.Swap<float>(ref t1, ref t2);
|
|
||||||
if (t1 > intervalMin)
|
|
||||||
intervalMin = t1;
|
|
||||||
if (t2 < intervalMax || intervalMax < 0.0f)
|
|
||||||
intervalMax = t2;
|
|
||||||
// intervalMax can only become smaller for other axis,
|
|
||||||
// and intervalMin only larger respectively, so stop early
|
|
||||||
if (intervalMax <= 0 || intervalMin >= maxDist)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (intervalMin > intervalMax)
|
|
||||||
return;
|
|
||||||
intervalMin = Math.Max(intervalMin, 0.0f);
|
|
||||||
intervalMax = Math.Min(intervalMax, maxDist);
|
|
||||||
|
|
||||||
uint[] offsetFront = new uint[3];
|
|
||||||
uint[] offsetBack = new uint[3];
|
|
||||||
uint[] offsetFront3 = new uint[3];
|
|
||||||
uint[] offsetBack3 = new uint[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 = new StackNode[64];
|
|
||||||
int stackPos = 0;
|
|
||||||
int node = 0;
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
uint tn = tree[node];
|
|
||||||
uint axis = (uint)(tn & (3 << 30)) >> 30;
|
|
||||||
bool BVH2 = Convert.ToBoolean(tn & (1 << 29));
|
|
||||||
int offset = (int)(tn & ~(7 << 29));
|
|
||||||
if (!BVH2)
|
|
||||||
{
|
|
||||||
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];
|
|
||||||
// ray passes between clip zones
|
|
||||||
if (tf < intervalMin && tb > intervalMax)
|
|
||||||
break;
|
|
||||||
int back = (int)(offset + offsetBack3[axis]);
|
|
||||||
node = back;
|
|
||||||
// ray passes through far node only
|
|
||||||
if (tf < intervalMin)
|
|
||||||
{
|
|
||||||
intervalMin = (tb >= intervalMin) ? tb : intervalMin;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
node = offset + (int)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 = (uint)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 = (int)tree[node + 1];
|
|
||||||
while (n > 0)
|
|
||||||
{
|
|
||||||
bool hit = intersectCallback.Invoke(r, objects[offset], ref maxDist, stopAtFirst);
|
|
||||||
if (stopAtFirst && hit)
|
|
||||||
return;
|
|
||||||
--n;
|
|
||||||
++offset;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
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];
|
|
||||||
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 = (int)stack[stackPos].node;
|
|
||||||
intervalMax = stack[stackPos].tfar;
|
|
||||||
break;
|
|
||||||
} while (true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void intersectPoint(Vector3 p, WorkerCallback intersectCallback)
|
|
||||||
{
|
|
||||||
if (!bounds.contains(p))
|
|
||||||
return;
|
|
||||||
|
|
||||||
StackNode[] stack = new StackNode[64];
|
|
||||||
int stackPos = 0;
|
|
||||||
int node = 0;
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
uint tn = tree[node];
|
|
||||||
uint axis = (uint)(tn & (3 << 30)) >> 30;
|
|
||||||
bool BVH2 = Convert.ToBoolean(tn & (1 << 29));
|
|
||||||
int offset = (int)(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[(int)axis] && tr > p[axis])
|
|
||||||
break;
|
|
||||||
int right = offset + 3;
|
|
||||||
node = right;
|
|
||||||
// point is in right node only
|
|
||||||
if (tl < p[(int)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 = (uint)right;
|
|
||||||
stackPos++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// leaf - test some objects
|
|
||||||
uint n = tree[node + 1];
|
|
||||||
while (n > 0)
|
|
||||||
{
|
|
||||||
intersectCallback.Invoke(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 = (int)stack[stackPos].node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void buildHierarchy(List<uint> tempTree, buildData dat, BuildStats stats)
|
void buildHierarchy(List<uint> tempTree, buildData dat, BuildStats stats)
|
||||||
{
|
{
|
||||||
// create space for the first node
|
// create space for the first node
|
||||||
@@ -546,6 +271,280 @@ namespace Game.Collision
|
|||||||
stats.updateLeaf(depth + 1, 0);
|
stats.updateLeaf(depth + 1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool readFromFile(BinaryReader reader)
|
||||||
|
{
|
||||||
|
var lo = reader.ReadStruct<Vector3>();
|
||||||
|
var hi = reader.ReadStruct<Vector3>();
|
||||||
|
bounds = new AxisAlignedBox(lo, hi);
|
||||||
|
|
||||||
|
uint treeSize = reader.ReadUInt32();
|
||||||
|
tree.Clear();
|
||||||
|
for (var i = 0; i < treeSize; i++)
|
||||||
|
tree.Add(reader.ReadUInt32());
|
||||||
|
|
||||||
|
var count = reader.ReadUInt32();
|
||||||
|
objects.Clear();
|
||||||
|
for (var i = 0; i < count; i++)
|
||||||
|
objects.Add(reader.ReadUInt32());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void build<T>(List<T> primitives, uint leafSize = 3, bool printStats = false) where T : IModel
|
||||||
|
{
|
||||||
|
if (primitives.Count == 0)
|
||||||
|
{
|
||||||
|
init_empty();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
buildData dat;
|
||||||
|
dat.maxPrims = (int)leafSize;
|
||||||
|
dat.numPrims = (uint)primitives.Count;
|
||||||
|
dat.indices = new uint[dat.numPrims];
|
||||||
|
dat.primBound = new AxisAlignedBox[dat.numPrims];
|
||||||
|
bounds = primitives[0].getBounds();
|
||||||
|
for (int i = 0; i < dat.numPrims; ++i)
|
||||||
|
{
|
||||||
|
dat.indices[i] = (uint)i;
|
||||||
|
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);
|
||||||
|
|
||||||
|
for (int i = 0; i < dat.numPrims; ++i)
|
||||||
|
objects.Add(dat.indices[i]);
|
||||||
|
tree = tempTree;
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint primCount() { return (uint)objects.Count; }
|
||||||
|
|
||||||
|
public void intersectRay(Ray r, WorkerCallback intersectCallback, ref float maxDist, bool stopAtFirst = false)
|
||||||
|
{
|
||||||
|
float intervalMin = -1.0f;
|
||||||
|
float intervalMax = -1.0f;
|
||||||
|
Vector3 org = r.Origin;
|
||||||
|
Vector3 dir = r.Direction;
|
||||||
|
Vector3 invDir = new Vector3();
|
||||||
|
for (int i = 0; i < 3; ++i)
|
||||||
|
{
|
||||||
|
invDir[i] = 1.0f / dir[i];
|
||||||
|
if (MathFunctions.fuzzyNe(dir[i], 0.0f))
|
||||||
|
{
|
||||||
|
float t1 = (bounds.Lo[i] - org[i]) * invDir[i];
|
||||||
|
float t2 = (bounds.Hi[i] - org[i]) * invDir[i];
|
||||||
|
if (t1 > t2)
|
||||||
|
MathFunctions.Swap<float>(ref t1, ref t2);
|
||||||
|
if (t1 > intervalMin)
|
||||||
|
intervalMin = t1;
|
||||||
|
if (t2 < intervalMax || intervalMax < 0.0f)
|
||||||
|
intervalMax = t2;
|
||||||
|
// intervalMax can only become smaller for other axis,
|
||||||
|
// and intervalMin only larger respectively, so stop early
|
||||||
|
if (intervalMax <= 0 || intervalMin >= maxDist)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (intervalMin > intervalMax)
|
||||||
|
return;
|
||||||
|
intervalMin = Math.Max(intervalMin, 0.0f);
|
||||||
|
intervalMax = Math.Min(intervalMax, maxDist);
|
||||||
|
|
||||||
|
uint[] offsetFront = new uint[3];
|
||||||
|
uint[] offsetBack = new uint[3];
|
||||||
|
uint[] offsetFront3 = new uint[3];
|
||||||
|
uint[] offsetBack3 = new uint[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 = new StackNode[64];
|
||||||
|
int stackPos = 0;
|
||||||
|
int node = 0;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
uint tn = tree[node];
|
||||||
|
uint axis = (uint)(tn & (3 << 30)) >> 30;
|
||||||
|
bool BVH2 = Convert.ToBoolean(tn & (1 << 29));
|
||||||
|
int offset = (int)(tn & ~(7 << 29));
|
||||||
|
if (!BVH2)
|
||||||
|
{
|
||||||
|
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];
|
||||||
|
// ray passes between clip zones
|
||||||
|
if (tf < intervalMin && tb > intervalMax)
|
||||||
|
break;
|
||||||
|
int back = (int)(offset + offsetBack3[axis]);
|
||||||
|
node = back;
|
||||||
|
// ray passes through far node only
|
||||||
|
if (tf < intervalMin)
|
||||||
|
{
|
||||||
|
intervalMin = (tb >= intervalMin) ? tb : intervalMin;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
node = offset + (int)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 = (uint)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 = (int)tree[node + 1];
|
||||||
|
while (n > 0)
|
||||||
|
{
|
||||||
|
bool hit = intersectCallback.Invoke(r, objects[offset], ref maxDist, stopAtFirst);
|
||||||
|
if (stopAtFirst && hit)
|
||||||
|
return;
|
||||||
|
--n;
|
||||||
|
++offset;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
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];
|
||||||
|
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 = (int)stack[stackPos].node;
|
||||||
|
intervalMax = stack[stackPos].tfar;
|
||||||
|
break;
|
||||||
|
} while (true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void intersectPoint(Vector3 p, WorkerCallback intersectCallback)
|
||||||
|
{
|
||||||
|
if (!bounds.contains(p))
|
||||||
|
return;
|
||||||
|
|
||||||
|
StackNode[] stack = new StackNode[64];
|
||||||
|
int stackPos = 0;
|
||||||
|
int node = 0;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
uint tn = tree[node];
|
||||||
|
uint axis = (uint)(tn & (3 << 30)) >> 30;
|
||||||
|
bool BVH2 = Convert.ToBoolean(tn & (1 << 29));
|
||||||
|
int offset = (int)(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[(int)axis] && tr > p[axis])
|
||||||
|
break;
|
||||||
|
int right = offset + 3;
|
||||||
|
node = right;
|
||||||
|
// point is in right node only
|
||||||
|
if (tl < p[(int)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 = (uint)right;
|
||||||
|
stackPos++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// leaf - test some objects
|
||||||
|
uint n = tree[node + 1];
|
||||||
|
while (n > 0)
|
||||||
|
{
|
||||||
|
intersectCallback.Invoke(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 = (int)stack[stackPos].node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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
|
// write leaf node
|
||||||
@@ -597,8 +596,18 @@ namespace Game.Collision
|
|||||||
|
|
||||||
public void updateInner() { numNodes++; }
|
public void updateInner() { numNodes++; }
|
||||||
public void updateBVH2() { numBVH2++; }
|
public void updateBVH2() { numBVH2++; }
|
||||||
public void updateLeaf(int depth, int n) { }
|
public void updateLeaf(int depth, int n)
|
||||||
public void printStats() { }
|
{
|
||||||
|
numLeaves++;
|
||||||
|
minDepth = Math.Min(depth, minDepth);
|
||||||
|
maxDepth = Math.Max(depth, maxDepth);
|
||||||
|
sumDepth += depth;
|
||||||
|
minObjects = Math.Min(n, minObjects);
|
||||||
|
maxObjects = Math.Max(n, maxObjects);
|
||||||
|
sumObjects += n;
|
||||||
|
int nl = Math.Min(n, 5);
|
||||||
|
++numLeavesN[nl];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ using Game.Network.Packets;
|
|||||||
using Game.Spells;
|
using Game.Spells;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Game.BattlePets;
|
||||||
|
|
||||||
namespace Game.Entities
|
namespace Game.Entities
|
||||||
{
|
{
|
||||||
@@ -2520,6 +2521,17 @@ namespace Game.Entities
|
|||||||
if (Global.DB2Mgr.GetMount(spellId) != null)
|
if (Global.DB2Mgr.GetMount(spellId) != null)
|
||||||
GetSession().GetCollectionMgr().AddMount(spellId, MountStatusFlags.None, false, IsInWorld ? false : true);
|
GetSession().GetCollectionMgr().AddMount(spellId, MountStatusFlags.None, false, IsInWorld ? false : true);
|
||||||
|
|
||||||
|
// need to add Battle pets automatically into pet journal
|
||||||
|
foreach (BattlePetSpeciesRecord entry in CliDB.BattlePetSpeciesStorage.Values)
|
||||||
|
{
|
||||||
|
if (entry.SummonSpellID == spellId && GetSession().GetBattlePetMgr().GetPetCount(entry.Id) == 0)
|
||||||
|
{
|
||||||
|
GetSession().GetBattlePetMgr().AddPet(entry.Id, entry.CreatureID, BattlePetMgr.RollPetBreed(entry.Id), BattlePetMgr.GetDefaultPetQuality(entry.Id));
|
||||||
|
UpdateCriteria(CriteriaTypes.OwnBattlePetCount);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// return true (for send learn packet) only if spell active (in case ranked spells) and not replace old spell
|
// return true (for send learn packet) only if spell active (in case ranked spells) and not replace old spell
|
||||||
return active && !disabled && !superceded_old;
|
return active && !disabled && !superceded_old;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user