From 5952441fcc886902f7b2f72eb839ae49d2c85012 Mon Sep 17 00:00:00 2001
From: Teravus Ovares
Date: Mon, 12 Nov 2007 21:45:49 +0000
Subject: * Added a lot of Glue to help with reporting proper collisions. * ODE
 - Fixed the iscolliding property to report a static true when colliding. *
 Added reporting of collisions to call UpdateMovementAnimations * Added Jump -
 air animation (with arms outstretched). * Added Fall Animations * ODE - Added
 a small amount of X, Y motion control while jumping or Falling * ODE - Avatar
 movement animations are still a bit odd sometimes, and had to get this up
 there.

---
 OpenSim/Region/Environment/Scenes/ScenePresence.cs |  46 ++++++++-
 .../BasicPhysicsPlugin/BasicPhysicsPlugin.cs       |  16 ++-
 .../Region/Physics/BulletXPlugin/BulletXPlugin.cs  |  29 +++++-
 OpenSim/Region/Physics/Manager/PhysicsActor.cs     |  87 +++++++++++++++-
 OpenSim/Region/Physics/OdePlugin/OdePlugin.cs      | 110 +++++++++++++++++----
 OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs  |  34 ++++++-
 6 files changed, 294 insertions(+), 28 deletions(-)

(limited to 'OpenSim/Region')

diff --git a/OpenSim/Region/Environment/Scenes/ScenePresence.cs b/OpenSim/Region/Environment/Scenes/ScenePresence.cs
index ab19973..5d643d1 100644
--- a/OpenSim/Region/Environment/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Environment/Scenes/ScenePresence.cs
@@ -52,6 +52,7 @@ namespace OpenSim.Region.Environment.Scenes
         private uint m_requestedSitTargetID = 0;
         private LLVector3 m_requestedSitOffset = new LLVector3();
         private float m_sitAvatarHeight = 2.0f;
+        private bool m_oldColliding = true;
 
         private bool m_isTyping = false;
 
@@ -388,6 +389,7 @@ namespace OpenSim.Region.Environment.Scenes
             {
                 m_scene.PhysScene.RemoveAvatar(PhysicsActor);
                 m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients;
+                m_physicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate;
                 PhysicsActor = null;
             }
         }
@@ -407,6 +409,7 @@ namespace OpenSim.Region.Environment.Scenes
         /// </summary>
         public void StopMovement()
         {
+            int x = 0;
         }
 
         public void AddNeighbourRegion(ulong regionHandle)
@@ -489,7 +492,7 @@ namespace OpenSim.Region.Environment.Scenes
                 // Console.WriteLine("DEBUG: HandleAgentUpdate: null PhysicsActor!");
                 return;
             }
-
+            
             int i = 0;
             bool update_movementflag = false;
             bool update_rotation = false;
@@ -497,6 +500,8 @@ namespace OpenSim.Region.Environment.Scenes
             Vector3 agent_control_v3 = new Vector3(0, 0, 0);
             Quaternion q = new Quaternion(bodyRotation.W, bodyRotation.X, bodyRotation.Y, bodyRotation.Z);
             bool oldflying = PhysicsActor.Flying;
+            
+
             PhysicsActor.Flying = ((flags & (uint) MainAvatar.ControlFlags.AGENT_CONTROL_FLY) != 0);
             if (PhysicsActor.Flying != oldflying)
             {
@@ -652,7 +657,18 @@ namespace OpenSim.Region.Environment.Scenes
                         }
                         else
                         {
-                            SendAnimPack(Animations.AnimsLLUUID["WALK"], 1);
+                            if (!PhysicsActor.IsColliding && m_physicsActor.Velocity.Z > 6)
+                            {
+                                SendAnimPack(Animations.AnimsLLUUID["FALLDOWN"], 1);
+                            }
+                            else if (!PhysicsActor.IsColliding && Velocity.Z > 0)
+                            {
+                                SendAnimPack(Animations.AnimsLLUUID["JUMP"], 1);
+                            }
+                            else
+                            {
+                                SendAnimPack(Animations.AnimsLLUUID["WALK"], 1);
+                            }
                         }
                     }
                 }
@@ -669,7 +685,22 @@ namespace OpenSim.Region.Environment.Scenes
                     }
                     else
                     {
-                        SendAnimPack(Animations.AnimsLLUUID["STAND"], 1);
+                        if (!PhysicsActor.IsColliding && m_physicsActor.Velocity.Z > 6 && !m_physicsActor.Flying)
+                        {
+                            SendAnimPack(Animations.AnimsLLUUID["FALLDOWN"], 1);
+                        }
+                        else if (!PhysicsActor.IsColliding && Velocity.Z > 0 && !m_physicsActor.Flying)
+                        {
+                            SendAnimPack(Animations.AnimsLLUUID["JUMP"], 1);
+                        }
+                        else
+                        {
+                            if (!m_physicsActor.Flying)
+                            {
+                                SendAnimPack(Animations.AnimsLLUUID["STAND"], 1);
+                            }
+                        }
+                        
                     }
                 }
             }
@@ -702,6 +733,7 @@ namespace OpenSim.Region.Environment.Scenes
                         direc.z *= 3;
                         //System.Console.WriteLine("Jump");
                         SendAnimPack(Animations.AnimsLLUUID["PRE_JUMP"], 1);
+                        SendAnimPack(Animations.AnimsLLUUID["JUMP"], 1);
                     }
                 }
             }
@@ -1115,8 +1147,16 @@ namespace OpenSim.Region.Environment.Scenes
 
             m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec);
             m_physicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients;
+            m_physicsActor.OnCollisionUpdate += PhysicsCollisionUpdate;
         }
+        private void PhysicsCollisionUpdate(EventArgs e)
+        {
+            bool isUserMoving = false;
+            if (Velocity.X > 0 || Velocity.Y > 0)
+                isUserMoving = true;
+            UpdateMovementAnimations(isUserMoving);
 
+        }
         internal void Close()
         {
             RemoveFromPhysicalScene();
diff --git a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs
index 1d1c14f..3283ec0 100644
--- a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs
+++ b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs
@@ -196,6 +196,11 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin
             _position = new PhysicsVector();
             _acceleration = new PhysicsVector();
         }
+        public override int PhysicsActorType
+        {
+            get { return (int)ActorTypes.Agent; }
+            set { return; }
+        }
         public override PhysicsVector RotationalVelocity
         {
             get { return m_rotationalVelocity; }
@@ -222,7 +227,16 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin
             get { return iscolliding; }
             set { iscolliding = value; }
         }
-
+        public override bool CollidingGround
+        {
+            get { return false; }
+            set { return; }
+        }
+        public override bool CollidingObj
+        {
+            get { return false; }
+            set { return; }
+        }
         public override PhysicsVector Position
         {
             get { return _position; }
diff --git a/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs b/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs
index 2db7a54..b51f024 100644
--- a/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs
+++ b/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs
@@ -705,6 +705,7 @@ namespace OpenSim.Region.Physics.BulletXPlugin
         protected AxiomQuaternion _orientation;
         protected PhysicsVector m_rotationalVelocity = PhysicsVector.Zero;
         protected RigidBody rigidBody;
+        protected int m_PhysicsActorType;
         private Boolean iscolliding = false;
         internal string _name;
 
@@ -784,6 +785,12 @@ namespace OpenSim.Region.Physics.BulletXPlugin
         { 
             get { return 0; } 
         }
+        public override int PhysicsActorType
+        {
+            get { return (int) m_PhysicsActorType; }
+            set { m_PhysicsActorType = value; }
+        }
+
         public RigidBody RigidBody
         {
             get { return rigidBody; }
@@ -814,6 +821,16 @@ namespace OpenSim.Region.Physics.BulletXPlugin
             get { return iscolliding; }
             set { iscolliding = value; }
         }
+        public override bool CollidingGround
+        {
+            get { return false; }
+            set { return; }
+        }
+        public override bool CollidingObj
+        {
+            get { return false; }
+            set { return; }
+        }
         public virtual void SetAcceleration(PhysicsVector accel)
         {
             lock (BulletXScene.BulletXLock)
@@ -956,7 +973,11 @@ namespace OpenSim.Region.Physics.BulletXPlugin
                 parent_scene.ddWorld.AddRigidBody(rigidBody);
             }
         }
