prevent potencial invalid refs

avinationmerge
UbitUmarov 2013-01-13 12:25:41 +00:00
parent 6e9092421b
commit 2028787c0d
2 changed files with 53 additions and 170 deletions

View File

@ -68,7 +68,6 @@ namespace OpenSim.Region.Physics.OdePlugin
/// ODE near callback delegate /// ODE near callback delegate
/// </summary> /// </summary>
private d.NearCallback nearCallback; private d.NearCallback nearCallback;
private d.NearCallback nearProbeCallback;
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private List<ContactResult> m_contactResults = new List<ContactResult>(); private List<ContactResult> m_contactResults = new List<ContactResult>();
private RayFilterFlags CurrentRayFilter; private RayFilterFlags CurrentRayFilter;
@ -78,7 +77,6 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
m_scene = pScene; m_scene = pScene;
nearCallback = near; nearCallback = near;
nearProbeCallback = nearProbe;
ray = d.CreateRay(IntPtr.Zero, 1.0f); ray = d.CreateRay(IntPtr.Zero, 1.0f);
d.GeomSetCategoryBits(ray, 0); d.GeomSetCategoryBits(ray, 0);
Box = d.CreateBox(IntPtr.Zero, 1.0f, 1.0f, 1.0f); Box = d.CreateBox(IntPtr.Zero, 1.0f, 1.0f, 1.0f);
@ -125,6 +123,24 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
if (req.callbackMethod != null) if (req.callbackMethod != null)
{ {
IntPtr geom = IntPtr.Zero;
if (req.actor != null)
{
if (m_scene.haveActor(req.actor))
{
if (req.actor is OdePrim)
geom = ((OdePrim)req.actor).prim_geom;
else if (req.actor is OdeCharacter)
geom = ((OdePrim)req.actor).prim_geom;
}
if (geom == IntPtr.Zero)
{
NoContacts(req);
continue;
}
}
CurrentRayFilter = req.filter; CurrentRayFilter = req.filter;
CurrentMaxCount = req.Count; CurrentMaxCount = req.Count;
@ -188,7 +204,7 @@ namespace OpenSim.Region.Physics.OdePlugin
CollisionContactGeomsPerTest |= (int)d.CONTACTS_UNIMPORTANT; CollisionContactGeomsPerTest |= (int)d.CONTACTS_UNIMPORTANT;
} }
if (req.geom == IntPtr.Zero) if (geom == IntPtr.Zero)
{ {
// translate ray filter to Collision flags // translate ray filter to Collision flags
catflags = 0; catflags = 0;
@ -226,7 +242,7 @@ namespace OpenSim.Region.Physics.OdePlugin
catflags |= CollisionCategories.Space; catflags |= CollisionCategories.Space;
d.GeomSetCollideBits(Plane, (uint)catflags); d.GeomSetCollideBits(Plane, (uint)catflags);
d.GeomSetCategoryBits(Plane, (uint)catflags); d.GeomSetCategoryBits(Plane, (uint)catflags);
doPlane(req); doPlane(req,IntPtr.Zero);
} }
else else
{ {
@ -242,12 +258,12 @@ namespace OpenSim.Region.Physics.OdePlugin
if (req.callbackMethod is ProbePlaneCallback) if (req.callbackMethod is ProbePlaneCallback)
{ {
d.GeomSetCollideBits(Plane, (uint)CollisionCategories.All); d.GeomSetCollideBits(Plane, (uint)CollisionCategories.All);
doPlane(req); doPlane(req,geom);
} }
else else
{ {
d.GeomSetCollideBits(ray, (uint)CollisionCategories.All); d.GeomSetCollideBits(ray, (uint)CollisionCategories.All);
doGeomRay(req); doGeomRay(req,geom);
} }
} }
} }
@ -267,6 +283,23 @@ namespace OpenSim.Region.Physics.OdePlugin
/// <param name="req"></param> /// <param name="req"></param>
/// ///
private void NoContacts(ODERayRequest req)
{
if (req.callbackMethod is RaycastCallback)
{
((RaycastCallback)req.callbackMethod)(false, Vector3.Zero, 0, 0, Vector3.Zero);
return;
}
List<ContactResult> cresult = new List<ContactResult>();
if (req.callbackMethod is RayCallback)
((RayCallback)req.callbackMethod)(cresult);
else if (req.callbackMethod is ProbeBoxCallback)
((ProbeBoxCallback)req.callbackMethod)(cresult);
else if (req.callbackMethod is ProbeSphereCallback)
((ProbeSphereCallback)req.callbackMethod)(cresult);
}
private const RayFilterFlags FilterActiveSpace = RayFilterFlags.agent | RayFilterFlags.physical | RayFilterFlags.LSLPhanton; private const RayFilterFlags FilterActiveSpace = RayFilterFlags.agent | RayFilterFlags.physical | RayFilterFlags.LSLPhanton;
// private const RayFilterFlags FilterStaticSpace = RayFilterFlags.water | RayFilterFlags.land | RayFilterFlags.nonphysical | RayFilterFlags.LSLPhanton; // private const RayFilterFlags FilterStaticSpace = RayFilterFlags.water | RayFilterFlags.land | RayFilterFlags.nonphysical | RayFilterFlags.LSLPhanton;
private const RayFilterFlags FilterStaticSpace = RayFilterFlags.water | RayFilterFlags.nonphysical | RayFilterFlags.LSLPhanton; private const RayFilterFlags FilterStaticSpace = RayFilterFlags.water | RayFilterFlags.nonphysical | RayFilterFlags.LSLPhanton;
@ -358,10 +391,10 @@ namespace OpenSim.Region.Physics.OdePlugin
((ProbeSphereCallback)req.callbackMethod)(cresult); ((ProbeSphereCallback)req.callbackMethod)(cresult);
} }
private void doPlane(ODERayRequest req) private void doPlane(ODERayRequest req,IntPtr geom)
{ {
// Collide tests // Collide tests
if (req.geom == IntPtr.Zero) if (geom == IntPtr.Zero)
{ {
if ((CurrentRayFilter & FilterActiveSpace) != 0) if ((CurrentRayFilter & FilterActiveSpace) != 0)
{ {
@ -375,7 +408,7 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
else else
{ {
d.SpaceCollide2(Plane, req.geom, IntPtr.Zero, nearCallback); d.SpaceCollide2(Plane, geom, IntPtr.Zero, nearCallback);
} }
List<ContactResult> cresult = new List<ContactResult>(m_contactResults.Count); List<ContactResult> cresult = new List<ContactResult>(m_contactResults.Count);
@ -392,10 +425,10 @@ namespace OpenSim.Region.Physics.OdePlugin
/// Method that actually initiates the raycast with a geom /// Method that actually initiates the raycast with a geom
/// </summary> /// </summary>
/// <param name="req"></param> /// <param name="req"></param>
private void doGeomRay(ODERayRequest req) private void doGeomRay(ODERayRequest req, IntPtr geom)
{ {
// Collide test // Collide test
d.SpaceCollide2(ray, req.geom, IntPtr.Zero, nearCallback); // still do this to have full AABB pre test d.SpaceCollide2(ray, geom, IntPtr.Zero, nearCallback); // still do this to have full AABB pre test
if (req.callbackMethod is RaycastCallback) if (req.callbackMethod is RaycastCallback)
{ {
@ -607,156 +640,6 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
} }
private void nearProbe(IntPtr space, IntPtr g1, IntPtr g2)
{
if (g1 == IntPtr.Zero || g1 == g2)
return;
if (m_contactResults.Count >= CurrentMaxCount)
return;
if (d.GeomIsSpace(g1))
{
try
{
d.SpaceCollide2(g1, g2, IntPtr.Zero, nearProbeCallback);
}
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, CollisionContactGeomsPerTest, m_scene.ContactgeomsArray, d.ContactGeom.unmanagedSizeOf);
}
catch (Exception e)
{
m_log.WarnFormat("[PHYSICS Ray]: Unable to collide test an object: {0}", e.Message);
return;
}
if (count == 0)
return;
uint ID = 0;
PhysicsActor p1 = null;
m_scene.actor_name_map.TryGetValue(g1, out p1);
if (p1 == null)
return;
switch (p1.PhysicsActorType)
{
case (int)ActorTypes.Prim:
RayFilterFlags thisFlags;
if (p1.IsPhysical)
thisFlags = RayFilterFlags.physical;
else
thisFlags = RayFilterFlags.nonphysical;
if (p1.Phantom)
thisFlags |= RayFilterFlags.phantom;
if (p1.IsVolumeDtc)
thisFlags |= RayFilterFlags.volumedtc;
if ((thisFlags & CurrentRayFilter) == 0)
return;
ID = ((OdePrim)p1).LocalID;
break;
case (int)ActorTypes.Agent:
if ((CurrentRayFilter & RayFilterFlags.agent) == 0)
return;
else
ID = ((OdeCharacter)p1).LocalID;
break;
case (int)ActorTypes.Ground:
if ((CurrentRayFilter & RayFilterFlags.land) == 0)
return;
break;
case (int)ActorTypes.Water:
if ((CurrentRayFilter & RayFilterFlags.water) == 0)
return;
break;
default:
break;
}
d.ContactGeom curcontact = new d.ContactGeom();
// closestHit for now only works for meshs, so must do it for others
if ((CurrentRayFilter & RayFilterFlags.ClosestHit) == 0)
{
// Loop all contacts, build results.
for (int i = 0; i < count; i++)
{
if (!GetCurContactGeom(i, ref curcontact))
break;
ContactResult collisionresult = new ContactResult();
collisionresult.ConsumerID = ID;
collisionresult.Pos.X = curcontact.pos.X;
collisionresult.Pos.Y = curcontact.pos.Y;
collisionresult.Pos.Z = curcontact.pos.Z;
collisionresult.Depth = curcontact.depth;
collisionresult.Normal.X = curcontact.normal.X;
collisionresult.Normal.Y = curcontact.normal.Y;
collisionresult.Normal.Z = curcontact.normal.Z;
lock (m_contactResults)
{
m_contactResults.Add(collisionresult);
if (m_contactResults.Count >= CurrentMaxCount)
return;
}
}
}
else
{
// keep only closest contact
ContactResult collisionresult = new ContactResult();
collisionresult.ConsumerID = ID;
collisionresult.Depth = float.MaxValue;
for (int i = 0; i < count; i++)
{
if (!GetCurContactGeom(i, ref curcontact))
break;
if (curcontact.depth < collisionresult.Depth)
{
collisionresult.Pos.X = curcontact.pos.X;
collisionresult.Pos.Y = curcontact.pos.Y;
collisionresult.Pos.Z = curcontact.pos.Z;
collisionresult.Depth = curcontact.depth;
collisionresult.Normal.X = curcontact.normal.X;
collisionresult.Normal.Y = curcontact.normal.Y;
collisionresult.Normal.Z = curcontact.normal.Z;
}
}
if (collisionresult.Depth != float.MaxValue)
{
lock (m_contactResults)
m_contactResults.Add(collisionresult);
}
}
}
/// <summary> /// <summary>
/// Dereference the creator scene so that it can be garbage collected if needed. /// Dereference the creator scene so that it can be garbage collected if needed.
/// </summary> /// </summary>
@ -788,7 +671,7 @@ namespace OpenSim.Region.Physics.OdePlugin
public struct ODERayRequest public struct ODERayRequest
{ {
public IntPtr geom; public PhysicsActor actor;
public Vector3 Origin; public Vector3 Origin;
public Vector3 Normal; public Vector3 Normal;
public int Count; public int Count;

View File

@ -2580,7 +2580,7 @@ namespace OpenSim.Region.Physics.OdePlugin
if (retMethod != null) if (retMethod != null)
{ {
ODERayRequest req = new ODERayRequest(); ODERayRequest req = new ODERayRequest();
req.geom = IntPtr.Zero; req.actor = null;
req.callbackMethod = retMethod; req.callbackMethod = retMethod;
req.length = length; req.length = length;
req.Normal = direction; req.Normal = direction;
@ -2597,7 +2597,7 @@ namespace OpenSim.Region.Physics.OdePlugin
if (retMethod != null) if (retMethod != null)
{ {
ODERayRequest req = new ODERayRequest(); ODERayRequest req = new ODERayRequest();
req.geom = IntPtr.Zero; req.actor = null;
req.callbackMethod = retMethod; req.callbackMethod = retMethod;
req.length = length; req.length = length;
req.Normal = direction; req.Normal = direction;
@ -2625,7 +2625,7 @@ namespace OpenSim.Region.Physics.OdePlugin
}; };
ODERayRequest req = new ODERayRequest(); ODERayRequest req = new ODERayRequest();
req.geom = IntPtr.Zero; req.actor = null;
req.callbackMethod = retMethod; req.callbackMethod = retMethod;
req.length = length; req.length = length;
req.Normal = direction; req.Normal = direction;
@ -2663,7 +2663,7 @@ namespace OpenSim.Region.Physics.OdePlugin
}; };
ODERayRequest req = new ODERayRequest(); ODERayRequest req = new ODERayRequest();
req.geom = IntPtr.Zero; req.actor = null;
req.callbackMethod = retMethod; req.callbackMethod = retMethod;
req.length = length; req.length = length;
req.Normal = direction; req.Normal = direction;
@ -2710,7 +2710,7 @@ namespace OpenSim.Region.Physics.OdePlugin
}; };
ODERayRequest req = new ODERayRequest(); ODERayRequest req = new ODERayRequest();
req.geom = geom; req.actor = actor;
req.callbackMethod = retMethod; req.callbackMethod = retMethod;
req.length = length; req.length = length;
req.Normal = direction; req.Normal = direction;
@ -2745,7 +2745,7 @@ namespace OpenSim.Region.Physics.OdePlugin
}; };
ODERayRequest req = new ODERayRequest(); ODERayRequest req = new ODERayRequest();
req.geom = IntPtr.Zero; req.actor = null;
req.callbackMethod = retMethod; req.callbackMethod = retMethod;
req.Normal = size; req.Normal = size;
req.Origin = position; req.Origin = position;
@ -2777,7 +2777,7 @@ namespace OpenSim.Region.Physics.OdePlugin
}; };
ODERayRequest req = new ODERayRequest(); ODERayRequest req = new ODERayRequest();
req.geom = IntPtr.Zero; req.actor = null;
req.callbackMethod = retMethod; req.callbackMethod = retMethod;
req.length = radius; req.length = radius;
req.Origin = position; req.Origin = position;
@ -2819,7 +2819,7 @@ namespace OpenSim.Region.Physics.OdePlugin
}; };
ODERayRequest req = new ODERayRequest(); ODERayRequest req = new ODERayRequest();
req.geom = geom; req.actor = null;
req.callbackMethod = retMethod; req.callbackMethod = retMethod;
req.length = plane.W; req.length = plane.W;
req.Normal.X = plane.X; req.Normal.X = plane.X;