diff options
Diffstat (limited to 'OpenSim/Region/Physics/OdePlugin/ODECharacter.cs')
-rw-r--r-- | OpenSim/Region/Physics/OdePlugin/ODECharacter.cs | 134 |
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 | ||
28 | using System; | 28 | using System; |
29 | using System.Reflection; | ||
29 | using OpenMetaverse; | 30 | using OpenMetaverse; |
30 | using Ode.NET; | 31 | using Ode.NET; |
31 | using OpenSim.Framework; | 32 | using OpenSim.Framework; |
32 | using OpenSim.Region.Physics.Manager; | 33 | using OpenSim.Region.Physics.Manager; |
34 | using log4net; | ||
33 | 35 | ||
34 | namespace OpenSim.Region.Physics.OdePlugin | 36 | namespace 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 | } |