From de32006f9a0843c9d115fc6c2c92d64046f52ee0 Mon Sep 17 00:00:00 2001 From: Teravus Ovares Date: Sat, 22 Dec 2007 05:43:34 +0000 Subject: [PATCH] * Added smoother handling of interpenetrating physical objects. * Fixes: * -- duplicating Active physical object causes objects to explode in opposite directions * -- Rezzing objects too close to you avatar causes avatar to shoot around in odd directions * Vanity --- CONTRIBUTORS.txt | 1 + OpenSim/Region/Environment/Scenes/Scene.cs | 1 + .../Region/Physics/OdePlugin/ODECharacter.cs | 4 +- OpenSim/Region/Physics/OdePlugin/OdePlugin.cs | 97 ++++++++++++++----- 4 files changed, 76 insertions(+), 27 deletions(-) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 1a97a37cac..5457f71103 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -17,6 +17,7 @@ OpenSim Developers * Babblefrog * Tedd * justincc (International Business Machines Corp.) +* Teravus (w3z) Patches diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs index 79803a54f2..89dc13000a 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.cs @@ -332,6 +332,7 @@ namespace OpenSim.Region.Environment.Scenes // If agent is a root agent. if (!agent.IsChildAgent) { + //agent.ControllingClient.new //this.CommsManager.InterRegion.InformRegionOfChildAgent(otherRegion.RegionHandle, agent.ControllingClient.RequestClientInfo()); InformClientOfNeighbor(agent, otherRegion); diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs index 04bf9a0956..3bdf180a0f 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs @@ -174,7 +174,7 @@ namespace OpenSim.Region.Physics.OdePlugin } if (m_wascolliding != m_iscolliding) { - base.SendCollisionUpdate(new CollisionEventUpdate()); + //base.SendCollisionUpdate(new CollisionEventUpdate()); } m_wascolliding = m_iscolliding; @@ -527,7 +527,7 @@ namespace OpenSim.Region.Physics.OdePlugin if (_velocity.Z < -6 && !m_hackSentFall) { m_hackSentFall = true; - base.SendCollisionUpdate(new CollisionEventUpdate()); + //base.SendCollisionUpdate(new CollisionEventUpdate()); m_pidControllerActive = false; } else if (flying && !m_hackSentFly) diff --git a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs index 305a930502..b4336c3088 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs @@ -281,37 +281,84 @@ namespace OpenSim.Region.Physics.OdePlugin break; } - if (name1 == "Terrain" || name2 == "Terrain") + // we don't want prim or avatar to explode + #region InterPenetration Handling - Unintended physics explosions + if (contacts[i].depth >= 0.08f) { - if ((p2.PhysicsActorType == (int)ActorTypes.Agent) && (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f)) + if (contacts[i].depth >= 1.00f) { - AvatarMovementTerrainContact.geom = contacts[i]; - joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementTerrainContact); + //MainLog.Instance.Debug("PHYSICS",contacts[i].depth.ToString()); + } + // If you interpenetrate a prim with an agent + if ((p2.PhysicsActorType == (int)ActorTypes.Agent && p1.PhysicsActorType == (int)ActorTypes.Prim) || (p1.PhysicsActorType == (int)ActorTypes.Agent && p2.PhysicsActorType == (int)ActorTypes.Prim)) + { + + if (p2.PhysicsActorType == (int)ActorTypes.Agent) + { + p2.CollidingObj = true; + contacts[i].depth = 0.003f; + p2.Velocity = p2.Velocity + new PhysicsVector(0, 0, 2.5f); + contacts[i].pos = new d.Vector3(contacts[i].pos.X + (p1.Size.X / 2), contacts[i].pos.Y + (p1.Size.Y / 2), contacts[i].pos.Z + (p1.Size.Z / 2)); + + } + else + { + contacts[i].depth = 0.0000000f; + } + if (p1.PhysicsActorType == (int)ActorTypes.Agent) + { + p1.CollidingObj = true; + contacts[i].depth = 0.003f; + p1.Velocity = p1.Velocity + new PhysicsVector(0, 0, 2.5f); + contacts[i].pos = new d.Vector3(contacts[i].pos.X + (p2.Size.X / 2), contacts[i].pos.Y + (p2.Size.Y / 2), contacts[i].pos.Z + (p2.Size.Z / 2)); + } + else + { + contacts[i].depth = 0.0000000f; + } + } + // If you interpenetrate a prim with another prim + if (p1.PhysicsActorType == (int)ActorTypes.Prim && p2.PhysicsActorType == (int)ActorTypes.Prim) + { + // Don't collide, one or both prim will explode. + contacts[i].depth = 0.0f; + } + } + #endregion + + if (contacts[i].depth > 0f) + { + if (name1 == "Terrain" || name2 == "Terrain") + { + + if ((p2.PhysicsActorType == (int)ActorTypes.Agent) && (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f)) + { + AvatarMovementTerrainContact.geom = contacts[i]; + joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementTerrainContact); + + } + else + { + TerrainContact.geom = contacts[i]; + joint = d.JointCreateContact(world, contactgroup, ref TerrainContact); + } } else { - TerrainContact.geom = contacts[i]; - joint = d.JointCreateContact(world, contactgroup, ref TerrainContact); + if ((p2.PhysicsActorType == (int)ActorTypes.Agent) && (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f)) + { + AvatarMovementprimContact.geom = contacts[i]; + joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementprimContact); + + } + else + { + contact.geom = contacts[i]; + joint = d.JointCreateContact(world, contactgroup, ref contact); + } } + d.JointAttach(joint, b1, b2); } - else - { - if ((p2.PhysicsActorType == (int)ActorTypes.Agent) && (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f)) - { - AvatarMovementprimContact.geom = contacts[i]; - joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementprimContact); - } - else - { - contact.geom = contacts[i]; - joint = d.JointCreateContact(world, contactgroup, ref contact); - } - } - - - d.JointAttach(joint, b1, b2); - - if (count > 3) { @@ -334,7 +381,7 @@ namespace OpenSim.Region.Physics.OdePlugin } // If the sim is running slow this frame, // don't process collision for prim! - if (timeStep < (m_SkipFramesAtms / 2)) + if (timeStep < (m_SkipFramesAtms / 3)) { foreach (OdePrim chr in _activeprims) {