BulletSim: implementation of vertical attraction motor.
parent
9e0db36c82
commit
59554758b1
|
@ -125,6 +125,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
// Therefore only m_VehicleBuoyancy=1 (0g) will use the script-requested .Z velocity.
|
// Therefore only m_VehicleBuoyancy=1 (0g) will use the script-requested .Z velocity.
|
||||||
|
|
||||||
//Attractor properties
|
//Attractor properties
|
||||||
|
private BSVMotor m_verticalAttractionMotor = new BSVMotor("VerticalAttraction");
|
||||||
private float m_verticalAttractionEfficiency = 1.0f; // damped
|
private float m_verticalAttractionEfficiency = 1.0f; // damped
|
||||||
private float m_verticalAttractionTimescale = 500f; // Timescale > 300 means no vert attractor.
|
private float m_verticalAttractionTimescale = 500f; // Timescale > 300 means no vert attractor.
|
||||||
|
|
||||||
|
@ -197,9 +198,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
break;
|
break;
|
||||||
case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY:
|
case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY:
|
||||||
m_verticalAttractionEfficiency = Math.Max(0.1f, Math.Min(pValue, 1f));
|
m_verticalAttractionEfficiency = Math.Max(0.1f, Math.Min(pValue, 1f));
|
||||||
|
m_verticalAttractionMotor.Efficiency = m_verticalAttractionEfficiency;
|
||||||
break;
|
break;
|
||||||
case Vehicle.VERTICAL_ATTRACTION_TIMESCALE:
|
case Vehicle.VERTICAL_ATTRACTION_TIMESCALE:
|
||||||
m_verticalAttractionTimescale = Math.Max(pValue, 0.01f);
|
m_verticalAttractionTimescale = Math.Max(pValue, 0.01f);
|
||||||
|
m_verticalAttractionMotor.TimeScale = m_verticalAttractionTimescale;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// These are vector properties but the engine lets you use a single float value to
|
// These are vector properties but the engine lets you use a single float value to
|
||||||
|
@ -530,12 +533,22 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
Refresh();
|
Refresh();
|
||||||
|
|
||||||
m_linearMotor = new BSVMotor("LinearMotor", m_linearMotorTimescale,
|
m_linearMotor = new BSVMotor("LinearMotor", m_linearMotorTimescale,
|
||||||
m_linearMotorDecayTimescale, m_linearFrictionTimescale, 1f);
|
m_linearMotorDecayTimescale, m_linearFrictionTimescale,
|
||||||
|
1f);
|
||||||
m_linearMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging)
|
m_linearMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging)
|
||||||
|
|
||||||
m_angularMotor = new BSVMotor("AngularMotor", m_angularMotorTimescale,
|
m_angularMotor = new BSVMotor("AngularMotor", m_angularMotorTimescale,
|
||||||
m_angularMotorDecayTimescale, m_angularFrictionTimescale, 1f);
|
m_angularMotorDecayTimescale, m_angularFrictionTimescale,
|
||||||
|
1f);
|
||||||
m_angularMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging)
|
m_angularMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging)
|
||||||
|
|
||||||
|
m_verticalAttractionMotor = new BSVMotor("VerticalAttraction", m_verticalAttractionTimescale,
|
||||||
|
BSMotor.Infinite, BSMotor.InfiniteVector,
|
||||||
|
m_verticalAttractionEfficiency);
|
||||||
|
// Z goes away and we keep X and Y
|
||||||
|
m_verticalAttractionMotor.FrictionTimescale = new Vector3(BSMotor.Infinite, BSMotor.Infinite, 0.1f);
|
||||||
|
m_verticalAttractionMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging)
|
||||||
|
|
||||||
// m_bankingMotor = new BSVMotor("BankingMotor", ...);
|
// m_bankingMotor = new BSVMotor("BankingMotor", ...);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -828,47 +841,64 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
|
|
||||||
Vector3 angularMotorContribution = m_angularMotor.Step(pTimestep);
|
Vector3 angularMotorContribution = m_angularMotor.Step(pTimestep);
|
||||||
|
|
||||||
|
// ==================================================================
|
||||||
|
// NO_DEFLECTION_UP says angular motion should not add any pitch or roll movement
|
||||||
|
if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0)
|
||||||
|
{
|
||||||
|
angularMotorContribution.X = 0f;
|
||||||
|
angularMotorContribution.Y = 0f;
|
||||||
|
VDetailLog("{0},MoveAngular,noDeflectionUp,angularMotorContrib={1}", Prim.LocalID, angularMotorContribution);
|
||||||
|
}
|
||||||
|
|
||||||
// ==================================================================
|
// ==================================================================
|
||||||
Vector3 verticalAttractionContribution = Vector3.Zero;
|
Vector3 verticalAttractionContribution = Vector3.Zero;
|
||||||
// If vertical attaction timescale is reasonable and we applied an angular force last time...
|
// If vertical attaction timescale is reasonable and we applied an angular force last time...
|
||||||
if (m_verticalAttractionTimescale < 300 && m_lastAngularVelocity != Vector3.Zero)
|
if (m_verticalAttractionTimescale < 500)
|
||||||
{
|
{
|
||||||
float VAservo = pTimestep * 0.2f / m_verticalAttractionTimescale;
|
|
||||||
if (Prim.IsColliding)
|
|
||||||
VAservo = pTimestep * 0.05f / m_verticalAttractionTimescale;
|
|
||||||
|
|
||||||
VAservo *= (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency);
|
|
||||||
|
|
||||||
// Create a vector of the vehicle "up" in world coordinates
|
|
||||||
Vector3 verticalError = Vector3.UnitZ * Prim.ForceOrientation;
|
Vector3 verticalError = Vector3.UnitZ * Prim.ForceOrientation;
|
||||||
// verticalError.X and .Y are the World error amounts. They are 0 when there is no
|
verticalError.Normalize();
|
||||||
// error (Vehicle Body is 'vertical'), and .Z will be 1. As the body leans to its
|
m_verticalAttractionMotor.SetCurrent(verticalError);
|
||||||
// side |.X| will increase to 1 and .Z fall to 0. As body inverts |.X| will fall
|
m_verticalAttractionMotor.SetTarget(Vector3.UnitZ);
|
||||||
// and .Z will go negative. Similar for tilt and |.Y|. .X and .Y must be
|
verticalAttractionContribution = m_verticalAttractionMotor.Step(pTimestep);
|
||||||
// modulated to prevent a stable inverted body.
|
/*
|
||||||
|
// Take a vector pointing up and convert it from world to vehicle relative coords.
|
||||||
|
Vector3 verticalError = Vector3.UnitZ * Prim.ForceOrientation;
|
||||||
|
verticalError.Normalize();
|
||||||
|
|
||||||
// Error is 0 (no error) to +/- 2 (max error)
|
// If vertical attraction correction is needed, the vector that was pointing up (UnitZ)
|
||||||
verticalError.X = Math.Max(-2f, Math.Min(verticalError.X, 2f));
|
// is now leaning to one side (rotated around the X axis) and the Y value will
|
||||||
verticalError.Y = Math.Max(-2f, Math.Min(verticalError.Y, 2f));
|
// go from zero (nearly straight up) to one (completely to the side) or leaning
|
||||||
|
// front-to-back (rotated around the Y axis) and the value of X will be between
|
||||||
|
// zero and one.
|
||||||
|
// The value of Z is how far the rotation is off with 1 meaning none and 0 being 90 degrees.
|
||||||
|
|
||||||
// scale it by VAservo (timestep and timescale)
|
// If verticalError.Z is negative, the vehicle is upside down. Add additional push.
|
||||||
verticalError = verticalError * VAservo;
|
if (verticalError.Z < 0f)
|
||||||
|
{
|
||||||
|
verticalError.X = 2f - verticalError.X;
|
||||||
|
verticalError.Y = 2f - verticalError.Y;
|
||||||
|
}
|
||||||
|
|
||||||
// As the body rotates around the X axis, then verticalError.Y increases; Rotated around Y
|
// Y error means needed rotation around X axis and visa versa.
|
||||||
// then .X increases, so change Body angular velocity X based on Y, and Y based on X.
|
|
||||||
// Z is not changed.
|
|
||||||
verticalAttractionContribution.X = verticalError.Y;
|
verticalAttractionContribution.X = verticalError.Y;
|
||||||
verticalAttractionContribution.Y = - verticalError.X;
|
verticalAttractionContribution.Y = - verticalError.X;
|
||||||
verticalAttractionContribution.Z = 0f;
|
verticalAttractionContribution.Z = 0f;
|
||||||
|
|
||||||
// scaling appears better usingsquare-law
|
// scale by the time scale and timestep
|
||||||
Vector3 angularVelocity = Prim.ForceRotationalVelocity;
|
Vector3 unscaledContrib = verticalAttractionContribution;
|
||||||
float bounce = 1.0f - (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency);
|
verticalAttractionContribution /= m_verticalAttractionTimescale;
|
||||||
verticalAttractionContribution.X += bounce * angularVelocity.X;
|
verticalAttractionContribution *= pTimestep;
|
||||||
verticalAttractionContribution.Y += bounce * angularVelocity.Y;
|
|
||||||
|
|
||||||
VDetailLog("{0},MoveAngular,verticalAttraction,VAservo={1},effic={2},verticalError={3},bounce={4},vertattr={5}",
|
// apply efficiency
|
||||||
Prim.LocalID, VAservo, m_verticalAttractionEfficiency, verticalError, bounce, verticalAttractionContribution);
|
Vector3 preEfficiencyContrib = verticalAttractionContribution;
|
||||||
|
float efficencySquared = m_verticalAttractionEfficiency * m_verticalAttractionEfficiency;
|
||||||
|
verticalAttractionContribution *= (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency);
|
||||||
|
|
||||||
|
VDetailLog("{0},MoveAngular,verticalAttraction,,verticalError={1},unscaled={2},preEff={3},eff={4},effSq={5},vertAttr={6}",
|
||||||
|
Prim.LocalID, verticalError, unscaledContrib, preEfficiencyContrib,
|
||||||
|
m_verticalAttractionEfficiency, efficencySquared,
|
||||||
|
verticalAttractionContribution);
|
||||||
|
*/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -988,15 +1018,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
VDetailLog("{0},BSDynamic.MoveAngular,motorOffset,applyTorqueImpulse={1}", Prim.LocalID, torqueFromOffset);
|
VDetailLog("{0},BSDynamic.MoveAngular,motorOffset,applyTorqueImpulse={1}", Prim.LocalID, torqueFromOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==================================================================
|
|
||||||
// NO_DEFLECTION_UP says angular motion should not add any pitch or roll movement
|
|
||||||
if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0)
|
|
||||||
{
|
|
||||||
m_lastAngularVelocity.X = 0;
|
|
||||||
m_lastAngularVelocity.Y = 0;
|
|
||||||
VDetailLog("{0},MoveAngular,noDeflectionUp,lastAngular={1}", Prim.LocalID, m_lastAngularVelocity);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ==================================================================
|
// ==================================================================
|
||||||
if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f))
|
if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f))
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue