diff --git a/OpenSim/Region/Environment/Scenes/ScenePresence.cs b/OpenSim/Region/Environment/Scenes/ScenePresence.cs index ab19973b55..5d643d148c 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 /// 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 1d1c14f991..3283ec0430 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 2db7a5487a..b51f0243fe 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 9ce7cf3b2f..49760dad28 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 m_objCollisionList; + public CollisionEventUpdate(uint localID, int colliderType, bool startOrEnd, List 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 98c5995f36..c93b96fe34 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,7 +907,29 @@ 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) { @@ -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 7652372758..1396458250 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 diff --git a/bin/data/avataranimations.xml b/bin/data/avataranimations.xml index 2a537274ff..ac769e296d 100644 --- a/bin/data/avataranimations.xml +++ b/bin/data/avataranimations.xml @@ -12,4 +12,6 @@ 201f3fdf-cb1f-dbec-201f-7333e328ae7c 47f5f6fb-22e5-ae44-f871-73aaaf4a6022 c541c47f-e0c0-058b-ad1a-d6ae3a4584d9 + 666307d9-a860-572d-6fd4-c3ab8865c094 + 2305bd75-1ca9-b03b-1faa-b176b8a8c49e