-
+        public override int PhysicsActorType
+        {
+            get { return (int)ActorTypes.Agent; }
+            set { return; }
+        }
         public override PhysicsVector Position
         {
             get { return base.Position; }
@@ -1103,7 +1124,11 @@ namespace OpenSim.Region.Physics.BulletXPlugin
 
             CreateRigidBody(parent_scene, mesh, pos, size);
         }
-
+        public override int PhysicsActorType
+        {
+            get { return (int)ActorTypes.Prim; }
+            set { return; }
+        }
         public override PhysicsVector Position
         {
             get { return base.Position; }
diff --git a/OpenSim/Region/Physics/Manager/PhysicsActor.cs b/OpenSim/Region/Physics/Manager/PhysicsActor.cs
index 9ce7cf3..49760da 100644
--- a/OpenSim/Region/Physics/Manager/PhysicsActor.cs
+++ b/OpenSim/Region/Physics/Manager/PhysicsActor.cs
@@ -27,6 +27,8 @@
 */
 using Axiom.Math;
 using OpenSim.Framework;
+using System;
+using System.Collections.Generic;
 
 namespace OpenSim.Region.Physics.Manager
 {
@@ -35,20 +37,75 @@ namespace OpenSim.Region.Physics.Manager
     public delegate void VelocityUpdate(PhysicsVector velocity);
 
     public delegate void OrientationUpdate(Quaternion orientation);
+    public enum ActorTypes : int
+    {
+        Unknown = 0,
+        Agent = 1,
+        Prim = 2, 
+        Ground = 3
+    }
+    public class CollisionEventUpdate : EventArgs 
+    {
+        // Raising the event on the object, so don't need to provide location..  further up the tree knows that info.
 
-   
+
+        public int m_colliderType;
+        public bool m_startOrEnd;
+        //public uint m_LocalID;
+        public List<uint> m_objCollisionList;
+        public CollisionEventUpdate(uint localID, int colliderType, bool startOrEnd, List<uint> objCollisionList)
+        {
+            m_colliderType = colliderType;
+            m_startOrEnd = startOrEnd;
+            m_objCollisionList = objCollisionList;
+
+        }
+        public CollisionEventUpdate(bool startOrEnd){
+            m_colliderType = (int)ActorTypes.Unknown;
+            m_startOrEnd = startOrEnd;
+            m_objCollisionList = null;
+        }
+        public CollisionEventUpdate() {
+            m_colliderType = (int)ActorTypes.Unknown;
+            m_startOrEnd = false;
+            m_objCollisionList = null;
+        }
+        public int collidertype{
+            get {
+                return m_colliderType;
+            }
+            set {
+                m_colliderType = value;
+            }
+        }
+        public bool startOrEnd {
+            get {
+                return m_startOrEnd;
+            }
+            set {
+                m_startOrEnd = value;
+            }
+        }
+        public void addCollider(uint localID) {
+            m_objCollisionList.Add(localID);
+        }
+    }
+        
+        
 
     
 
     public abstract class PhysicsActor
     { 
         public delegate void RequestTerseUpdate();
+        public delegate void CollisionUpdate(EventArgs e);
 
 #pragma warning disable 67
         public event PositionUpdate OnPositionUpdate;
         public event VelocityUpdate OnVelocityUpdate;
         public event OrientationUpdate OnOrientationUpdate;
         public event RequestTerseUpdate OnRequestTerseUpdate;
+        public event CollisionUpdate OnCollisionUpdate;
 #pragma warning restore 67
 
         public static PhysicsActor Null
@@ -74,6 +131,14 @@ namespace OpenSim.Region.Physics.Manager
             }
             
         }
+        public virtual void SendCollisionUpdate(EventArgs e)
+        {
+            CollisionUpdate handler = OnCollisionUpdate;
+            if (handler != null)
+            {
+                OnCollisionUpdate(e);
+            }
+        }
 
 
         public abstract PhysicsVector Position { get; set; }
@@ -83,6 +148,7 @@ namespace OpenSim.Region.Physics.Manager
         public abstract PhysicsVector Acceleration { get; }
 
         public abstract Quaternion Orientation { get; set; }
+        public abstract int PhysicsActorType { get; set; }
 
         public abstract bool IsPhysical {get; set;}
 
@@ -91,6 +157,9 @@ namespace OpenSim.Region.Physics.Manager
         public abstract bool ThrottleUpdates { get; set; }
 
         public abstract bool IsColliding { get; set; }
+        public abstract bool CollidingGround { get; set; }
+        public abstract bool CollidingObj { get; set; }
+
         public abstract PhysicsVector RotationalVelocity { get; set; }
 
         public abstract bool Kinematic { get; set; }
@@ -107,7 +176,16 @@ namespace OpenSim.Region.Physics.Manager
             get { return PhysicsVector.Zero; }
             set { return; }
         }
