BulletSim: increase vehicle stability by suppressing Bullet's update to angular velocity.

integration
Robert Adams 2012-11-26 10:47:34 -08:00
parent 084e3926ca
commit 5685b33071
4 changed files with 27 additions and 60 deletions

View File

@ -805,6 +805,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// m_angularFrictionTimescale // body angular velocity decay rate // m_angularFrictionTimescale // body angular velocity decay rate
// m_lastAngularVelocity // what was last applied to body // m_lastAngularVelocity // what was last applied to body
/*
if (m_angularMotorDirection.LengthSquared() > 0.0001) if (m_angularMotorDirection.LengthSquared() > 0.0001)
{ {
Vector3 origVel = m_angularMotorVelocity; Vector3 origVel = m_angularMotorVelocity;
@ -823,6 +824,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
{ {
m_angularMotorVelocity = Vector3.Zero; m_angularMotorVelocity = Vector3.Zero;
} }
*/
Vector3 angularMotorContribution = m_angularMotor.Step(pTimestep); Vector3 angularMotorContribution = m_angularMotor.Step(pTimestep);
@ -842,15 +844,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// verticalError.X and .Y are the World error amounts. They are 0 when there is no // verticalError.X and .Y are the World error amounts. They are 0 when there is no
// error (Vehicle Body is 'vertical'), and .Z will be 1. As the body leans to its // error (Vehicle Body is 'vertical'), and .Z will be 1. As the body leans to its
// side |.X| will increase to 1 and .Z fall to 0. As body inverts |.X| will fall // side |.X| will increase to 1 and .Z fall to 0. As body inverts |.X| will fall
// and .Z will go // negative. Similar for tilt and |.Y|. .X and .Y must be // and .Z will go negative. Similar for tilt and |.Y|. .X and .Y must be
// modulated to prevent a stable inverted body. // modulated to prevent a stable inverted body.
// Error is 0 (no error) to +/- 2 (max error) // Error is 0 (no error) to +/- 2 (max error)
if (verticalError.Z < 0.0f) verticalError.X = Math.Max(-2f, Math.Min(verticalError.X, 2f));
{ verticalError.Y = Math.Max(-2f, Math.Min(verticalError.Y, 2f));
verticalError.X = 2.0f - verticalError.X;
verticalError.Y = 2.0f - verticalError.Y;
}
// scale it by VAservo (timestep and timescale) // scale it by VAservo (timestep and timescale)
verticalError = verticalError * VAservo; verticalError = verticalError * VAservo;
@ -1013,10 +1013,15 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// Also remove any motion that is on the object so added motion is only from vehicle. // Also remove any motion that is on the object so added motion is only from vehicle.
Vector3 applyAngularForce = ((m_lastAngularVelocity * pTimestep) Vector3 applyAngularForce = ((m_lastAngularVelocity * pTimestep)
- Prim.ForceRotationalVelocity); - Prim.ForceRotationalVelocity);
// Unscale the force by the angular factor so it overwhelmes the Bullet additions.
Prim.ForceRotationalVelocity = applyAngularForce; Prim.ForceRotationalVelocity = applyAngularForce;
VDetailLog("{0},MoveAngular,done,newRotVel={1},lastAngular={2}", VDetailLog("{0},MoveAngular,done,angMotor={1},vertAttr={2},bank={3},deflect={4},newAngForce={5},lastAngular={6}",
Prim.LocalID, applyAngularForce, m_lastAngularVelocity); Prim.LocalID,
angularMotorContribution, verticalAttractionContribution,
bankingContribution, deflectionContribution,
applyAngularForce, m_lastAngularVelocity
);
} }
} }

View File

