BulletSim: tweaking so avatar can be pushed. In particular, llPushObject,

which called BSCharacter.AddForce, can now move a character.
LSLKeyTest
Robert Adams 2016-01-02 17:36:42 -08:00
parent 151001c70b
commit d4e88f8883
5 changed files with 57 additions and 18 deletions

View File

@ -187,12 +187,25 @@ public class BSActorAvatarMove : BSActor
if (m_controllingPrim.IsColliding)
{
// If we are colliding with a stationary object, presume we're standing and don't move around
// if colliding with something stationary and we're not doing volume detect .
if (!m_controllingPrim.ColliderIsMoving && !m_controllingPrim.ColliderIsVolumeDetect)
{
m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,collidingWithStationary,zeroingMotion", m_controllingPrim.LocalID);
m_controllingPrim.IsStationary = true;
m_controllingPrim.ZeroMotion(true /* inTaintTime */);
m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,collidingWithStationary,totalForce={1}, vel={2}", /* DEBUG */
m_controllingPrim.LocalID, m_physicsScene.PE.GetTotalForce(m_controllingPrim.PhysBody), m_controllingPrim.Velocity); /* DEBUG */
// If velocity is very small, assume it is movement creep and suppress it.
// Applying push forces (Character.AddForce) should move the avatar and that is only seen here as velocity.
if ( (m_controllingPrim.Velocity.LengthSquared() < BSParam.AvatarStopZeroThresholdSquared)
&& (m_physicsScene.PE.GetTotalForce(m_controllingPrim.PhysBody).LengthSquared() < BSParam.AvatarStopZeroThresholdSquared) )
{
m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,collidingWithStationary,zeroingMotion", m_controllingPrim.LocalID);
m_controllingPrim.IsStationary = true;
m_controllingPrim.ZeroMotion(true /* inTaintTime */);
}
else
{
m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,collidingWithStationary,not zeroing because velocity={1}",
m_controllingPrim.LocalID, m_controllingPrim.Velocity);
}
}
// Standing has more friction on the ground
@ -222,8 +235,8 @@ public class BSActorAvatarMove : BSActor
}
}
m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,taint,stopping,target={1},colliding={2}",
m_controllingPrim.LocalID, m_velocityMotor.TargetValue, m_controllingPrim.IsColliding);
m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,taint,stopping,target={1},colliding={2},isStationary={3}",
m_controllingPrim.LocalID, m_velocityMotor.TargetValue, m_controllingPrim.IsColliding,m_controllingPrim.IsStationary);
}
else
{
@ -237,6 +250,8 @@ public class BSActorAvatarMove : BSActor
m_physicsScene.PE.SetFriction(m_controllingPrim.PhysBody, m_controllingPrim.Friction);
}
// If not flying and not colliding, assume falling and keep the downward motion component.
// This check is done here for the next jump test.
if (!m_controllingPrim.Flying && !m_controllingPrim.IsColliding)
{
stepVelocity.Z = m_controllingPrim.RawVelocity.Z;
@ -267,11 +282,9 @@ public class BSActorAvatarMove : BSActor
}
else
{
// Since we're not affected by anything, the avatar must be falling and we do not want that to be too fast.
if (m_controllingPrim.RawVelocity.Z < BSParam.AvatarTerminalVelocity)
{
stepVelocity.Z = BSParam.AvatarTerminalVelocity;
}
else
@ -315,7 +328,11 @@ public class BSActorAvatarMove : BSActor
if (m_controllingPrim.IsStationary)
{
entprop.Position = m_controllingPrim.RawPosition;
entprop.Velocity = OMV.Vector3.Zero;
// Suppress small movement velocity
if (entprop.Velocity.LengthSquared() < BSParam.AvatarStopZeroThresholdSquared) {
m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,OnPreUpdate,zeroing velocity={1}", m_controllingPrim.LocalID, entprop.Velocity);
entprop.Velocity = OMV.Vector3.Zero;
}
m_physicsScene.PE.SetTranslation(m_controllingPrim.PhysBody, entprop.Position, entprop.Rotation);
}

View File

@ -652,13 +652,16 @@ public sealed class BSCharacter : BSPhysObject
public override void AddForce(OMV.Vector3 force, bool pushforce)
{
// Since this force is being applied in only one step, make this a force per second.
OMV.Vector3 addForce = force / PhysScene.LastTimeStep;
OMV.Vector3 addForce = force;
// compensate for density variation
// with a adicional parameter to sync with old ode
if(pushforce)
addForce = addForce * Density * BSParam.DensityScaleFactor * 0.08f;;
// The interaction of this force with the simulator rate and collision occurance is tricky.
// ODE multiplies the force by 100
// ubODE multiplies the force by 5.3
// BulletSim, after much in-world testing, thinks it gets a similar effect by multiplying mass*0.315f
// This number could be a feature of friction or timing, but it seems to move avatars the same as ubODE
addForce *= Mass * BSParam.AvatarAddForcePushFactor;
DetailLog("{0},BSCharacter.addForce,call,force={1},addForce={2},push={3},mass={4}", LocalID, force, addForce, pushforce, Mass);
AddForce(addForce, pushforce, false);
}
@ -666,7 +669,7 @@ public sealed class BSCharacter : BSPhysObject
if (force.IsFinite())
{
OMV.Vector3 addForce = Util.ClampV(force, BSParam.MaxAddForceMagnitude);
// DetailLog("{0},BSCharacter.addForce,call,force={1}", LocalID, addForce);
// DetailLog("{0},BSCharacter.addForce,call,force={1},push={2},inTaint={3}", LocalID, addForce, pushforce, inTaintTime);
PhysScene.TaintedObject(inTaintTime, LocalID, "BSCharacter.AddForce", delegate()
{
@ -674,6 +677,9 @@ public sealed class BSCharacter : BSPhysObject
// DetailLog("{0},BSCharacter.addForce,taint,force={1}", LocalID, addForce);
if (PhysBody.HasPhysicalBody)
{
// Bullet adds this central force to the total force for this tick.
// Deep down in Bullet:
// linearVelocity += totalForce / mass * timeStep;
PhysScene.PE.ApplyCentralForce(PhysBody, addForce);
PhysScene.PE.Activate(PhysBody, true);
}

View File

@ -149,7 +149,9 @@ public static class BSParam
public static float AvatarFlyingGroundUpForce { get; private set; }
public static float AvatarTerminalVelocity { get; private set; }
public static float AvatarContactProcessingThreshold { get; private set; }
public static float AvatarAddForcePushFactor { get; private set; }
public static float AvatarStopZeroThreshold { get; private set; }
public static float AvatarStopZeroThresholdSquared { get; private set; }
public static int AvatarJumpFrames { get; private set; }
public static float AvatarBelowGroundUpCorrectionMeters { get; private set; }
public static float AvatarStepHeight { get; private set; }
@ -230,6 +232,8 @@ public static class BSParam
public static float PID_D { get; private set; } // derivative
public static float PID_P { get; private set; } // proportional
public static float DebugNumber { get; private set; } // A console setable number used for debugging
// Various constants that come from that other virtual world that shall not be named.
public const float MinGravityZ = -1f;
public const float MaxGravityZ = 28f;
@ -601,7 +605,7 @@ public static class BSParam
1.3f ),
// For historical reasons, density is reported * 100
new ParameterDefn<float>("AvatarDensity", "Density of an avatar. Changed on avatar recreation. Scaled times 100.",
3500f) , // 3.5 * 100
350f) , // 3.5 * 100
new ParameterDefn<float>("AvatarRestitution", "Bouncyness. Changed on avatar recreation.",
0f ),
new ParameterDefn<int>("AvatarShape", "Code for avatar physical shape: 0:capsule, 1:cube, 2:ovoid, 2:mesh",
@ -626,8 +630,12 @@ public static class BSParam
-54.0f ),
new ParameterDefn<float>("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions",
0.1f ),
new ParameterDefn<float>("AvatarAddForcePushFactor", "BSCharacter.AddForce is multiplied by this and mass to be like other physics engines",
0.315f ),
new ParameterDefn<float>("AvatarStopZeroThreshold", "Movement velocity below which avatar is assumed to be stopped",
0.1f ),
0.1f,
(s) => { return (float)AvatarStopZeroThreshold; },
(s,v) => { AvatarStopZeroThreshold = v; AvatarStopZeroThresholdSquared = v * v; } ),
new ParameterDefn<float>("AvatarBelowGroundUpCorrectionMeters", "Meters to move avatar up if it seems to be below ground",
1.0f ),
new ParameterDefn<int>("AvatarJumpFrames", "Number of frames to allow jump forces. Changes jump height.",
@ -812,6 +820,9 @@ public static class BSParam
new ParameterDefn<float>("LinkConstraintSolverIterations", "Number of solver iterations when computing constraint. (0 = Bullet default)",
40 ),
new ParameterDefn<float>("DebugNumber", "A console setable number sometimes used for debugging",
1.0f ),
new ParameterDefn<int>("PhysicsMetricFrames", "Frames between outputting detailed phys metrics. (0 is off)",
0,
(s) => { return s.PhysicsMetricDumpFrames; },

View File

@ -239,8 +239,10 @@ public abstract class BSPhysObject : PhysicsActor
public virtual OMV.Vector3 RawVelocity { get; set; }
public abstract OMV.Vector3 ForceVelocity { get; set; }
// RawForce is a constant force applied to object (see Force { set; } )
public OMV.Vector3 RawForce { get; set; }
public OMV.Vector3 RawTorque { get; set; }
public override void AddAngularForce(OMV.Vector3 force, bool pushforce)
{
AddAngularForce(force, pushforce, false);
@ -570,7 +572,11 @@ public abstract class BSPhysObject : PhysicsActor
PhysScene.TaintedObject(LocalID, TypeName+".SubscribeEvents", delegate()
{
if (PhysBody.HasPhysicalBody)
{
CurrentCollisionFlags = PhysScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
DetailLog("{0},{1}.SubscribeEvents,setting collision. ms={2}, collisionFlags={3:x}",
LocalID, TypeName, ms, CurrentCollisionFlags);
}
});
}
else

View File

@ -679,7 +679,6 @@ namespace OpenSim.Region.PhysicsModule.BulletS
try
{
numSubSteps = PE.PhysicsStep(World, timeStep, m_maxSubSteps, m_fixedTimeStep, out updatedEntityCount, out collidersCount);
}
catch (Exception e)
{