* Added a routine to check if a PhysicsVector and Quaternion is finite

* Now validating input to the Physics scene and warning when something is awry.
* This should help nail down that Non Finite Avatar Position Detected issue.
0.6.5-rc1
Teravus Ovares 2009-04-07 16:13:17 +00:00
parent 11f8ea30f9
commit 9bbc7e8bf6
3 changed files with 193 additions and 45 deletions

View File

@ -153,6 +153,20 @@ namespace OpenSim.Region.Physics.Manager
return v*f; return v*f;
} }
public static bool isFinite(PhysicsVector v)
{
if (v == null)
return false;
if (Single.IsInfinity(v.X) || Single.IsNaN(v.X))
return false;
if (Single.IsInfinity(v.Y) || Single.IsNaN(v.Y))
return false;
if (Single.IsInfinity(v.Z) || Single.IsNaN(v.Z))
return false;
return true;
}
public virtual bool IsIdentical(PhysicsVector v, float tolerance) public virtual bool IsIdentical(PhysicsVector v, float tolerance)
{ {
PhysicsVector diff = this - v; PhysicsVector diff = this - v;

View File

@ -380,10 +380,23 @@ namespace OpenSim.Region.Physics.OdePlugin
set set
{ {
if (Body == IntPtr.Zero || Shell == IntPtr.Zero) if (Body == IntPtr.Zero || Shell == IntPtr.Zero)
_position.X = value.X; _position.Y = value.Y; _position.Z = value.Z; {
if (PhysicsVector.isFinite(value))
m_taintPosition.X = value.X; m_taintPosition.Y = value.Y; m_taintPosition.Z = value.Z; {
_parent_scene.AddPhysicsActorTaint(this); _position.X = value.X;
_position.Y = value.Y;
_position.Z = value.Z;
m_taintPosition.X = value.X;
m_taintPosition.Y = value.Y;
m_taintPosition.Z = value.Z;
_parent_scene.AddPhysicsActorTaint(this);
}
else
{
m_log.Warn("[PHYSICS]: Got a NaN Position from Scene on a Character");
}
}
} }
} }
@ -402,15 +415,22 @@ namespace OpenSim.Region.Physics.OdePlugin
get { return new PhysicsVector(CAPSULE_RADIUS*2, CAPSULE_RADIUS*2, CAPSULE_LENGTH); } get { return new PhysicsVector(CAPSULE_RADIUS*2, CAPSULE_RADIUS*2, CAPSULE_LENGTH); }
set set
{ {
m_pidControllerActive = true; if (PhysicsVector.isFinite(value))
{
m_pidControllerActive = true;
PhysicsVector SetSize = value; PhysicsVector SetSize = value;
m_tainted_CAPSULE_LENGTH = (SetSize.Z * 1.15f) - CAPSULE_RADIUS * 2.0f; m_tainted_CAPSULE_LENGTH = (SetSize.Z*1.15f) - CAPSULE_RADIUS*2.0f;
//m_log.Info("[SIZE]: " + CAPSULE_LENGTH.ToString()); //m_log.Info("[SIZE]: " + CAPSULE_LENGTH.ToString());
Velocity = new PhysicsVector(0f, 0f, 0f); Velocity = new PhysicsVector(0f, 0f, 0f);
_parent_scene.AddPhysicsActorTaint(this); _parent_scene.AddPhysicsActorTaint(this);
}
else
{
m_log.Warn("[PHYSICS]: Got a NaN Size from Scene on a Character");
}
} }
} }
@ -616,8 +636,15 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
set set
{ {
m_pidControllerActive = true; if (PhysicsVector.isFinite(value))
_target_velocity = value; {
m_pidControllerActive = true;
_target_velocity = value;
}
else
{
m_log.Warn("[PHYSICS]: Got a NaN velocity from Scene in a Character");
}
} }
} }
@ -667,22 +694,29 @@ namespace OpenSim.Region.Physics.OdePlugin
/// <param name="force"></param> /// <param name="force"></param>
public override void AddForce(PhysicsVector force, bool pushforce) public override void AddForce(PhysicsVector force, bool pushforce)
{ {
if (pushforce) if (PhysicsVector.isFinite(force))
{ {
m_pidControllerActive = false; if (pushforce)
force *= 100f; {
doForce(force); m_pidControllerActive = false;
//m_log.Debug("Push!"); force *= 100f;
//_target_velocity.X += force.X; doForce(force);
// _target_velocity.Y += force.Y; //m_log.Debug("Push!");
//_target_velocity.Z += force.Z; //_target_velocity.X += force.X;
// _target_velocity.Y += force.Y;
//_target_velocity.Z += force.Z;
}
else
{
m_pidControllerActive = true;
_target_velocity.X += force.X;
_target_velocity.Y += force.Y;
_target_velocity.Z += force.Z;
}
} }
else else
{ {
m_pidControllerActive = true; m_log.Warn("[PHYSICS]: Got a NaN force applied to a Character");
_target_velocity.X += force.X;
_target_velocity.Y += force.Y;
_target_velocity.Z += force.Z;
} }
//m_lastUpdateSent = false; //m_lastUpdateSent = false;
} }
@ -847,8 +881,14 @@ namespace OpenSim.Region.Physics.OdePlugin
// end add Kitto Flora // end add Kitto Flora
} }
if (PhysicsVector.isFinite(vec))
doForce(vec); {
doForce(vec);
}
else
{
m_log.Warn("[PHYSICS]: Got a NaN force vector in Move()");
}
} }
/// <summary> /// <summary>