@ -1380,54 +1380,16 @@ public sealed class BSPrim : BSPhysObject
public override void UpdateProperties(EntityProperties entprop) public override void UpdateProperties(EntityProperties entprop)
{ {
/*
UpdatedProperties changed = 0;
// assign to the local variables so the normal set action does not happen
// if (_position != entprop.Position)
if (!_position.ApproxEquals(entprop.Position, POSITION_TOLERANCE))
{
_position = entprop.Position;
changed |= UpdatedProperties.Position;
}
// if (_orientation != entprop.Rotation)
if (!_orientation.ApproxEquals(entprop.Rotation, ROTATION_TOLERANCE))
{
_orientation = entprop.Rotation;
changed |= UpdatedProperties.Rotation;
}
// if (_velocity != entprop.Velocity)
if (!_velocity.ApproxEquals(entprop.Velocity, VELOCITY_TOLERANCE))
{
_velocity = entprop.Velocity;
changed |= UpdatedProperties.Velocity;
}
// if (_acceleration != entprop.Acceleration)
if (!_acceleration.ApproxEquals(entprop.Acceleration, ACCELERATION_TOLERANCE))
{
_acceleration = entprop.Acceleration;
changed |= UpdatedProperties.Acceleration;
}
// if (_rotationalVelocity != entprop.RotationalVelocity)
if (!_rotationalVelocity.ApproxEquals(entprop.RotationalVelocity, ROTATIONAL_VELOCITY_TOLERANCE))
{
_rotationalVelocity = entprop.RotationalVelocity;
changed |= UpdatedProperties.RotationalVel;
}
if (changed != 0)
{
// Only update the position of single objects and linkset roots
if (Linkset.IsRoot(this))
{
base.RequestPhysicsterseUpdate();
}
}
*/
// Don't check for damping here -- it's done in BulletSim and SceneObjectPart.
// Updates only for individual prims and for the root object of a linkset. // Updates only for individual prims and for the root object of a linkset.
if (Linkset.IsRoot(this)) if (Linkset.IsRoot(this))
{ {
// A temporary kludge to suppress the rotational effects introduced on vehicles by Bullet
// TODO: handle physics introduced by Bullet with computed vehicle physics.
if (_vehicle.IsActive)
{
entprop.RotationalVelocity = OMV.Vector3.Zero;
}
// Assign directly to the local variables so the normal set action does not happen // Assign directly to the local variables so the normal set action does not happen
_position = entprop.Position; _position = entprop.Position;
_orientation = entprop.Rotation; _orientation = entprop.Rotation;

View File

@ -515,9 +515,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
collidersCount = 0; collidersCount = 0;
} }
// Don't have to use the pointers passed back since we know it is the same pinned memory we passed in // Don't have to use the pointers passed back since we know it is the same pinned memory we passed in.
// Get a value for 'now' so all the collision and update routines don't have to get their own // Get a value for 'now' so all the collision and update routines don't have to get their own.
SimulationNowTime = Util.EnvironmentTickCount(); SimulationNowTime = Util.EnvironmentTickCount();
// If there were collisions, process them by sending the event to the prim. // If there were collisions, process them by sending the event to the prim.
@ -563,6 +563,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
ObjectsWithCollisions.Remove(po); ObjectsWithCollisions.Remove(po);
ObjectsWithNoMoreCollisions.Clear(); ObjectsWithNoMoreCollisions.Clear();
} }
// Done with collisions.
// If any of the objects had updated properties, tell the object it has been changed by the physics engine // If any of the objects had updated properties, tell the object it has been changed by the physics engine
if (updatedEntityCount > 0) if (updatedEntityCount > 0)
@ -586,9 +587,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
// The physics engine returns the number of milliseconds it simulated this call. // The physics engine returns the number of milliseconds it simulated this call.
// These are summed and normalized to one second and divided by 1000 to give the reported physics FPS. // These are summed and normalized to one second and divided by 1000 to give the reported physics FPS.
// We multiply by 55 to give a recognizable running rate (55 or less). // Multiply by 55 to give a nominal frame rate of 55.
return numSubSteps * m_fixedTimeStep * 1000 * 55; return (float)numSubSteps * m_fixedTimeStep * 1000f * 55f;
// return timeStep * 1000 * 55;
} }
// Something has collided // Something has collided
@ -1172,7 +1172,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
(s) => { return s.m_params[0].avatarFriction; }, (s) => { return s.m_params[0].avatarFriction; },
(s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarFriction, p, l, v); } ), (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarFriction, p, l, v); } ),
new ParameterDefn("AvatarStandingFriction", "Avatar friction when standing. Changed on avatar recreation.", new ParameterDefn("AvatarStandingFriction", "Avatar friction when standing. Changed on avatar recreation.",
0.99f, 10.0f,
(s,cf,p,v) => { s.m_params[0].avatarStandingFriction = cf.GetFloat(p, v); }, (s,cf,p,v) => { s.m_params[0].avatarStandingFriction = cf.GetFloat(p, v); },
(s) => { return s.m_params[0].avatarStandingFriction; }, (s) => { return s.m_params[0].avatarStandingFriction; },
(s,p,l,v) => { s.m_params[0].avatarStandingFriction = v; } ), (s,p,l,v) => { s.m_params[0].avatarStandingFriction = v; } ),

View File

@ -357,7 +357,7 @@ public enum CollisionFlags : uint
CF_CHARACTER_OBJECT = 1 << 4, CF_CHARACTER_OBJECT = 1 << 4,
CF_DISABLE_VISUALIZE_OBJECT = 1 << 5, CF_DISABLE_VISUALIZE_OBJECT = 1 << 5,
CF_DISABLE_SPU_COLLISION_PROCESS = 1 << 6, CF_DISABLE_SPU_COLLISION_PROCESS = 1 << 6,
// Following used by BulletSim to control collisions // Following used by BulletSim to control collisions and updates
BS_SUBSCRIBE_COLLISION_EVENTS = 1 << 10, BS_SUBSCRIBE_COLLISION_EVENTS = 1 << 10,
BS_FLOATS_ON_WATER = 1 << 11, BS_FLOATS_ON_WATER = 1 << 11,
BS_NONE = 0, BS_NONE = 0,