aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
diff options
context:
space:
mode:
authorTeravus Ovares2008-12-10 23:46:20 +0000
committerTeravus Ovares2008-12-10 23:46:20 +0000
commit7f80eff06732969f0d7f89e8774fc212123557e6 (patch)
tree0f927e87faa0012e0be938d3f5d62155c2be083e /OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
parent* refactor: Move test infrastructure code to its own package so that it can b... (diff)
downloadopensim-SC-7f80eff06732969f0d7f89e8774fc212123557e6.zip
opensim-SC-7f80eff06732969f0d7f89e8774fc212123557e6.tar.gz
opensim-SC-7f80eff06732969f0d7f89e8774fc212123557e6.tar.bz2
opensim-SC-7f80eff06732969f0d7f89e8774fc212123557e6.tar.xz
* Committing a slightly distilled version of nlin's ODECharacter race condition eliminator.
* The modifications that I made were only so that it didn't require changes to the public physics api.
Diffstat (limited to 'OpenSim/Region/Physics/OdePlugin/ODECharacter.cs')
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODECharacter.cs134
1 files changed, 96 insertions, 38 deletions
diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
index 6957cca..666fa86 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
@@ -26,10 +26,12 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Reflection;
29using OpenMetaverse; 30using OpenMetaverse;
30using Ode.NET; 31using Ode.NET;
31using OpenSim.Framework; 32using OpenSim.Framework;
32using OpenSim.Region.Physics.Manager; 33using OpenSim.Region.Physics.Manager;
34using log4net;
33 35
34namespace OpenSim.Region.Physics.OdePlugin 36namespace OpenSim.Region.Physics.OdePlugin
35{ 37{
@@ -55,7 +57,7 @@ namespace OpenSim.Region.Physics.OdePlugin
55 } 57 }
56 public class OdeCharacter : PhysicsActor 58 public class OdeCharacter : PhysicsActor
57 { 59 {
58 //private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 60 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
59 61
60 private PhysicsVector _position; 62 private PhysicsVector _position;
61 private d.Vector3 _zeroPosition; 63 private d.Vector3 _zeroPosition;
@@ -89,6 +91,10 @@ namespace OpenSim.Region.Physics.OdePlugin
89 private bool m_hackSentFly = false; 91 private bool m_hackSentFly = false;
90 public uint m_localID = 0; 92 public uint m_localID = 0;
91 public bool m_returnCollisions = false; 93 public bool m_returnCollisions = false;
94 // taints and their non-tainted counterparts
95 public bool m_isPhysical = false; // the current physical status
96 public bool m_tainted_isPhysical = false; // set when the physical status is tainted (false=not existing in physics engine, true=existing)
97 private float m_tainted_CAPSULE_LENGTH; // set when the capsule length changes.
92 98
93 private float m_buoyancy = 0f; 99 private float m_buoyancy = 0f;
94 100
@@ -108,10 +114,10 @@ namespace OpenSim.Region.Physics.OdePlugin
108 | CollisionCategories.Body 114 | CollisionCategories.Body
109 | CollisionCategories.Character 115 | CollisionCategories.Character
110 | CollisionCategories.Land); 116 | CollisionCategories.Land);
111 public IntPtr Body; 117 public IntPtr Body = IntPtr.Zero;
112 private OdeScene _parent_scene; 118 private OdeScene _parent_scene;
113 public IntPtr Shell; 119 public IntPtr Shell = IntPtr.Zero;
114 public IntPtr Amotor; 120 public IntPtr Amotor = IntPtr.Zero;
115 public d.Mass ShellMass; 121 public d.Mass ShellMass;
116 public bool collidelock = false; 122 public bool collidelock = false;
117 123
@@ -147,14 +153,16 @@ namespace OpenSim.Region.Physics.OdePlugin
147 } 153 }
148 CAPSULE_LENGTH = (size.Z * 1.15f) - CAPSULE_RADIUS * 2.0f; 154 CAPSULE_LENGTH = (size.Z * 1.15f) - CAPSULE_RADIUS * 2.0f;
149 //m_log.Info("[SIZE]: " + CAPSULE_LENGTH.ToString()); 155 //m_log.Info("[SIZE]: " + CAPSULE_LENGTH.ToString());
156 m_tainted_CAPSULE_LENGTH = CAPSULE_LENGTH;
157
158 m_isPhysical = false; // current status: no ODE information exists
159 m_tainted_isPhysical = true; // new tainted status: need to create ODE information
150 160
151 lock (_parent_scene.OdeLock) 161 lock (_parent_scene.OdeLock)
152 { 162 {
153 AvatarGeomAndBodyCreation(pos.X, pos.Y, pos.Z, m_tensor); 163 _parent_scene.AddPhysicsActorTaint(this);
154 } 164 }
155 m_name = avName; 165 m_name = avName;
156 parent_scene.geom_name_map[Shell] = avName;
157 parent_scene.actor_name_map[Shell] = (PhysicsActor) this;
158 } 166 }
159 167
160 public override int PhysicsActorType 168 public override int PhysicsActorType
@@ -389,27 +397,13 @@ namespace OpenSim.Region.Physics.OdePlugin
389 m_pidControllerActive = true; 397 m_pidControllerActive = true;
390 lock (_parent_scene.OdeLock) 398 lock (_parent_scene.OdeLock)
391 { 399 {
392 d.JointDestroy(Amotor);
393
394 PhysicsVector SetSize = value; 400 PhysicsVector SetSize = value;
395 float prevCapsule = CAPSULE_LENGTH; 401 m_tainted_CAPSULE_LENGTH = (SetSize.Z * 1.15f) - CAPSULE_RADIUS * 2.0f;
396 // float capsuleradius = CAPSULE_RADIUS;
397 //capsuleradius = 0.2f;
398
399 CAPSULE_LENGTH = (SetSize.Z * 1.15f) - CAPSULE_RADIUS * 2.0f;
400 //m_log.Info("[SIZE]: " + CAPSULE_LENGTH.ToString()); 402 //m_log.Info("[SIZE]: " + CAPSULE_LENGTH.ToString());
401 d.BodyDestroy(Body);
402
403 _parent_scene.waitForSpaceUnlock(_parent_scene.space);
404 403
405 d.GeomDestroy(Shell);
406 AvatarGeomAndBodyCreation(_position.X, _position.Y,
407 _position.Z + (Math.Abs(CAPSULE_LENGTH - prevCapsule) * 2), m_tensor);
408 Velocity = new PhysicsVector(0f, 0f, 0f); 404 Velocity = new PhysicsVector(0f, 0f, 0f);
409
410 } 405 }
411 _parent_scene.geom_name_map[Shell] = m_name; 406 _parent_scene.AddPhysicsActorTaint(this);
412 _parent_scene.actor_name_map[Shell] = (PhysicsActor) this;
413 } 407 }
414 } 408 }
415 409
@@ -419,9 +413,12 @@ namespace OpenSim.Region.Physics.OdePlugin
419 /// <param name="npositionX"></param> 413 /// <param name="npositionX"></param>
420 /// <param name="npositionY"></param> 414 /// <param name="npositionY"></param>
421 /// <param name="npositionZ"></param> 415 /// <param name="npositionZ"></param>
416
417 // WARNING: This MUST NOT be called outside of ProcessTaints, else we can have unsynchronized access
418 // to ODE internals. ProcessTaints is called from within thread-locked Simulate(), so it is the only
419 // place that is safe to call this routine AvatarGeomAndBodyCreation.
422 private void AvatarGeomAndBodyCreation(float npositionX, float npositionY, float npositionZ, float tensor) 420 private void AvatarGeomAndBodyCreation(float npositionX, float npositionY, float npositionZ, float tensor)
423 { 421 {
424
425 int dAMotorEuler = 1; 422 int dAMotorEuler = 1;
426 _parent_scene.waitForSpaceUnlock(_parent_scene.space); 423 _parent_scene.waitForSpaceUnlock(_parent_scene.space);
427 Shell = d.CreateCapsule(_parent_scene.space, CAPSULE_RADIUS, CAPSULE_LENGTH); 424 Shell = d.CreateCapsule(_parent_scene.space, CAPSULE_RADIUS, CAPSULE_LENGTH);
@@ -477,9 +474,6 @@ namespace OpenSim.Region.Physics.OdePlugin
477 // 474 //
478 //m_log.Info("[PHYSICSAV]: Rotation: " + bodyrotation.M00 + " : " + bodyrotation.M01 + " : " + bodyrotation.M02 + " : " + bodyrotation.M10 + " : " + bodyrotation.M11 + " : " + bodyrotation.M12 + " : " + bodyrotation.M20 + " : " + bodyrotation.M21 + " : " + bodyrotation.M22); 475 //m_log.Info("[PHYSICSAV]: Rotation: " + bodyrotation.M00 + " : " + bodyrotation.M01 + " : " + bodyrotation.M02 + " : " + bodyrotation.M10 + " : " + bodyrotation.M11 + " : " + bodyrotation.M12 + " : " + bodyrotation.M20 + " : " + bodyrotation.M21 + " : " + bodyrotation.M22);
479 //standupStraight(); 476 //standupStraight();
480
481
482
483 } 477 }
484 478
485 // 479 //
@@ -872,17 +866,8 @@ namespace OpenSim.Region.Physics.OdePlugin
872 { 866 {
873 lock (_parent_scene.OdeLock) 867 lock (_parent_scene.OdeLock)
874 { 868 {
875 // Kill the Amotor 869 m_tainted_isPhysical = false;
876 d.JointDestroy(Amotor); 870 _parent_scene.AddPhysicsActorTaint(this);
877
878 //kill the Geometry
879 _parent_scene.waitForSpaceUnlock(_parent_scene.space);
880
881 d.GeomDestroy(Shell);
882 _parent_scene.geom_name_map.Remove(Shell);
883
884 //kill the body
885 d.BodyDestroy(Body);
886 } 871 }
887 } 872 }
888 873
@@ -922,5 +907,78 @@ namespace OpenSim.Region.Physics.OdePlugin
922 return true; 907 return true;
923 return false; 908 return false;
924 } 909 }
910
911 public void ProcessTaints(float timestep)
912 {
913
914 if (m_tainted_isPhysical != m_isPhysical)
915 {
916 if (m_tainted_isPhysical)
917 {
918 // Create avatar capsule and related ODE data
919 if (!(Shell == IntPtr.Zero && Body == IntPtr.Zero && Amotor == IntPtr.Zero))
920 {
921 m_log.Warn("[PHYSICS]: re-creating the following avatar ODE data, even though it already exists - "
922 + (Shell!=IntPtr.Zero ? "Shell ":"")
923 + (Body!=IntPtr.Zero ? "Body ":"")
924 + (Amotor!=IntPtr.Zero ? "Amotor ":"") );
925 }
926 AvatarGeomAndBodyCreation(_position.X, _position.Y, _position.Z, m_tensor);
927
928 _parent_scene.geom_name_map[Shell] = m_name;
929 _parent_scene.actor_name_map[Shell] = (PhysicsActor)this;
930 }
931 else
932 {
933 // destroy avatar capsule and related ODE data
934
935 // Kill the Amotor
936 d.JointDestroy(Amotor);
937 Amotor = IntPtr.Zero;
938
939 //kill the Geometry
940 _parent_scene.waitForSpaceUnlock(_parent_scene.space);
941
942 d.GeomDestroy(Shell);
943 _parent_scene.geom_name_map.Remove(Shell);
944 Shell = IntPtr.Zero;
945
946 //kill the body
947 d.BodyDestroy(Body);
948 Body=IntPtr.Zero;
949 }
950
951 m_isPhysical = m_tainted_isPhysical;
952 }
953
954 if (m_tainted_CAPSULE_LENGTH != CAPSULE_LENGTH)
955 {
956 if (Shell != IntPtr.Zero && Body != IntPtr.Zero && Amotor != IntPtr.Zero)
957 {
958
959 m_pidControllerActive = true;
960 // no lock needed on _parent_scene.OdeLock because we are called from within the thread lock in OdePlugin's simulate()
961 d.JointDestroy(Amotor);
962 float prevCapsule = CAPSULE_LENGTH;
963 CAPSULE_LENGTH = m_tainted_CAPSULE_LENGTH;
964 //m_log.Info("[SIZE]: " + CAPSULE_LENGTH.ToString());
965 d.BodyDestroy(Body);
966 d.GeomDestroy(Shell);
967 AvatarGeomAndBodyCreation(_position.X, _position.Y,
968 _position.Z + (Math.Abs(CAPSULE_LENGTH - prevCapsule) * 2), m_tensor);
969 Velocity = new PhysicsVector(0f, 0f, 0f);
970
971 _parent_scene.geom_name_map[Shell] = m_name;
972 _parent_scene.actor_name_map[Shell] = (PhysicsActor)this;
973 }
974 else
975 {
976 m_log.Warn("[PHYSICS]: trying to change capsule size, but the following ODE data is missing - "
977 + (Shell==IntPtr.Zero ? "Shell ":"")
978 + (Body==IntPtr.Zero ? "Body ":"")
979 + (Amotor==IntPtr.Zero ? "Amotor ":"") );
980 }
981 }
982 }
925 } 983 }
926} 984}