diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
index 6c0c6907f2..d738247a63 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
@@ -70,7 +70,6 @@ namespace OpenSim.Region.Physics.OdePlugin
private Vector3 _position;
private d.Vector3 _zeroPosition;
- // private d.Matrix3 m_StandUpRotation;
private bool _zeroFlag = false;
private bool m_lastUpdateSent = false;
private Vector3 _velocity;
@@ -100,7 +99,14 @@ namespace OpenSim.Region.Physics.OdePlugin
private bool m_hackSentFall = false;
private bool m_hackSentFly = false;
private int m_requestedUpdateFrequency = 0;
- private Vector3 m_taintPosition = Vector3.Zero;
+ private Vector3 m_taintPosition;
+
+ ///
+ /// Hold set forces so we can process them outside physics calculations. This prevents race conditions if we set force
+ /// while calculatios are going on
+ ///
+ private Vector3 m_taintForce;
+
internal uint m_localID = 0;
// taints and their non-tainted counterparts
private bool m_isPhysical = false; // the current physical status
@@ -553,8 +559,6 @@ namespace OpenSim.Region.Physics.OdePlugin
// place that is safe to call this routine AvatarGeomAndBodyCreation.
private void AvatarGeomAndBodyCreation(float npositionX, float npositionY, float npositionZ, float tensor)
{
- //CAPSULE_LENGTH = -5;
- //CAPSULE_RADIUS = -5;
int dAMotorEuler = 1;
// _parent_scene.waitForSpaceUnlock(_parent_scene.space);
if (CAPSULE_LENGTH <= 0)
@@ -827,7 +831,9 @@ namespace OpenSim.Region.Physics.OdePlugin
{
m_pidControllerActive = false;
force *= 100f;
- doForce(force);
+ m_taintForce += force;
+ _parent_scene.AddPhysicsActorTaint(this);
+
// If uncommented, things get pushed off world
//
// m_log.Debug("Push!");
@@ -852,15 +858,6 @@ namespace OpenSim.Region.Physics.OdePlugin
{
}
- ///
- /// After all of the forces add up with 'add force' we apply them with doForce
- ///
- ///
- public void doForce(Vector3 force)
- {
- d.BodyAddForce(Body, force.X, force.Y, force.Z);
- }
-
public override void SetMomentum(Vector3 momentum)
{
}
@@ -1026,7 +1023,8 @@ namespace OpenSim.Region.Physics.OdePlugin
if (vec.IsFinite())
{
- doForce(vec);
+ // Apply the total force acting on this avatar
+ d.BodyAddForce(Body, vec.X, vec.Y, vec.Z);
if (!_zeroFlag)
AlignAvatarTiltWithCurrentDirectionOfMovement(vec);
@@ -1247,6 +1245,19 @@ namespace OpenSim.Region.Physics.OdePlugin
}
}
+ if (m_taintForce != Vector3.Zero)
+ {
+ if (Body != IntPtr.Zero)
+ {
+ // FIXME: This is not a good solution since it's subject to a race condition if a force is another
+ // thread sets a new force while we're in this loop (since it could be obliterated by
+ // m_taintForce = Vector3.Zero. Need to lock ProcessTaints() when we set a new tainted force.
+ d.BodyAddForce(Body, m_taintForce.X, m_taintForce.Y, m_taintForce.Z);
+ }
+
+ m_taintForce = Vector3.Zero;
+ }
+
if (m_taintTargetVelocity != _target_velocity)
_target_velocity = m_taintTargetVelocity;