diff --git a/OpenSim/Region/PhysicsModules/ubOde/ODEApi.cs b/OpenSim/Region/PhysicsModules/ubOde/ODEApi.cs index acb5203155..554b251eae 100644 --- a/OpenSim/Region/PhysicsModules/ubOde/ODEApi.cs +++ b/OpenSim/Region/PhysicsModules/ubOde/ODEApi.cs @@ -261,20 +261,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde internal static readonly int unmanagedSizeOf = Marshal.SizeOf(typeof(ContactGeom)); } - [StructLayout(LayoutKind.Sequential)] - internal class ContactGeomClass - { - - internal Vector3 pos; - internal Vector3 normal; - internal dReal depth; - internal IntPtr g1; - internal IntPtr g2; - internal int side1; - internal int side2; - internal static readonly int unmanagedSizeOf = Marshal.SizeOf(typeof(ContactGeomClass)); - } - /* [StructLayout(LayoutKind.Sequential)] internal struct GeomClass diff --git a/OpenSim/Region/PhysicsModules/ubOde/ODECharacter.cs b/OpenSim/Region/PhysicsModules/ubOde/ODECharacter.cs index d76d782c89..e556e5a758 100644 --- a/OpenSim/Region/PhysicsModules/ubOde/ODECharacter.cs +++ b/OpenSim/Region/PhysicsModules/ubOde/ODECharacter.cs @@ -1059,8 +1059,8 @@ namespace OpenSim.Region.PhysicsModule.ubOde } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal bool Collide(IntPtr me, IntPtr other, bool reverse, ref SafeNativeMethods.ContactGeomClass contact, - ref SafeNativeMethods.ContactGeomClass altContact, ref bool useAltcontact, ref bool feetcollision) + internal bool Collide(IntPtr me, IntPtr other, bool reverse, ref SafeNativeMethods.ContactGeom contact, + ref SafeNativeMethods.ContactGeom altContact, ref bool useAltcontact, ref bool feetcollision) { feetcollision = false; useAltcontact = false; @@ -2314,9 +2314,10 @@ namespace OpenSim.Region.PhysicsModule.ubOde return false; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AddChange(changes what, object arg) { - m_parent_scene.AddChange((PhysicsActor)this, what, arg); + m_parent_scene.AddChange(this, what, arg); } private struct strAvatarSize diff --git a/OpenSim/Region/PhysicsModules/ubOde/ODEPrim.cs b/OpenSim/Region/PhysicsModules/ubOde/ODEPrim.cs index 3b710e1537..3764a2059e 100644 --- a/OpenSim/Region/PhysicsModules/ubOde/ODEPrim.cs +++ b/OpenSim/Region/PhysicsModules/ubOde/ODEPrim.cs @@ -4246,7 +4246,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AddChange(changes what, object arg) { - m_parentScene.AddChange((PhysicsActor) this, what, arg); + m_parentScene.AddChange(this, what, arg); } private struct strVehicleBoolParam diff --git a/OpenSim/Region/PhysicsModules/ubOde/ODERayCastRequestManager.cs b/OpenSim/Region/PhysicsModules/ubOde/ODERayCastRequestManager.cs index 1ec02ac19f..0d55ebd9eb 100644 --- a/OpenSim/Region/PhysicsModules/ubOde/ODERayCastRequestManager.cs +++ b/OpenSim/Region/PhysicsModules/ubOde/ODERayCastRequestManager.cs @@ -53,6 +53,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde /// Scene that created this object. /// private readonly ODEScene m_scene; + private readonly SafeNativeMethods.ContactGeom[] m_contacts; IntPtr ray; // the ray. we only need one for our lifetime @@ -69,11 +70,11 @@ namespace OpenSim.Region.PhysicsModule.ubOde private RayFilterFlags CurrentRayFilter; private int CurrentMaxCount; ContactResult SharedCollisionResult = new ContactResult(); - SafeNativeMethods.ContactGeomClass Sharedcontact = new SafeNativeMethods.ContactGeomClass(); public ODERayCastRequestManager(ODEScene pScene) { m_scene = pScene; + m_contacts = pScene.m_contacts; nearCallback = near; ray = SafeNativeMethods.CreateRay(IntPtr.Zero, 1.0f); SafeNativeMethods.GeomSetCategoryBits(ray, 0); @@ -384,18 +385,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde } } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private bool GetCurContactGeom(int index, ref SafeNativeMethods.ContactGeomClass newcontactgeom) - { - IntPtr ContactgeomsArray = m_scene.ContactgeomsArray; - if (index >= CollisionContactGeomsPerTest) - return false; - - IntPtr contactptr = new IntPtr(ContactgeomsArray.ToInt64() + (Int64)(index * SafeNativeMethods.ContactGeomClass.unmanagedSizeOf)); - Marshal.PtrToStructure(contactptr, newcontactgeom); - return true; - } - // This is the standard Near. g1 is the ray private void near(IntPtr dummy, IntPtr g1, IntPtr g2) { @@ -421,7 +410,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde int count = 0; try { - count = SafeNativeMethods.CollidePtr(g1, g2, CollisionContactGeomsPerTest, m_scene.ContactgeomsArray, SafeNativeMethods.ContactGeomClass.unmanagedSizeOf); + count = SafeNativeMethods.CollidePtr(g1, g2, CollisionContactGeomsPerTest, m_scene.ContactgeomsArray, SafeNativeMethods.ContactGeom.unmanagedSizeOf); } catch (Exception e) { @@ -472,17 +461,14 @@ namespace OpenSim.Region.PhysicsModule.ubOde // Loop all contacts, build results. for (int i = 0; i < count; i++) { - if (!GetCurContactGeom(i, ref Sharedcontact)) - break; - lock (m_contactResults) { m_contactResults.Add(new ContactResult { ConsumerID = ID, - Pos = new Vector3(Sharedcontact.pos.X, Sharedcontact.pos.Y, Sharedcontact.pos.Z), - Normal = new Vector3(Sharedcontact.normal.X, Sharedcontact.normal.Y, Sharedcontact.normal.Z), - Depth = Sharedcontact.depth + Pos = new Vector3(m_contacts[i].pos.X, m_contacts[i].pos.Y, m_contacts[i].pos.Z), + Normal = new Vector3(m_contacts[i].normal.X, m_contacts[i].normal.Y, m_contacts[i].normal.Z), + Depth = m_contacts[i].depth }); if (m_contactResults.Count >= CurrentMaxCount) return; @@ -497,18 +483,15 @@ namespace OpenSim.Region.PhysicsModule.ubOde for (int i = 0; i < count; i++) { - if (!GetCurContactGeom(i, ref Sharedcontact)) - break; - - if (Sharedcontact.depth < SharedCollisionResult.Depth) + if (m_contacts[i].depth < SharedCollisionResult.Depth) { - SharedCollisionResult.Pos.X = Sharedcontact.pos.X; - SharedCollisionResult.Pos.Y = Sharedcontact.pos.Y; - SharedCollisionResult.Pos.Z = Sharedcontact.pos.Z; - SharedCollisionResult.Normal.X = Sharedcontact.normal.X; - SharedCollisionResult.Normal.Y = Sharedcontact.normal.Y; - SharedCollisionResult.Normal.Z = Sharedcontact.normal.Z; - SharedCollisionResult.Depth = Sharedcontact.depth; + SharedCollisionResult.Pos.X = m_contacts[i].pos.X; + SharedCollisionResult.Pos.Y = m_contacts[i].pos.Y; + SharedCollisionResult.Pos.Z = m_contacts[i].pos.Z; + SharedCollisionResult.Normal.X = m_contacts[i].normal.X; + SharedCollisionResult.Normal.Y = m_contacts[i].normal.Y; + SharedCollisionResult.Normal.Z = m_contacts[i].normal.Z; + SharedCollisionResult.Depth = m_contacts[i].depth; } } @@ -529,7 +512,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde int count = 0; try { - count = SafeNativeMethods.CollidePtr(ray, chr.collider, CollisionContactGeomsPerTest, m_scene.ContactgeomsArray, SafeNativeMethods.ContactGeomClass.unmanagedSizeOf); + count = SafeNativeMethods.CollidePtr(ray, chr.collider, CollisionContactGeomsPerTest, m_scene.ContactgeomsArray, SafeNativeMethods.ContactGeom.unmanagedSizeOf); if (count == 0) return; } @@ -546,17 +529,14 @@ namespace OpenSim.Region.PhysicsModule.ubOde // Loop all contacts, build results. for (int i = 0; i < count; i++) { - if (!GetCurContactGeom(i, ref Sharedcontact)) - break; - lock (m_contactResults) { m_contactResults.Add(new ContactResult { ConsumerID = id, - Pos = new Vector3(Sharedcontact.pos.X, Sharedcontact.pos.Y, Sharedcontact.pos.Z), - Normal = new Vector3(Sharedcontact.normal.X, Sharedcontact.normal.Y, Sharedcontact.normal.Z), - Depth = Sharedcontact.depth + Pos = new Vector3(m_contacts[i].pos.X, m_contacts[i].pos.Y, m_contacts[i].pos.Z), + Normal = new Vector3(m_contacts[i].normal.X, m_contacts[i].normal.Y, m_contacts[i].normal.Z), + Depth = m_contacts[i].depth }); if (m_contactResults.Count >= CurrentMaxCount) return; @@ -571,18 +551,15 @@ namespace OpenSim.Region.PhysicsModule.ubOde for (int i = 0; i < count; i++) { - if (!GetCurContactGeom(i, ref Sharedcontact)) - break; - - if (Sharedcontact.depth < SharedCollisionResult.Depth) + if (m_contacts[i].depth < SharedCollisionResult.Depth) { - SharedCollisionResult.Pos.X = Sharedcontact.pos.X; - SharedCollisionResult.Pos.Y = Sharedcontact.pos.Y; - SharedCollisionResult.Pos.Z = Sharedcontact.pos.Z; - SharedCollisionResult.Normal.X = Sharedcontact.normal.X; - SharedCollisionResult.Normal.Y = Sharedcontact.normal.Y; - SharedCollisionResult.Normal.Z = Sharedcontact.normal.Z; - SharedCollisionResult.Depth = Sharedcontact.depth; + SharedCollisionResult.Pos.X = m_contacts[i].pos.X; + SharedCollisionResult.Pos.Y = m_contacts[i].pos.Y; + SharedCollisionResult.Pos.Z = m_contacts[i].pos.Z; + SharedCollisionResult.Normal.X = m_contacts[i].normal.X; + SharedCollisionResult.Normal.Y = m_contacts[i].normal.Y; + SharedCollisionResult.Normal.Z = m_contacts[i].normal.Z; + SharedCollisionResult.Depth = m_contacts[i].depth; } } @@ -603,7 +580,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde int count = 0; try { - count = SafeNativeMethods.CollidePtr(ray, terrain, CollisionContactGeomsPerTest, m_scene.ContactgeomsArray, SafeNativeMethods.ContactGeomClass.unmanagedSizeOf); + count = SafeNativeMethods.CollidePtr(ray, terrain, CollisionContactGeomsPerTest, m_scene.ContactgeomsArray, SafeNativeMethods.ContactGeom.unmanagedSizeOf); if (count == 0) return; } @@ -619,17 +596,14 @@ namespace OpenSim.Region.PhysicsModule.ubOde // Loop all contacts, build results. for (int i = 0; i < count; i++) { - if (!GetCurContactGeom(i, ref Sharedcontact)) - break; - lock (m_contactResults) { m_contactResults.Add(new ContactResult { ConsumerID = 0, - Pos = new Vector3(Sharedcontact.pos.X, Sharedcontact.pos.Y, Sharedcontact.pos.Z), - Normal = new Vector3(Sharedcontact.normal.X, Sharedcontact.normal.Y, Sharedcontact.normal.Z), - Depth = Sharedcontact.depth + Pos = new Vector3(m_contacts[i].pos.X, m_contacts[i].pos.Y, m_contacts[i].pos.Z), + Normal = new Vector3(m_contacts[i].normal.X, m_contacts[i].normal.Y, m_contacts[i].normal.Z), + Depth = m_contacts[i].depth }); if (m_contactResults.Count >= CurrentMaxCount) return; @@ -644,18 +618,15 @@ namespace OpenSim.Region.PhysicsModule.ubOde for (int i = 0; i < count; i++) { - if (!GetCurContactGeom(i, ref Sharedcontact)) - break; - - if (Sharedcontact.depth < SharedCollisionResult.Depth) + if (m_contacts[i].depth < SharedCollisionResult.Depth) { - SharedCollisionResult.Pos.X = Sharedcontact.pos.X; - SharedCollisionResult.Pos.Y = Sharedcontact.pos.Y; - SharedCollisionResult.Pos.Z = Sharedcontact.pos.Z; - SharedCollisionResult.Normal.X = Sharedcontact.normal.X; - SharedCollisionResult.Normal.Y = Sharedcontact.normal.Y; - SharedCollisionResult.Normal.Z = Sharedcontact.normal.Z; - SharedCollisionResult.Depth = Sharedcontact.depth; + SharedCollisionResult.Pos.X = m_contacts[i].pos.X; + SharedCollisionResult.Pos.Y = m_contacts[i].pos.Y; + SharedCollisionResult.Pos.Z = m_contacts[i].pos.Z; + SharedCollisionResult.Normal.X = m_contacts[i].normal.X; + SharedCollisionResult.Normal.Y = m_contacts[i].normal.Y; + SharedCollisionResult.Normal.Z = m_contacts[i].normal.Z; + SharedCollisionResult.Depth = m_contacts[i].depth; } } diff --git a/OpenSim/Region/PhysicsModules/ubOde/ODEScene.cs b/OpenSim/Region/PhysicsModules/ubOde/ODEScene.cs index 89b5b1ad70..20326d9da3 100644 --- a/OpenSim/Region/PhysicsModules/ubOde/ODEScene.cs +++ b/OpenSim/Region/PhysicsModules/ubOde/ODEScene.cs @@ -244,7 +244,11 @@ namespace OpenSim.Region.PhysicsModule.ubOde private int contactsPerCollision = 80; internal IntPtr ContactgeomsArray = IntPtr.Zero; - private IntPtr GlobalContactsArray = IntPtr.Zero; + internal SafeNativeMethods.ContactGeom[] m_contacts; + internal GCHandle m_contactsHandler; + + private IntPtr GlobalContactsArray; + private SafeNativeMethods.Contact contactSharedForJoints = new SafeNativeMethods.Contact(); const int maxContactJoints = 6000; @@ -343,8 +347,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde _charactersList = new List(m_frameWorkScene.RegionInfo.AgentCapacity); - m_rayCastManager = new ODERayCastRequestManager(this); - WorldExtents.X = m_frameWorkScene.RegionInfo.RegionSizeX; m_regionWidth = (int)WorldExtents.X; WorldExtents.Y = m_frameWorkScene.RegionInfo.RegionSizeY; @@ -469,7 +471,10 @@ namespace OpenSim.Region.PhysicsModule.ubOde HalfOdeStep = ODE_STEPSIZE * 0.5f; odetimestepMS = (int)(1000.0f * ODE_STEPSIZE + 0.5f); - ContactgeomsArray = Marshal.AllocHGlobal(contactsPerCollision * SafeNativeMethods.ContactGeomClass.unmanagedSizeOf); + m_contacts = new SafeNativeMethods.ContactGeom[contactsPerCollision]; + m_contactsHandler = GCHandle.Alloc(m_contacts, GCHandleType.Pinned); + ContactgeomsArray = m_contactsHandler.AddrOfPinnedObject(); + GlobalContactsArray = Marshal.AllocHGlobal((maxContactJoints + 100) * SafeNativeMethods.Contact.unmanagedSizeOf); contactSharedForJoints.geom.g1 = IntPtr.Zero; @@ -515,6 +520,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde m_lastMeshExpire = m_lastframe; step_time = -1; + m_rayCastManager = new ODERayCastRequestManager(this); base.Initialise(m_frameWorkScene.PhysicsRequestAsset, (m_frameWorkScene.Heightmap != null ? m_frameWorkScene.Heightmap.GetFloatsSerialised() : new float[m_frameWorkScene.RegionInfo.RegionSizeX * m_frameWorkScene.RegionInfo.RegionSizeY]), @@ -530,10 +536,8 @@ namespace OpenSim.Region.PhysicsModule.ubOde */ #region Collision Detection - - // sets a global contact for a joint for contactgeom , and base contact description) [MethodImpl(MethodImplOptions.AggressiveInlining)] - private IntPtr CreateContacJoint(ref SafeNativeMethods.ContactGeomClass contactGeom, bool smooth) + private IntPtr CreateContacJoint(ref SafeNativeMethods.ContactGeom contactGeom, bool smooth) { if (ContactJointCount >= maxContactJoints) return IntPtr.Zero; @@ -548,19 +552,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde return SafeNativeMethods.JointCreateContactPtr(world, JointContactGroup, contact); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private bool GetCurContactGeom(int index, ref SafeNativeMethods.ContactGeomClass newcontactgeom) - { - if (ContactgeomsArray == IntPtr.Zero || index >= contactsPerCollision) - return false; - - IntPtr contactptr = new IntPtr(ContactgeomsArray.ToInt64() + (Int64)(index * SafeNativeMethods.ContactGeomClass.unmanagedSizeOf)); - Marshal.PtrToStructure(contactptr, newcontactgeom); - return true; - } - - SafeNativeMethods.ContactGeomClass CurWorkContact = new SafeNativeMethods.ContactGeomClass(); - SafeNativeMethods.ContactGeomClass altWorkContact = new SafeNativeMethods.ContactGeomClass(); + SafeNativeMethods.ContactGeom altWorkContact = new SafeNativeMethods.ContactGeom(); /// /// This is our near callback. A geometry is near a body @@ -607,10 +599,10 @@ namespace OpenSim.Region.PhysicsModule.ubOde SafeNativeMethods.GeomGetCategoryBits(g2) == (uint)CollisionCategories.VolumeDtc) { int cflags = unchecked((int)(1 | SafeNativeMethods.CONTACTS_UNIMPORTANT)); - count = SafeNativeMethods.CollidePtr(g1, g2, cflags, ContactgeomsArray, SafeNativeMethods.ContactGeomClass.unmanagedSizeOf); + count = SafeNativeMethods.CollidePtr(g1, g2, cflags, ContactgeomsArray, SafeNativeMethods.ContactGeom.unmanagedSizeOf); } else - count = SafeNativeMethods.CollidePtr(g1, g2, contactsPerCollision, ContactgeomsArray, SafeNativeMethods.ContactGeomClass.unmanagedSizeOf); + count = SafeNativeMethods.CollidePtr(g1, g2, contactsPerCollision, ContactgeomsArray, SafeNativeMethods.ContactGeom.unmanagedSizeOf); } catch (SEHException) { @@ -641,17 +633,13 @@ namespace OpenSim.Region.PhysicsModule.ubOde return; } - // get first contact - if (!GetCurContactGeom(0, ref CurWorkContact)) - return; - // do volume detection case if ((p1.IsVolumeDtc || p2.IsVolumeDtc)) { ContactPoint volDepthContact = new ContactPoint( - new Vector3(CurWorkContact.pos.X, CurWorkContact.pos.Y, CurWorkContact.pos.Z), - new Vector3(CurWorkContact.normal.X, CurWorkContact.normal.Y, CurWorkContact.normal.Z), - CurWorkContact.depth, false + new Vector3(m_contacts[0].pos.X, m_contacts[0].pos.Y, m_contacts[0].pos.Z), + new Vector3(m_contacts[0].normal.X, m_contacts[0].normal.Y, m_contacts[0].normal.Z), + m_contacts[0].depth, false ); collision_accounting_events(p1, p2, volDepthContact); @@ -773,8 +761,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde bool FeetCollision = false; int ncontacts = 0; - int i = 0; - ContactPoint maxDepthContact = new ContactPoint(); float minDepth = float.MaxValue; @@ -791,15 +777,15 @@ namespace OpenSim.Region.PhysicsModule.ubOde IntPtr b1 = SafeNativeMethods.GeomGetBody(g1); IntPtr b2 = SafeNativeMethods.GeomGetBody(g2); - - while (true) + + for (int i = 0; i < count; ++i) { noskip = true; useAltcontact = false; if (dop1ava) { - if ((((OdeCharacter)p1).Collide(g1, g2, false, ref CurWorkContact, ref altWorkContact, ref useAltcontact, ref FeetCollision))) + if ((((OdeCharacter)p1).Collide(g1, g2, false, ref m_contacts[i], ref altWorkContact, ref useAltcontact, ref FeetCollision))) { if (p2.PhysicsActorType == (int)ActorTypes.Agent) { @@ -814,7 +800,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde } else if (dop2ava) { - if ((((OdeCharacter)p2).Collide(g2, g1, true, ref CurWorkContact, ref altWorkContact, ref useAltcontact, ref FeetCollision))) + if ((((OdeCharacter)p2).Collide(g2, g1, true, ref m_contacts[i], ref altWorkContact, ref useAltcontact, ref FeetCollision))) { if (p1.PhysicsActorType == (int)ActorTypes.Agent) { @@ -832,7 +818,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde { Joint = useAltcontact ? CreateContacJoint(ref altWorkContact, smoothMesh) : - CreateContacJoint(ref CurWorkContact, smoothMesh); + CreateContacJoint(ref m_contacts[i], smoothMesh); if (Joint == IntPtr.Zero) break; @@ -840,30 +826,24 @@ namespace OpenSim.Region.PhysicsModule.ubOde ncontacts++; - if (CurWorkContact.depth > maxDepth) + if (m_contacts[i].depth > maxDepth) { - maxDepth = CurWorkContact.depth; + maxDepth = m_contacts[i].depth; maxDepthContact.PenetrationDepth = maxDepth; - maxDepthContact.Position.X = CurWorkContact.pos.X; - maxDepthContact.Position.Y = CurWorkContact.pos.Y; - maxDepthContact.Position.Z = CurWorkContact.pos.Z; + maxDepthContact.Position.X = m_contacts[i].pos.X; + maxDepthContact.Position.Y = m_contacts[i].pos.Y; + maxDepthContact.Position.Z = m_contacts[i].pos.Z; maxDepthContact.CharacterFeet = FeetCollision; } - if (CurWorkContact.depth < minDepth) + if (m_contacts[i].depth < minDepth) { - minDepth = CurWorkContact.depth; - maxDepthContact.SurfaceNormal.X = CurWorkContact.normal.X; - maxDepthContact.SurfaceNormal.Y = CurWorkContact.normal.Y; - maxDepthContact.SurfaceNormal.Z = CurWorkContact.normal.Z; + minDepth = m_contacts[i].depth; + maxDepthContact.SurfaceNormal.X = m_contacts[i].normal.X; + maxDepthContact.SurfaceNormal.Y = m_contacts[i].normal.Y; + maxDepthContact.SurfaceNormal.Z = m_contacts[i].normal.Z; } } - - if (++i >= count) - break; - - if (!GetCurContactGeom(i, ref CurWorkContact)) - break; } if (ncontacts > 0) @@ -882,7 +862,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde int count = 0; try { - count = SafeNativeMethods.CollidePtr(p1.collider, p2.collider, contactsPerCollision, ContactgeomsArray, SafeNativeMethods.ContactGeomClass.unmanagedSizeOf); + count = SafeNativeMethods.CollidePtr(p1.collider, p2.collider, contactsPerCollision, ContactgeomsArray, SafeNativeMethods.ContactGeom.unmanagedSizeOf); } catch (SEHException) { @@ -901,8 +881,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde return; // get first contact - if (!GetCurContactGeom(0, ref CurWorkContact)) - return; ContactData contactdata1 = new ContactData(0, 0, false); ContactData contactdata2 = new ContactData(0, 0, false); @@ -911,8 +889,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde bool FeetCollision = false; int ncontacts = 0; - int i = 0; - ContactPoint maxDepthContact = new ContactPoint(); float minDepth = float.MaxValue; @@ -923,11 +899,11 @@ namespace OpenSim.Region.PhysicsModule.ubOde bool useAltcontact; - while (true) + for (int i = 0; i < count; ++i) { useAltcontact = false; - if (p1.Collide(p1.collider, p2.collider, false, ref CurWorkContact, ref altWorkContact, ref useAltcontact, ref FeetCollision)) + if (p1.Collide(p1.collider, p2.collider, false, ref m_contacts[i], ref altWorkContact, ref useAltcontact, ref FeetCollision)) { p1.CollidingObj = true; p1.CollidingObj = true; @@ -935,7 +911,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde if (useAltcontact) Joint = CreateContacJoint(ref altWorkContact, false); else - Joint = CreateContacJoint(ref CurWorkContact, false); + Joint = CreateContacJoint(ref m_contacts[i], false); if (Joint == IntPtr.Zero) break; @@ -943,30 +919,24 @@ namespace OpenSim.Region.PhysicsModule.ubOde ncontacts++; - if (CurWorkContact.depth > maxDepth) + if (m_contacts[i].depth > maxDepth) { - maxDepth = CurWorkContact.depth; + maxDepth = m_contacts[i].depth; maxDepthContact.PenetrationDepth = maxDepth; - maxDepthContact.Position.X = CurWorkContact.pos.X; - maxDepthContact.Position.Y = CurWorkContact.pos.Y; - maxDepthContact.Position.Z = CurWorkContact.pos.Z; + maxDepthContact.Position.X = m_contacts[i].pos.X; + maxDepthContact.Position.Y = m_contacts[i].pos.Y; + maxDepthContact.Position.Z = m_contacts[i].pos.Z; maxDepthContact.CharacterFeet = FeetCollision; } - if (CurWorkContact.depth < minDepth) + if (m_contacts[i].depth < minDepth) { - minDepth = CurWorkContact.depth; - maxDepthContact.SurfaceNormal.X = CurWorkContact.normal.X; - maxDepthContact.SurfaceNormal.Y = CurWorkContact.normal.Y; - maxDepthContact.SurfaceNormal.Z = CurWorkContact.normal.Z; + minDepth = m_contacts[i].depth; + maxDepthContact.SurfaceNormal.X = m_contacts[i].normal.X; + maxDepthContact.SurfaceNormal.Y = m_contacts[i].normal.Y; + maxDepthContact.SurfaceNormal.Z = m_contacts[i].normal.Z; } } - - if (++i >= count) - break; - - if (!GetCurContactGeom(i, ref CurWorkContact)) - break; } if (ncontacts > 0) @@ -1522,12 +1492,11 @@ namespace OpenSim.Region.PhysicsModule.ubOde /// Called to queue a change to a actor /// to use in place of old taint mechanism so changes do have a time sequence /// - + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AddChange(PhysicsActor _actor, changes _what, Object _arg) { if (world == IntPtr.Zero) return; - ODEchangeitem item = new ODEchangeitem { actor = _actor, @@ -2240,14 +2209,14 @@ namespace OpenSim.Region.PhysicsModule.ubOde if (m_terrainHeightsHandler.IsAllocated) m_terrainHeightsHandler.Free(); - m_terrainHeights = null; - if (ContactgeomsArray != IntPtr.Zero) + if (m_contactsHandler != null && m_contactsHandler.IsAllocated) { - Marshal.FreeHGlobal(ContactgeomsArray); + m_contactsHandler.Free(); ContactgeomsArray = IntPtr.Zero; } + if (GlobalContactsArray != IntPtr.Zero) { Marshal.FreeHGlobal(GlobalContactsArray);