本文整理汇总了C#中ContactResult类的典型用法代码示例。如果您正苦于以下问题:C# ContactResult类的具体用法?C# ContactResult怎么用?C# ContactResult使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
ContactResult类属于命名空间,在下文中一共展示了ContactResult类的10个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: near
//.........这里部分代码省略.........
if (d.GeomGetClass(g1) == d.GeomClassID.HeightfieldClass || d.GeomGetClass(g2) == d.GeomClassID.HeightfieldClass)
return;
// Raytest against AABBs of spaces first, then dig into the spaces it hits for actual geoms.
if (d.GeomIsSpace(g1) || d.GeomIsSpace(g2))
{
if (g1 == IntPtr.Zero || g2 == IntPtr.Zero)
return;
// Separating static prim geometry spaces.
// We'll be calling near recursivly if one
// of them is a space to find all of the
// contact points in the space
try
{
d.SpaceCollide2(g1, g2, IntPtr.Zero, nearCallback);
}
catch (AccessViolationException)
{
m_log.Warn("[PHYSICS]: Unable to collide test a space");
return;
}
//Colliding a space or a geom with a space or a geom. so drill down
//Collide all geoms in each space..
//if (d.GeomIsSpace(g1)) d.SpaceCollide(g1, IntPtr.Zero, nearCallback);
//if (d.GeomIsSpace(g2)) d.SpaceCollide(g2, IntPtr.Zero, nearCallback);
return;
}
if (g1 == IntPtr.Zero || g2 == IntPtr.Zero)
return;
int count = 0;
try
{
if (g1 == g2)
return; // Can't collide with yourself
lock (contacts)
{
count = d.Collide(g1, g2, contacts.GetLength(0), contacts, d.ContactGeom.SizeOf);
}
}
catch (SEHException)
{
m_log.Error("[PHYSICS]: The Operating system shut down ODE because of corrupt memory. This could be a result of really irregular terrain. If this repeats continuously, restart using Basic Physics and terrain fill your terrain. Restarting the sim.");
}
catch (Exception e)
{
m_log.WarnFormat("[PHYSICS]: Unable to collide test an object: {0}", e.Message);
return;
}
PhysicsActor p1 = null;
PhysicsActor p2 = null;
if (g1 != IntPtr.Zero)
m_scene.actor_name_map.TryGetValue(g1, out p1);
if (g2 != IntPtr.Zero)
m_scene.actor_name_map.TryGetValue(g1, out p2);
// Loop over contacts, build results.
for (int i = 0; i < count; i++)
{
if (p1 != null) {
if (p1 is OdePrim)
{
ContactResult collisionresult = new ContactResult();
collisionresult.ConsumerID = ((OdePrim)p1).m_localID;
collisionresult.Pos = new Vector3(contacts[i].pos.X, contacts[i].pos.Y, contacts[i].pos.Z);
collisionresult.Depth = contacts[i].depth;
lock (m_contactResults)
m_contactResults.Add(collisionresult);
}
}
if (p2 != null)
{
if (p2 is OdePrim)
{
ContactResult collisionresult = new ContactResult();
collisionresult.ConsumerID = ((OdePrim)p2).m_localID;
collisionresult.Pos = new Vector3(contacts[i].pos.X, contacts[i].pos.Y, contacts[i].pos.Z);
collisionresult.Depth = contacts[i].depth;
lock (m_contactResults)
m_contactResults.Add(collisionresult);
}
}
}
}
示例2: llCastRay
public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
{
m_host.AddScriptLPS(1);
Vector3 dir = new Vector3((float)(end-start).x, (float)(end-start).y, (float)(end-start).z);
Vector3 startvector = new Vector3((float)start.x, (float)start.y, (float)start.z);
Vector3 endvector = new Vector3((float)end.x, (float)end.y, (float)end.z);
int count = 0;
// int detectPhantom = 0;
int dataFlags = 0;
int rejectTypes = 0;
for (int i = 0; i < options.Length; i += 2)
{
if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS)
{
count = options.GetLSLIntegerItem(i + 1);
}
// else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM)
// {
// detectPhantom = options.GetLSLIntegerItem(i + 1);
// }
else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS)
{
dataFlags = options.GetLSLIntegerItem(i + 1);
}
else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES)
{
rejectTypes = options.GetLSLIntegerItem(i + 1);
}
}
LSL_List list = new LSL_List();
List<ContactResult> results = World.PhysicsScene.RaycastWorld(startvector, dir, dir.Length(), count);
double distance = Util.GetDistanceTo(startvector, endvector);
if (distance == 0)
distance = 0.001;
Vector3 posToCheck = startvector;
ITerrainChannel channel = World.RequestModuleInterface<ITerrainChannel>();
bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND);
bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS);
bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL);
bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
for (float i = 0; i <= distance; i += 0.1f)
{
posToCheck = startvector + (dir * (i / (float)distance));
if (checkTerrain && channel[(int)(posToCheck.X + startvector.X), (int)(posToCheck.Y + startvector.Y)] < posToCheck.Z)
{
ContactResult result = new ContactResult();
result.ConsumerID = 0;
result.Depth = 0;
result.Normal = Vector3.Zero;
result.Pos = posToCheck;
results.Add(result);
checkTerrain = false;
}
if (checkAgents)
{
World.ForEachRootScenePresence(delegate(ScenePresence sp)
{
if (sp.AbsolutePosition.ApproxEquals(posToCheck, sp.PhysicsActor.Size.X))
{
ContactResult result = new ContactResult ();
result.ConsumerID = sp.LocalId;
result.Depth = 0;
result.Normal = Vector3.Zero;
result.Pos = posToCheck;
results.Add(result);
}
});
}
}
int refcount = 0;
foreach (ContactResult result in results)
{
if ((rejectTypes & ScriptBaseClass.RC_REJECT_LAND)
== ScriptBaseClass.RC_REJECT_LAND && result.ConsumerID == 0)
continue;
ISceneEntity entity = World.GetSceneObjectPart(result.ConsumerID);
if (entity == null && (rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) != ScriptBaseClass.RC_REJECT_AGENTS)
entity = World.GetScenePresence(result.ConsumerID); //Only check if we should be looking for agents
if (entity == null)
{
list.Add(UUID.Zero);
if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM)
list.Add(0);
//.........这里部分代码省略.........
示例3: GroundIntersection
private ContactResult? GroundIntersection(Vector3 rayStart, Vector3 rayEnd)
{
double[,] heightfield = World.Heightmap.GetDoubles();
List<ContactResult> contacts = new List<ContactResult>();
double min = 2048.0;
double max = 0.0;
// Find the min and max of the heightfield
for (int x = 0 ; x < World.Heightmap.Width ; x++)
{
for (int y = 0 ; y < World.Heightmap.Height ; y++)
{
if (heightfield[x, y] > max)
max = heightfield[x, y];
if (heightfield[x, y] < min)
min = heightfield[x, y];
}
}
// A ray extends past rayEnd, but doesn't go back before
// rayStart. If the start is above the highest point of the ground
// and the ray goes up, we can't hit the ground. Ever.
if (rayStart.Z > max && rayEnd.Z >= rayStart.Z)
return null;
// Same for going down
if (rayStart.Z < min && rayEnd.Z <= rayStart.Z)
return null;
List<Tri> trilist = new List<Tri>();
// Create our triangle list
for (int x = 1 ; x < World.Heightmap.Width ; x++)
{
for (int y = 1 ; y < World.Heightmap.Height ; y++)
{
Tri t1 = new Tri();
Tri t2 = new Tri();
Vector3 p1 = new Vector3(x-1, y-1, (float)heightfield[x-1, y-1]);
Vector3 p2 = new Vector3(x, y-1, (float)heightfield[x, y-1]);
Vector3 p3 = new Vector3(x, y, (float)heightfield[x, y]);
Vector3 p4 = new Vector3(x-1, y, (float)heightfield[x-1, y]);
t1.p1 = p1;
t1.p2 = p2;
t1.p3 = p3;
t2.p1 = p3;
t2.p2 = p4;
t2.p3 = p1;
trilist.Add(t1);
trilist.Add(t2);
}
}
// Ray direction
Vector3 rayDirection = rayEnd - rayStart;
foreach (Tri t in trilist)
{
// Compute triangle plane normal and edges
Vector3 u = t.p2 - t.p1;
Vector3 v = t.p3 - t.p1;
Vector3 n = Vector3.Cross(u, v);
if (n == Vector3.Zero)
continue;
Vector3 w0 = rayStart - t.p1;
double a = -Vector3.Dot(n, w0);
double b = Vector3.Dot(n, rayDirection);
// Not intersecting the plane, or in plane (same thing)
// Ignoring this MAY cause the ground to not be detected
// sometimes
if (Math.Abs(b) < 0.000001)
continue;
double r = a / b;
// ray points away from plane
if (r < 0.0)
continue;
Vector3 ip = rayStart + Vector3.Multiply(rayDirection, (float)r);
float uu = Vector3.Dot(u, u);
float uv = Vector3.Dot(u, v);
float vv = Vector3.Dot(v, v);
Vector3 w = ip - t.p1;
float wu = Vector3.Dot(w, u);
float wv = Vector3.Dot(w, v);
float d = uv * uv - uu * vv;
float cs = (uv * wv - vv * wu) / d;
if (cs < 0 || cs > 1.0)
//.........这里部分代码省略.........
示例4: RaycastWorld
public override List<ContactResult> RaycastWorld(Vector3 position, Vector3 direction, float length, int Count)
{
ContactResult[] ourResults = null;
RayCallback retMethod = delegate(List<ContactResult> results)
{
ourResults = new ContactResult[results.Count];
results.CopyTo(ourResults, 0);
};
int waitTime = 0;
m_rayCastManager.QueueRequest(position, direction, length, Count, retMethod);
while (ourResults == null && waitTime < 1000)
{
Thread.Sleep(1);
waitTime++;
}
if (ourResults == null)
return new List<ContactResult>();
return new List<ContactResult>(ourResults);
}
示例5: AvatarIntersection
private ContactResult[] AvatarIntersection(Vector3 rayStart, Vector3 rayEnd)
{
List<ContactResult> contacts = new List<ContactResult>();
Vector3 ab = rayEnd - rayStart;
World.ForEachScenePresence(delegate(ScenePresence sp)
{
Vector3 ac = sp.AbsolutePosition - rayStart;
// Vector3 bc = sp.AbsolutePosition - rayEnd;
double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
if (d > 1.5)
return;
double d2 = Vector3.Dot(Vector3.Negate(ab), ac);
if (d2 > 0)
return;
double dp = Math.Sqrt(Vector3.Mag(ac) * Vector3.Mag(ac) - d * d);
Vector3 p = rayStart + Vector3.Divide(Vector3.Multiply(ab, (float)dp), (float)Vector3.Mag(ab));
if (!InBoundingBox(sp, p))
return;
ContactResult result = new ContactResult ();
result.ConsumerID = sp.LocalId;
result.Depth = Vector3.Distance(rayStart, p);
result.Normal = Vector3.Zero;
result.Pos = p;
contacts.Add(result);
});
return contacts.ToArray();
}
示例6: ObjectIntersection
private ContactResult[] ObjectIntersection(Vector3 rayStart, Vector3 rayEnd, bool includePhysical, bool includeNonPhysical, bool includePhantom)
{
Ray ray = new Ray(rayStart, Vector3.Normalize(rayEnd - rayStart));
List<ContactResult> contacts = new List<ContactResult>();
Vector3 ab = rayEnd - rayStart;
World.ForEachSOG(delegate(SceneObjectGroup group)
{
if (m_host.ParentGroup == group)
return;
if (group.IsAttachment)
return;
if (group.RootPart.PhysActor == null)
{
if (!includePhantom)
return;
}
else
{
if (group.RootPart.PhysActor.IsPhysical)
{
if (!includePhysical)
return;
}
else
{
if (!includeNonPhysical)
return;
}
}
// Find the radius ouside of which we don't even need to hit test
float minX;
float maxX;
float minY;
float maxY;
float minZ;
float maxZ;
float radius = 0.0f;
group.GetAxisAlignedBoundingBoxRaw(out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
if (Math.Abs(minX) > radius)
radius = Math.Abs(minX);
if (Math.Abs(minY) > radius)
radius = Math.Abs(minY);
if (Math.Abs(minZ) > radius)
radius = Math.Abs(minZ);
if (Math.Abs(maxX) > radius)
radius = Math.Abs(maxX);
if (Math.Abs(maxY) > radius)
radius = Math.Abs(maxY);
if (Math.Abs(maxZ) > radius)
radius = Math.Abs(maxZ);
radius = radius*1.413f;
Vector3 ac = group.AbsolutePosition - rayStart;
// Vector3 bc = group.AbsolutePosition - rayEnd;
double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
// Too far off ray, don't bother
if (d > radius)
return;
// Behind ray, drop
double d2 = Vector3.Dot(Vector3.Negate(ab), ac);
if (d2 > 0)
return;
ray = new Ray(rayStart, Vector3.Normalize(rayEnd - rayStart));
EntityIntersection intersection = group.TestIntersection(ray, true, false);
// Miss.
if (!intersection.HitTF)
return;
Vector3 b1 = group.AbsolutePosition + new Vector3(minX, minY, minZ);
Vector3 b2 = group.AbsolutePosition + new Vector3(maxX, maxY, maxZ);
//m_log.DebugFormat("[LLCASTRAY]: min<{0},{1},{2}>, max<{3},{4},{5}> = hitp<{6},{7},{8}>", b1.X,b1.Y,b1.Z,b2.X,b2.Y,b2.Z,intersection.ipoint.X,intersection.ipoint.Y,intersection.ipoint.Z);
if (!(intersection.ipoint.X >= b1.X && intersection.ipoint.X <= b2.X &&
intersection.ipoint.Y >= b1.Y && intersection.ipoint.Y <= b2.Y &&
intersection.ipoint.Z >= b1.Z && intersection.ipoint.Z <= b2.Z))
return;
ContactResult result = new ContactResult ();
result.ConsumerID = group.LocalId;
result.Depth = intersection.distance;
result.Normal = intersection.normal;
result.Pos = intersection.ipoint;
contacts.Add(result);
});
return contacts.ToArray();
}
示例7: RaycastActor
// don't like this
public override List<ContactResult> RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count)
{
if (actor != null)
{
IntPtr geom;
if (actor is OdePrim)
geom = ((OdePrim)actor).prim_geom;
else if (actor is OdeCharacter)
geom = ((OdePrim)actor).prim_geom;
else
return new List<ContactResult>();
if (geom == IntPtr.Zero)
return new List<ContactResult>();
ContactResult[] ourResults = null;
RayCallback retMethod = delegate(List<ContactResult> results)
{
ourResults = new ContactResult[results.Count];
results.CopyTo(ourResults, 0);
};
int waitTime = 0;
m_rayCastManager.QueueRequest(geom,position, direction, length, Count, retMethod);
while (ourResults == null && waitTime < 1000)
{
Thread.Sleep(1);
waitTime++;
}
if (ourResults == null)
return new List<ContactResult>();
return new List<ContactResult>(ourResults);
}
return new List<ContactResult>();
}
示例8: near
// This is the standard Near. g2 is the ray
private void near(IntPtr space, IntPtr g1, IntPtr g2)
{
//Don't test against heightfield Geom, or you'll be sorry!
// Exclude heightfield geom
if (g1 == IntPtr.Zero || g1 == g2)
return;
if (d.GeomGetClass(g1) == d.GeomClassID.HeightfieldClass)
return;
// Raytest against AABBs of spaces first, then dig into the spaces it hits for actual geoms.
if (d.GeomIsSpace(g1))
{
try
{
d.SpaceCollide2(g1, g2, IntPtr.Zero, nearCallback);
}
catch (Exception e)
{
m_log.WarnFormat("[PHYSICS Ray]: Unable to Space collide test an object: {0}", e.Message);
}
return;
}
int count = 0;
try
{
count = d.CollidePtr(g1, g2, ColisionContactGeomsPerTest, m_scene.ContactgeomsArray, d.ContactGeom.unmanagedSizeOf);
}
catch (SEHException)
{
m_log.Error("[PHYSICS Ray]: The Operating system shut down ODE because of corrupt memory. This could be a result of really irregular terrain. If this repeats continuously, restart using Basic Physics and terrain fill your terrain. Restarting the sim.");
}
catch (Exception e)
{
m_log.WarnFormat("[PHYSICS Ray]: Unable to collide test an object: {0}", e.Message);
return;
}
if (count == 0)
return;
PhysicsActor p1 = null;
if (g1 != IntPtr.Zero)
m_scene.actor_name_map.TryGetValue(g1, out p1);
d.ContactGeom curcontact = new d.ContactGeom();
// Loop over contacts, build results.
for (int i = 0; i < count; i++)
{
if (!GetCurContactGeom(i, ref curcontact))
break;
if (p1 != null) {
if (p1 is OdePrim)
{
ContactResult collisionresult = new ContactResult();
collisionresult.ConsumerID = ((OdePrim)p1).m_localID;
collisionresult.Pos = new Vector3(curcontact.pos.X, curcontact.pos.Y, curcontact.pos.Z);
collisionresult.Depth = curcontact.depth;
collisionresult.Normal = new Vector3(curcontact.normal.X, curcontact.normal.Y,
curcontact.normal.Z);
lock (m_contactResults)
m_contactResults.Add(collisionresult);
}
}
}
}
示例9: llCastRay
public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
{
Vector3 dir = new Vector3((float) (end - start).x, (float) (end - start).y, (float) (end - start).z);
Vector3 startvector = new Vector3((float) start.x, (float) start.y, (float) start.z);
Vector3 endvector = new Vector3((float) end.x, (float) end.y, (float) end.z);
int count = 0;
int detectPhantom = 0;
int dataFlags = 0;
int rejectTypes = 0;
for (int i = 0; i < options.Length; i += 2)
{
if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS)
{
count = options.GetLSLIntegerItem(i + 1);
}
else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM)
{
detectPhantom = options.GetLSLIntegerItem(i + 1);
}
else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS)
{
dataFlags = options.GetLSLIntegerItem(i + 1);
}
else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES)
{
rejectTypes = options.GetLSLIntegerItem(i + 1);
}
}
LSL_List list = new LSL_List();
List<ContactResult> results = World.PhysicsScene.RaycastWorld(startvector, dir, dir.Length(), count);
double distance = Util.GetDistanceTo(startvector, endvector);
if (distance == 0)
distance = 0.001;
Vector3 posToCheck = startvector;
ITerrainChannel channel = World.RequestModuleInterface<ITerrainChannel>();
List<IScenePresence> presences =
new List<IScenePresence>(World.Entities.GetPresences(startvector, (float) distance));
bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND);
bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS);
bool checkNonPhysical =
!((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL);
bool checkPhysical =
!((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
for (float i = 0; i <= distance; i += 0.1f)
{
posToCheck = startvector + (dir*(i/(float) distance));
float groundHeight = channel[(int) (posToCheck.X + startvector.X), (int) (posToCheck.Y + startvector.Y)];
if (checkTerrain && groundHeight > posToCheck.Z)
{
ContactResult result = new ContactResult
{
ConsumerID = 0,
Depth = 0,
Normal = Vector3.Zero,
Pos = posToCheck
};
results.Add(result);
checkTerrain = false;
}
if (checkAgents)
{
for (int presenceCount = 0; presenceCount < presences.Count; presenceCount++)
{
IScenePresence sp = presences[presenceCount];
if (sp.AbsolutePosition.ApproxEquals(posToCheck, sp.PhysicsActor.Size.X))
{
ContactResult result = new ContactResult
{
ConsumerID = sp.LocalId,
Depth = 0,
Normal = Vector3.Zero,
Pos = posToCheck
};
results.Add(result);
presences.RemoveAt(presenceCount);
if (presenceCount > 0)
presenceCount--; //Reset its position since we removed this one
}
}
}
}
int refcount = 0;
List<ContactResult> newResults = new List<ContactResult>();
foreach (ContactResult result in results)
{
foreach (ContactResult r in newResults)
if (r.ConsumerID == result.ConsumerID)
newResults.Add(result);
}
castRaySort(startvector, ref newResults);
foreach (ContactResult result in newResults)
{
if ((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND &&
result.ConsumerID == 0)
continue;
//.........这里部分代码省略.........
示例10: ObjectIntersection
private ContactResult[] ObjectIntersection(Vector3 rayStart, Vector3 rayEnd, bool includePhysical, bool includeNonPhysical, bool includePhantom, int max)
{
List<ContactResult> contacts = World.PhysicsScene.RaycastWorld(rayStart, Vector3.Normalize(rayEnd - rayStart), Vector3.Distance(rayEnd, rayStart), max);
for (int i = 0; i < contacts.Count; i++)
{
ISceneEntity grp = World.GetGroupByPrim(contacts[i].ConsumerID);
if(grp == null || (!includePhysical && grp.RootChild.PhysActor.IsPhysical) ||
(!includeNonPhysical && !grp.RootChild.PhysActor.IsPhysical))
contacts.RemoveAt(i--);
}
if (includePhantom)
{
Ray ray = new Ray(rayStart, Vector3.Normalize(rayEnd - rayStart));
Vector3 ab = rayEnd - rayStart;
ISceneEntity[] objlist = World.Entities.GetEntities();
foreach (ISceneEntity group in objlist)
{
if (m_host.ParentEntity == group)
continue;
if (group.IsAttachment)
continue;
if (group.RootChild.PhysActor != null)
continue;
// Find the radius ouside of which we don't even need to hit test
float minX;
float maxX;
float minY;
float maxY;
float minZ;
float maxZ;
float radius = 0.0f;
group.GetAxisAlignedBoundingBoxRaw(out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
if (Math.Abs(minX) > radius)
radius = Math.Abs(minX);
if (Math.Abs(minY) > radius)
radius = Math.Abs(minY);
if (Math.Abs(minZ) > radius)
radius = Math.Abs(minZ);
if (Math.Abs(maxX) > radius)
radius = Math.Abs(maxX);
if (Math.Abs(maxY) > radius)
radius = Math.Abs(maxY);
if (Math.Abs(maxZ) > radius)
radius = Math.Abs(maxZ);
radius = radius * 1.413f;
Vector3 ac = group.AbsolutePosition - rayStart;
// Vector3 bc = group.AbsolutePosition - rayEnd;
double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
// Too far off ray, don't bother
if (d > radius)
continue;
// Behind ray, drop
double d2 = Vector3.Dot(Vector3.Negate(ab), ac);
if (d2 > 0)
continue;
ray = new Ray(rayStart, Vector3.Normalize(rayEnd - rayStart));
EntityIntersection intersection = group.TestIntersection(ray, true, false);
// Miss.
if (!intersection.HitTF)
continue;
Vector3 b1 = new Vector3(minX, minY, minZ);
Vector3 b2 = new Vector3(maxX, maxY, maxZ);
//m_log.DebugFormat("[LLCASTRAY]: min<{0},{1},{2}>, max<{3},{4},{5}> = hitp<{6},{7},{8}>", b1.X,b1.Y,b1.Z,b2.X,b2.Y,b2.Z,intersection.ipoint.X,intersection.ipoint.Y,intersection.ipoint.Z);
if (!(intersection.ipoint.X >= b1.X && intersection.ipoint.X <= b2.X &&
intersection.ipoint.Y >= b1.Y && intersection.ipoint.Y <= b2.Y &&
intersection.ipoint.Z >= b1.Z && intersection.ipoint.Z <= b2.Z))
continue;
ContactResult result = new ContactResult();
result.ConsumerID = group.LocalId;
result.Depth = intersection.distance;
result.Normal = intersection.normal;
result.Pos = intersection.ipoint;
contacts.Add(result);
}
}
return contacts.ToArray();
}