Merge branch 'master' into careminster
Conflicts: OpenSim/Region/Framework/Scenes/ScenePresence.csavinationmerge
commit
7e98dfd70b
|
@ -588,18 +588,18 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
m_bodyRot = value;
|
m_bodyRot = value;
|
||||||
// m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, m_bodyRot);
|
|
||||||
if (PhysicsActor != null)
|
if (PhysicsActor != null)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
PhysicsActor.Orientation = value;
|
PhysicsActor.Orientation = m_bodyRot;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.Error("[SCENE PRESENCE]: Orientation " + e.Message);
|
m_log.Error("[SCENE PRESENCE]: Orientation " + e.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, m_bodyRot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -66,7 +66,6 @@ public sealed class BSCharacter : BSPhysObject
|
||||||
private float _buoyancy;
|
private float _buoyancy;
|
||||||
|
|
||||||
// The friction and velocity of the avatar is modified depending on whether walking or not.
|
// The friction and velocity of the avatar is modified depending on whether walking or not.
|
||||||
private OMV.Vector3 _appliedVelocity; // the last velocity applied to the avatar
|
|
||||||
private float _currentFriction; // the friction currently being used (changed by setVelocity).
|
private float _currentFriction; // the friction currently being used (changed by setVelocity).
|
||||||
|
|
||||||
private BSVMotor _velocityMotor;
|
private BSVMotor _velocityMotor;
|
||||||
|
@ -85,37 +84,27 @@ public sealed class BSCharacter : BSPhysObject
|
||||||
_physicsActorType = (int)ActorTypes.Agent;
|
_physicsActorType = (int)ActorTypes.Agent;
|
||||||
_position = pos;
|
_position = pos;
|
||||||
|
|
||||||
|
_flying = isFlying;
|
||||||
|
_orientation = OMV.Quaternion.Identity;
|
||||||
|
_velocity = OMV.Vector3.Zero;
|
||||||
|
_buoyancy = ComputeBuoyancyFromFlying(isFlying);
|
||||||
|
_currentFriction = BSParam.AvatarStandingFriction;
|
||||||
|
_avatarDensity = BSParam.AvatarDensity;
|
||||||
|
|
||||||
// Old versions of ScenePresence passed only the height. If width and/or depth are zero,
|
// Old versions of ScenePresence passed only the height. If width and/or depth are zero,
|
||||||
// replace with the default values.
|
// replace with the default values.
|
||||||
_size = size;
|
_size = size;
|
||||||
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.
|
// The dimensions of the physical capsule are kept in the scale.
|
||||||
// _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;
|
|
||||||
_orientation = OMV.Quaternion.Identity;
|
|
||||||
_velocity = OMV.Vector3.Zero;
|
|
||||||
_appliedVelocity = OMV.Vector3.Zero;
|
|
||||||
_buoyancy = ComputeBuoyancyFromFlying(isFlying);
|
|
||||||
_currentFriction = BSParam.AvatarStandingFriction;
|
|
||||||
_avatarDensity = BSParam.AvatarDensity;
|
|
||||||
|
|
||||||
// The dimensions of the avatar capsule are kept in the scale.
|
|
||||||
// Physics creates a unit capsule which is scaled by the physics engine.
|
// Physics creates a unit capsule which is scaled by the physics engine.
|
||||||
ComputeAvatarScale(_size);
|
Scale = ComputeAvatarScale(_size);
|
||||||
// set _avatarVolume and _mass based on capsule size, _density and Scale
|
// set _avatarVolume and _mass based on capsule size, _density and Scale
|
||||||
ComputeAvatarVolumeAndMass();
|
ComputeAvatarVolumeAndMass();
|
||||||
|
|
||||||
|
SetupMovementMotor();
|
||||||
|
|
||||||
DetailLog("{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5}",
|
DetailLog("{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5}",
|
||||||
LocalID, _size, Scale, _avatarDensity, _avatarVolume, RawMass);
|
LocalID, _size, Scale, _avatarDensity, _avatarVolume, RawMass);
|
||||||
|
|
||||||
|
@ -152,13 +141,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 +180,63 @@ 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;
|
||||||
|
|
||||||
|
/*
|
||||||
|
// If moveForce is very small, zero things so we don't keep sending microscopic updates to the user
|
||||||
|
float moveForceMagnitudeSquared = moveForce.LengthSquared();
|
||||||
|
if (moveForceMagnitudeSquared < 0.0001)
|
||||||
|
{
|
||||||
|
DetailLog("{0},BSCharacter.MoveMotor,zeroMovement,stepVel={1},vel={2},mass={3},magSq={4},moveForce={5}",
|
||||||
|
LocalID, stepVelocity, _velocity, Mass, moveForceMagnitudeSquared, moveForce);
|
||||||
|
ForceVelocity = OMV.Vector3.Zero;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddForce(moveForce, false, true);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
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();
|
||||||
|
@ -207,14 +252,13 @@ public sealed class BSCharacter : BSPhysObject
|
||||||
}
|
}
|
||||||
|
|
||||||
set {
|
set {
|
||||||
// When an avatar's size is set, only the height is changed.
|
|
||||||
_size = value;
|
_size = value;
|
||||||
// Old versions of ScenePresence passed only the height. If width and/or depth are zero,
|
// Old versions of ScenePresence passed only the height. If width and/or depth are zero,
|
||||||
// replace with the default values.
|
// replace with the default values.
|
||||||
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;
|
||||||
|
|
||||||
ComputeAvatarScale(_size);
|
Scale = ComputeAvatarScale(_size);
|
||||||
ComputeAvatarVolumeAndMass();
|
ComputeAvatarVolumeAndMass();
|
||||||
DetailLog("{0},BSCharacter.setSize,call,size={1},scale={2},density={3},volume={4},mass={5}",
|
DetailLog("{0},BSCharacter.setSize,call,size={1},scale={2},density={3},volume={4},mass={5}",
|
||||||
LocalID, _size, Scale, _avatarDensity, _avatarVolume, RawMass);
|
LocalID, _size, Scale, _avatarDensity, _avatarVolume, RawMass);
|
||||||
|
@ -433,15 +477,15 @@ public sealed class BSCharacter : BSPhysObject
|
||||||
{
|
{
|
||||||
DetailLog("{0},BSCharacter.setTargetVelocity,call,vel={1}", LocalID, value);
|
DetailLog("{0},BSCharacter.setTargetVelocity,call,vel={1}", LocalID, value);
|
||||||
OMV.Vector3 targetVel = value;
|
OMV.Vector3 targetVel = value;
|
||||||
|
if (_setAlwaysRun)
|
||||||
|
targetVel *= BSParam.AvatarAlwaysRunFactor;
|
||||||
|
|
||||||
PhysicsScene.TaintedObject("BSCharacter.setTargetVelocity", delegate()
|
PhysicsScene.TaintedObject("BSCharacter.setTargetVelocity", delegate()
|
||||||
{
|
{
|
||||||
_velocityMotor.Reset();
|
_velocityMotor.Reset();
|
||||||
_velocityMotor.SetTarget(targetVel);
|
_velocityMotor.SetTarget(targetVel);
|
||||||
_velocityMotor.SetCurrent(_velocity);
|
_velocityMotor.SetCurrent(_velocity);
|
||||||
_velocityMotor.Enabled = true;
|
_velocityMotor.Enabled = true;
|
||||||
|
|
||||||
// Make sure a property update happens next step so the motor gets incorporated.
|
|
||||||
BulletSimAPI.PushUpdate2(PhysBody.ptr);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -490,8 +534,6 @@ public sealed class BSCharacter : BSPhysObject
|
||||||
BulletSimAPI.SetFriction2(PhysBody.ptr, _currentFriction);
|
BulletSimAPI.SetFriction2(PhysBody.ptr, _currentFriction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Remember the set velocity so we can suppress the reduction by friction, ...
|
|
||||||
_appliedVelocity = value;
|
|
||||||
|
|
||||||
BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, _velocity);
|
BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, _velocity);
|
||||||
BulletSimAPI.Activate2(PhysBody.ptr, true);
|
BulletSimAPI.Activate2(PhysBody.ptr, true);
|
||||||
|
@ -519,18 +561,18 @@ public sealed class BSCharacter : BSPhysObject
|
||||||
public override OMV.Quaternion Orientation {
|
public override OMV.Quaternion Orientation {
|
||||||
get { return _orientation; }
|
get { return _orientation; }
|
||||||
set {
|
set {
|
||||||
|
// Orientation is set zillions of times when an avatar is walking. It's like
|
||||||
|
// the viewer doesn't trust us.
|
||||||
|
if (_orientation != value)
|
||||||
|
{
|
||||||
_orientation = value;
|
_orientation = value;
|
||||||
// m_log.DebugFormat("{0}: set orientation to {1}", LogHeader, _orientation);
|
|
||||||
PhysicsScene.TaintedObject("BSCharacter.setOrientation", delegate()
|
PhysicsScene.TaintedObject("BSCharacter.setOrientation", delegate()
|
||||||
{
|
{
|
||||||
if (PhysBody.HasPhysicalBody)
|
ForceOrientation = _orientation;
|
||||||
{
|
|
||||||
// _position = BulletSimAPI.GetPosition2(BSBody.ptr);
|
|
||||||
BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Go directly to Bullet to get/set the value.
|
// Go directly to Bullet to get/set the value.
|
||||||
public override OMV.Quaternion ForceOrientation
|
public override OMV.Quaternion ForceOrientation
|
||||||
{
|
{
|
||||||
|
@ -542,9 +584,13 @@ public sealed class BSCharacter : BSPhysObject
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
_orientation = value;
|
_orientation = value;
|
||||||
|
if (PhysBody.HasPhysicalBody)
|
||||||
|
{
|
||||||
|
// _position = BulletSimAPI.GetPosition2(BSBody.ptr);
|
||||||
BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation);
|
BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
public override int PhysicsActorType {
|
public override int PhysicsActorType {
|
||||||
get { return _physicsActorType; }
|
get { return _physicsActorType; }
|
||||||
set { _physicsActorType = value;
|
set { _physicsActorType = value;
|
||||||
|
@ -668,7 +714,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 +730,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);
|
||||||
|
@ -703,21 +755,31 @@ public sealed class BSCharacter : BSPhysObject
|
||||||
public override void SetMomentum(OMV.Vector3 momentum) {
|
public override void SetMomentum(OMV.Vector3 momentum) {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ComputeAvatarScale(OMV.Vector3 size)
|
private OMV.Vector3 ComputeAvatarScale(OMV.Vector3 size)
|
||||||
{
|
{
|
||||||
OMV.Vector3 newScale = size;
|
OMV.Vector3 newScale;
|
||||||
// newScale.X = PhysicsScene.Params.avatarCapsuleWidth;
|
|
||||||
// newScale.Y = PhysicsScene.Params.avatarCapsuleDepth;
|
|
||||||
|
|
||||||
// From the total height, remove the capsule half spheres that are at each end
|
// Bullet's capsule total height is the "passed height + radius * 2";
|
||||||
// The 1.15f came from ODE. Not sure what this factors in.
|
// The base capsule is 1 diameter and 2 height (passed radius=0.5, passed height = 1)
|
||||||
// newScale.Z = (size.Z * 1.15f) - (newScale.X + newScale.Y);
|
// The number we pass in for 'scaling' is the multiplier to get that base
|
||||||
|
// shape to be the size desired.
|
||||||
|
// So, when creating the scale for the avatar height, we take the passed height
|
||||||
|
// (size.Z) and remove the caps.
|
||||||
|
// Another oddity of the Bullet capsule implementation is that it presumes the Y
|
||||||
|
// dimension is the radius of the capsule. Even though some of the code allows
|
||||||
|
// for a asymmetrical capsule, other parts of the code presume it is cylindrical.
|
||||||
|
|
||||||
|
// Scale is multiplier of radius with one of "0.5"
|
||||||
|
newScale.X = size.X / 2f;
|
||||||
|
newScale.Y = size.Y / 2f;
|
||||||
|
|
||||||
// The total scale height is the central cylindar plus the caps on the two ends.
|
// The total scale height is the central cylindar plus the caps on the two ends.
|
||||||
newScale.Z = size.Z + (Math.Min(size.X, size.Y) * 2f);
|
newScale.Z = (size.Z + (Math.Min(size.X, size.Y) * 2)) / 2f;
|
||||||
|
// If smaller than the endcaps, just fake like we're almost that small
|
||||||
|
if (newScale.Z < 0)
|
||||||
|
newScale.Z = 0.1f;
|
||||||
|
|
||||||
// Convert diameters to radii and height to half height -- the way Bullet expects it.
|
return newScale;
|
||||||
Scale = newScale / 2f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// set _avatarVolume and _mass based on capsule size, _density and Scale
|
// set _avatarVolume and _mass based on capsule size, _density and Scale
|
||||||
|
@ -725,14 +787,14 @@ public sealed class BSCharacter : BSPhysObject
|
||||||
{
|
{
|
||||||
_avatarVolume = (float)(
|
_avatarVolume = (float)(
|
||||||
Math.PI
|
Math.PI
|
||||||
* Scale.X
|
* Size.X / 2f
|
||||||
* Scale.Y // the area of capsule cylinder
|
* Size.Y / 2f // the area of capsule cylinder
|
||||||
* Scale.Z // times height of capsule cylinder
|
* Size.Z // times height of capsule cylinder
|
||||||
+ 1.33333333f
|
+ 1.33333333f
|
||||||
* Math.PI
|
* Math.PI
|
||||||
* Scale.X
|
* Size.X / 2f
|
||||||
* Math.Min(Scale.X, Scale.Y)
|
* Math.Min(Size.X, Size.Y) / 2
|
||||||
* Scale.Y // plus the volume of the capsule end caps
|
* Size.Y / 2f // plus the volume of the capsule end caps
|
||||||
);
|
);
|
||||||
_mass = _avatarDensity * _avatarVolume;
|
_mass = _avatarDensity * _avatarVolume;
|
||||||
}
|
}
|
||||||
|
@ -750,39 +812,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;
|
||||||
|
|
|
@ -68,6 +68,7 @@ public static class BSParam
|
||||||
// Avatar parameters
|
// Avatar parameters
|
||||||
public static float AvatarFriction { get; private set; }
|
public static float AvatarFriction { get; private set; }
|
||||||
public static float AvatarStandingFriction { get; private set; }
|
public static float AvatarStandingFriction { get; private set; }
|
||||||
|
public static float AvatarAlwaysRunFactor { get; private set; }
|
||||||
public static float AvatarDensity { get; private set; }
|
public static float AvatarDensity { get; private set; }
|
||||||
public static float AvatarRestitution { get; private set; }
|
public static float AvatarRestitution { get; private set; }
|
||||||
public static float AvatarCapsuleWidth { get; private set; }
|
public static float AvatarCapsuleWidth { get; private set; }
|
||||||
|
@ -367,6 +368,11 @@ public static class BSParam
|
||||||
(s,cf,p,v) => { AvatarStandingFriction = cf.GetFloat(p, v); },
|
(s,cf,p,v) => { AvatarStandingFriction = cf.GetFloat(p, v); },
|
||||||
(s) => { return AvatarStandingFriction; },
|
(s) => { return AvatarStandingFriction; },
|
||||||
(s,p,l,v) => { AvatarStandingFriction = v; } ),
|
(s,p,l,v) => { AvatarStandingFriction = v; } ),
|
||||||
|
new ParameterDefn("AvatarAlwaysRunFactor", "Speed multiplier if avatar is set to always run",
|
||||||
|
1.3f,
|
||||||
|
(s,cf,p,v) => { AvatarAlwaysRunFactor = cf.GetFloat(p, v); },
|
||||||
|
(s) => { return AvatarAlwaysRunFactor; },
|
||||||
|
(s,p,l,v) => { AvatarAlwaysRunFactor = v; } ),
|
||||||
new ParameterDefn("AvatarDensity", "Density of an avatar. Changed on avatar recreation.",
|
new ParameterDefn("AvatarDensity", "Density of an avatar. Changed on avatar recreation.",
|
||||||
3.5f,
|
3.5f,
|
||||||
(s,cf,p,v) => { AvatarDensity = cf.GetFloat(p, v); },
|
(s,cf,p,v) => { AvatarDensity = cf.GetFloat(p, v); },
|
||||||
|
|
|
@ -420,8 +420,7 @@ public sealed class BSShapeCollection : IDisposable
|
||||||
if (!haveShape && prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_CAPSULE)
|
if (!haveShape && prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_CAPSULE)
|
||||||
{
|
{
|
||||||
// an avatar capsule is close to a native shape (it is not shared)
|
// an avatar capsule is close to a native shape (it is not shared)
|
||||||
GetReferenceToNativeShape(prim, BSPhysicsShapeType.SHAPE_CAPSULE,
|
GetReferenceToNativeShape(prim, BSPhysicsShapeType.SHAPE_CAPSULE, FixedShapeKey.KEY_CAPSULE, shapeCallback);
|
||||||
FixedShapeKey.KEY_CAPSULE, shapeCallback);
|
|
||||||
if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,avatarCapsule,shape={1}", prim.LocalID, prim.PhysShape);
|
if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,avatarCapsule,shape={1}", prim.LocalID, prim.PhysShape);
|
||||||
ret = true;
|
ret = true;
|
||||||
haveShape = true;
|
haveShape = true;
|
||||||
|
@ -573,6 +572,9 @@ public sealed class BSShapeCollection : IDisposable
|
||||||
{
|
{
|
||||||
// The proper scale has been calculated in the prim.
|
// The proper scale has been calculated in the prim.
|
||||||
newShape = new BulletShape(
|
newShape = new BulletShape(
|
||||||
|
// Bullet's capsule total height is the passed "height + (radius * 2)" so, the base
|
||||||
|
// capsule is radius of 0.5f (1 diameter) and height of two (1.0f + 0.5f * 2)".
|
||||||
|
// This must be taken into account when computing the scaling of the capsule.
|
||||||
BulletSimAPI.BuildCapsuleShape2(PhysicsScene.World.ptr, 1f, 1f, prim.Scale)
|
BulletSimAPI.BuildCapsuleShape2(PhysicsScene.World.ptr, 1f, 1f, prim.Scale)
|
||||||
, shapeType);
|
, shapeType);
|
||||||
if (DDetail) DetailLog("{0},BSShapeCollection.BuiletPhysicalNativeShape,capsule,scale={1}", prim.LocalID, prim.Scale);
|
if (DDetail) DetailLog("{0},BSShapeCollection.BuiletPhysicalNativeShape,capsule,scale={1}", prim.LocalID, prim.Scale);
|
||||||
|
|
|
@ -205,4 +205,17 @@ public class BSShapeCompound : BSShape
|
||||||
}
|
}
|
||||||
public override void Dereference(BSScene physicsScene) { }
|
public override void Dereference(BSScene physicsScene) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class BSShapeAvatar : BSShape
|
||||||
|
{
|
||||||
|
private static string LogHeader = "[BULLETSIM SHAPE AVATAR]";
|
||||||
|
public BSShapeAvatar() : base()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
public static BSShape GetReference(BSPhysObject prim)
|
||||||
|
{
|
||||||
|
return new BSShapeNull();
|
||||||
|
}
|
||||||
|
public override void Dereference(BSScene physicsScene) { }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,6 +69,7 @@ public enum BSPhysicsShapeType
|
||||||
SHAPE_TERRAIN = 21,
|
SHAPE_TERRAIN = 21,
|
||||||
SHAPE_COMPOUND = 22,
|
SHAPE_COMPOUND = 22,
|
||||||
SHAPE_HEIGHTMAP = 23,
|
SHAPE_HEIGHTMAP = 23,
|
||||||
|
SHAPE_AVATAR = 24,
|
||||||
};
|
};
|
||||||
|
|
||||||
// The native shapes have predefined shape hash keys
|
// The native shapes have predefined shape hash keys
|
||||||
|
@ -80,6 +81,7 @@ public enum FixedShapeKey : ulong
|
||||||
KEY_CONE = 3,
|
KEY_CONE = 3,
|
||||||
KEY_CYLINDER = 4,
|
KEY_CYLINDER = 4,
|
||||||
KEY_CAPSULE = 5,
|
KEY_CAPSULE = 5,
|
||||||
|
KEY_AVATAR = 6,
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
|
|
@ -915,9 +915,9 @@
|
||||||
TerrainCollisionMargin = 0.04
|
TerrainCollisionMargin = 0.04
|
||||||
|
|
||||||
AvatarFriction = 0.2
|
AvatarFriction = 0.2
|
||||||
AvatarStandingFriction = 0.99
|
AvatarStandingFriction = 10.0
|
||||||
AvatarRestitution = 0.0
|
AvatarRestitution = 0.0
|
||||||
AvatarDensity = 60.0
|
AvatarDensity = 3.5
|
||||||
AvatarCapsuleWidth = 0.6
|
AvatarCapsuleWidth = 0.6
|
||||||
AvatarCapsuleDepth = 0.45
|
AvatarCapsuleDepth = 0.45
|
||||||
AvatarCapsuleHeight = 1.5
|
AvatarCapsuleHeight = 1.5
|
||||||
|
|
Loading…
Reference in New Issue