-
+        public override bool CollidingGround
+        {
+            get {return false;}
+            set {return;}
+        }
+        public override bool CollidingObj 
+        {
+            get { return false; }
+            set { return; }
+        }
         public override PhysicsVector Size
         {
             get { return PhysicsVector.Zero; }
@@ -161,6 +239,11 @@ namespace OpenSim.Region.Physics.Manager
             get { return false; }
             set { return; }
         }
+        public override int PhysicsActorType
+        {
+            get { return (int)ActorTypes.Unknown; }
+            set { return; }
+        }
 
         public override bool Kinematic
         {
diff --git a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
index 98c5995..c93b96f 100644
--- a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
+++ b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
@@ -89,6 +89,7 @@ namespace OpenSim.Region.Physics.OdePlugin
         private d.ContactGeom[] contacts = new d.ContactGeom[30];
         private d.Contact contact;
         private d.Contact TerrainContact;
+        
         private int m_physicsiterations = 10;
         private float m_SkipFramesAtms = 0.40f; // Drop frames gracefully at a 400 ms lag
         private PhysicsActor PANull = new NullPhysicsActor();
@@ -208,11 +209,16 @@ namespace OpenSim.Region.Physics.OdePlugin
                 }
                 
                 
-                    d.JointAttach(joint, b1, b2);
-               
-                
+                d.JointAttach(joint, b1, b2);
+
+
+                PhysicsActor p1;
                 PhysicsActor p2;
 
+                if (!actor_name_map.TryGetValue(g2, out p1))
+                {
+                    p1 = PANull;
+                }
                 if (!actor_name_map.TryGetValue(g2, out p2))
                 {
                     p2 = PANull;
@@ -220,6 +226,17 @@ namespace OpenSim.Region.Physics.OdePlugin
 
                 // We only need to test p2 for 'jump crouch purposes'
                 p2.IsColliding = true;
+                switch(p1.PhysicsActorType) {
+                    case (int)ActorTypes.Agent:
+                        p2.CollidingObj = true;
+                        break;
+                    case (int)ActorTypes.Prim:
+                        p2.CollidingObj = true;
+                        break;
+                    case (int)ActorTypes.Unknown:
+                        p2.CollidingGround = true;
+                        break;
+                }
                 if (count > 3)
                 {
                     p2.ThrottleUpdates = true;
@@ -237,6 +254,8 @@ namespace OpenSim.Region.Physics.OdePlugin
 
                 
                 chr.IsColliding = false;
+                chr.CollidingGround = false;
+                chr.CollidingObj = false;
                 d.SpaceCollide2(space, chr.Shell, IntPtr.Zero, nearCallback);
                 foreach (OdeCharacter ch2 in _characters)
                 /// should be a separate space -- lots of avatars will be N**2 slow
@@ -308,11 +327,9 @@ namespace OpenSim.Region.Physics.OdePlugin
                         p = (OdePrim) prim;
                         p.disableBody();
                     }
-                    if (!((OdePrim)prim).prim_geom.Equals(null))
-                    {
-                        if (((OdePrim)prim).prim_geom != (IntPtr) 0)
-                            d.GeomDestroy(((OdePrim)prim).prim_geom);
-                    }
+                    
+                    d.GeomDestroy(((OdePrim)prim).prim_geom);
+                    
                     _prims.Remove((OdePrim)prim);
                     
                 }
@@ -642,8 +659,9 @@ namespace OpenSim.Region.Physics.OdePlugin
         public static float CAPSULE_LENGTH = 0.79f;
         private bool flying = false;
         private bool m_iscolliding = false;
+        private bool m_wascolliding = false;
         
-        private bool[] m_colliderarr = new bool[10];
+        private bool[] m_colliderarr = new bool[11];
 
         private bool jumping = false;
         //private float gravityAccel;
@@ -661,7 +679,7 @@ namespace OpenSim.Region.Physics.OdePlugin
             _acceleration = new PhysicsVector();
             _parent_scene = parent_scene;
             
-            for (int i = 0; i < 10; i++)
+            for (int i = 0; i < 11; i++)
             {
                 m_colliderarr[i] = false;
             }
@@ -679,7 +697,11 @@ namespace OpenSim.Region.Physics.OdePlugin
             parent_scene.geom_name_map[Shell] = avName;
             parent_scene.actor_name_map[Shell] = (PhysicsActor)this;
         }
-
+        public override int PhysicsActorType
+        {
+            get { return (int)ActorTypes.Agent; }
+            set { return; }
+        }
         public override bool IsPhysical
         {
             get { return false; }
@@ -705,16 +727,16 @@ namespace OpenSim.Region.Physics.OdePlugin
                 int truecount=0;
                 int falsecount=0;
 
-                if (m_colliderarr.Length >= 6)
+                if (m_colliderarr.Length >= 10)
                 {
-                    for (i = 0; i < 6; i++)
+                    for (i = 0; i < 10; i++)
                     {
                         m_colliderarr[i] = m_colliderarr[i + 1];
                     }
                 }
-                m_colliderarr[6] = value;
+                m_colliderarr[10] = value;
 
-                for (i = 0; i < 7; i++)
+                for (i = 0; i < 11; i++)
                 {
                     if (m_colliderarr[i])
                     {
@@ -728,7 +750,7 @@ namespace OpenSim.Region.Physics.OdePlugin
                 
                 // Equal truecounts and false counts means we're colliding with something.
 
-                if (falsecount > truecount)
+                if (falsecount > 1.2 * truecount)
                 {
                     m_iscolliding = false;
                 }
@@ -736,9 +758,25 @@ namespace OpenSim.Region.Physics.OdePlugin
                 {
                     m_iscolliding = true;
                 }
+                if (m_wascolliding != m_iscolliding)
+                {
+                    base.SendCollisionUpdate(new CollisionEventUpdate());
+                }
+                m_wascolliding = m_iscolliding;
             }
         }
-            public override PhysicsVector Position
+        public override bool CollidingGround
+        {
+            get { return false; }
+            set { return; }
+        }
+        public override bool CollidingObj
+        {
+            get { return false; }
+            set { return; }
+        }
+
+        public override PhysicsVector Position
         {
             get { return _position; }
             set
@@ -869,8 +907,30 @@ namespace OpenSim.Region.Physics.OdePlugin
                 {
                     d.Vector3 pos = d.BodyGetPosition(Body);
                     vec.Z = (_target_velocity.Z - vel.Z) * PID_D + (_zeroPosition.Z - pos.Z) * PID_P;
+                    if (_target_velocity.X > 0)
+                    {
+                        vec.X = ((_target_velocity.X - vel.X) / 1.2f) * PID_D;
+                    }
+                    if (_target_velocity.Y > 0)
+                    {
+                        vec.Y = ((_target_velocity.Y - vel.Y) / 1.2f) * PID_D;
+                    }
+                }
+                else if (!m_iscolliding && !flying)
+                {
+                    d.Vector3 pos = d.BodyGetPosition(Body);
+                    if (_target_velocity.X > 0)
+                    {
+                        vec.X = ((_target_velocity.X - vel.X)/1.2f) * PID_D;
+                    }
+                    if (_target_velocity.Y > 0)
+                    {
+                        vec.Y = ((_target_velocity.Y - vel.Y)/1.2f) * PID_D;
+                    }
+
                 }
 
+
                 if (flying)
                 {
                     vec.Z = (_target_velocity.Z - vel.Z)*PID_D;
@@ -1012,6 +1072,11 @@ namespace OpenSim.Region.Physics.OdePlugin
                     //  don't do .add() here; old geoms get recycled with the same hash
             }
         }
+        public override int PhysicsActorType
+        {
+            get { return (int)ActorTypes.Prim; }
+            set { return; }
+        }
         public void enableBody()
         {
             // Sets the geom to a body
@@ -1028,6 +1093,7 @@ namespace OpenSim.Region.Physics.OdePlugin
             d.GeomSetBody(prim_geom, Body);
             d.BodySetAutoDisableFlag(Body, true);
             d.BodySetAutoDisableSteps(Body,20);
+            
             _parent_scene.addActivePrim(this);
         }
         public void setMass()
@@ -1122,6 +1188,16 @@ namespace OpenSim.Region.Physics.OdePlugin
             get { return iscolliding; }
             set { iscolliding = value; }
         }