View File

@ -2325,7 +2325,17 @@ namespace OpenSim.Region.Physics.OdePlugin
public override PhysicsVector Size public override PhysicsVector Size
{ {
get { return _size; } get { return _size; }
set { _size = value; } set
{
if (PhysicsVector.isFinite(value))
{
_size = value;
}
else
{
m_log.Warn("[PHYSICS]: Got NaN Size on object");
}
}
} }
public override float Mass public override float Mass
@ -2337,7 +2347,17 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
//get { return PhysicsVector.Zero; } //get { return PhysicsVector.Zero; }
get { return m_force; } get { return m_force; }
set { m_force = value; } set
{
if (PhysicsVector.isFinite(value))
{
m_force = value;
}
else
{
m_log.Warn("[PHYSICS]: NaN in Force Applied to an Object");
}
}
} }
public override int VehicleType public override int VehicleType
@ -2402,10 +2422,18 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
set set
{ {
_velocity = value; if (PhysicsVector.isFinite(value))
{
_velocity = value;
m_taintVelocity = value;
_parent_scene.AddPhysicsActorTaint(this);
}
else
{
m_log.Warn("[PHYSICS]: Got NaN Velocity in Object");
}
m_taintVelocity = value;
_parent_scene.AddPhysicsActorTaint(this);
} }
} }
@ -2421,8 +2449,15 @@ namespace OpenSim.Region.Physics.OdePlugin
set set
{ {
m_taintTorque = value; if (PhysicsVector.isFinite(value))
_parent_scene.AddPhysicsActorTaint(this); {
m_taintTorque = value;
_parent_scene.AddPhysicsActorTaint(this);
}
else
{
m_log.Warn("[PHYSICS]: Got NaN Torque in Object");
}
} }
} }
@ -2441,7 +2476,27 @@ namespace OpenSim.Region.Physics.OdePlugin
public override Quaternion Orientation public override Quaternion Orientation
{ {
get { return _orientation; } get { return _orientation; }
set { _orientation = value; } set
{
if (QuaternionIsFinite(value))
_orientation = value;
else
m_log.Warn("[PHYSICS]: Got NaN quaternion Orientation from Scene in Object");
}
}
internal static bool QuaternionIsFinite(Quaternion q)
{
if (Single.IsNaN(q.X) || Single.IsInfinity(q.X))
return false;
if (Single.IsNaN(q.Y) || Single.IsInfinity(q.Y))
return false;
if (Single.IsNaN(q.Z) || Single.IsInfinity(q.Z))
return false;
if (Single.IsNaN(q.W) || Single.IsInfinity(q.W))
return false;
return true;
} }
public override PhysicsVector Acceleration public override PhysicsVector Acceleration
@ -2457,15 +2512,29 @@ namespace OpenSim.Region.Physics.OdePlugin
public override void AddForce(PhysicsVector force, bool pushforce) public override void AddForce(PhysicsVector force, bool pushforce)
{ {
m_forcelist.Add(force); if (PhysicsVector.isFinite(force))
m_taintforce = true; {
m_forcelist.Add(force);
m_taintforce = true;
}
else
{
m_log.Warn("[PHYSICS]: Got Invalid linear force vector from Scene in Object");
}
//m_log.Info("[PHYSICS]: Added Force:" + force.ToString() + " to prim at " + Position.ToString()); //m_log.Info("[PHYSICS]: Added Force:" + force.ToString() + " to prim at " + Position.ToString());
} }
public override void AddAngularForce(PhysicsVector force, bool pushforce) public override void AddAngularForce(PhysicsVector force, bool pushforce)
{ {
m_angularforcelist.Add(force); if (PhysicsVector.isFinite(force))
m_taintaddangularforce = true; {
m_angularforcelist.Add(force);
m_taintaddangularforce = true;
}
else
{
m_log.Warn("[PHYSICS]: Got Invalid Angular force vector from Scene in Object");
}
} }
public override PhysicsVector RotationalVelocity public override PhysicsVector RotationalVelocity
@ -2482,7 +2551,17 @@ namespace OpenSim.Region.Physics.OdePlugin
return m_rotationalVelocity; return m_rotationalVelocity;
} }
set { m_rotationalVelocity = value; } set
{
if (PhysicsVector.isFinite(value))
{
m_rotationalVelocity = value;
}
else
{
m_log.Warn("[PHYSICS]: Got NaN RotationalVelocity in Object");
}
}
} }
public override void CrossingFailure() public override void CrossingFailure()
@ -2518,12 +2597,18 @@ namespace OpenSim.Region.Physics.OdePlugin
public override void LockAngularMotion(PhysicsVector axis) public override void LockAngularMotion(PhysicsVector axis)
{ {
// reverse the zero/non zero values for ODE. // reverse the zero/non zero values for ODE.
if (PhysicsVector.isFinite(axis))
axis.X = (axis.X > 0) ? 1f : 0f; {
axis.Y = (axis.Y > 0) ? 1f : 0f; axis.X = (axis.X > 0) ? 1f : 0f;
axis.Z = (axis.Z > 0) ? 1f : 0f; axis.Y = (axis.Y > 0) ? 1f : 0f;
m_log.DebugFormat("[axislock]: <{0},{1},{2}>", axis.X, axis.Y, axis.Z); axis.Z = (axis.Z > 0) ? 1f : 0f;
m_taintAngularLock = new PhysicsVector(axis.X, axis.Y, axis.Z); ; m_log.DebugFormat("[axislock]: <{0},{1},{2}>", axis.X, axis.Y, axis.Z);
m_taintAngularLock = new PhysicsVector(axis.X, axis.Y, axis.Z);
}
else
{
m_log.Warn("[PHYSICS]: Got NaN locking axis from Scene on Object");
}
} }
public void UpdatePositionAndVelocity() public void UpdatePositionAndVelocity()
@ -2734,7 +2819,16 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
} }
public override PhysicsVector PIDTarget { set { m_PIDTarget = value; ; } } public override PhysicsVector PIDTarget
{
set
{
if (PhysicsVector.isFinite(value))
m_PIDTarget = value;
else
m_log.Warn("[PHYSICS]: Got NaN PIDTarget from Scene on Object");
}
}
public override bool PIDActive { set { m_usePID = value; } } public override bool PIDActive { set { m_usePID = value; } }
public override float PIDTau { set { m_PIDTau = value; } } public override float PIDTau { set { m_PIDTau = value; } }