From a2ab3b88de764112996b1e37d74c1e7b7355b1d8 Mon Sep 17 00:00:00 2001 From: teravus Date: Wed, 3 Oct 2012 18:30:44 -0400 Subject: [PATCH] Soliciting for comments on smoothness of physics objects for this build. This introduces expected contact point hints to the ODE Collider to better determine when to throttle updates as excessive. This /should/ smooth physics objects out again, however, I cannot know every configuration of OpenSimulator, so I'm requesting that testers please examine this change on their build. Thanks! --- OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 13 ++++++- OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 41 +++++++++++++++++--- 2 files changed, 46 insertions(+), 8 deletions(-) diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index 1b477543c9..e7b3b2b278 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -63,6 +63,9 @@ namespace OpenSim.Region.Physics.OdePlugin private bool m_isphysical; + public int ExpectedCollisionContacts { get { return m_expectedCollisionContacts; } } + private int m_expectedCollisionContacts = 0; + /// /// Is this prim subject to physics? Even if not, it's still solid for collision purposes. /// @@ -150,7 +153,7 @@ namespace OpenSim.Region.Physics.OdePlugin private PrimitiveBaseShape _pbs; private OdeScene _parent_scene; - + /// /// The physics space which contains prim geometries /// @@ -840,7 +843,7 @@ namespace OpenSim.Region.Physics.OdePlugin int vertexStride, triStride; mesh.getVertexListAsPtrToFloatArray(out vertices, out vertexStride, out vertexCount); // Note, that vertices are fixed in unmanaged heap mesh.getIndexListAsPtrToIntArray(out indices, out triStride, out indexCount); // Also fixed, needs release after usage - + m_expectedCollisionContacts = indexCount; mesh.releaseSourceMeshData(); // free up the original mesh data to save memory // We must lock here since m_MeshToTriMeshMap is static and multiple scene threads may call this method at @@ -1377,6 +1380,7 @@ Console.WriteLine("CreateGeom:"); { //Console.WriteLine(" CreateGeom 1"); SetGeom(d.CreateSphere(m_targetSpace, _size.X / 2)); + m_expectedCollisionContacts = 3; } catch (AccessViolationException) { @@ -1391,6 +1395,7 @@ Console.WriteLine("CreateGeom:"); { //Console.WriteLine(" CreateGeom 2"); SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z)); + m_expectedCollisionContacts = 4; } catch (AccessViolationException) { @@ -1406,6 +1411,7 @@ Console.WriteLine("CreateGeom:"); { //Console.WriteLine(" CreateGeom 3"); SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z)); + m_expectedCollisionContacts = 4; } catch (AccessViolationException) { @@ -1421,6 +1427,7 @@ Console.WriteLine("CreateGeom:"); { //Console.WriteLine(" CreateGeom 4"); SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z)); + m_expectedCollisionContacts = 4; } catch (AccessViolationException) { @@ -1446,11 +1453,13 @@ Console.WriteLine("CreateGeom:"); _parent_scene.geom_name_map.Remove(prim_geom); _parent_scene.actor_name_map.Remove(prim_geom); d.GeomDestroy(prim_geom); + m_expectedCollisionContacts = 0; prim_geom = IntPtr.Zero; } catch (System.AccessViolationException) { prim_geom = IntPtr.Zero; + m_expectedCollisionContacts = 0; m_log.ErrorFormat("[PHYSICS]: PrimGeom dead for {0}", Name); return false; diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index 929b019ecf..7a50c4c66a 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs @@ -336,6 +336,7 @@ namespace OpenSim.Region.Physics.OdePlugin public int geomContactPointsStartthrottle = 3; public int geomUpdatesPerThrottledUpdate = 15; + private const int avatarExpectedContacts = 3; public float bodyPIDD = 35f; public float bodyPIDG = 25; @@ -474,6 +475,8 @@ namespace OpenSim.Region.Physics.OdePlugin private OdePrim cp1; private OdeCharacter cc2; private OdePrim cp2; + private int p1ExpectedPoints = 0; + private int p2ExpectedPoints = 0; //private int cStartStop = 0; //private string cDictKey = ""; @@ -498,6 +501,7 @@ namespace OpenSim.Region.Physics.OdePlugin public int physics_logging_interval = 0; public bool physics_logging_append_existing_logfile = false; + public d.Vector3 xyz = new d.Vector3(128.1640f, 128.3079f, 25.7600f); public d.Vector3 hpr = new d.Vector3(125.5000f, -17.0000f, 0.0000f); @@ -644,7 +648,7 @@ namespace OpenSim.Region.Physics.OdePlugin contactsPerCollision = physicsconfig.GetInt("contacts_per_collision", 80); - geomContactPointsStartthrottle = physicsconfig.GetInt("geom_contactpoints_start_throttling", 3); + geomContactPointsStartthrottle = physicsconfig.GetInt("geom_contactpoints_start_throttling", 5); geomUpdatesPerThrottledUpdate = physicsconfig.GetInt("geom_updates_before_throttled_update", 15); geomCrossingFailuresBeforeOutofbounds = physicsconfig.GetInt("geom_crossing_failures_before_outofbounds", 5); @@ -1064,7 +1068,10 @@ namespace OpenSim.Region.Physics.OdePlugin PhysicsActor p1; PhysicsActor p2; - + + p1ExpectedPoints = 0; + p2ExpectedPoints = 0; + if (!actor_name_map.TryGetValue(g1, out p1)) { p1 = PANull; @@ -1121,9 +1128,13 @@ namespace OpenSim.Region.Physics.OdePlugin switch (p1.PhysicsActorType) { case (int)ActorTypes.Agent: + p1ExpectedPoints = avatarExpectedContacts; p2.CollidingObj = true; break; case (int)ActorTypes.Prim: + if (p1 != null && p1 is OdePrim) + p1ExpectedPoints = ((OdePrim) p1).ExpectedCollisionContacts; + if (p2.Velocity.LengthSquared() > 0.0f) p2.CollidingObj = true; break; @@ -1319,6 +1330,7 @@ namespace OpenSim.Region.Physics.OdePlugin if ((p2.PhysicsActorType == (int) ActorTypes.Agent) && (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f)) { + p2ExpectedPoints = avatarExpectedContacts; // Avatar is moving on terrain, use the movement terrain contact AvatarMovementTerrainContact.geom = curContact; @@ -1332,6 +1344,7 @@ namespace OpenSim.Region.Physics.OdePlugin { if (p2.PhysicsActorType == (int)ActorTypes.Agent) { + p2ExpectedPoints = avatarExpectedContacts; // Avatar is standing on terrain, use the non moving terrain contact TerrainContact.geom = curContact; @@ -1356,9 +1369,18 @@ namespace OpenSim.Region.Physics.OdePlugin } if (p2 is OdePrim) - material = ((OdePrim)p2).m_material; - + { + material = ((OdePrim) p2).m_material; + p2ExpectedPoints = ((OdePrim)p2).ExpectedCollisionContacts; + } + + // Unnessesary because p1 is defined above + //if (p1 is OdePrim) + // { + // p1ExpectedPoints = ((OdePrim)p1).ExpectedCollisionContacts; + // } //m_log.DebugFormat("Material: {0}", material); + m_materialContacts[material, movintYN].geom = curContact; if (m_global_contactcount < maxContactsbeforedeath) @@ -1379,7 +1401,10 @@ namespace OpenSim.Region.Physics.OdePlugin int material = (int)Material.Wood; if (p2 is OdePrim) + { material = ((OdePrim)p2).m_material; + p2ExpectedPoints = ((OdePrim)p2).ExpectedCollisionContacts; + } //m_log.DebugFormat("Material: {0}", material); m_materialContacts[material, movintYN].geom = curContact; @@ -1429,6 +1454,7 @@ namespace OpenSim.Region.Physics.OdePlugin { if ((p2.PhysicsActorType == (int)ActorTypes.Agent)) { + p2ExpectedPoints = avatarExpectedContacts; if ((Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f)) { // Avatar is moving on a prim, use the Movement prim contact @@ -1458,7 +1484,10 @@ namespace OpenSim.Region.Physics.OdePlugin int material = (int)Material.Wood; if (p2 is OdePrim) + { material = ((OdePrim)p2).m_material; + p2ExpectedPoints = ((OdePrim)p2).ExpectedCollisionContacts; + } //m_log.DebugFormat("Material: {0}", material); m_materialContacts[material, 0].geom = curContact; @@ -1479,8 +1508,8 @@ namespace OpenSim.Region.Physics.OdePlugin } collision_accounting_events(p1, p2, maxDepthContact); - - if (count > geomContactPointsStartthrottle) + + if (count > ((p1ExpectedPoints + p2ExpectedPoints) * 0.25) + (geomContactPointsStartthrottle)) { // If there are more then 3 contact points, it's likely // that we've got a pile of objects, so ...