BulletSim: tweaking so avatar can be pushed. In particular, llPushObject,
which called BSCharacter.AddForce, can now move a character.LSLKeyTest
parent
151001c70b
commit
d4e88f8883
|
@ -187,12 +187,25 @@ public class BSActorAvatarMove : BSActor
|
||||||
|
|
||||||
if (m_controllingPrim.IsColliding)
|
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)
|
if (!m_controllingPrim.ColliderIsMoving && !m_controllingPrim.ColliderIsVolumeDetect)
|
||||||
{
|
{
|
||||||
m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,collidingWithStationary,zeroingMotion", m_controllingPrim.LocalID);
|
m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,collidingWithStationary,totalForce={1}, vel={2}", /* DEBUG */
|
||||||
m_controllingPrim.IsStationary = true;
|
m_controllingPrim.LocalID, m_physicsScene.PE.GetTotalForce(m_controllingPrim.PhysBody), m_controllingPrim.Velocity); /* DEBUG */
|
||||||
m_controllingPrim.ZeroMotion(true /* inTaintTime */);
|
// 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
|
// 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_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,taint,stopping,target={1},colliding={2},isStationary={3}",
|
||||||
m_controllingPrim.LocalID, m_velocityMotor.TargetValue, m_controllingPrim.IsColliding);
|
m_controllingPrim.LocalID, m_velocityMotor.TargetValue, m_controllingPrim.IsColliding,m_controllingPrim.IsStationary);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -237,6 +250,8 @@ public class BSActorAvatarMove : BSActor
|
||||||
m_physicsScene.PE.SetFriction(m_controllingPrim.PhysBody, m_controllingPrim.Friction);
|
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)
|
if (!m_controllingPrim.Flying && !m_controllingPrim.IsColliding)
|
||||||
{
|
{
|
||||||
stepVelocity.Z = m_controllingPrim.RawVelocity.Z;
|
stepVelocity.Z = m_controllingPrim.RawVelocity.Z;
|
||||||
|
@ -267,11 +282,9 @@ public class BSActorAvatarMove : BSActor
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
// Since we're not affected by anything, the avatar must be falling and we do not want that to be too fast.
|
// 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)
|
if (m_controllingPrim.RawVelocity.Z < BSParam.AvatarTerminalVelocity)
|
||||||
{
|
{
|
||||||
|
|
||||||
stepVelocity.Z = BSParam.AvatarTerminalVelocity;
|
stepVelocity.Z = BSParam.AvatarTerminalVelocity;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -315,7 +328,11 @@ public class BSActorAvatarMove : BSActor
|
||||||
if (m_controllingPrim.IsStationary)
|
if (m_controllingPrim.IsStationary)
|
||||||
{
|
{
|
||||||
entprop.Position = m_controllingPrim.RawPosition;
|
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);
|
m_physicsScene.PE.SetTranslation(m_controllingPrim.PhysBody, entprop.Position, entprop.Rotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -652,13 +652,16 @@ public sealed class BSCharacter : BSPhysObject
|
||||||
public override void AddForce(OMV.Vector3 force, bool pushforce)
|
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.
|
// 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
|
// The interaction of this force with the simulator rate and collision occurance is tricky.
|
||||||
// with a adicional parameter to sync with old ode
|
// ODE multiplies the force by 100
|
||||||
if(pushforce)
|
// ubODE multiplies the force by 5.3
|
||||||
addForce = addForce * Density * BSParam.DensityScaleFactor * 0.08f;;
|
// 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);
|
AddForce(addForce, pushforce, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -666,7 +669,7 @@ public sealed class BSCharacter : BSPhysObject
|
||||||
if (force.IsFinite())
|
if (force.IsFinite())
|
||||||
{
|
{
|
||||||
OMV.Vector3 addForce = Util.ClampV(force, BSParam.MaxAddForceMagnitude);
|
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()
|
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);
|
// DetailLog("{0},BSCharacter.addForce,taint,force={1}", LocalID, addForce);
|
||||||
if (PhysBody.HasPhysicalBody)
|
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.ApplyCentralForce(PhysBody, addForce);
|
||||||
PhysScene.PE.Activate(PhysBody, true);
|
PhysScene.PE.Activate(PhysBody, true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -149,7 +149,9 @@ public static class BSParam
|
||||||
public static float AvatarFlyingGroundUpForce { get; private set; }
|
public static float AvatarFlyingGroundUpForce { get; private set; }
|
||||||
public static float AvatarTerminalVelocity { get; private set; }
|
public static float AvatarTerminalVelocity { get; private set; }
|
||||||
public static float AvatarContactProcessingThreshold { 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 AvatarStopZeroThreshold { get; private set; }
|
||||||
|
public static float AvatarStopZeroThresholdSquared { get; private set; }
|
||||||
public static int AvatarJumpFrames { get; private set; }
|
public static int AvatarJumpFrames { get; private set; }
|
||||||
public static float AvatarBelowGroundUpCorrectionMeters { get; private set; }
|
public static float AvatarBelowGroundUpCorrectionMeters { get; private set; }
|
||||||
public static float AvatarStepHeight { 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_D { get; private set; } // derivative
|
||||||
public static float PID_P { get; private set; } // proportional
|
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.
|
// Various constants that come from that other virtual world that shall not be named.
|
||||||
public const float MinGravityZ = -1f;
|
public const float MinGravityZ = -1f;
|
||||||
public const float MaxGravityZ = 28f;
|
public const float MaxGravityZ = 28f;
|
||||||
|
@ -601,7 +605,7 @@ public static class BSParam
|
||||||
1.3f ),
|
1.3f ),
|
||||||
// For historical reasons, density is reported * 100
|
// For historical reasons, density is reported * 100
|
||||||
new ParameterDefn<float>("AvatarDensity", "Density of an avatar. Changed on avatar recreation. Scaled times 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.",
|
new ParameterDefn<float>("AvatarRestitution", "Bouncyness. Changed on avatar recreation.",
|
||||||
0f ),
|
0f ),
|
||||||
new ParameterDefn<int>("AvatarShape", "Code for avatar physical shape: 0:capsule, 1:cube, 2:ovoid, 2:mesh",
|
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 ),
|
-54.0f ),
|
||||||
new ParameterDefn<float>("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions",
|
new ParameterDefn<float>("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions",
|
||||||
0.1f ),
|
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",
|
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",
|
new ParameterDefn<float>("AvatarBelowGroundUpCorrectionMeters", "Meters to move avatar up if it seems to be below ground",
|
||||||
1.0f ),
|
1.0f ),
|
||||||
new ParameterDefn<int>("AvatarJumpFrames", "Number of frames to allow jump forces. Changes jump height.",
|
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)",
|
new ParameterDefn<float>("LinkConstraintSolverIterations", "Number of solver iterations when computing constraint. (0 = Bullet default)",
|
||||||
40 ),
|
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)",
|
new ParameterDefn<int>("PhysicsMetricFrames", "Frames between outputting detailed phys metrics. (0 is off)",
|
||||||
0,
|
0,
|
||||||
(s) => { return s.PhysicsMetricDumpFrames; },
|
(s) => { return s.PhysicsMetricDumpFrames; },
|
||||||
|
|
|
@ -239,8 +239,10 @@ public abstract class BSPhysObject : PhysicsActor
|
||||||
public virtual OMV.Vector3 RawVelocity { get; set; }
|
public virtual OMV.Vector3 RawVelocity { get; set; }
|
||||||
public abstract OMV.Vector3 ForceVelocity { 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 RawForce { get; set; }
|
||||||
public OMV.Vector3 RawTorque { get; set; }
|
public OMV.Vector3 RawTorque { get; set; }
|
||||||
|
|
||||||
public override void AddAngularForce(OMV.Vector3 force, bool pushforce)
|
public override void AddAngularForce(OMV.Vector3 force, bool pushforce)
|
||||||
{
|
{
|
||||||
AddAngularForce(force, pushforce, false);
|
AddAngularForce(force, pushforce, false);
|
||||||
|
@ -570,7 +572,11 @@ public abstract class BSPhysObject : PhysicsActor
|
||||||
PhysScene.TaintedObject(LocalID, TypeName+".SubscribeEvents", delegate()
|
PhysScene.TaintedObject(LocalID, TypeName+".SubscribeEvents", delegate()
|
||||||
{
|
{
|
||||||
if (PhysBody.HasPhysicalBody)
|
if (PhysBody.HasPhysicalBody)
|
||||||
|
{
|
||||||
CurrentCollisionFlags = PhysScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
|
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
|
else
|
||||||
|
|
|
@ -679,7 +679,6 @@ namespace OpenSim.Region.PhysicsModule.BulletS
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
numSubSteps = PE.PhysicsStep(World, timeStep, m_maxSubSteps, m_fixedTimeStep, out updatedEntityCount, out collidersCount);
|
numSubSteps = PE.PhysicsStep(World, timeStep, m_maxSubSteps, m_fixedTimeStep, out updatedEntityCount, out collidersCount);
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue