Core/Battlegrounds: Move to scripts And a lot of misc commits i couldn't recover.
Port From (https://github.com/TrinityCore/TrinityCore/commit/d0d5d309bb5877dc2fcb27f6cb123707a31ec1e8)
This commit is contained in:
@@ -19,7 +19,7 @@ namespace Game.Collision
|
||||
|
||||
void InitEmpty()
|
||||
{
|
||||
tree= new uint[3];
|
||||
tree = new uint[3];
|
||||
objects = Array.Empty<uint>();
|
||||
bounds = AxisAlignedBox.Zero();
|
||||
// create space for the first node
|
||||
@@ -76,7 +76,7 @@ namespace Game.Collision
|
||||
rightOrig = right; // save this for later
|
||||
float nodeL = float.PositiveInfinity;
|
||||
float nodeR = float.NegativeInfinity;
|
||||
for (int i = left; i <= right; )
|
||||
for (int i = left; i <= right;)
|
||||
{
|
||||
int obj = (int)dat.indices[i];
|
||||
float minb = dat.primBound[obj].Lo.GetAt(axis);
|
||||
@@ -306,6 +306,7 @@ namespace Game.Collision
|
||||
}
|
||||
|
||||
public uint PrimCount() { return (uint)objects.Length; }
|
||||
public AxisAlignedBox bound() { return bounds; }
|
||||
|
||||
public void IntersectRay(Ray r, WorkerCallback intersectCallback, ref float maxDist, bool stopAtFirst = false)
|
||||
{
|
||||
@@ -410,7 +411,7 @@ namespace Game.Collision
|
||||
while (n > 0)
|
||||
{
|
||||
bool hit = intersectCallback.Invoke(r, objects[offset], ref maxDist, stopAtFirst);
|
||||
if (stopAtFirst && hit)
|
||||
if (stopAtFirst && hit)
|
||||
return;
|
||||
--n;
|
||||
++offset;
|
||||
|
||||
@@ -40,34 +40,41 @@ namespace Game.Collision
|
||||
|
||||
public class WModelAreaCallback : WorkerCallback
|
||||
{
|
||||
public WModelAreaCallback(List<GroupModel> vals, Vector3 down)
|
||||
List<GroupModel> prims;
|
||||
public GroupModel[] hit = new GroupModel[3];
|
||||
|
||||
public WModelAreaCallback(List<GroupModel> vals)
|
||||
{
|
||||
prims = vals;
|
||||
hit = null;
|
||||
zDist = float.PositiveInfinity;
|
||||
zVec = down;
|
||||
}
|
||||
|
||||
List<GroupModel> prims;
|
||||
public GroupModel hit;
|
||||
public float zDist;
|
||||
Vector3 zVec;
|
||||
public override void Invoke(Vector3 point, uint entry)
|
||||
public override bool Invoke(Ray ray, uint entry, ref float distance, bool stopAtFirstHit)
|
||||
{
|
||||
float group_Z;
|
||||
if (prims[(int)entry].IsInsideObject(point, zVec, out group_Z))
|
||||
GroupModel.InsideResult result = prims[(int)entry].IsInsideObject(ray, out float group_Z);
|
||||
if ( result != GroupModel.InsideResult.OutOfBounds)
|
||||
{
|
||||
if (group_Z < zDist)
|
||||
if (result != GroupModel.InsideResult.MaybeInside)
|
||||
{
|
||||
zDist = group_Z;
|
||||
hit = prims[(int)entry];
|
||||
if (group_Z < distance)
|
||||
{
|
||||
distance = group_Z;
|
||||
hit[(int)result] = prims[(int)entry];
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
hit[(int)result] = prims[(int)entry];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public class WModelRayCallBack : WorkerCallback
|
||||
{
|
||||
List<GroupModel> models;
|
||||
public bool hit;
|
||||
|
||||
public WModelRayCallBack(List<GroupModel> mod)
|
||||
{
|
||||
models = mod;
|
||||
@@ -79,8 +86,6 @@ namespace Game.Collision
|
||||
if (result) hit = true;
|
||||
return hit;
|
||||
}
|
||||
List<GroupModel> models;
|
||||
public bool hit;
|
||||
}
|
||||
|
||||
public class GModelRayCallback : WorkerCallback
|
||||
|
||||
@@ -251,19 +251,56 @@ namespace Game.Collision
|
||||
return callback.hit;
|
||||
}
|
||||
|
||||
public bool IsInsideObject(Vector3 pos, Vector3 down, out float z_dist)
|
||||
bool IsInsideOrAboveBound(AxisAlignedBox bounds, Vector3 point)
|
||||
{
|
||||
z_dist = 0f;
|
||||
if (triangles.Empty() || !iBound.contains(pos))
|
||||
return false;
|
||||
return point.X >= bounds.Lo.X
|
||||
&& point.Y >= bounds.Lo.Y
|
||||
&& point.Z >= bounds.Lo.Z
|
||||
&& point.X <= bounds.Hi.X
|
||||
&& point.Y <= bounds.Hi.Y;
|
||||
}
|
||||
|
||||
Vector3 rPos = pos - 0.1f * down;
|
||||
float dist = float.PositiveInfinity;
|
||||
Ray ray = new(rPos, down);
|
||||
bool hit = IntersectRay(ray, ref dist, false);
|
||||
if (hit)
|
||||
z_dist = dist - 0.1f;
|
||||
return hit;
|
||||
public enum InsideResult
|
||||
{
|
||||
Inside = 0,
|
||||
MaybeInside = 1,
|
||||
Above = 2,
|
||||
OutOfBounds = -1
|
||||
}
|
||||
|
||||
public InsideResult IsInsideObject(Ray ray, out float z_dist)
|
||||
{
|
||||
z_dist = 0;
|
||||
|
||||
if (triangles.Empty() || !IsInsideOrAboveBound(iBound, ray.Origin))
|
||||
return InsideResult.OutOfBounds;
|
||||
|
||||
if (meshTree.bound().Hi.Z >= ray.Origin.Z)
|
||||
{
|
||||
float dist = float.PositiveInfinity;
|
||||
if (IntersectRay(ray, ref dist, false))
|
||||
{
|
||||
z_dist = dist - 0.1f;
|
||||
return InsideResult.Inside;
|
||||
}
|
||||
if (meshTree.bound().contains(ray.Origin))
|
||||
return InsideResult.MaybeInside;
|
||||
}
|
||||
else
|
||||
{
|
||||
// some group models don't have any floor to intersect with
|
||||
// so we should attempt to intersect with a model part below this group
|
||||
// then find back where we originated from (in WorldModel::GetLocationInfo)
|
||||
float dist = float.PositiveInfinity;
|
||||
float delta = ray.Origin.Z - meshTree.bound().Hi.Z;
|
||||
if (IntersectRay(ray.bumpedRay(delta), ref dist, false))
|
||||
{
|
||||
z_dist = dist - 0.1f + delta;
|
||||
return InsideResult.Above;
|
||||
}
|
||||
}
|
||||
|
||||
return InsideResult.OutOfBounds;
|
||||
}
|
||||
|
||||
public bool GetLiquidLevel(Vector3 pos, out float liqHeight)
|
||||
@@ -321,13 +358,26 @@ namespace Game.Collision
|
||||
if (groupModels.Empty())
|
||||
return false;
|
||||
|
||||
WModelAreaCallback callback = new(groupModels, down);
|
||||
groupTree.IntersectPoint(p, callback);
|
||||
if (callback.hit != null)
|
||||
WModelAreaCallback callback = new(groupModels);
|
||||
Ray r = new(p - down * 0.1f, down);
|
||||
float zDist = groupTree.bound().extent().Length();
|
||||
groupTree.IntersectRay(r, callback, ref zDist, false);
|
||||
if (callback.hit[(int)GroupModel.InsideResult.Inside] != null)
|
||||
{
|
||||
info.rootId = (int)RootWMOID;
|
||||
info.hitModel = callback.hit;
|
||||
dist = callback.zDist;
|
||||
info.hitModel = callback.hit[(int)GroupModel.InsideResult.Inside];
|
||||
dist = zDist;
|
||||
return true;
|
||||
}
|
||||
|
||||
// some group models don't have any floor to intersect with
|
||||
// so we should attempt to intersect with a model part below the group `p` is in (stored in GroupModel::ABOVE)
|
||||
// then find back where we originated from (GroupModel::MAYBE_INSIDE)
|
||||
if (callback.hit[(int)GroupModel.InsideResult.MaybeInside] != null && callback.hit[(int)GroupModel.InsideResult.Above] != null)
|
||||
{
|
||||
info.rootId = (int)RootWMOID;
|
||||
info.hitModel = callback.hit[(int)GroupModel.InsideResult.MaybeInside];
|
||||
dist = zDist;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user