+        public override bool CollidingGround
+        {
+            get { return false; }
+            set { return; }
+        }
+        public override bool CollidingObj
+        {
+            get { return false; }
+            set { return; }
+        }
         public override bool ThrottleUpdates
         {
             get { return m_throttleUpdates; }
diff --git a/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs b/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs
index 7652372..1396458 100644
--- a/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs
+++ b/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs
@@ -204,7 +204,11 @@ namespace OpenSim.Region.Physics.PhysXPlugin
             _acceleration = new PhysicsVector();
             _character = character;
         }
-
+        public override int PhysicsActorType
+        {
+            get { return (int)ActorTypes.Agent; }
+            set { return; }
+        }
         public override bool IsPhysical
         {
             get { return false; }
@@ -225,6 +229,16 @@ namespace OpenSim.Region.Physics.PhysXPlugin
             get { return iscolliding; }
             set { iscolliding = value; }
         }
+        public override bool CollidingGround
+        {
+            get { return false; }
+            set { return; }
+        }
+        public override bool CollidingObj
+        {
+            get { return false; }
+            set { return; }
+        }
         public override PhysicsVector RotationalVelocity
         {
             get { return m_rotationalVelocity; }
@@ -339,7 +353,11 @@ namespace OpenSim.Region.Physics.PhysXPlugin
             _acceleration = new PhysicsVector();
             _prim = prim;
         }
-
+        public override int PhysicsActorType
+        {
+            get { return (int)ActorTypes.Prim; }
+            set { return; }
+        }
         public override bool IsPhysical
         {
             get { return false; }
@@ -365,10 +383,20 @@ namespace OpenSim.Region.Physics.PhysXPlugin
         {
             get
             {
-                return false; //no flying prims for you
+                return false; 
             }
             set { }
         }
+        public override bool CollidingGround
+        {
+            get { return false; }
+            set { return; }
+        }
+        public override bool CollidingObj
+        {
+            get { return false; }
+            set { return; }
+        }
         public override PhysicsVector Position
         {
             get
-- 
cgit v1.1