From ac2f98b846eba85ab3d9acb5bd0f355a404de86c Mon Sep 17 00:00:00 2001
From: Teravus Ovares (Dan Olivares)
Date: Fri, 16 Oct 2009 03:32:30 -0400
Subject: * A hacky attempt at resolving mantis #4260.   I think ODE was unable
 to allocate memory, and therefore the unmanaged wrapper call fails or worse..
    there's some unmanaged resource accounting in the ODEPlugin for
 ODECharacter that isn't being done properly now. * The broken avatar may not
 be able to move, but it won't stop simulate from pressing on now.   And, the
 simulator will try to destroy the avatar's physics proxy and recreate it
 again...    but if this is what I think it is, it may not help.

---
 OpenSim/Region/Framework/Scenes/ScenePresence.cs |  9 +++++++++
 OpenSim/Region/Physics/OdePlugin/ODECharacter.cs | 24 ++++++++++++++++++++++--
 2 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 646a483..96fa467 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -3410,11 +3410,20 @@ namespace OpenSim.Region.Framework.Scenes
             scene.AddPhysicsActorTaint(m_physicsActor);
             //m_physicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients;
             m_physicsActor.OnCollisionUpdate += PhysicsCollisionUpdate;
+            m_physicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong
             m_physicsActor.SubscribeEvents(500);
             m_physicsActor.LocalID = LocalId;
             
         }
 
+        private void OutOfBoundsCall(PhysicsVector pos)
+        {
+            bool flying = m_physicsActor.Flying;
+            RemoveFromPhysicalScene();
+
+            AddToPhysicalScene(flying);
+        }
+
         // Event called by the physics plugin to tell the avatar about a collision.
         private void PhysicsCollisionUpdate(EventArgs e)
         {
diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
index bd81d50..bd05c92 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
@@ -1105,7 +1105,18 @@ namespace OpenSim.Region.Physics.OdePlugin
         public void UpdatePositionAndVelocity()
         {
             //  no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit!
-            d.Vector3 vec = d.BodyGetPosition(Body);
+            d.Vector3 vec;
+            try
+            {
+                vec = d.BodyGetPosition(Body);
+                //throw new NullReferenceException("foo!");
+            }
+            catch (NullReferenceException)
+            {
+                vec = new d.Vector3(Position.X, Position.Y, Position.Z);
+                base.RaiseOutOfBounds(_position);
+            }
+            
 
             //  kluge to keep things in bounds.  ODE lets dead avatars drift away (they should be removed!)
             if (vec.X < 0.0f) vec.X = 0.0f;
@@ -1137,7 +1148,16 @@ namespace OpenSim.Region.Physics.OdePlugin
             else
             {
                 m_lastUpdateSent = false;
-                vec = d.BodyGetLinearVel(Body);
+                try
+                {
+                    vec = d.BodyGetLinearVel(Body);
+                }
+                catch (NullReferenceException)
+                {
+                    vec.X = _velocity.X;
+                    vec.Y = _velocity.Y;
+                    vec.Z = _velocity.Z;
+                }
                 _velocity.X = (vec.X);
                 _velocity.Y = (vec.Y);
 
-- 
cgit v1.1