BulletSim: fix problem of avatars appearing to walk through walls
by moving the movement motor to a pre-step action and out of its questionable previous home in UpdateProperties.0.7.5-pf-bulletsim
parent
1f6aaad0b5
commit
70e0a86601
|
@ -91,17 +91,7 @@ public sealed class BSCharacter : BSPhysObject
|
||||||
if (_size.X == 0f) _size.X = BSParam.AvatarCapsuleDepth;
|
if (_size.X == 0f) _size.X = BSParam.AvatarCapsuleDepth;
|
||||||
if (_size.Y == 0f) _size.Y = BSParam.AvatarCapsuleWidth;
|
if (_size.Y == 0f) _size.Y = BSParam.AvatarCapsuleWidth;
|
||||||
|
|
||||||
// A motor to control the acceleration and deceleration of the avatar movement.
|
SetupMovementMotor();
|
||||||
// _velocityMotor = new BSVMotor("BSCharacter.Velocity", 3f, 5f, BSMotor.InfiniteVector, 1f);
|
|
||||||
// _velocityMotor = new BSPIDVMotor("BSCharacter.Velocity", 3f, 5f, BSMotor.InfiniteVector, 1f);
|
|
||||||
// Infinite decay and timescale values so motor only changes current to target values.
|
|
||||||
_velocityMotor = new BSVMotor("BSCharacter.Velocity",
|
|
||||||
0.2f, // time scale
|
|
||||||
BSMotor.Infinite, // decay time scale
|
|
||||||
BSMotor.InfiniteVector, // friction timescale
|
|
||||||
1f // efficiency
|
|
||||||
);
|
|
||||||
_velocityMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG so motor will output detail log messages.
|
|
||||||
|
|
||||||
_flying = isFlying;
|
_flying = isFlying;
|
||||||
_orientation = OMV.Quaternion.Identity;
|
_orientation = OMV.Quaternion.Identity;
|
||||||
|
@ -152,13 +142,12 @@ public sealed class BSCharacter : BSPhysObject
|
||||||
|
|
||||||
ZeroMotion(true);
|
ZeroMotion(true);
|
||||||
ForcePosition = _position;
|
ForcePosition = _position;
|
||||||
|
|
||||||
// Set the velocity and compute the proper friction
|
// Set the velocity and compute the proper friction
|
||||||
ForceVelocity = _velocity;
|
|
||||||
// Setting the current and target in the motor will cause it to start computing any deceleration.
|
|
||||||
_velocityMotor.Reset();
|
_velocityMotor.Reset();
|
||||||
_velocityMotor.SetCurrent(_velocity);
|
|
||||||
_velocityMotor.SetTarget(_velocity);
|
_velocityMotor.SetTarget(_velocity);
|
||||||
_velocityMotor.Enabled = false;
|
_velocityMotor.SetCurrent(_velocity);
|
||||||
|
ForceVelocity = _velocity;
|
||||||
|
|
||||||
// This will enable or disable the flying buoyancy of the avatar.
|
// This will enable or disable the flying buoyancy of the avatar.
|
||||||
// Needs to be reset especially when an avatar is recreated after crossing a region boundry.
|
// Needs to be reset especially when an avatar is recreated after crossing a region boundry.
|
||||||
|
@ -192,6 +181,48 @@ public sealed class BSCharacter : BSPhysObject
|
||||||
PhysBody.ApplyCollisionMask();
|
PhysBody.ApplyCollisionMask();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The avatar's movement is controlled by this motor that speeds up and slows down
|
||||||
|
// the avatar seeking to reach the motor's target speed.
|
||||||
|
// This motor runs as a prestep action for the avatar so it will keep the avatar
|
||||||
|
// standing as well as moving. Destruction of the avatar will destroy the pre-step action.
|
||||||
|
private void SetupMovementMotor()
|
||||||
|
{
|
||||||
|
|
||||||
|
// Someday, use a PID motor for asymmetric speed up and slow down
|
||||||
|
// _velocityMotor = new BSPIDVMotor("BSCharacter.Velocity", 3f, 5f, BSMotor.InfiniteVector, 1f);
|
||||||
|
|
||||||
|
// Infinite decay and timescale values so motor only changes current to target values.
|
||||||
|
_velocityMotor = new BSVMotor("BSCharacter.Velocity",
|
||||||
|
0.2f, // time scale
|
||||||
|
BSMotor.Infinite, // decay time scale
|
||||||
|
BSMotor.InfiniteVector, // friction timescale
|
||||||
|
1f // efficiency
|
||||||
|
);
|
||||||
|
// _velocityMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG so motor will output detail log messages.
|
||||||
|
|
||||||
|
RegisterPreStepAction("BSCharactor.Movement", LocalID, delegate(float timeStep)
|
||||||
|
{
|
||||||
|
// TODO: Decide if the step parameters should be changed depending on the avatar's
|
||||||
|
// state (flying, colliding, ...). There is code in ODE to do this.
|
||||||
|
|
||||||
|
OMV.Vector3 stepVelocity = _velocityMotor.Step(timeStep);
|
||||||
|
|
||||||
|
// If falling, we keep the world's downward vector no matter what the other axis specify.
|
||||||
|
if (!Flying && !IsColliding)
|
||||||
|
{
|
||||||
|
stepVelocity.Z = _velocity.Z;
|
||||||
|
DetailLog("{0},BSCharacter.MoveMotor,taint,overrideStepZWithWorldZ,stepVel={1}",
|
||||||
|
LocalID, stepVelocity);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 'stepVelocity' is now the speed we'd like the avatar to move in. Turn that into an instantanous force.
|
||||||
|
OMV.Vector3 moveForce = (stepVelocity - _velocity) * Mass / PhysicsScene.LastTimeStep;
|
||||||
|
DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}",
|
||||||
|
LocalID, stepVelocity, _velocity, Mass, moveForce);
|
||||||
|
AddForce(moveForce, false, true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public override void RequestPhysicsterseUpdate()
|
public override void RequestPhysicsterseUpdate()
|
||||||
{
|
{
|
||||||
base.RequestPhysicsterseUpdate();
|
base.RequestPhysicsterseUpdate();
|
||||||
|
@ -668,7 +699,13 @@ public sealed class BSCharacter : BSPhysObject
|
||||||
public override float APIDStrength { set { return; } }
|
public override float APIDStrength { set { return; } }
|
||||||
public override float APIDDamping { set { return; } }
|
public override float APIDDamping { set { return; } }
|
||||||
|
|
||||||
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.
|
||||||
|
OMV.Vector3 addForce = force / PhysicsScene.LastTimeStep;
|
||||||
|
AddForce(addForce, pushforce, false);
|
||||||
|
}
|
||||||
|
private void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) {
|
||||||
if (force.IsFinite())
|
if (force.IsFinite())
|
||||||
{
|
{
|
||||||
float magnitude = force.Length();
|
float magnitude = force.Length();
|
||||||
|
@ -678,10 +715,10 @@ public sealed class BSCharacter : BSPhysObject
|
||||||
force = force / magnitude * BSParam.MaxAddForceMagnitude;
|
force = force / magnitude * BSParam.MaxAddForceMagnitude;
|
||||||
}
|
}
|
||||||
|
|
||||||
OMV.Vector3 addForce = force / PhysicsScene.LastTimeStep;
|
OMV.Vector3 addForce = force;
|
||||||
DetailLog("{0},BSCharacter.addForce,call,force={1}", LocalID, addForce);
|
DetailLog("{0},BSCharacter.addForce,call,force={1}", LocalID, addForce);
|
||||||
|
|
||||||
PhysicsScene.TaintedObject("BSCharacter.AddForce", delegate()
|
PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.AddForce", delegate()
|
||||||
{
|
{
|
||||||
// Bullet adds this central force to the total force for this tick
|
// Bullet adds this central force to the total force for this tick
|
||||||
DetailLog("{0},BSCharacter.addForce,taint,force={1}", LocalID, addForce);
|
DetailLog("{0},BSCharacter.addForce,taint,force={1}", LocalID, addForce);
|
||||||
|
@ -750,39 +787,6 @@ public sealed class BSCharacter : BSPhysObject
|
||||||
// Do some sanity checking for the avatar. Make sure it's above ground and inbounds.
|
// Do some sanity checking for the avatar. Make sure it's above ground and inbounds.
|
||||||
PositionSanityCheck(true);
|
PositionSanityCheck(true);
|
||||||
|
|
||||||
if (_velocityMotor.Enabled)
|
|
||||||
{
|
|
||||||
// TODO: Decide if the step parameters should be changed depending on the avatar's
|
|
||||||
// state (flying, colliding, ...).
|
|
||||||
|
|
||||||
OMV.Vector3 stepVelocity = _velocityMotor.Step(PhysicsScene.LastTimeStep);
|
|
||||||
|
|
||||||
// Check for cases to turn off the motor.
|
|
||||||
if (
|
|
||||||
// If the walking motor is all done, turn it off
|
|
||||||
(_velocityMotor.TargetValue.ApproxEquals(OMV.Vector3.Zero, 0.01f) && _velocityMotor.ErrorIsZero) )
|
|
||||||
{
|
|
||||||
ZeroMotion(true);
|
|
||||||
stepVelocity = OMV.Vector3.Zero;
|
|
||||||
_velocityMotor.Enabled = false;
|
|
||||||
DetailLog("{0},BSCharacter.UpdateProperties,taint,disableVelocityMotor,m={1}", LocalID, _velocityMotor);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// If the motor is not being turned off...
|
|
||||||
// If falling, we keep the world's downward vector no matter what the other axis specify.
|
|
||||||
if (!Flying && !IsColliding)
|
|
||||||
{
|
|
||||||
stepVelocity.Z = entprop.Velocity.Z;
|
|
||||||
DetailLog("{0},BSCharacter.UpdateProperties,taint,overrideStepZWithWorldZ,stepVel={1}", LocalID, stepVelocity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_velocity = stepVelocity;
|
|
||||||
entprop.Velocity = _velocity;
|
|
||||||
BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, _velocity);
|
|
||||||
}
|
|
||||||
|
|
||||||
// remember the current and last set values
|
// remember the current and last set values
|
||||||
LastEntityProperties = CurrentEntityProperties;
|
LastEntityProperties = CurrentEntityProperties;
|
||||||
CurrentEntityProperties = entprop;
|
CurrentEntityProperties = entprop;
|
||||||
|
|
Loading…
Reference in New Issue