Merge branch 'master' into connector_plugin
commit
88f2fbc8f1
|
@ -80,10 +80,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
private Quaternion m_referenceFrame = Quaternion.Identity;
|
private Quaternion m_referenceFrame = Quaternion.Identity;
|
||||||
|
|
||||||
// Linear properties
|
// Linear properties
|
||||||
|
private BSVMotor m_linearMotor = new BSVMotor("LinearMotor");
|
||||||
private Vector3 m_linearMotorDirection = Vector3.Zero; // velocity requested by LSL, decayed by time
|
private Vector3 m_linearMotorDirection = Vector3.Zero; // velocity requested by LSL, decayed by time
|
||||||
private Vector3 m_linearMotorOffset = Vector3.Zero; // the point of force can be offset from the center
|
private Vector3 m_linearMotorOffset = Vector3.Zero; // the point of force can be offset from the center
|
||||||
private Vector3 m_linearMotorDirectionLASTSET = Vector3.Zero; // velocity requested by LSL
|
private Vector3 m_linearMotorDirectionLASTSET = Vector3.Zero; // velocity requested by LSL
|
||||||
private Vector3 m_newVelocity = Vector3.Zero; // velocity computed to be applied to body
|
|
||||||
private Vector3 m_linearFrictionTimescale = Vector3.Zero;
|
private Vector3 m_linearFrictionTimescale = Vector3.Zero;
|
||||||
private float m_linearMotorDecayTimescale = 0;
|
private float m_linearMotorDecayTimescale = 0;
|
||||||
private float m_linearMotorTimescale = 0;
|
private float m_linearMotorTimescale = 0;
|
||||||
|
@ -93,6 +93,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
// private Vector3 m_linearMotorOffset = Vector3.Zero;
|
// private Vector3 m_linearMotorOffset = Vector3.Zero;
|
||||||
|
|
||||||
//Angular properties
|
//Angular properties
|
||||||
|
private BSVMotor m_angularMotor = new BSVMotor("AngularMotor");
|
||||||
private Vector3 m_angularMotorDirection = Vector3.Zero; // angular velocity requested by LSL motor
|
private Vector3 m_angularMotorDirection = Vector3.Zero; // angular velocity requested by LSL motor
|
||||||
// private int m_angularMotorApply = 0; // application frame counter
|
// private int m_angularMotorApply = 0; // application frame counter
|
||||||
private Vector3 m_angularMotorVelocity = Vector3.Zero; // current angular motor velocity
|
private Vector3 m_angularMotorVelocity = Vector3.Zero; // current angular motor velocity
|
||||||
|
@ -152,10 +153,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
m_angularDeflectionTimescale = Math.Max(pValue, 0.01f);
|
m_angularDeflectionTimescale = Math.Max(pValue, 0.01f);
|
||||||
break;
|
break;
|
||||||
case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE:
|
case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE:
|
||||||
m_angularMotorDecayTimescale = Math.Max(pValue, 0.01f);
|
m_angularMotorDecayTimescale = Math.Max(0.01f, Math.Min(pValue,120));
|
||||||
|
m_angularMotor.TargetValueDecayTimeScale = m_angularMotorDecayTimescale;
|
||||||
break;
|
break;
|
||||||
case Vehicle.ANGULAR_MOTOR_TIMESCALE:
|
case Vehicle.ANGULAR_MOTOR_TIMESCALE:
|
||||||
m_angularMotorTimescale = Math.Max(pValue, 0.01f);
|
m_angularMotorTimescale = Math.Max(pValue, 0.01f);
|
||||||
|
m_angularMotor.TimeScale = m_angularMotorTimescale;
|
||||||
break;
|
break;
|
||||||
case Vehicle.BANKING_EFFICIENCY:
|
case Vehicle.BANKING_EFFICIENCY:
|
||||||
m_bankingEfficiency = Math.Max(-1f, Math.Min(pValue, 1f));
|
m_bankingEfficiency = Math.Max(-1f, Math.Min(pValue, 1f));
|
||||||
|
@ -185,10 +188,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
m_linearDeflectionTimescale = Math.Max(pValue, 0.01f);
|
m_linearDeflectionTimescale = Math.Max(pValue, 0.01f);
|
||||||
break;
|
break;
|
||||||
case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE:
|
case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE:
|
||||||
m_linearMotorDecayTimescale = Math.Max(pValue, 0.01f);
|
m_linearMotorDecayTimescale = Math.Max(0.01f, Math.Min(pValue,120));
|
||||||
|
m_linearMotor.TargetValueDecayTimeScale = m_linearMotorDecayTimescale;
|
||||||
break;
|
break;
|
||||||
case Vehicle.LINEAR_MOTOR_TIMESCALE:
|
case Vehicle.LINEAR_MOTOR_TIMESCALE:
|
||||||
m_linearMotorTimescale = Math.Max(pValue, 0.01f);
|
m_linearMotorTimescale = Math.Max(pValue, 0.01f);
|
||||||
|
m_linearMotor.TimeScale = m_linearMotorTimescale;
|
||||||
break;
|
break;
|
||||||
case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY:
|
case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY:
|
||||||
m_verticalAttractionEfficiency = Math.Max(0.1f, Math.Min(pValue, 1f));
|
m_verticalAttractionEfficiency = Math.Max(0.1f, Math.Min(pValue, 1f));
|
||||||
|
@ -201,17 +206,20 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
// set all of the components to the same value
|
// set all of the components to the same value
|
||||||
case Vehicle.ANGULAR_FRICTION_TIMESCALE:
|
case Vehicle.ANGULAR_FRICTION_TIMESCALE:
|
||||||
m_angularFrictionTimescale = new Vector3(pValue, pValue, pValue);
|
m_angularFrictionTimescale = new Vector3(pValue, pValue, pValue);
|
||||||
|
m_angularMotor.FrictionTimescale = m_angularFrictionTimescale;
|
||||||
break;
|
break;
|
||||||
case Vehicle.ANGULAR_MOTOR_DIRECTION:
|
case Vehicle.ANGULAR_MOTOR_DIRECTION:
|
||||||
m_angularMotorDirection = new Vector3(pValue, pValue, pValue);
|
m_angularMotorDirection = new Vector3(pValue, pValue, pValue);
|
||||||
// m_angularMotorApply = 100;
|
m_angularMotor.SetTarget(m_angularMotorDirection);
|
||||||
break;
|
break;
|
||||||
case Vehicle.LINEAR_FRICTION_TIMESCALE:
|
case Vehicle.LINEAR_FRICTION_TIMESCALE:
|
||||||
m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue);
|
m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue);
|
||||||
|
m_linearMotor.FrictionTimescale = m_linearFrictionTimescale;
|
||||||
break;
|
break;
|
||||||
case Vehicle.LINEAR_MOTOR_DIRECTION:
|
case Vehicle.LINEAR_MOTOR_DIRECTION:
|
||||||
m_linearMotorDirection = new Vector3(pValue, pValue, pValue);
|
m_linearMotorDirection = new Vector3(pValue, pValue, pValue);
|
||||||
m_linearMotorDirectionLASTSET = new Vector3(pValue, pValue, pValue);
|
m_linearMotorDirectionLASTSET = new Vector3(pValue, pValue, pValue);
|
||||||
|
m_linearMotor.SetTarget(m_linearMotorDirection);
|
||||||
break;
|
break;
|
||||||
case Vehicle.LINEAR_MOTOR_OFFSET:
|
case Vehicle.LINEAR_MOTOR_OFFSET:
|
||||||
m_linearMotorOffset = new Vector3(pValue, pValue, pValue);
|
m_linearMotorOffset = new Vector3(pValue, pValue, pValue);
|
||||||
|
@ -227,6 +235,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
{
|
{
|
||||||
case Vehicle.ANGULAR_FRICTION_TIMESCALE:
|
case Vehicle.ANGULAR_FRICTION_TIMESCALE:
|
||||||
m_angularFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
m_angularFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||||
|
m_angularMotor.FrictionTimescale = m_angularFrictionTimescale;
|
||||||
break;
|
break;
|
||||||
case Vehicle.ANGULAR_MOTOR_DIRECTION:
|
case Vehicle.ANGULAR_MOTOR_DIRECTION:
|
||||||
// Limit requested angular speed to 2 rps= 4 pi rads/sec
|
// Limit requested angular speed to 2 rps= 4 pi rads/sec
|
||||||
|
@ -234,14 +243,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
pValue.Y = Math.Max(-12.56f, Math.Min(pValue.Y, 12.56f));
|
pValue.Y = Math.Max(-12.56f, Math.Min(pValue.Y, 12.56f));
|
||||||
pValue.Z = Math.Max(-12.56f, Math.Min(pValue.Z, 12.56f));
|
pValue.Z = Math.Max(-12.56f, Math.Min(pValue.Z, 12.56f));
|
||||||
m_angularMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
m_angularMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||||
// m_angularMotorApply = 100;
|
m_angularMotor.SetTarget(m_angularMotorDirection);
|
||||||
break;
|
break;
|
||||||
case Vehicle.LINEAR_FRICTION_TIMESCALE:
|
case Vehicle.LINEAR_FRICTION_TIMESCALE:
|
||||||
m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||||
|
m_linearMotor.FrictionTimescale = m_linearFrictionTimescale;
|
||||||
break;
|
break;
|
||||||
case Vehicle.LINEAR_MOTOR_DIRECTION:
|
case Vehicle.LINEAR_MOTOR_DIRECTION:
|
||||||
m_linearMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
m_linearMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||||
m_linearMotorDirectionLASTSET = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
m_linearMotorDirectionLASTSET = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||||
|
m_linearMotor.SetTarget(m_linearMotorDirection);
|
||||||
break;
|
break;
|
||||||
case Vehicle.LINEAR_MOTOR_OFFSET:
|
case Vehicle.LINEAR_MOTOR_OFFSET:
|
||||||
m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||||
|
@ -319,6 +330,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
|
|
||||||
m_referenceFrame = Quaternion.Identity;
|
m_referenceFrame = Quaternion.Identity;
|
||||||
m_flags = (VehicleFlag)0;
|
m_flags = (VehicleFlag)0;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Vehicle.TYPE_SLED:
|
case Vehicle.TYPE_SLED:
|
||||||
|
@ -351,10 +363,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
m_bankingMix = 1;
|
m_bankingMix = 1;
|
||||||
|
|
||||||
m_referenceFrame = Quaternion.Identity;
|
m_referenceFrame = Quaternion.Identity;
|
||||||
m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
|
m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY
|
||||||
m_flags &=
|
| VehicleFlag.HOVER_TERRAIN_ONLY
|
||||||
~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
|
| VehicleFlag.HOVER_GLOBAL_HEIGHT
|
||||||
VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
|
| VehicleFlag.HOVER_UP_ONLY);
|
||||||
|
m_flags |= (VehicleFlag.NO_DEFLECTION_UP
|
||||||
|
| VehicleFlag.LIMIT_ROLL_ONLY
|
||||||
|
| VehicleFlag.LIMIT_MOTOR_UP);
|
||||||
break;
|
break;
|
||||||
case Vehicle.TYPE_CAR:
|
case Vehicle.TYPE_CAR:
|
||||||
m_linearMotorDirection = Vector3.Zero;
|
m_linearMotorDirection = Vector3.Zero;
|
||||||
|
@ -510,6 +525,18 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
| VehicleFlag.HOVER_GLOBAL_HEIGHT);
|
| VehicleFlag.HOVER_GLOBAL_HEIGHT);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update any physical parameters based on this type.
|
||||||
|
Refresh();
|
||||||
|
|
||||||
|
m_linearMotor = new BSVMotor("LinearMotor", m_linearMotorTimescale,
|
||||||
|
m_linearMotorDecayTimescale, m_linearFrictionTimescale, 1f);
|
||||||
|
m_linearMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging)
|
||||||
|
m_angularMotor = new BSVMotor("AngularMotor", m_angularMotorTimescale,
|
||||||
|
m_angularMotorDecayTimescale, m_angularFrictionTimescale, 1f);
|
||||||
|
m_angularMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging)
|
||||||
|
|
||||||
|
// m_bankingMotor = new BSVMotor("BankingMotor", ...);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Some of the properties of this prim may have changed.
|
// Some of the properties of this prim may have changed.
|
||||||
|
@ -518,13 +545,25 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
{
|
{
|
||||||
if (IsActive)
|
if (IsActive)
|
||||||
{
|
{
|
||||||
|
m_vehicleMass = Prim.Linkset.LinksetMass;
|
||||||
|
|
||||||
// Friction effects are handled by this vehicle code
|
// Friction effects are handled by this vehicle code
|
||||||
BulletSimAPI.SetFriction2(Prim.PhysBody.ptr, 0f);
|
float friction = 0f;
|
||||||
BulletSimAPI.SetHitFraction2(Prim.PhysBody.ptr, 0f);
|
BulletSimAPI.SetFriction2(Prim.PhysBody.ptr, friction);
|
||||||
|
|
||||||
// BulletSimAPI.SetAngularDamping2(Prim.PhysBody.ptr, 0.8f);
|
// Moderate angular movement introduced by Bullet.
|
||||||
|
// TODO: possibly set AngularFactor and LinearFactor for the type of vehicle.
|
||||||
|
// Maybe compute linear and angular factor and damping from params.
|
||||||
|
float angularDamping = PhysicsScene.Params.vehicleAngularDamping;
|
||||||
|
BulletSimAPI.SetAngularDamping2(Prim.PhysBody.ptr, angularDamping);
|
||||||
|
|
||||||
VDetailLog("{0},BSDynamics.Refresh,zeroingFriction and adding damping", Prim.LocalID);
|
// DEBUG DEBUG DEBUG: use uniform inertia to smooth movement added by Bullet
|
||||||
|
// Vector3 localInertia = new Vector3(1f, 1f, 1f);
|
||||||
|
Vector3 localInertia = new Vector3(m_vehicleMass, m_vehicleMass, m_vehicleMass);
|
||||||
|
BulletSimAPI.SetMassProps2(Prim.PhysBody.ptr, m_vehicleMass, localInertia);
|
||||||
|
|
||||||
|
VDetailLog("{0},BSDynamics.Refresh,frict={1},inert={2},aDamp={3}",
|
||||||
|
Prim.LocalID, friction, localInertia, angularDamping);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -551,97 +590,38 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
{
|
{
|
||||||
if (!IsActive) return;
|
if (!IsActive) return;
|
||||||
|
|
||||||
// DEBUG
|
|
||||||
// Because Bullet does apply forces to the vehicle, our last computed
|
|
||||||
// linear and angular velocities are not what is happening now.
|
|
||||||
// Vector3 externalAngularVelocity = Prim.ForceRotationalVelocity - m_lastAngularVelocity;
|
|
||||||
// m_lastAngularVelocity += (externalAngularVelocity * 0.5f) * pTimestep;
|
|
||||||
// m_lastAngularVelocity = Prim.ForceRotationalVelocity; // DEBUG: account for what Bullet did last time
|
|
||||||
// m_lastLinearVelocityVector = Prim.ForceVelocity * Quaternion.Inverse(Prim.ForceOrientation); // DEBUG:
|
|
||||||
// END DEBUG
|
|
||||||
|
|
||||||
m_vehicleMass = Prim.Linkset.LinksetMass;
|
|
||||||
|
|
||||||
MoveLinear(pTimestep);
|
MoveLinear(pTimestep);
|
||||||
// Commented out for debug
|
|
||||||
MoveAngular(pTimestep);
|
MoveAngular(pTimestep);
|
||||||
// Prim.ApplyTorqueImpulse(-Prim.RotationalVelocity * m_vehicleMass, false); // DEBUG DEBUG
|
|
||||||
// Prim.ForceRotationalVelocity = -Prim.RotationalVelocity; // DEBUG DEBUG
|
|
||||||
|
|
||||||
LimitRotation(pTimestep);
|
LimitRotation(pTimestep);
|
||||||
|
|
||||||
// remember the position so next step we can limit absolute movement effects
|
// remember the position so next step we can limit absolute movement effects
|
||||||
m_lastPositionVector = Prim.ForcePosition;
|
m_lastPositionVector = Prim.ForcePosition;
|
||||||
|
|
||||||
VDetailLog("{0},BSDynamics.Step,frict={1},grav={2},inertia={3},mass={4}", // DEBUG DEBUG
|
|
||||||
Prim.LocalID,
|
|
||||||
BulletSimAPI.GetFriction2(Prim.PhysBody.ptr),
|
|
||||||
BulletSimAPI.GetGravity2(Prim.PhysBody.ptr),
|
|
||||||
Prim.Inertia,
|
|
||||||
m_vehicleMass
|
|
||||||
);
|
|
||||||
VDetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}",
|
VDetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}",
|
||||||
Prim.LocalID, Prim.ForcePosition, Prim.Force, Prim.ForceVelocity, Prim.RotationalVelocity);
|
Prim.LocalID, Prim.ForcePosition, Prim.Force, Prim.ForceVelocity, Prim.RotationalVelocity);
|
||||||
}// end Step
|
}
|
||||||
|
|
||||||
// Apply the effect of the linear motor.
|
// Apply the effect of the linear motor.
|
||||||
// Also does hover and float.
|
// Also does hover and float.
|
||||||
private void MoveLinear(float pTimestep)
|
private void MoveLinear(float pTimestep)
|
||||||
{
|
{
|
||||||
// m_linearMotorDirection is the target direction we are moving relative to the vehicle coordinates
|
Vector3 linearMotorContribution = m_linearMotor.Step(pTimestep);
|
||||||
// m_lastLinearVelocityVector is the current speed we are moving in that direction
|
|
||||||
if (m_linearMotorDirection.LengthSquared() > 0.001f)
|
|
||||||
{
|
|
||||||
Vector3 origDir = m_linearMotorDirection; // DEBUG
|
|
||||||
Vector3 origVel = m_lastLinearVelocityVector; // DEBUG
|
|
||||||
// DEBUG: the vehicle velocity rotated to be relative to vehicle coordinates for comparison
|
|
||||||
Vector3 vehicleVelocity = Prim.ForceVelocity * Quaternion.Inverse(Prim.ForceOrientation); // DEBUG
|
|
||||||
|
|
||||||
// Add (desiredVelocity - lastAppliedVelocity) / howLongItShouldTakeToComplete
|
|
||||||
Vector3 addAmount = (m_linearMotorDirection - m_lastLinearVelocityVector)/(m_linearMotorTimescale) * pTimestep;
|
|
||||||
m_lastLinearVelocityVector += addAmount;
|
|
||||||
|
|
||||||
float decayFactor = (1.0f / m_linearMotorDecayTimescale) * pTimestep;
|
|
||||||
m_linearMotorDirection *= (1f - decayFactor);
|
|
||||||
|
|
||||||
// Rotate new object velocity from vehicle relative to world coordinates
|
// Rotate new object velocity from vehicle relative to world coordinates
|
||||||
m_newVelocity = m_lastLinearVelocityVector * Prim.ForceOrientation;
|
linearMotorContribution *= Prim.ForceOrientation;
|
||||||
|
|
||||||
// Apply friction for next time
|
|
||||||
Vector3 frictionFactor = (Vector3.One / m_linearFrictionTimescale) * pTimestep;
|
|
||||||
m_lastLinearVelocityVector *= (Vector3.One - frictionFactor);
|
|
||||||
|
|
||||||
VDetailLog("{0},MoveLinear,nonZero,origlmDir={1},origlvVel={2},vehVel={3},add={4},decay={5},frict={6},lmDir={7},lvVec={8},newVel={9}",
|
|
||||||
Prim.LocalID, origDir, origVel, vehicleVelocity, addAmount, decayFactor, frictionFactor,
|
|
||||||
m_linearMotorDirection, m_lastLinearVelocityVector, m_newVelocity);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// if what remains of direction is very small, zero it.
|
|
||||||
m_linearMotorDirection = Vector3.Zero;
|
|
||||||
m_lastLinearVelocityVector = Vector3.Zero;
|
|
||||||
m_newVelocity = Vector3.Zero;
|
|
||||||
|
|
||||||
VDetailLog("{0},MoveLinear,zeroed", Prim.LocalID);
|
|
||||||
}
|
|
||||||
|
|
||||||
// m_newVelocity is velocity computed from linear motor in world coordinates
|
|
||||||
|
|
||||||
|
// ==================================================================
|
||||||
// Gravity and Buoyancy
|
// Gravity and Buoyancy
|
||||||
// There is some gravity, make a gravity force vector that is applied after object velocity.
|
// There is some gravity, make a gravity force vector that is applied after object velocity.
|
||||||
// m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g;
|
// m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g;
|
||||||
Vector3 grav = Prim.PhysicsScene.DefaultGravity * (1f - m_VehicleBuoyancy);
|
Vector3 grav = Prim.PhysicsScene.DefaultGravity * (1f - m_VehicleBuoyancy);
|
||||||
|
|
||||||
/*
|
// Current vehicle position
|
||||||
* RA: Not sure why one would do this unless we are hoping external forces are doing gravity, ...
|
|
||||||
// Preserve the current Z velocity
|
|
||||||
Vector3 vel_now = m_prim.Velocity;
|
|
||||||
m_dir.Z = vel_now.Z; // Preserve the accumulated falling velocity
|
|
||||||
*/
|
|
||||||
|
|
||||||
Vector3 pos = Prim.ForcePosition;
|
Vector3 pos = Prim.ForcePosition;
|
||||||
// Vector3 accel = new Vector3(-(m_dir.X - m_lastLinearVelocityVector.X / 0.1f), -(m_dir.Y - m_lastLinearVelocityVector.Y / 0.1f), m_dir.Z - m_lastLinearVelocityVector.Z / 0.1f);
|
|
||||||
|
|
||||||
|
// ==================================================================
|
||||||
|
Vector3 terrainHeightContribution = Vector3.Zero;
|
||||||
// If below the terrain, move us above the ground a little.
|
// If below the terrain, move us above the ground a little.
|
||||||
float terrainHeight = Prim.PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos);
|
float terrainHeight = Prim.PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos);
|
||||||
// Taking the rotated size doesn't work here because m_prim.Size is the size of the root prim and not the linkset.
|
// Taking the rotated size doesn't work here because m_prim.Size is the size of the root prim and not the linkset.
|
||||||
|
@ -650,11 +630,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
// if (rotatedSize.Z < terrainHeight)
|
// if (rotatedSize.Z < terrainHeight)
|
||||||
if (pos.Z < terrainHeight)
|
if (pos.Z < terrainHeight)
|
||||||
{
|
{
|
||||||
|
// TODO: correct position by applying force rather than forcing position.
|
||||||
pos.Z = terrainHeight + 2;
|
pos.Z = terrainHeight + 2;
|
||||||
Prim.ForcePosition = pos;
|
Prim.ForcePosition = pos;
|
||||||
VDetailLog("{0},MoveLinear,terrainHeight,terrainHeight={1},pos={2}", Prim.LocalID, terrainHeight, pos);
|
VDetailLog("{0},MoveLinear,terrainHeight,terrainHeight={1},pos={2}", Prim.LocalID, terrainHeight, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ==================================================================
|
||||||
|
Vector3 hoverContribution = Vector3.Zero;
|
||||||
// Check if hovering
|
// Check if hovering
|
||||||
// m_VhoverEfficiency: 0=bouncy, 1=totally damped
|
// m_VhoverEfficiency: 0=bouncy, 1=totally damped
|
||||||
// m_VhoverTimescale: time to achieve height
|
// m_VhoverTimescale: time to achieve height
|
||||||
|
@ -694,24 +677,22 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
// RA: where does the 50 come from?
|
// RA: where does the 50 come from?
|
||||||
float verticalCorrectionVelocity = pTimestep * ((verticalError * 50.0f) / m_VhoverTimescale);
|
float verticalCorrectionVelocity = pTimestep * ((verticalError * 50.0f) / m_VhoverTimescale);
|
||||||
// Replace Vertical speed with correction figure if significant
|
// Replace Vertical speed with correction figure if significant
|
||||||
if (Math.Abs(verticalError) > 0.01f)
|
if (verticalError > 0.01f)
|
||||||
{
|
{
|
||||||
m_newVelocity.Z += verticalCorrectionVelocity;
|
hoverContribution = new Vector3(0f, 0f, verticalCorrectionVelocity);
|
||||||
//KF: m_VhoverEfficiency is not yet implemented
|
//KF: m_VhoverEfficiency is not yet implemented
|
||||||
}
|
}
|
||||||
else if (verticalError < -0.01)
|
else if (verticalError < -0.01)
|
||||||
{
|
{
|
||||||
m_newVelocity.Z -= verticalCorrectionVelocity;
|
hoverContribution = new Vector3(0f, 0f, -verticalCorrectionVelocity);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_newVelocity.Z = 0f;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VDetailLog("{0},MoveLinear,hover,pos={1},dir={2},height={3},target={4}", Prim.LocalID, pos, m_newVelocity, m_VhoverHeight, m_VhoverTargetHeight);
|
VDetailLog("{0},MoveLinear,hover,pos={1},dir={2},height={3},target={4}",
|
||||||
|
Prim.LocalID, pos, hoverContribution, m_VhoverHeight, m_VhoverTargetHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ==================================================================
|
||||||
Vector3 posChange = pos - m_lastPositionVector;
|
Vector3 posChange = pos - m_lastPositionVector;
|
||||||
if (m_BlockingEndPoint != Vector3.Zero)
|
if (m_BlockingEndPoint != Vector3.Zero)
|
||||||
{
|
{
|
||||||
|
@ -749,70 +730,77 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#region downForce
|
// ==================================================================
|
||||||
Vector3 downForce = Vector3.Zero;
|
Vector3 limitMotorUpContribution = Vector3.Zero;
|
||||||
|
|
||||||
if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0)
|
if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0)
|
||||||
{
|
{
|
||||||
// If the vehicle is motoring into the sky, get it going back down.
|
// If the vehicle is motoring into the sky, get it going back down.
|
||||||
// Is this an angular force or both linear and angular??
|
|
||||||
float distanceAboveGround = pos.Z - terrainHeight;
|
float distanceAboveGround = pos.Z - terrainHeight;
|
||||||
if (distanceAboveGround > 2f)
|
if (distanceAboveGround > 1f)
|
||||||
{
|
{
|
||||||
// downForce = new Vector3(0, 0, (-distanceAboveGround / m_bankingTimescale) * pTimestep);
|
// downForce = new Vector3(0, 0, (-distanceAboveGround / m_bankingTimescale) * pTimestep);
|
||||||
// downForce = new Vector3(0, 0, -distanceAboveGround / m_bankingTimescale);
|
// downForce = new Vector3(0, 0, -distanceAboveGround / m_bankingTimescale);
|
||||||
downForce = new Vector3(0, 0, -distanceAboveGround);
|
limitMotorUpContribution = new Vector3(0, 0, -distanceAboveGround);
|
||||||
}
|
}
|
||||||
// TODO: this calculation is all wrong. From the description at
|
// TODO: this calculation is all wrong. From the description at
|
||||||
// (http://wiki.secondlife.com/wiki/Category:LSL_Vehicle), the downForce
|
// (http://wiki.secondlife.com/wiki/Category:LSL_Vehicle), the downForce
|
||||||
// has a decay factor. This says this force should
|
// has a decay factor. This says this force should
|
||||||
// be computed with a motor.
|
// be computed with a motor.
|
||||||
VDetailLog("{0},MoveLinear,limitMotorUp,distAbove={1},downForce={2}",
|
VDetailLog("{0},MoveLinear,limitMotorUp,distAbove={1},downForce={2}",
|
||||||
Prim.LocalID, distanceAboveGround, downForce);
|
Prim.LocalID, distanceAboveGround, limitMotorUpContribution);
|
||||||
}
|
}
|
||||||
#endregion // downForce
|
|
||||||
|
// ==================================================================
|
||||||
|
Vector3 newVelocity = linearMotorContribution
|
||||||
|
+ terrainHeightContribution
|
||||||
|
+ hoverContribution
|
||||||
|
+ limitMotorUpContribution;
|
||||||
|
|
||||||
// If not changing some axis, reduce out velocity
|
// If not changing some axis, reduce out velocity
|
||||||
if ((m_flags & (VehicleFlag.NO_X)) != 0)
|
if ((m_flags & (VehicleFlag.NO_X)) != 0)
|
||||||
m_newVelocity.X = 0;
|
newVelocity.X = 0;
|
||||||
if ((m_flags & (VehicleFlag.NO_Y)) != 0)
|
if ((m_flags & (VehicleFlag.NO_Y)) != 0)
|
||||||
m_newVelocity.Y = 0;
|
newVelocity.Y = 0;
|
||||||
if ((m_flags & (VehicleFlag.NO_Z)) != 0)
|
if ((m_flags & (VehicleFlag.NO_Z)) != 0)
|
||||||
m_newVelocity.Z = 0;
|
newVelocity.Z = 0;
|
||||||
|
|
||||||
|
// ==================================================================
|
||||||
// Clamp REALLY high or low velocities
|
// Clamp REALLY high or low velocities
|
||||||
if (m_newVelocity.LengthSquared() > 1e6f)
|
float newVelocityLengthSq = newVelocity.LengthSquared();
|
||||||
|
if (newVelocityLengthSq > 1e6f)
|
||||||
{
|
{
|
||||||
m_newVelocity /= m_newVelocity.Length();
|
newVelocity /= newVelocity.Length();
|
||||||
m_newVelocity *= 1000f;
|
newVelocity *= 1000f;
|
||||||
}
|
}
|
||||||
else if (m_newVelocity.LengthSquared() < 1e-6f)
|
else if (newVelocityLengthSq < 1e-6f)
|
||||||
m_newVelocity = Vector3.Zero;
|
newVelocity = Vector3.Zero;
|
||||||
|
|
||||||
|
// ==================================================================
|
||||||
// Stuff new linear velocity into the vehicle
|
// Stuff new linear velocity into the vehicle
|
||||||
Prim.ForceVelocity = m_newVelocity;
|
Prim.ForceVelocity = newVelocity;
|
||||||
// Prim.ApplyForceImpulse((m_newVelocity - Prim.Velocity) * m_vehicleMass, false); // DEBUG DEBUG
|
// Prim.ApplyForceImpulse((m_newVelocity - Prim.Velocity) * m_vehicleMass, false); // DEBUG DEBUG
|
||||||
|
|
||||||
Vector3 totalDownForce = downForce + grav;
|
// Other linear forces are applied as forces.
|
||||||
|
Vector3 totalDownForce = grav * m_vehicleMass;
|
||||||
if (totalDownForce != Vector3.Zero)
|
if (totalDownForce != Vector3.Zero)
|
||||||
{
|
{
|
||||||
Prim.AddForce(totalDownForce * m_vehicleMass, false);
|
Prim.AddForce(totalDownForce, false);
|
||||||
// Prim.ApplyForceImpulse(totalDownForce * m_vehicleMass, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VDetailLog("{0},MoveLinear,done,lmDir={1},lmVel={2},newVel={3},primVel={4},totalDown={5}",
|
VDetailLog("{0},MoveLinear,done,lmDir={1},lmVel={2},newVel={3},primVel={4},totalDown={5}",
|
||||||
Prim.LocalID, m_linearMotorDirection, m_lastLinearVelocityVector, m_newVelocity, Prim.Velocity, totalDownForce);
|
Prim.LocalID, m_linearMotorDirection, m_lastLinearVelocityVector,
|
||||||
|
newVelocity, Prim.Velocity, totalDownForce);
|
||||||
|
|
||||||
} // end MoveLinear()
|
} // end MoveLinear()
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
// Apply the effect of the angular motor.
|
// Apply the effect of the angular motor.
|
||||||
private void MoveAngular(float pTimestep)
|
private void MoveAngular(float pTimestep)
|
||||||
{
|
{
|
||||||
// m_angularMotorDirection // angular velocity requested by LSL motor
|
// m_angularMotorDirection // angular velocity requested by LSL motor
|
||||||
// m_angularMotorApply // application frame counter
|
|
||||||
// m_angularMotorVelocity // current angular motor velocity (ramps up and down)
|
// m_angularMotorVelocity // current angular motor velocity (ramps up and down)
|
||||||
// m_angularMotorTimescale // motor angular velocity ramp up rate
|
// m_angularMotorTimescale // motor angular velocity ramp up time
|
||||||
// m_angularMotorDecayTimescale // motor angular velocity decay rate
|
// m_angularMotorDecayTimescale // motor angular velocity decay rate
|
||||||
// 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
|
||||||
|
@ -836,18 +824,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
m_angularMotorVelocity = Vector3.Zero;
|
m_angularMotorVelocity = Vector3.Zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Vertical attactor
|
Vector3 angularMotorContribution = m_angularMotor.Step(pTimestep);
|
||||||
|
|
||||||
Vector3 vertattr = Vector3.Zero;
|
|
||||||
Vector3 deflection = Vector3.Zero;
|
|
||||||
Vector3 banking = Vector3.Zero;
|
|
||||||
|
|
||||||
|
// ==================================================================
|
||||||
|
Vector3 verticalAttractionContribution = Vector3.Zero;
|
||||||
// If vertical attaction timescale is reasonable and we applied an angular force last time...
|
// If vertical attaction timescale is reasonable and we applied an angular force last time...
|
||||||
if (m_verticalAttractionTimescale < 300 && m_lastAngularVelocity != Vector3.Zero)
|
if (m_verticalAttractionTimescale < 300 && m_lastAngularVelocity != Vector3.Zero)
|
||||||
{
|
{
|
||||||
float VAservo = pTimestep * 0.2f / m_verticalAttractionTimescale;
|
float VAservo = pTimestep * 0.2f / m_verticalAttractionTimescale;
|
||||||
if (Prim.IsColliding)
|
if (Prim.IsColliding)
|
||||||
VAservo = pTimestep * 0.05f / (m_verticalAttractionTimescale);
|
VAservo = pTimestep * 0.05f / m_verticalAttractionTimescale;
|
||||||
|
|
||||||
VAservo *= (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency);
|
VAservo *= (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency);
|
||||||
|
|
||||||
|
@ -871,24 +857,23 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
// As the body rotates around the X axis, then verticalError.Y increases; Rotated around Y
|
// As the body rotates around the X axis, then verticalError.Y increases; Rotated around Y
|
||||||
// then .X increases, so change Body angular velocity X based on Y, and Y based on X.
|
// then .X increases, so change Body angular velocity X based on Y, and Y based on X.
|
||||||
// Z is not changed.
|
// Z is not changed.
|
||||||
vertattr.X = verticalError.Y;
|
verticalAttractionContribution.X = verticalError.Y;
|
||||||
vertattr.Y = - verticalError.X;
|
verticalAttractionContribution.Y = - verticalError.X;
|
||||||
vertattr.Z = 0f;
|
verticalAttractionContribution.Z = 0f;
|
||||||
|
|
||||||
// scaling appears better usingsquare-law
|
// scaling appears better usingsquare-law
|
||||||
Vector3 angularVelocity = Prim.ForceRotationalVelocity;
|
Vector3 angularVelocity = Prim.ForceRotationalVelocity;
|
||||||
float bounce = 1.0f - (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency);
|
float bounce = 1.0f - (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency);
|
||||||
vertattr.X += bounce * angularVelocity.X;
|
verticalAttractionContribution.X += bounce * angularVelocity.X;
|
||||||
vertattr.Y += bounce * angularVelocity.Y;
|
verticalAttractionContribution.Y += bounce * angularVelocity.Y;
|
||||||
|
|
||||||
VDetailLog("{0},MoveAngular,verticalAttraction,VAservo={1},effic={2},verticalError={3},bounce={4},vertattr={5}",
|
VDetailLog("{0},MoveAngular,verticalAttraction,VAservo={1},effic={2},verticalError={3},bounce={4},vertattr={5}",
|
||||||
Prim.LocalID, VAservo, m_verticalAttractionEfficiency, verticalError, bounce, vertattr);
|
Prim.LocalID, VAservo, m_verticalAttractionEfficiency, verticalError, bounce, verticalAttractionContribution);
|
||||||
|
|
||||||
}
|
}
|
||||||
#endregion // Vertical attactor
|
|
||||||
|
|
||||||
#region Deflection
|
|
||||||
|
|
||||||
|
// ==================================================================
|
||||||
|
Vector3 deflectionContribution = Vector3.Zero;
|
||||||
if (m_angularDeflectionEfficiency != 0)
|
if (m_angularDeflectionEfficiency != 0)
|
||||||
{
|
{
|
||||||
// Compute a scaled vector that points in the preferred axis (X direction)
|
// Compute a scaled vector that points in the preferred axis (X direction)
|
||||||
|
@ -899,18 +884,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
Vector3 preferredAxisOfMotion = scaledDefaultDirection * Quaternion.Add(Prim.ForceOrientation, m_referenceFrame);
|
Vector3 preferredAxisOfMotion = scaledDefaultDirection * Quaternion.Add(Prim.ForceOrientation, m_referenceFrame);
|
||||||
|
|
||||||
// Scale by efficiency and timescale
|
// Scale by efficiency and timescale
|
||||||
deflection = (preferredAxisOfMotion * (m_angularDeflectionEfficiency) / m_angularDeflectionTimescale) * pTimestep;
|
deflectionContribution = (preferredAxisOfMotion * (m_angularDeflectionEfficiency) / m_angularDeflectionTimescale) * pTimestep;
|
||||||
|
|
||||||
VDetailLog("{0},MoveAngular,Deflection,perfAxis={1},deflection={2}",
|
VDetailLog("{0},MoveAngular,Deflection,perfAxis={1},deflection={2}",
|
||||||
Prim.LocalID, preferredAxisOfMotion, deflection);
|
Prim.LocalID, preferredAxisOfMotion, deflectionContribution);
|
||||||
// This deflection computation is not correct.
|
// This deflection computation is not correct.
|
||||||
deflection = Vector3.Zero;
|
deflectionContribution = Vector3.Zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
// ==================================================================
|
||||||
|
Vector3 bankingContribution = Vector3.Zero;
|
||||||
#region Banking
|
|
||||||
|
|
||||||
if (m_bankingEfficiency != 0)
|
if (m_bankingEfficiency != 0)
|
||||||
{
|
{
|
||||||
Vector3 dir = Vector3.One * Prim.ForceOrientation;
|
Vector3 dir = Vector3.One * Prim.ForceOrientation;
|
||||||
|
@ -925,6 +908,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
float mix = Math.Abs(m_bankingMix);
|
float mix = Math.Abs(m_bankingMix);
|
||||||
if (m_angularMotorVelocity.X == 0)
|
if (m_angularMotorVelocity.X == 0)
|
||||||
{
|
{
|
||||||
|
// The vehicle is stopped
|
||||||
/*if (!parent.Orientation.ApproxEquals(this.m_referenceFrame, 0.25f))
|
/*if (!parent.Orientation.ApproxEquals(this.m_referenceFrame, 0.25f))
|
||||||
{
|
{
|
||||||
Vector3 axisAngle;
|
Vector3 axisAngle;
|
||||||
|
@ -938,9 +922,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
banking.Z += (effSquared*(mult*mix))*(m_angularMotorVelocity.X) * 4;
|
{
|
||||||
if (!Prim.IsColliding && Math.Abs(m_angularMotorVelocity.X) > mix)
|
bankingContribution.Z += (effSquared * (mult * mix)) * (m_angularMotorVelocity.X) * 4;
|
||||||
|
}
|
||||||
|
|
||||||
//If they are colliding, we probably shouldn't shove the prim around... probably
|
//If they are colliding, we probably shouldn't shove the prim around... probably
|
||||||
|
if (!Prim.IsColliding && Math.Abs(m_angularMotorVelocity.X) > mix)
|
||||||
{
|
{
|
||||||
float angVelZ = m_angularMotorVelocity.X*-1;
|
float angVelZ = m_angularMotorVelocity.X*-1;
|
||||||
/*if(angVelZ > mix)
|
/*if(angVelZ > mix)
|
||||||
|
@ -954,22 +941,23 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
else if (bankingRot.X < -3)
|
else if (bankingRot.X < -3)
|
||||||
bankingRot.X = -3;
|
bankingRot.X = -3;
|
||||||
bankingRot *= Prim.ForceOrientation;
|
bankingRot *= Prim.ForceOrientation;
|
||||||
banking += bankingRot;
|
bankingContribution += bankingRot;
|
||||||
}
|
}
|
||||||
m_angularMotorVelocity.X *= m_bankingEfficiency == 1 ? 0.0f : 1 - m_bankingEfficiency;
|
m_angularMotorVelocity.X *= m_bankingEfficiency == 1 ? 0.0f : 1 - m_bankingEfficiency;
|
||||||
VDetailLog("{0},MoveAngular,Banking,bEff={1},angMotVel={2},banking={3}",
|
VDetailLog("{0},MoveAngular,Banking,bEff={1},angMotVel={2},effSq={3},mult={4},mix={5},banking={6}",
|
||||||
Prim.LocalID, m_bankingEfficiency, m_angularMotorVelocity, banking);
|
Prim.LocalID, m_bankingEfficiency, m_angularMotorVelocity, effSquared, mult, mix, bankingContribution);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
// ==================================================================
|
||||||
|
m_lastVertAttractor = verticalAttractionContribution;
|
||||||
m_lastVertAttractor = vertattr;
|
|
||||||
|
|
||||||
// Sum velocities
|
// Sum velocities
|
||||||
m_lastAngularVelocity = m_angularMotorVelocity + vertattr + banking + deflection;
|
m_lastAngularVelocity = angularMotorContribution
|
||||||
|
+ verticalAttractionContribution
|
||||||
#region Linear Motor Offset
|
+ bankingContribution
|
||||||
|
+ deflectionContribution;
|
||||||
|
|
||||||
|
// ==================================================================
|
||||||
//Offset section
|
//Offset section
|
||||||
if (m_linearMotorOffset != Vector3.Zero)
|
if (m_linearMotorOffset != Vector3.Zero)
|
||||||
{
|
{
|
||||||
|
@ -985,8 +973,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
//
|
//
|
||||||
// The torque created is the linear velocity crossed with the offset
|
// The torque created is the linear velocity crossed with the offset
|
||||||
|
|
||||||
// NOTE: this computation does should be in the linear section
|
// TODO: this computation should be in the linear section
|
||||||
// because there we know the impulse being applied.
|
// because that is where we know the impulse being applied.
|
||||||
Vector3 torqueFromOffset = Vector3.Zero;
|
Vector3 torqueFromOffset = Vector3.Zero;
|
||||||
// torqueFromOffset = Vector3.Cross(m_linearMotorOffset, appliedImpulse);
|
// torqueFromOffset = Vector3.Cross(m_linearMotorOffset, appliedImpulse);
|
||||||
if (float.IsNaN(torqueFromOffset.X))
|
if (float.IsNaN(torqueFromOffset.X))
|
||||||
|
@ -1000,8 +988,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
VDetailLog("{0},BSDynamic.MoveAngular,motorOffset,applyTorqueImpulse={1}", Prim.LocalID, torqueFromOffset);
|
VDetailLog("{0},BSDynamic.MoveAngular,motorOffset,applyTorqueImpulse={1}", Prim.LocalID, torqueFromOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
// ==================================================================
|
||||||
|
// NO_DEFLECTION_UP says angular motion should not add any pitch or roll movement
|
||||||
if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0)
|
if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0)
|
||||||
{
|
{
|
||||||
m_lastAngularVelocity.X = 0;
|
m_lastAngularVelocity.X = 0;
|
||||||
|
@ -1009,6 +997,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
VDetailLog("{0},MoveAngular,noDeflectionUp,lastAngular={1}", Prim.LocalID, m_lastAngularVelocity);
|
VDetailLog("{0},MoveAngular,noDeflectionUp,lastAngular={1}", Prim.LocalID, m_lastAngularVelocity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ==================================================================
|
||||||
if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f))
|
if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f))
|
||||||
{
|
{
|
||||||
m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero.
|
m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero.
|
||||||
|
@ -1021,18 +1010,20 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
// The above calculates the absolute angular velocity needed. Angular velocity is massless.
|
// The above calculates the absolute angular velocity needed. Angular velocity is massless.
|
||||||
// Since we are stuffing the angular velocity directly into the object, the computed
|
// Since we are stuffing the angular velocity directly into the object, the computed
|
||||||
// velocity needs to be scaled by the timestep.
|
// velocity needs to be scaled by the timestep.
|
||||||
Vector3 applyAngularForce = ((m_lastAngularVelocity * pTimestep) - Prim.ForceRotationalVelocity);
|
// Also remove any motion that is on the object so added motion is only from vehicle.
|
||||||
|
Vector3 applyAngularForce = ((m_lastAngularVelocity * pTimestep)
|
||||||
|
- Prim.ForceRotationalVelocity);
|
||||||
Prim.ForceRotationalVelocity = applyAngularForce;
|
Prim.ForceRotationalVelocity = applyAngularForce;
|
||||||
|
|
||||||
// Decay the angular movement for next time
|
VDetailLog("{0},MoveAngular,done,newRotVel={1},lastAngular={2}",
|
||||||
Vector3 decayamount = (Vector3.One / m_angularFrictionTimescale) * pTimestep;
|
Prim.LocalID, applyAngularForce, m_lastAngularVelocity);
|
||||||
m_lastAngularVelocity *= Vector3.One - decayamount;
|
}
|
||||||
|
|
||||||
VDetailLog("{0},MoveAngular,done,newRotVel={1},decay={2},lastAngular={3}",
|
|
||||||
Prim.LocalID, applyAngularForce, decayamount, m_lastAngularVelocity);
|
|
||||||
}
|
}
|
||||||
} //end MoveAngular
|
|
||||||
|
|
||||||
|
// This is from previous instantiations of XXXDynamics.cs.
|
||||||
|
// Applies roll reference frame.
|
||||||
|
// TODO: is this the right way to separate the code to do this operation?
|
||||||
|
// Should this be in MoveAngular()?
|
||||||
internal void LimitRotation(float timestep)
|
internal void LimitRotation(float timestep)
|
||||||
{
|
{
|
||||||
Quaternion rotq = Prim.ForceOrientation;
|
Quaternion rotq = Prim.ForceOrientation;
|
||||||
|
|
|
@ -0,0 +1,191 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyrightD
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Reflection;
|
||||||
|
using Nini.Config;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
|
{
|
||||||
|
|
||||||
|
public struct MaterialAttributes
|
||||||
|
{
|
||||||
|
// Material type values that correspond with definitions for LSL
|
||||||
|
public enum Material : int
|
||||||
|
{
|
||||||
|
Stone = 0,
|
||||||
|
Metal,
|
||||||
|
Glass,
|
||||||
|
Wood,
|
||||||
|
Flesh,
|
||||||
|
Plastic,
|
||||||
|
Rubber,
|
||||||
|
Light,
|
||||||
|
// Hereafter are BulletSim additions
|
||||||
|
Avatar,
|
||||||
|
NumberOfTypes // the count of types in the enum.
|
||||||
|
}
|
||||||
|
// Names must be in the order of the above enum.
|
||||||
|
public static string[] MaterialNames = { "Stone", "Metal", "Glass", "Wood",
|
||||||
|
"Flesh", "Plastic", "Rubber", "Light", "Avatar" };
|
||||||
|
public static string[] MaterialAttribs = { "Density", "Friction", "Restitution",
|
||||||
|
"ccdMotionThreshold", "ccdSweptSphereRadius" };
|
||||||
|
|
||||||
|
public MaterialAttributes(string t, float d, float f, float r, float ccdM, float ccdS)
|
||||||
|
{
|
||||||
|
type = t;
|
||||||
|
density = d;
|
||||||
|
friction = f;
|
||||||
|
restitution = r;
|
||||||
|
ccdMotionThreshold = ccdM;
|
||||||
|
ccdSweptSphereRadius = ccdS;
|
||||||
|
}
|
||||||
|
public string type;
|
||||||
|
public float density;
|
||||||
|
public float friction;
|
||||||
|
public float restitution;
|
||||||
|
public float ccdMotionThreshold;
|
||||||
|
public float ccdSweptSphereRadius;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class BSMaterials
|
||||||
|
{
|
||||||
|
public static MaterialAttributes[] Attributes;
|
||||||
|
|
||||||
|
static BSMaterials()
|
||||||
|
{
|
||||||
|
// Attribute sets for both the non-physical and physical instances of materials.
|
||||||
|
Attributes = new MaterialAttributes[(int)MaterialAttributes.Material.NumberOfTypes * 2];
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is where all the default material attributes are defined.
|
||||||
|
public static void InitializeFromDefaults(ConfigurationParameters parms)
|
||||||
|
{
|
||||||
|
// public static string[] MaterialNames = { "Stone", "Metal", "Glass", "Wood",
|
||||||
|
// "Flesh", "Plastic", "Rubber", "Light", "Avatar" };
|
||||||
|
float dFriction = parms.defaultFriction;
|
||||||
|
float dRestitution = parms.defaultRestitution;
|
||||||
|
float dDensity = parms.defaultDensity;
|
||||||
|
float dCcdM = parms.ccdMotionThreshold;
|
||||||
|
float dCcdS = parms.ccdSweptSphereRadius;
|
||||||
|
Attributes[(int)MaterialAttributes.Material.Stone] =
|
||||||
|
new MaterialAttributes("stone",dDensity,dFriction,dRestitution, dCcdM, dCcdS);
|
||||||
|
Attributes[(int)MaterialAttributes.Material.Metal] =
|
||||||
|
new MaterialAttributes("metal",dDensity,dFriction,dRestitution, dCcdM, dCcdS);
|
||||||
|
Attributes[(int)MaterialAttributes.Material.Glass] =
|
||||||
|
new MaterialAttributes("glass",dDensity,dFriction,dRestitution, dCcdM, dCcdS);
|
||||||
|
Attributes[(int)MaterialAttributes.Material.Wood] =
|
||||||
|
new MaterialAttributes("wood",dDensity,dFriction,dRestitution, dCcdM, dCcdS);
|
||||||
|
Attributes[(int)MaterialAttributes.Material.Flesh] =
|
||||||
|
new MaterialAttributes("flesh",dDensity,dFriction,dRestitution, dCcdM, dCcdS);
|
||||||
|
Attributes[(int)MaterialAttributes.Material.Plastic] =
|
||||||
|
new MaterialAttributes("plastic",dDensity,dFriction,dRestitution, dCcdM, dCcdS);
|
||||||
|
Attributes[(int)MaterialAttributes.Material.Rubber] =
|
||||||
|
new MaterialAttributes("rubber",dDensity,dFriction,dRestitution, dCcdM, dCcdS);
|
||||||
|
Attributes[(int)MaterialAttributes.Material.Light] =
|
||||||
|
new MaterialAttributes("light",dDensity,dFriction,dRestitution, dCcdM, dCcdS);
|
||||||
|
Attributes[(int)MaterialAttributes.Material.Avatar] =
|
||||||
|
new MaterialAttributes("avatar",dDensity,dFriction,dRestitution, dCcdM, dCcdS);
|
||||||
|
|
||||||
|
Attributes[(int)MaterialAttributes.Material.Stone + (int)MaterialAttributes.Material.NumberOfTypes] =
|
||||||
|
new MaterialAttributes("stonePhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS);
|
||||||
|
Attributes[(int)MaterialAttributes.Material.Metal + (int)MaterialAttributes.Material.NumberOfTypes] =
|
||||||
|
new MaterialAttributes("metalPhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS);
|
||||||
|
Attributes[(int)MaterialAttributes.Material.Glass + (int)MaterialAttributes.Material.NumberOfTypes] =
|
||||||
|
new MaterialAttributes("glassPhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS);
|
||||||
|
Attributes[(int)MaterialAttributes.Material.Wood + (int)MaterialAttributes.Material.NumberOfTypes] =
|
||||||
|
new MaterialAttributes("woodPhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS);
|
||||||
|
Attributes[(int)MaterialAttributes.Material.Flesh + (int)MaterialAttributes.Material.NumberOfTypes] =
|
||||||
|
new MaterialAttributes("fleshPhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS);
|
||||||
|
Attributes[(int)MaterialAttributes.Material.Plastic + (int)MaterialAttributes.Material.NumberOfTypes] =
|
||||||
|
new MaterialAttributes("plasticPhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS);
|
||||||
|
Attributes[(int)MaterialAttributes.Material.Rubber + (int)MaterialAttributes.Material.NumberOfTypes] =
|
||||||
|
new MaterialAttributes("rubberPhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS);
|
||||||
|
Attributes[(int)MaterialAttributes.Material.Light + (int)MaterialAttributes.Material.NumberOfTypes] =
|
||||||
|
new MaterialAttributes("lightPhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS);
|
||||||
|
Attributes[(int)MaterialAttributes.Material.Avatar + (int)MaterialAttributes.Material.NumberOfTypes] =
|
||||||
|
new MaterialAttributes("avatarPhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Under the [BulletSim] section, one can change the individual material
|
||||||
|
// attribute values. The format of the configuration parameter is:
|
||||||
|
// <materialName><Attribute>["Physical"] = floatValue
|
||||||
|
// For instance:
|
||||||
|
// [BulletSim]
|
||||||
|
// StoneFriction = 0.2
|
||||||
|
// FleshRestitutionPhysical = 0.8
|
||||||
|
// Materials can have different parameters for their static and
|
||||||
|
// physical instantiations. When setting the non-physical value,
|
||||||
|
// both values are changed. Setting the physical value only changes
|
||||||
|
// the physical value.
|
||||||
|
public static void InitializefromParameters(IConfig pConfig)
|
||||||
|
{
|
||||||
|
int matType = 0;
|
||||||
|
foreach (string matName in MaterialAttributes.MaterialNames)
|
||||||
|
{
|
||||||
|
foreach (string attribName in MaterialAttributes.MaterialAttribs)
|
||||||
|
{
|
||||||
|
string paramName = matName + attribName;
|
||||||
|
if (pConfig.Contains(paramName))
|
||||||
|
{
|
||||||
|
float paramValue = pConfig.GetFloat(paramName);
|
||||||
|
SetAttributeValue(matType, attribName, paramValue);
|
||||||
|
// set the physical value also
|
||||||
|
SetAttributeValue(matType + (int)MaterialAttributes.Material.NumberOfTypes, attribName, paramValue);
|
||||||
|
}
|
||||||
|
paramName += "Physical";
|
||||||
|
if (pConfig.Contains(paramName))
|
||||||
|
{
|
||||||
|
float paramValue = pConfig.GetFloat(paramName);
|
||||||
|
SetAttributeValue(matType + (int)MaterialAttributes.Material.NumberOfTypes, attribName, paramValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
matType++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void SetAttributeValue(int matType, string attribName, float val)
|
||||||
|
{
|
||||||
|
MaterialAttributes thisAttrib = Attributes[matType];
|
||||||
|
FieldInfo fieldInfo = thisAttrib.GetType().GetField(attribName);
|
||||||
|
if (fieldInfo != null)
|
||||||
|
{
|
||||||
|
fieldInfo.SetValue(thisAttrib, val);
|
||||||
|
Attributes[matType] = thisAttrib;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MaterialAttributes GetAttributes(MaterialAttributes.Material type, bool isPhysical)
|
||||||
|
{
|
||||||
|
int ind = (int)type;
|
||||||
|
if (isPhysical) ind += (int)MaterialAttributes.Material.NumberOfTypes;
|
||||||
|
return Attributes[ind];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
|
@ -7,8 +7,27 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
{
|
{
|
||||||
public abstract class BSMotor
|
public abstract class BSMotor
|
||||||
{
|
{
|
||||||
|
public BSMotor(string useName)
|
||||||
|
{
|
||||||
|
UseName = useName;
|
||||||
|
PhysicsScene = null;
|
||||||
|
}
|
||||||
public virtual void Reset() { }
|
public virtual void Reset() { }
|
||||||
public virtual void Zero() { }
|
public virtual void Zero() { }
|
||||||
|
|
||||||
|
public string UseName { get; private set; }
|
||||||
|
// Used only for outputting debug information. Might not be set so check for null.
|
||||||
|
public BSScene PhysicsScene { get; set; }
|
||||||
|
protected void MDetailLog(string msg, params Object[] parms)
|
||||||
|
{
|
||||||
|
if (PhysicsScene != null)
|
||||||
|
{
|
||||||
|
if (PhysicsScene.VehicleLoggingEnabled)
|
||||||
|
{
|
||||||
|
PhysicsScene.DetailLog(msg, parms);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Can all the incremental stepping be replaced with motor classes?
|
// Can all the incremental stepping be replaced with motor classes?
|
||||||
public class BSVMotor : BSMotor
|
public class BSVMotor : BSMotor
|
||||||
|
@ -18,20 +37,27 @@ public class BSVMotor : BSMotor
|
||||||
|
|
||||||
public float TimeScale { get; set; }
|
public float TimeScale { get; set; }
|
||||||
public float TargetValueDecayTimeScale { get; set; }
|
public float TargetValueDecayTimeScale { get; set; }
|
||||||
public Vector3 CurrentValueReductionTimescale { get; set; }
|
public Vector3 FrictionTimescale { get; set; }
|
||||||
public float Efficiency { get; set; }
|
public float Efficiency { get; set; }
|
||||||
|
|
||||||
public Vector3 TargetValue { get; private set; }
|
public Vector3 TargetValue { get; private set; }
|
||||||
public Vector3 CurrentValue { get; private set; }
|
public Vector3 CurrentValue { get; private set; }
|
||||||
|
|
||||||
|
public BSVMotor(string useName)
|
||||||
|
: base(useName)
|
||||||
BSVMotor(float timeScale, float decayTimeScale, Vector3 frictionTimeScale, float efficiency)
|
{
|
||||||
|
TimeScale = TargetValueDecayTimeScale = Efficiency = 1f;
|
||||||
|
FrictionTimescale = Vector3.Zero;
|
||||||
|
CurrentValue = TargetValue = Vector3.Zero;
|
||||||
|
}
|
||||||
|
public BSVMotor(string useName, float timeScale, float decayTimeScale, Vector3 frictionTimeScale, float efficiency)
|
||||||
|
: this(useName)
|
||||||
{
|
{
|
||||||
TimeScale = timeScale;
|
TimeScale = timeScale;
|
||||||
TargetValueDecayTimeScale = decayTimeScale;
|
TargetValueDecayTimeScale = decayTimeScale;
|
||||||
CurrentValueReductionTimescale = frictionTimeScale;
|
FrictionTimescale = frictionTimeScale;
|
||||||
Efficiency = efficiency;
|
Efficiency = efficiency;
|
||||||
|
CurrentValue = TargetValue = Vector3.Zero;
|
||||||
}
|
}
|
||||||
public void SetCurrent(Vector3 current)
|
public void SetCurrent(Vector3 current)
|
||||||
{
|
{
|
||||||
|
@ -43,30 +69,50 @@ public class BSVMotor : BSMotor
|
||||||
}
|
}
|
||||||
public Vector3 Step(float timeStep)
|
public Vector3 Step(float timeStep)
|
||||||
{
|
{
|
||||||
if (CurrentValue.LengthSquared() > 0.001f)
|
Vector3 returnCurrent = Vector3.Zero;
|
||||||
|
if (!CurrentValue.ApproxEquals(TargetValue, 0.01f))
|
||||||
{
|
{
|
||||||
// Vector3 origDir = Target; // DEBUG
|
Vector3 origTarget = TargetValue; // DEBUG
|
||||||
// Vector3 origVel = CurrentValue; // DEBUG
|
Vector3 origCurrVal = CurrentValue; // DEBUG
|
||||||
|
|
||||||
// Add (desiredVelocity - currentAppliedVelocity) / howLongItShouldTakeToComplete
|
// Addition = (desiredVector - currentAppliedVector) / secondsItShouldTakeToComplete
|
||||||
Vector3 addAmount = (TargetValue - CurrentValue)/(TargetValue) * timeStep;
|
Vector3 addAmount = (TargetValue - CurrentValue)/TimeScale * timeStep;
|
||||||
CurrentValue += addAmount;
|
CurrentValue += addAmount;
|
||||||
|
returnCurrent = CurrentValue;
|
||||||
|
|
||||||
|
// The desired value reduces to zero when also reduces the difference with current.
|
||||||
float decayFactor = (1.0f / TargetValueDecayTimeScale) * timeStep;
|
float decayFactor = (1.0f / TargetValueDecayTimeScale) * timeStep;
|
||||||
TargetValue *= (1f - decayFactor);
|
TargetValue *= (1f - decayFactor);
|
||||||
|
|
||||||
Vector3 frictionFactor = (Vector3.One / CurrentValueReductionTimescale) * timeStep;
|
Vector3 frictionFactor = Vector3.Zero;
|
||||||
|
frictionFactor = (Vector3.One / FrictionTimescale) * timeStep;
|
||||||
CurrentValue *= (Vector3.One - frictionFactor);
|
CurrentValue *= (Vector3.One - frictionFactor);
|
||||||
|
|
||||||
|
MDetailLog("{0},BSVMotor.Step,nonZero,{1},origTarget={2},origCurr={3},timeStep={4},timeScale={5},addAmnt={6},targetDecay={7},decayFact={8},fricTS={9},frictFact={10}",
|
||||||
|
BSScene.DetailLogZero, UseName, origTarget, origCurrVal,
|
||||||
|
timeStep, TimeScale, addAmount,
|
||||||
|
TargetValueDecayTimeScale, decayFactor,
|
||||||
|
FrictionTimescale, frictionFactor);
|
||||||
|
MDetailLog("{0},BSVMotor.Step,nonZero,{1},curr={2},target={3},add={4},decay={5},frict={6},ret={7}",
|
||||||
|
BSScene.DetailLogZero, UseName, TargetValue, CurrentValue,
|
||||||
|
addAmount, decayFactor, frictionFactor, returnCurrent);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// if what remains of direction is very small, zero it.
|
// Difference between what we have and target is small. Motor is done.
|
||||||
TargetValue = Vector3.Zero;
|
|
||||||
CurrentValue = Vector3.Zero;
|
CurrentValue = Vector3.Zero;
|
||||||
|
TargetValue = Vector3.Zero;
|
||||||
|
|
||||||
|
MDetailLog("{0},BSVMotor.Step,zero,{1},curr={2},target={3},ret={4}",
|
||||||
|
BSScene.DetailLogZero, UseName, TargetValue, CurrentValue, returnCurrent);
|
||||||
|
|
||||||
// VDetailLog("{0},MoveLinear,zeroed", Prim.LocalID);
|
|
||||||
}
|
}
|
||||||
return CurrentValue;
|
return returnCurrent;
|
||||||
|
}
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return String.Format("<{0},curr={1},targ={2},decayTS={3},frictTS={4}>",
|
||||||
|
UseName, CurrentValue, TargetValue, TargetValueDecayTimeScale, FrictionTimescale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,7 +126,8 @@ public class BSFMotor : BSMotor
|
||||||
public float Target { get; private set; }
|
public float Target { get; private set; }
|
||||||
public float CurrentValue { get; private set; }
|
public float CurrentValue { get; private set; }
|
||||||
|
|
||||||
BSFMotor(float timeScale, float decayTimescale, float friction, float efficiency)
|
public BSFMotor(string useName, float timeScale, float decayTimescale, float friction, float efficiency)
|
||||||
|
: base(useName)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
public void SetCurrent(float target)
|
public void SetCurrent(float target)
|
||||||
|
@ -97,7 +144,8 @@ public class BSFMotor : BSMotor
|
||||||
public class BSPIDMotor : BSMotor
|
public class BSPIDMotor : BSMotor
|
||||||
{
|
{
|
||||||
// TODO: write and use this one
|
// TODO: write and use this one
|
||||||
BSPIDMotor()
|
public BSPIDMotor(string useName)
|
||||||
|
: base(useName)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -342,13 +342,12 @@ public sealed class BSPrim : BSPhysObject
|
||||||
// TODO: check for out of bounds
|
// TODO: check for out of bounds
|
||||||
|
|
||||||
// The above code computes a force to apply to correct any out-of-bounds problems. Apply same.
|
// The above code computes a force to apply to correct any out-of-bounds problems. Apply same.
|
||||||
|
// TODO: This should be intergrated with a geneal physics action mechanism.
|
||||||
|
// TODO: This should be moderated with PID'ness.
|
||||||
if (ret)
|
if (ret)
|
||||||
{
|
|
||||||
PhysicsScene.TaintedObject(inTaintTime, "BSPrim.PositionSanityCheck:belowTerrain", delegate()
|
|
||||||
{
|
{
|
||||||
// Apply upforce and overcome gravity.
|
// Apply upforce and overcome gravity.
|
||||||
ForceVelocity = ForceVelocity + upForce - PhysicsScene.DefaultGravity;
|
AddForce(upForce - PhysicsScene.DefaultGravity, false, inTaintTime);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,23 +39,10 @@ using log4net;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
|
|
||||||
// TODOs for BulletSim (for BSScene, BSPrim, BSCharacter and BulletSim)
|
// TODOs for BulletSim (for BSScene, BSPrim, BSCharacter and BulletSim)
|
||||||
// Test sculpties (verified that they don't work)
|
|
||||||
// Compute physics FPS reasonably
|
|
||||||
// Based on material, set density and friction
|
// Based on material, set density and friction
|
||||||
// Don't use constraints in linksets of non-physical objects. Means having to move children manually.
|
|
||||||
// Four states of prim: Physical, regular, phantom and selected. Are we modeling these correctly?
|
|
||||||
// In SL one can set both physical and phantom (gravity, does not effect others, makes collisions with ground)
|
|
||||||
// At the moment, physical and phantom causes object to drop through the terrain
|
|
||||||
// Physical phantom objects and related typing (collision options )
|
|
||||||
// Check out llVolumeDetect. Must do something for that.
|
|
||||||
// Use collision masks for collision with terrain and phantom objects
|
|
||||||
// More efficient memory usage when passing hull information from BSPrim to BulletSim
|
// More efficient memory usage when passing hull information from BSPrim to BulletSim
|
||||||
// Should prim.link() and prim.delink() membership checking happen at taint time?
|
|
||||||
// Mesh sharing. Use meshHash to tell if we already have a hull of that shape and only create once.
|
|
||||||
// Do attachments need to be handled separately? Need collision events. Do not collide with VolumeDetect
|
// Do attachments need to be handled separately? Need collision events. Do not collide with VolumeDetect
|
||||||
// Implement LockAngularMotion
|
// Implement LockAngularMotion
|
||||||
// Decide if clearing forces is the right thing to do when setting position (BulletSim::SetObjectTranslation)
|
|
||||||
// Remove mesh and Hull stuff. Use mesh passed to bullet and use convexdecom from bullet.
|
|
||||||
// Add PID movement operations. What does ScenePresence.MoveToTarget do?
|
// Add PID movement operations. What does ScenePresence.MoveToTarget do?
|
||||||
// Check terrain size. 128 or 127?
|
// Check terrain size. 128 or 127?
|
||||||
// Raycast
|
// Raycast
|
||||||
|
@ -234,6 +221,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
if (m_physicsLoggingEnabled)
|
if (m_physicsLoggingEnabled)
|
||||||
{
|
{
|
||||||
PhysicsLogging = new Logging.LogWriter(m_physicsLoggingDir, m_physicsLoggingPrefix, m_physicsLoggingFileMinutes);
|
PhysicsLogging = new Logging.LogWriter(m_physicsLoggingDir, m_physicsLoggingPrefix, m_physicsLoggingFileMinutes);
|
||||||
|
PhysicsLogging.ErrorLogger = m_log; // for DEBUG. Let's the logger output error messages.
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -308,6 +296,13 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
// Do any replacements in the parameters
|
// Do any replacements in the parameters
|
||||||
m_physicsLoggingPrefix = m_physicsLoggingPrefix.Replace("%REGIONNAME%", RegionName);
|
m_physicsLoggingPrefix = m_physicsLoggingPrefix.Replace("%REGIONNAME%", RegionName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The material characteristics.
|
||||||
|
BSMaterials.InitializeFromDefaults(Params);
|
||||||
|
if (pConfig != null)
|
||||||
|
{
|
||||||
|
BSMaterials.InitializefromParameters(pConfig);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1069,7 +1064,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
(s,p,l,v) => { s.PID_P = v; } ),
|
(s,p,l,v) => { s.PID_P = v; } ),
|
||||||
|
|
||||||
new ParameterDefn("DefaultFriction", "Friction factor used on new objects",
|
new ParameterDefn("DefaultFriction", "Friction factor used on new objects",
|
||||||
0.5f,
|
0.2f,
|
||||||
(s,cf,p,v) => { s.m_params[0].defaultFriction = cf.GetFloat(p, v); },
|
(s,cf,p,v) => { s.m_params[0].defaultFriction = cf.GetFloat(p, v); },
|
||||||
(s) => { return s.m_params[0].defaultFriction; },
|
(s) => { return s.m_params[0].defaultFriction; },
|
||||||
(s,p,l,v) => { s.m_params[0].defaultFriction = v; } ),
|
(s,p,l,v) => { s.m_params[0].defaultFriction = v; } ),
|
||||||
|
@ -1084,7 +1079,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
(s) => { return s.m_params[0].defaultRestitution; },
|
(s) => { return s.m_params[0].defaultRestitution; },
|
||||||
(s,p,l,v) => { s.m_params[0].defaultRestitution = v; } ),
|
(s,p,l,v) => { s.m_params[0].defaultRestitution = v; } ),
|
||||||
new ParameterDefn("CollisionMargin", "Margin around objects before collisions are calculated (must be zero!)",
|
new ParameterDefn("CollisionMargin", "Margin around objects before collisions are calculated (must be zero!)",
|
||||||
0f,
|
0.04f,
|
||||||
(s,cf,p,v) => { s.m_params[0].collisionMargin = cf.GetFloat(p, v); },
|
(s,cf,p,v) => { s.m_params[0].collisionMargin = cf.GetFloat(p, v); },
|
||||||
(s) => { return s.m_params[0].collisionMargin; },
|
(s) => { return s.m_params[0].collisionMargin; },
|
||||||
(s,p,l,v) => { s.m_params[0].collisionMargin = v; } ),
|
(s,p,l,v) => { s.m_params[0].collisionMargin = v; } ),
|
||||||
|
@ -1151,7 +1146,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
(s) => { return s.m_params[0].terrainImplementation; },
|
(s) => { return s.m_params[0].terrainImplementation; },
|
||||||
(s,p,l,v) => { s.m_params[0].terrainImplementation = v; } ),
|
(s,p,l,v) => { s.m_params[0].terrainImplementation = v; } ),
|
||||||
new ParameterDefn("TerrainFriction", "Factor to reduce movement against terrain surface" ,
|
new ParameterDefn("TerrainFriction", "Factor to reduce movement against terrain surface" ,
|
||||||
0.5f,
|
0.3f,
|
||||||
(s,cf,p,v) => { s.m_params[0].terrainFriction = cf.GetFloat(p, v); },
|
(s,cf,p,v) => { s.m_params[0].terrainFriction = cf.GetFloat(p, v); },
|
||||||
(s) => { return s.m_params[0].terrainFriction; },
|
(s) => { return s.m_params[0].terrainFriction; },
|
||||||
(s,p,l,v) => { s.m_params[0].terrainFriction = v; /* TODO: set on real terrain */} ),
|
(s,p,l,v) => { s.m_params[0].terrainFriction = v; /* TODO: set on real terrain */} ),
|
||||||
|
@ -1165,13 +1160,19 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
(s,cf,p,v) => { s.m_params[0].terrainRestitution = cf.GetFloat(p, v); },
|
(s,cf,p,v) => { s.m_params[0].terrainRestitution = cf.GetFloat(p, v); },
|
||||||
(s) => { return s.m_params[0].terrainRestitution; },
|
(s) => { return s.m_params[0].terrainRestitution; },
|
||||||
(s,p,l,v) => { s.m_params[0].terrainRestitution = v; /* TODO: set on real terrain */ } ),
|
(s,p,l,v) => { s.m_params[0].terrainRestitution = v; /* TODO: set on real terrain */ } ),
|
||||||
|
new ParameterDefn("TerrainCollisionMargin", "Margin where collision checking starts" ,
|
||||||
|
0.04f,
|
||||||
|
(s,cf,p,v) => { s.m_params[0].terrainCollisionMargin = cf.GetFloat(p, v); },
|
||||||
|
(s) => { return s.m_params[0].terrainCollisionMargin; },
|
||||||
|
(s,p,l,v) => { s.m_params[0].terrainCollisionMargin = v; /* TODO: set on real terrain */ } ),
|
||||||
|
|
||||||
new ParameterDefn("AvatarFriction", "Factor to reduce movement against an avatar. Changed on avatar recreation.",
|
new ParameterDefn("AvatarFriction", "Factor to reduce movement against an avatar. Changed on avatar recreation.",
|
||||||
0.2f,
|
0.2f,
|
||||||
(s,cf,p,v) => { s.m_params[0].avatarFriction = cf.GetFloat(p, v); },
|
(s,cf,p,v) => { s.m_params[0].avatarFriction = cf.GetFloat(p, v); },
|
||||||
(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.",
|
||||||
10f,
|
0.99f,
|
||||||
(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; } ),
|
||||||
|
@ -1206,6 +1207,11 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
(s) => { return s.m_params[0].avatarContactProcessingThreshold; },
|
(s) => { return s.m_params[0].avatarContactProcessingThreshold; },
|
||||||
(s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarContactProcessingThreshold, p, l, v); } ),
|
(s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarContactProcessingThreshold, p, l, v); } ),
|
||||||
|
|
||||||
|
new ParameterDefn("VehicleAngularDamping", "Factor to damp vehicle angular movement per second (0.0 - 1.0)",
|
||||||
|
0.95f,
|
||||||
|
(s,cf,p,v) => { s.m_params[0].vehicleAngularDamping = cf.GetFloat(p, v); },
|
||||||
|
(s) => { return s.m_params[0].vehicleAngularDamping; },
|
||||||
|
(s,p,l,v) => { s.m_params[0].vehicleAngularDamping = v; } ),
|
||||||
|
|
||||||
new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)",
|
new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)",
|
||||||
0f,
|
0f,
|
||||||
|
|
|
@ -93,7 +93,7 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys
|
||||||
{
|
{
|
||||||
m_mapInfo.Ptr = BulletSimAPI.CreateHeightMapInfo2(PhysicsScene.World.ptr, m_mapInfo.ID,
|
m_mapInfo.Ptr = BulletSimAPI.CreateHeightMapInfo2(PhysicsScene.World.ptr, m_mapInfo.ID,
|
||||||
m_mapInfo.minCoords, m_mapInfo.maxCoords,
|
m_mapInfo.minCoords, m_mapInfo.maxCoords,
|
||||||
m_mapInfo.heightMap, BSTerrainManager.TERRAIN_COLLISION_MARGIN);
|
m_mapInfo.heightMap, PhysicsScene.Params.terrainCollisionMargin);
|
||||||
|
|
||||||
// Create the terrain shape from the mapInfo
|
// Create the terrain shape from the mapInfo
|
||||||
m_mapInfo.terrainShape = new BulletShape(BulletSimAPI.CreateTerrainShape2(m_mapInfo.Ptr),
|
m_mapInfo.terrainShape = new BulletShape(BulletSimAPI.CreateTerrainShape2(m_mapInfo.Ptr),
|
||||||
|
|
|
@ -80,8 +80,6 @@ public sealed class BSTerrainManager
|
||||||
// amount to make sure that a bounding box is built for the terrain.
|
// amount to make sure that a bounding box is built for the terrain.
|
||||||
public const float HEIGHT_EQUAL_FUDGE = 0.2f;
|
public const float HEIGHT_EQUAL_FUDGE = 0.2f;
|
||||||
|
|
||||||
public const float TERRAIN_COLLISION_MARGIN = 0.0f;
|
|
||||||
|
|
||||||
// Until the whole simulator is changed to pass us the region size, we rely on constants.
|
// Until the whole simulator is changed to pass us the region size, we rely on constants.
|
||||||
public Vector3 DefaultRegionSize = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionHeight);
|
public Vector3 DefaultRegionSize = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionHeight);
|
||||||
|
|
||||||
|
@ -129,7 +127,8 @@ public sealed class BSTerrainManager
|
||||||
{
|
{
|
||||||
// The ground plane is here to catch things that are trying to drop to negative infinity
|
// The ground plane is here to catch things that are trying to drop to negative infinity
|
||||||
BulletShape groundPlaneShape = new BulletShape(
|
BulletShape groundPlaneShape = new BulletShape(
|
||||||
BulletSimAPI.CreateGroundPlaneShape2(BSScene.GROUNDPLANE_ID, 1f, TERRAIN_COLLISION_MARGIN),
|
BulletSimAPI.CreateGroundPlaneShape2(BSScene.GROUNDPLANE_ID, 1f,
|
||||||
|
PhysicsScene.Params.terrainCollisionMargin),
|
||||||
BSPhysicsShapeType.SHAPE_GROUNDPLANE);
|
BSPhysicsShapeType.SHAPE_GROUNDPLANE);
|
||||||
m_groundPlane = new BulletBody(BSScene.GROUNDPLANE_ID,
|
m_groundPlane = new BulletBody(BSScene.GROUNDPLANE_ID,
|
||||||
BulletSimAPI.CreateBodyWithDefaultMotionState2(groundPlaneShape.ptr, BSScene.GROUNDPLANE_ID,
|
BulletSimAPI.CreateBodyWithDefaultMotionState2(groundPlaneShape.ptr, BSScene.GROUNDPLANE_ID,
|
||||||
|
@ -164,6 +163,8 @@ public sealed class BSTerrainManager
|
||||||
|
|
||||||
// Release all the terrain we have allocated
|
// Release all the terrain we have allocated
|
||||||
public void ReleaseTerrain()
|
public void ReleaseTerrain()
|
||||||
|
{
|
||||||
|
lock (m_terrains)
|
||||||
{
|
{
|
||||||
foreach (KeyValuePair<Vector3, BSTerrainPhys> kvp in m_terrains)
|
foreach (KeyValuePair<Vector3, BSTerrainPhys> kvp in m_terrains)
|
||||||
{
|
{
|
||||||
|
@ -171,11 +172,14 @@ public sealed class BSTerrainManager
|
||||||
}
|
}
|
||||||
m_terrains.Clear();
|
m_terrains.Clear();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// The simulator wants to set a new heightmap for the terrain.
|
// The simulator wants to set a new heightmap for the terrain.
|
||||||
public void SetTerrain(float[] heightMap) {
|
public void SetTerrain(float[] heightMap) {
|
||||||
float[] localHeightMap = heightMap;
|
float[] localHeightMap = heightMap;
|
||||||
PhysicsScene.TaintedObject("TerrainManager.SetTerrain", delegate()
|
// If there are multiple requests for changes to the same terrain between ticks,
|
||||||
|
// only do that last one.
|
||||||
|
PhysicsScene.PostTaintObject("TerrainManager.SetTerrain-"+ m_worldOffset.ToString(), 0, delegate()
|
||||||
{
|
{
|
||||||
if (m_worldOffset != Vector3.Zero && MegaRegionParentPhysicsScene != null)
|
if (m_worldOffset != Vector3.Zero && MegaRegionParentPhysicsScene != null)
|
||||||
{
|
{
|
||||||
|
@ -211,6 +215,7 @@ public sealed class BSTerrainManager
|
||||||
// terrain shape is created and added to the body.
|
// terrain shape is created and added to the body.
|
||||||
// This call is most often used to update the heightMap and parameters of the terrain.
|
// This call is most often used to update the heightMap and parameters of the terrain.
|
||||||
// (The above does suggest that some simplification/refactoring is in order.)
|
// (The above does suggest that some simplification/refactoring is in order.)
|
||||||
|
// Called during taint-time.
|
||||||
private void UpdateTerrain(uint id, float[] heightMap,
|
private void UpdateTerrain(uint id, float[] heightMap,
|
||||||
Vector3 minCoords, Vector3 maxCoords, bool inTaintTime)
|
Vector3 minCoords, Vector3 maxCoords, bool inTaintTime)
|
||||||
{
|
{
|
||||||
|
@ -220,7 +225,7 @@ public sealed class BSTerrainManager
|
||||||
// Find high and low points of passed heightmap.
|
// Find high and low points of passed heightmap.
|
||||||
// The min and max passed in is usually the area objects can be in (maximum
|
// The min and max passed in is usually the area objects can be in (maximum
|
||||||
// object height, for instance). The terrain wants the bounding box for the
|
// object height, for instance). The terrain wants the bounding box for the
|
||||||
// terrain so we replace passed min and max Z with the actual terrain min/max Z.
|
// terrain so replace passed min and max Z with the actual terrain min/max Z.
|
||||||
float minZ = float.MaxValue;
|
float minZ = float.MaxValue;
|
||||||
float maxZ = float.MinValue;
|
float maxZ = float.MinValue;
|
||||||
foreach (float height in heightMap)
|
foreach (float height in heightMap)
|
||||||
|
@ -238,6 +243,8 @@ public sealed class BSTerrainManager
|
||||||
|
|
||||||
Vector3 terrainRegionBase = new Vector3(minCoords.X, minCoords.Y, 0f);
|
Vector3 terrainRegionBase = new Vector3(minCoords.X, minCoords.Y, 0f);
|
||||||
|
|
||||||
|
lock (m_terrains)
|
||||||
|
{
|
||||||
BSTerrainPhys terrainPhys;
|
BSTerrainPhys terrainPhys;
|
||||||
if (m_terrains.TryGetValue(terrainRegionBase, out terrainPhys))
|
if (m_terrains.TryGetValue(terrainRegionBase, out terrainPhys))
|
||||||
{
|
{
|
||||||
|
@ -245,8 +252,6 @@ public sealed class BSTerrainManager
|
||||||
DetailLog("{0},UpdateTerrain:UpdateExisting,call,id={1},base={2},minC={3},maxC={4}",
|
DetailLog("{0},UpdateTerrain:UpdateExisting,call,id={1},base={2},minC={3},maxC={4}",
|
||||||
BSScene.DetailLogZero, id, terrainRegionBase, minCoords, minCoords);
|
BSScene.DetailLogZero, id, terrainRegionBase, minCoords, minCoords);
|
||||||
|
|
||||||
PhysicsScene.TaintedObject(inTaintTime, "BSScene.UpdateTerrain:UpdateExisting", delegate()
|
|
||||||
{
|
|
||||||
// Remove old terrain from the collection
|
// Remove old terrain from the collection
|
||||||
m_terrains.Remove(terrainRegionBase);
|
m_terrains.Remove(terrainRegionBase);
|
||||||
// Release any physical memory it may be using.
|
// Release any physical memory it may be using.
|
||||||
|
@ -271,7 +276,6 @@ public sealed class BSTerrainManager
|
||||||
// I hate doing this, but just bail
|
// I hate doing this, but just bail
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -283,23 +287,13 @@ public sealed class BSTerrainManager
|
||||||
if (newTerrainID >= BSScene.CHILDTERRAIN_ID)
|
if (newTerrainID >= BSScene.CHILDTERRAIN_ID)
|
||||||
newTerrainID = ++m_terrainCount;
|
newTerrainID = ++m_terrainCount;
|
||||||
|
|
||||||
float[] heightMapX = heightMap;
|
DetailLog("{0},UpdateTerrain:NewTerrain,taint,newID={1},minCoord={2},maxCoord={3}",
|
||||||
Vector3 minCoordsX = minCoords;
|
|
||||||
Vector3 maxCoordsX = maxCoords;
|
|
||||||
|
|
||||||
DetailLog("{0},UpdateTerrain:NewTerrain,call,id={1}, minC={2}, maxC={3}",
|
|
||||||
BSScene.DetailLogZero, newTerrainID, minCoords, minCoords);
|
BSScene.DetailLogZero, newTerrainID, minCoords, minCoords);
|
||||||
|
|
||||||
// Code that must happen at taint-time
|
|
||||||
PhysicsScene.TaintedObject(inTaintTime, "BSScene.UpdateTerrain:NewTerrain", delegate()
|
|
||||||
{
|
|
||||||
DetailLog("{0},UpdateTerrain:NewTerrain,taint,baseX={1},baseY={2}",
|
|
||||||
BSScene.DetailLogZero, minCoordsX.X, minCoordsX.Y);
|
|
||||||
BSTerrainPhys newTerrainPhys = BuildPhysicalTerrain(terrainRegionBase, id, heightMap, minCoords, maxCoords);
|
BSTerrainPhys newTerrainPhys = BuildPhysicalTerrain(terrainRegionBase, id, heightMap, minCoords, maxCoords);
|
||||||
m_terrains.Add(terrainRegionBase, newTerrainPhys);
|
m_terrains.Add(terrainRegionBase, newTerrainPhys);
|
||||||
|
|
||||||
m_terrainModified = true;
|
m_terrainModified = true;
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -349,6 +343,7 @@ public sealed class BSTerrainManager
|
||||||
// with the same parameters as last time.
|
// with the same parameters as last time.
|
||||||
if (!m_terrainModified && lastHeightTX == tX && lastHeightTY == tY)
|
if (!m_terrainModified && lastHeightTX == tX && lastHeightTY == tY)
|
||||||
return lastHeight;
|
return lastHeight;
|
||||||
|
m_terrainModified = false;
|
||||||
|
|
||||||
lastHeightTX = tX;
|
lastHeightTX = tX;
|
||||||
lastHeightTY = tY;
|
lastHeightTY = tY;
|
||||||
|
@ -358,19 +353,19 @@ public sealed class BSTerrainManager
|
||||||
int offsetY = ((int)(tY / (int)DefaultRegionSize.Y)) * (int)DefaultRegionSize.Y;
|
int offsetY = ((int)(tY / (int)DefaultRegionSize.Y)) * (int)DefaultRegionSize.Y;
|
||||||
Vector3 terrainBaseXYZ = new Vector3(offsetX, offsetY, 0f);
|
Vector3 terrainBaseXYZ = new Vector3(offsetX, offsetY, 0f);
|
||||||
|
|
||||||
|
lock (m_terrains)
|
||||||
|
{
|
||||||
BSTerrainPhys physTerrain;
|
BSTerrainPhys physTerrain;
|
||||||
if (m_terrains.TryGetValue(terrainBaseXYZ, out physTerrain))
|
if (m_terrains.TryGetValue(terrainBaseXYZ, out physTerrain))
|
||||||
{
|
{
|
||||||
ret = physTerrain.GetHeightAtXYZ(loc - terrainBaseXYZ);
|
ret = physTerrain.GetHeightAtXYZ(loc - terrainBaseXYZ);
|
||||||
DetailLog("{0},BSTerrainManager.GetTerrainHeightAtXYZ,loc={1},base={2},height={3}",
|
|
||||||
BSScene.DetailLogZero, loc, terrainBaseXYZ, ret);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PhysicsScene.Logger.ErrorFormat("{0} GetTerrainHeightAtXY: terrain not found: region={1}, x={2}, y={3}",
|
PhysicsScene.Logger.ErrorFormat("{0} GetTerrainHeightAtXY: terrain not found: region={1}, x={2}, y={3}",
|
||||||
LogHeader, PhysicsScene.RegionName, tX, tY);
|
LogHeader, PhysicsScene.RegionName, tX, tY);
|
||||||
}
|
}
|
||||||
m_terrainModified = false;
|
}
|
||||||
lastHeight = ret;
|
lastHeight = ret;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -217,8 +217,6 @@ public sealed class BSTerrainMesh : BSTerrainPhys
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
verticesCount = verticesCount / 3;
|
verticesCount = verticesCount / 3;
|
||||||
physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,completeVerts,verCount={1}",
|
|
||||||
BSScene.DetailLogZero, verticesCount);
|
|
||||||
|
|
||||||
for (int yy = 0; yy < sizeY; yy++)
|
for (int yy = 0; yy < sizeY; yy++)
|
||||||
{
|
{
|
||||||
|
@ -235,8 +233,6 @@ public sealed class BSTerrainMesh : BSTerrainPhys
|
||||||
indicesCount += 6;
|
indicesCount += 6;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,completeIndices,indCount={1}", // DEEBUG DEBUG DEBUG
|
|
||||||
LogHeader, indicesCount); // DEBUG
|
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
|
|
@ -287,6 +287,8 @@ public struct ConfigurationParameters
|
||||||
public float terrainFriction;
|
public float terrainFriction;
|
||||||
public float terrainHitFraction;
|
public float terrainHitFraction;
|
||||||
public float terrainRestitution;
|
public float terrainRestitution;
|
||||||
|
public float terrainCollisionMargin;
|
||||||
|
|
||||||
public float avatarFriction;
|
public float avatarFriction;
|
||||||
public float avatarStandingFriction;
|
public float avatarStandingFriction;
|
||||||
public float avatarDensity;
|
public float avatarDensity;
|
||||||
|
@ -296,6 +298,8 @@ public struct ConfigurationParameters
|
||||||
public float avatarCapsuleHeight;
|
public float avatarCapsuleHeight;
|
||||||
public float avatarContactProcessingThreshold;
|
public float avatarContactProcessingThreshold;
|
||||||
|
|
||||||
|
public float vehicleAngularDamping;
|
||||||
|
|
||||||
public float maxPersistantManifoldPoolSize;
|
public float maxPersistantManifoldPoolSize;
|
||||||
public float maxCollisionAlgorithmPoolSize;
|
public float maxCollisionAlgorithmPoolSize;
|
||||||
public float shouldDisableContactPoolDynamicAllocation;
|
public float shouldDisableContactPoolDynamicAllocation;
|
||||||
|
@ -481,6 +485,9 @@ public static extern IntPtr BuildNativeShape2(IntPtr world, ShapeData shapeData)
|
||||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||||
public static extern bool IsNativeShape2(IntPtr shape);
|
public static extern bool IsNativeShape2(IntPtr shape);
|
||||||
|
|
||||||
|
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||||
|
public static extern void SetShapeCollisionMargin(IntPtr shape, float margin);
|
||||||
|
|
||||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||||
public static extern IntPtr BuildCapsuleShape2(IntPtr world, float radius, float height, Vector3 scale);
|
public static extern IntPtr BuildCapsuleShape2(IntPtr world, float radius, float height, Vector3 scale);
|
||||||
|
|
||||||
|
|
|
@ -221,10 +221,10 @@
|
||||||
; to false if you have compatibility problems.
|
; to false if you have compatibility problems.
|
||||||
;CacheSculptMaps = true
|
;CacheSculptMaps = true
|
||||||
|
|
||||||
; Choose one of the physics engines below
|
; Choose one of the physics engines below.
|
||||||
; OpenDynamicsEngine is by some distance the most developed physics engine
|
; OpenDynamicsEngine is by some distance the most developed physics engine.
|
||||||
; basicphysics effectively does not model physics at all, making all objects phantom
|
; BulletSim is a high performance, up-and-coming physics engine.
|
||||||
|
; basicphysics effectively does not model physics at all, making all objects phantom.
|
||||||
physics = OpenDynamicsEngine
|
physics = OpenDynamicsEngine
|
||||||
;physics = basicphysics
|
;physics = basicphysics
|
||||||
;physics = POS
|
;physics = POS
|
||||||
|
@ -908,15 +908,18 @@
|
||||||
|
|
||||||
[BulletSim]
|
[BulletSim]
|
||||||
; World parameters
|
; World parameters
|
||||||
DefaultFriction = 0.50
|
DefaultFriction = 0.20
|
||||||
DefaultDensity = 10.000006836
|
DefaultDensity = 10.000006836
|
||||||
DefaultRestitution = 0.0
|
DefaultRestitution = 0.0
|
||||||
Gravity = -9.80665
|
Gravity = -9.80665
|
||||||
|
|
||||||
TerrainFriction = 0.50
|
TerrainFriction = 0.30
|
||||||
TerrainHitFriction = 0.8
|
TerrainHitFraction = 0.8
|
||||||
TerrainRestitution = 0
|
TerrainRestitution = 0
|
||||||
|
TerrainCollisionMargin = 0.04
|
||||||
|
|
||||||
AvatarFriction = 0.2
|
AvatarFriction = 0.2
|
||||||
|
AvatarStandingFriction = 0.99
|
||||||
AvatarRestitution = 0.0
|
AvatarRestitution = 0.0
|
||||||
AvatarDensity = 60.0
|
AvatarDensity = 60.0
|
||||||
AvatarCapsuleWidth = 0.6
|
AvatarCapsuleWidth = 0.6
|
||||||
|
@ -930,27 +933,15 @@
|
||||||
LinearDamping = 0.0
|
LinearDamping = 0.0
|
||||||
AngularDamping = 0.0
|
AngularDamping = 0.0
|
||||||
DeactivationTime = 0.2
|
DeactivationTime = 0.2
|
||||||
LinearSleepingThreshold = 0.8
|
CollisionMargin = 0.04
|
||||||
AngularSleepingThreshold = 1.0
|
|
||||||
CcdMotionThreshold = 0.0
|
|
||||||
CcdSweptSphereRadius = 0.0
|
|
||||||
ContactProcessingThreshold = 0.1
|
|
||||||
; If setting a pool size, also disable dynamic allocation (default pool size is 4096 with dynamic alloc)
|
|
||||||
MaxPersistantManifoldPoolSize = 0
|
|
||||||
ShouldDisableContactPoolDynamicAllocation = False
|
|
||||||
ShouldForceUpdateAllAabbs = False
|
|
||||||
ShouldRandomizeSolverOrder = True
|
|
||||||
ShouldSplitSimulationIslands = True
|
|
||||||
ShouldEnableFrictionCaching = False
|
|
||||||
NumberOfSolverIterations = 0
|
|
||||||
|
|
||||||
; Linkset constraint parameters
|
; Linkset constraint parameters
|
||||||
|
LinkImplementation = 1 ; 0=constraint, 1=compound
|
||||||
LinkConstraintUseFrameOffset = False
|
LinkConstraintUseFrameOffset = False
|
||||||
LinkConstraintEnableTransMotor = True
|
LinkConstraintEnableTransMotor = True
|
||||||
LinkConstraintTransMotorMaxVel = 5.0
|
LinkConstraintTransMotorMaxVel = 5.0
|
||||||
LinkConstraintTransMotorMaxForce = 0.1
|
LinkConstraintTransMotorMaxForce = 0.1
|
||||||
|
|
||||||
|
|
||||||
; Whether to mesh sculpties
|
; Whether to mesh sculpties
|
||||||
MeshSculptedPrim = true
|
MeshSculptedPrim = true
|
||||||
|
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue