Merge branch 'master' into connector_plugin
commit
88f2fbc8f1
|
@ -80,10 +80,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
private Quaternion m_referenceFrame = Quaternion.Identity;
|
||||
|
||||
// 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_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_newVelocity = Vector3.Zero; // velocity computed to be applied to body
|
||||
private Vector3 m_linearFrictionTimescale = Vector3.Zero;
|
||||
private float m_linearMotorDecayTimescale = 0;
|
||||
private float m_linearMotorTimescale = 0;
|
||||
|
@ -93,6 +93,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
// private Vector3 m_linearMotorOffset = Vector3.Zero;
|
||||
|
||||
//Angular properties
|
||||
private BSVMotor m_angularMotor = new BSVMotor("AngularMotor");
|
||||
private Vector3 m_angularMotorDirection = Vector3.Zero; // angular velocity requested by LSL motor
|
||||
// private int m_angularMotorApply = 0; // application frame counter
|
||||
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);
|
||||
break;
|
||||
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;
|
||||
case Vehicle.ANGULAR_MOTOR_TIMESCALE:
|
||||
m_angularMotorTimescale = Math.Max(pValue, 0.01f);
|
||||
m_angularMotor.TimeScale = m_angularMotorTimescale;
|
||||
break;
|
||||
case Vehicle.BANKING_EFFICIENCY:
|
||||
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);
|
||||
break;
|
||||
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;
|
||||
case Vehicle.LINEAR_MOTOR_TIMESCALE:
|
||||
m_linearMotorTimescale = Math.Max(pValue, 0.01f);
|
||||
m_linearMotor.TimeScale = m_linearMotorTimescale;
|
||||
break;
|
||||
case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY:
|
||||
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
|
||||
case Vehicle.ANGULAR_FRICTION_TIMESCALE:
|
||||
m_angularFrictionTimescale = new Vector3(pValue, pValue, pValue);
|
||||
m_angularMotor.FrictionTimescale = m_angularFrictionTimescale;
|
||||
break;
|
||||
case Vehicle.ANGULAR_MOTOR_DIRECTION:
|
||||
m_angularMotorDirection = new Vector3(pValue, pValue, pValue);
|
||||
// m_angularMotorApply = 100;
|
||||
m_angularMotor.SetTarget(m_angularMotorDirection);
|
||||
break;
|
||||
case Vehicle.LINEAR_FRICTION_TIMESCALE:
|
||||
m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue);
|
||||
m_linearMotor.FrictionTimescale = m_linearFrictionTimescale;
|
||||
break;
|
||||
case Vehicle.LINEAR_MOTOR_DIRECTION:
|
||||
m_linearMotorDirection = new Vector3(pValue, pValue, pValue);
|
||||
m_linearMotorDirectionLASTSET = new Vector3(pValue, pValue, pValue);
|
||||
m_linearMotor.SetTarget(m_linearMotorDirection);
|
||||
break;
|
||||
case Vehicle.LINEAR_MOTOR_OFFSET:
|
||||
m_linearMotorOffset = new Vector3(pValue, pValue, pValue);
|
||||
|
@ -227,6 +235,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
{
|
||||
case Vehicle.ANGULAR_FRICTION_TIMESCALE:
|
||||
m_angularFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||
m_angularMotor.FrictionTimescale = m_angularFrictionTimescale;
|
||||
break;
|
||||
case Vehicle.ANGULAR_MOTOR_DIRECTION:
|
||||
// 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.Z = Math.Max(-12.56f, Math.Min(pValue.Z, 12.56f));
|
||||
m_angularMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||
// m_angularMotorApply = 100;
|
||||
m_angularMotor.SetTarget(m_angularMotorDirection);
|
||||
break;
|
||||
case Vehicle.LINEAR_FRICTION_TIMESCALE:
|
||||
m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||
m_linearMotor.FrictionTimescale = m_linearFrictionTimescale;
|
||||
break;
|
||||
case Vehicle.LINEAR_MOTOR_DIRECTION:
|
||||
m_linearMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||
m_linearMotorDirectionLASTSET = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||
m_linearMotor.SetTarget(m_linearMotorDirection);
|
||||
break;
|
||||
case Vehicle.LINEAR_MOTOR_OFFSET:
|
||||
m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||
|
@ -319,6 +330,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
|
||||
m_referenceFrame = Quaternion.Identity;
|
||||
m_flags = (VehicleFlag)0;
|
||||
|
||||
break;
|
||||
|
||||
case Vehicle.TYPE_SLED:
|
||||
|
@ -351,10 +363,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
m_bankingMix = 1;
|
||||
|
||||
m_referenceFrame = Quaternion.Identity;
|
||||
m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
|
||||
m_flags &=
|
||||
~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
|
||||
VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
|
||||
m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY
|
||||
| VehicleFlag.HOVER_TERRAIN_ONLY
|
||||
| VehicleFlag.HOVER_GLOBAL_HEIGHT
|
||||
| VehicleFlag.HOVER_UP_ONLY);
|
||||
m_flags |= (VehicleFlag.NO_DEFLECTION_UP
|
||||
| VehicleFlag.LIMIT_ROLL_ONLY
|
||||
| VehicleFlag.LIMIT_MOTOR_UP);
|
||||
break;
|
||||
case Vehicle.TYPE_CAR:
|
||||
m_linearMotorDirection = Vector3.Zero;
|
||||
|
@ -510,6 +525,18 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
| VehicleFlag.HOVER_GLOBAL_HEIGHT);
|
||||
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.
|
||||
|
@ -518,13 +545,25 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
{
|
||||
if (IsActive)
|
||||
{
|
||||
m_vehicleMass = Prim.Linkset.LinksetMass;
|
||||
|
||||
// Friction effects are handled by this vehicle code
|
||||
BulletSimAPI.SetFriction2(Prim.PhysBody.ptr, 0f);
|
||||
BulletSimAPI.SetHitFraction2(Prim.PhysBody.ptr, 0f);
|
||||
float friction = 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;
|
||||
|
||||
// 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);
|
||||
// Commented out for debug
|
||||
MoveAngular(pTimestep);
|
||||
// Prim.ApplyTorqueImpulse(-Prim.RotationalVelocity * m_vehicleMass, false); // DEBUG DEBUG
|
||||
// Prim.ForceRotationalVelocity = -Prim.RotationalVelocity; // DEBUG DEBUG
|
||||
|
||||
LimitRotation(pTimestep);
|
||||
|
||||
// remember the position so next step we can limit absolute movement effects
|
||||
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}",
|
||||
Prim.LocalID, Prim.ForcePosition, Prim.Force, Prim.ForceVelocity, Prim.RotationalVelocity);
|
||||
}// end Step
|
||||
}
|
||||
|
||||
// Apply the effect of the linear motor.
|
||||
// Also does hover and float.
|
||||
private void MoveLinear(float pTimestep)
|
||||
{
|
||||
// m_linearMotorDirection is the target direction we are moving relative to the vehicle coordinates
|
||||
// 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
|
||||
Vector3 linearMotorContribution = m_linearMotor.Step(pTimestep);
|
||||
|
||||
// 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
|
||||
m_newVelocity = m_lastLinearVelocityVector * 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
|
||||
// Rotate new object velocity from vehicle relative to world coordinates
|
||||
linearMotorContribution *= Prim.ForceOrientation;
|
||||
|
||||
// ==================================================================
|
||||
// Gravity and Buoyancy
|
||||
// There is some gravity, make a gravity force vector that is applied after object velocity.
|
||||
// m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g;
|
||||
Vector3 grav = Prim.PhysicsScene.DefaultGravity * (1f - m_VehicleBuoyancy);
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
// Current vehicle position
|
||||
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.
|
||||
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.
|
||||
|
@ -650,11 +630,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
// if (rotatedSize.Z < terrainHeight)
|
||||
if (pos.Z < terrainHeight)
|
||||
{
|
||||
// TODO: correct position by applying force rather than forcing position.
|
||||
pos.Z = terrainHeight + 2;
|
||||
Prim.ForcePosition = pos;
|
||||
VDetailLog("{0},MoveLinear,terrainHeight,terrainHeight={1},pos={2}", Prim.LocalID, terrainHeight, pos);
|
||||
}
|
||||
|
||||
// ==================================================================
|
||||
Vector3 hoverContribution = Vector3.Zero;
|
||||
// Check if hovering
|
||||
// m_VhoverEfficiency: 0=bouncy, 1=totally damped
|
||||
// m_VhoverTimescale: time to achieve height
|
||||
|
@ -694,24 +677,22 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
// RA: where does the 50 come from?
|
||||
float verticalCorrectionVelocity = pTimestep * ((verticalError * 50.0f) / m_VhoverTimescale);
|
||||
// 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
|
||||
}
|
||||
else if (verticalError < -0.01)
|
||||
{
|
||||
m_newVelocity.Z -= verticalCorrectionVelocity;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_newVelocity.Z = 0f;
|
||||
hoverContribution = new Vector3(0f, 0f, -verticalCorrectionVelocity);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
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 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;
|
||||
if (distanceAboveGround > 2f)
|
||||
if (distanceAboveGround > 1f)
|
||||
{
|
||||
// downForce = new Vector3(0, 0, (-distanceAboveGround / m_bankingTimescale) * pTimestep);
|
||||
// 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
|
||||
// (http://wiki.secondlife.com/wiki/Category:LSL_Vehicle), the downForce
|
||||
// has a decay factor. This says this force should
|
||||
// be computed with a motor.
|
||||
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 ((m_flags & (VehicleFlag.NO_X)) != 0)
|
||||
m_newVelocity.X = 0;
|
||||
newVelocity.X = 0;
|
||||
if ((m_flags & (VehicleFlag.NO_Y)) != 0)
|
||||
m_newVelocity.Y = 0;
|
||||
newVelocity.Y = 0;
|
||||
if ((m_flags & (VehicleFlag.NO_Z)) != 0)
|
||||
m_newVelocity.Z = 0;
|
||||
newVelocity.Z = 0;
|
||||
|
||||
// ==================================================================
|
||||
// Clamp REALLY high or low velocities
|
||||
if (m_newVelocity.LengthSquared() > 1e6f)
|
||||
float newVelocityLengthSq = newVelocity.LengthSquared();
|
||||
if (newVelocityLengthSq > 1e6f)
|
||||
{
|
||||
m_newVelocity /= m_newVelocity.Length();
|
||||
m_newVelocity *= 1000f;
|
||||
newVelocity /= newVelocity.Length();
|
||||
newVelocity *= 1000f;
|
||||
}
|
||||
else if (m_newVelocity.LengthSquared() < 1e-6f)
|
||||
m_newVelocity = Vector3.Zero;
|
||||
else if (newVelocityLengthSq < 1e-6f)
|
||||
newVelocity = Vector3.Zero;
|
||||
|
||||
// ==================================================================
|
||||
// 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
|
||||
|
||||
Vector3 totalDownForce = downForce + grav;
|
||||
// Other linear forces are applied as forces.
|
||||
Vector3 totalDownForce = grav * m_vehicleMass;
|
||||
if (totalDownForce != Vector3.Zero)
|
||||
{
|
||||
Prim.AddForce(totalDownForce * m_vehicleMass, false);
|
||||
// Prim.ApplyForceImpulse(totalDownForce * m_vehicleMass, false);
|
||||
Prim.AddForce(totalDownForce, false);
|
||||
}
|
||||
|
||||
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()
|
||||
|
||||
// =======================================================================
|
||||
// =======================================================================
|
||||
// Apply the effect of the angular motor.
|
||||
private void MoveAngular(float pTimestep)
|
||||
{
|
||||
// m_angularMotorDirection // angular velocity requested by LSL motor
|
||||
// m_angularMotorApply // application frame counter
|
||||
// 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_angularFrictionTimescale // body angular velocity decay rate
|
||||
// m_lastAngularVelocity // what was last applied to body
|
||||
|
@ -836,18 +824,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
m_angularMotorVelocity = Vector3.Zero;
|
||||
}
|
||||
|
||||
#region Vertical attactor
|
||||
|
||||
Vector3 vertattr = Vector3.Zero;
|
||||
Vector3 deflection = Vector3.Zero;
|
||||
Vector3 banking = Vector3.Zero;
|
||||
Vector3 angularMotorContribution = m_angularMotor.Step(pTimestep);
|
||||
|
||||
// ==================================================================
|
||||
Vector3 verticalAttractionContribution = Vector3.Zero;
|
||||
// If vertical attaction timescale is reasonable and we applied an angular force last time...
|
||||
if (m_verticalAttractionTimescale < 300 && m_lastAngularVelocity != Vector3.Zero)
|
||||
{
|
||||
float VAservo = pTimestep * 0.2f / m_verticalAttractionTimescale;
|
||||
if (Prim.IsColliding)
|
||||
VAservo = pTimestep * 0.05f / (m_verticalAttractionTimescale);
|
||||
VAservo = pTimestep * 0.05f / m_verticalAttractionTimescale;
|
||||
|
||||
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
|
||||
// then .X increases, so change Body angular velocity X based on Y, and Y based on X.
|
||||
// Z is not changed.
|
||||
vertattr.X = verticalError.Y;
|
||||
vertattr.Y = - verticalError.X;
|
||||
vertattr.Z = 0f;
|
||||
verticalAttractionContribution.X = verticalError.Y;
|
||||
verticalAttractionContribution.Y = - verticalError.X;
|
||||
verticalAttractionContribution.Z = 0f;
|
||||
|
||||
// scaling appears better usingsquare-law
|
||||
Vector3 angularVelocity = Prim.ForceRotationalVelocity;
|
||||
float bounce = 1.0f - (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency);
|
||||
vertattr.X += bounce * angularVelocity.X;
|
||||
vertattr.Y += bounce * angularVelocity.Y;
|
||||
verticalAttractionContribution.X += bounce * angularVelocity.X;
|
||||
verticalAttractionContribution.Y += bounce * angularVelocity.Y;
|
||||
|
||||
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)
|
||||
{
|
||||
// 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);
|
||||
|
||||
// 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}",
|
||||
Prim.LocalID, preferredAxisOfMotion, deflection);
|
||||
Prim.LocalID, preferredAxisOfMotion, deflectionContribution);
|
||||
// This deflection computation is not correct.
|
||||
deflection = Vector3.Zero;
|
||||
deflectionContribution = Vector3.Zero;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Banking
|
||||
|
||||
// ==================================================================
|
||||
Vector3 bankingContribution = Vector3.Zero;
|
||||
if (m_bankingEfficiency != 0)
|
||||
{
|
||||
Vector3 dir = Vector3.One * Prim.ForceOrientation;
|
||||
|
@ -925,6 +908,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
float mix = Math.Abs(m_bankingMix);
|
||||
if (m_angularMotorVelocity.X == 0)
|
||||
{
|
||||
// The vehicle is stopped
|
||||
/*if (!parent.Orientation.ApproxEquals(this.m_referenceFrame, 0.25f))
|
||||
{
|
||||
Vector3 axisAngle;
|
||||
|
@ -938,9 +922,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
}*/
|
||||
}
|
||||
else
|
||||
banking.Z += (effSquared*(mult*mix))*(m_angularMotorVelocity.X) * 4;
|
||||
{
|
||||
bankingContribution.Z += (effSquared * (mult * mix)) * (m_angularMotorVelocity.X) * 4;
|
||||
}
|
||||
|
||||
//If they are colliding, we probably shouldn't shove the prim around... probably
|
||||
if (!Prim.IsColliding && Math.Abs(m_angularMotorVelocity.X) > mix)
|
||||
//If they are colliding, we probably shouldn't shove the prim around... probably
|
||||
{
|
||||
float angVelZ = m_angularMotorVelocity.X*-1;
|
||||
/*if(angVelZ > mix)
|
||||
|
@ -954,22 +941,23 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
else if (bankingRot.X < -3)
|
||||
bankingRot.X = -3;
|
||||
bankingRot *= Prim.ForceOrientation;
|
||||
banking += bankingRot;
|
||||
bankingContribution += bankingRot;
|
||||
}
|
||||
m_angularMotorVelocity.X *= m_bankingEfficiency == 1 ? 0.0f : 1 - m_bankingEfficiency;
|
||||
VDetailLog("{0},MoveAngular,Banking,bEff={1},angMotVel={2},banking={3}",
|
||||
Prim.LocalID, m_bankingEfficiency, m_angularMotorVelocity, banking);
|
||||
VDetailLog("{0},MoveAngular,Banking,bEff={1},angMotVel={2},effSq={3},mult={4},mix={5},banking={6}",
|
||||
Prim.LocalID, m_bankingEfficiency, m_angularMotorVelocity, effSquared, mult, mix, bankingContribution);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
m_lastVertAttractor = vertattr;
|
||||
// ==================================================================
|
||||
m_lastVertAttractor = verticalAttractionContribution;
|
||||
|
||||
// Sum velocities
|
||||
m_lastAngularVelocity = m_angularMotorVelocity + vertattr + banking + deflection;
|
||||
|
||||
#region Linear Motor Offset
|
||||
m_lastAngularVelocity = angularMotorContribution
|
||||
+ verticalAttractionContribution
|
||||
+ bankingContribution
|
||||
+ deflectionContribution;
|
||||
|
||||
// ==================================================================
|
||||
//Offset section
|
||||
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
|
||||
|
||||
// NOTE: this computation does should be in the linear section
|
||||
// because there we know the impulse being applied.
|
||||
// TODO: this computation should be in the linear section
|
||||
// because that is where we know the impulse being applied.
|
||||
Vector3 torqueFromOffset = Vector3.Zero;
|
||||
// torqueFromOffset = Vector3.Cross(m_linearMotorOffset, appliedImpulse);
|
||||
if (float.IsNaN(torqueFromOffset.X))
|
||||
|
@ -1000,8 +988,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
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)
|
||||
{
|
||||
m_lastAngularVelocity.X = 0;
|
||||
|
@ -1009,6 +997,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
VDetailLog("{0},MoveAngular,noDeflectionUp,lastAngular={1}", Prim.LocalID, m_lastAngularVelocity);
|
||||
}
|
||||
|
||||
// ==================================================================
|
||||
if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f))
|
||||
{
|
||||
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.
|
||||
// Since we are stuffing the angular velocity directly into the object, the computed
|
||||
// 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;
|
||||
|
||||
// Decay the angular movement for next time
|
||||
Vector3 decayamount = (Vector3.One / m_angularFrictionTimescale) * pTimestep;
|
||||
m_lastAngularVelocity *= Vector3.One - decayamount;
|
||||
|
||||
VDetailLog("{0},MoveAngular,done,newRotVel={1},decay={2},lastAngular={3}",
|
||||
Prim.LocalID, applyAngularForce, decayamount, m_lastAngularVelocity);
|
||||
VDetailLog("{0},MoveAngular,done,newRotVel={1},lastAngular={2}",
|
||||
Prim.LocalID, applyAngularForce, 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)
|
||||
{
|
||||
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,104 +1,152 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
{
|
||||
public abstract class BSMotor
|
||||
{
|
||||
public virtual void Reset() { }
|
||||
public virtual void Zero() { }
|
||||
}
|
||||
// Can all the incremental stepping be replaced with motor classes?
|
||||
public class BSVMotor : BSMotor
|
||||
{
|
||||
public Vector3 FrameOfReference { get; set; }
|
||||
public Vector3 Offset { get; set; }
|
||||
|
||||
public float TimeScale { get; set; }
|
||||
public float TargetValueDecayTimeScale { get; set; }
|
||||
public Vector3 CurrentValueReductionTimescale { get; set; }
|
||||
public float Efficiency { get; set; }
|
||||
|
||||
public Vector3 TargetValue { get; private set; }
|
||||
public Vector3 CurrentValue { get; private set; }
|
||||
|
||||
|
||||
|
||||
BSVMotor(float timeScale, float decayTimeScale, Vector3 frictionTimeScale, float efficiency)
|
||||
{
|
||||
TimeScale = timeScale;
|
||||
TargetValueDecayTimeScale = decayTimeScale;
|
||||
CurrentValueReductionTimescale = frictionTimeScale;
|
||||
Efficiency = efficiency;
|
||||
}
|
||||
public void SetCurrent(Vector3 current)
|
||||
{
|
||||
CurrentValue = current;
|
||||
}
|
||||
public void SetTarget(Vector3 target)
|
||||
{
|
||||
TargetValue = target;
|
||||
}
|
||||
public Vector3 Step(float timeStep)
|
||||
{
|
||||
if (CurrentValue.LengthSquared() > 0.001f)
|
||||
{
|
||||
// Vector3 origDir = Target; // DEBUG
|
||||
// Vector3 origVel = CurrentValue; // DEBUG
|
||||
|
||||
// Add (desiredVelocity - currentAppliedVelocity) / howLongItShouldTakeToComplete
|
||||
Vector3 addAmount = (TargetValue - CurrentValue)/(TargetValue) * timeStep;
|
||||
CurrentValue += addAmount;
|
||||
|
||||
float decayFactor = (1.0f / TargetValueDecayTimeScale) * timeStep;
|
||||
TargetValue *= (1f - decayFactor);
|
||||
|
||||
Vector3 frictionFactor = (Vector3.One / CurrentValueReductionTimescale) * timeStep;
|
||||
CurrentValue *= (Vector3.One - frictionFactor);
|
||||
}
|
||||
else
|
||||
{
|
||||
// if what remains of direction is very small, zero it.
|
||||
TargetValue = Vector3.Zero;
|
||||
CurrentValue = Vector3.Zero;
|
||||
|
||||
// VDetailLog("{0},MoveLinear,zeroed", Prim.LocalID);
|
||||
}
|
||||
return CurrentValue;
|
||||
}
|
||||
}
|
||||
|
||||
public class BSFMotor : BSMotor
|
||||
{
|
||||
public float TimeScale { get; set; }
|
||||
public float DecayTimeScale { get; set; }
|
||||
public float Friction { get; set; }
|
||||
public float Efficiency { get; set; }
|
||||
|
||||
public float Target { get; private set; }
|
||||
public float CurrentValue { get; private set; }
|
||||
|
||||
BSFMotor(float timeScale, float decayTimescale, float friction, float efficiency)
|
||||
{
|
||||
}
|
||||
public void SetCurrent(float target)
|
||||
{
|
||||
}
|
||||
public void SetTarget(float target)
|
||||
{
|
||||
}
|
||||
public float Step(float timeStep)
|
||||
{
|
||||
return 0f;
|
||||
}
|
||||
}
|
||||
public class BSPIDMotor : BSMotor
|
||||
{
|
||||
// TODO: write and use this one
|
||||
BSPIDMotor()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
{
|
||||
public abstract class BSMotor
|
||||
{
|
||||
public BSMotor(string useName)
|
||||
{
|
||||
UseName = useName;
|
||||
PhysicsScene = null;
|
||||
}
|
||||
public virtual void Reset() { }
|
||||
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?
|
||||
public class BSVMotor : BSMotor
|
||||
{
|
||||
public Vector3 FrameOfReference { get; set; }
|
||||
public Vector3 Offset { get; set; }
|
||||
|
||||
public float TimeScale { get; set; }
|
||||
public float TargetValueDecayTimeScale { get; set; }
|
||||
public Vector3 FrictionTimescale { get; set; }
|
||||
public float Efficiency { get; set; }
|
||||
|
||||
public Vector3 TargetValue { get; private set; }
|
||||
public Vector3 CurrentValue { get; private set; }
|
||||
|
||||
public BSVMotor(string useName)
|
||||
: base(useName)
|
||||
{
|
||||
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;
|
||||
TargetValueDecayTimeScale = decayTimeScale;
|
||||
FrictionTimescale = frictionTimeScale;
|
||||
Efficiency = efficiency;
|
||||
CurrentValue = TargetValue = Vector3.Zero;
|
||||
}
|
||||
public void SetCurrent(Vector3 current)
|
||||
{
|
||||
CurrentValue = current;
|
||||
}
|
||||
public void SetTarget(Vector3 target)
|
||||
{
|
||||
TargetValue = target;
|
||||
}
|
||||
public Vector3 Step(float timeStep)
|
||||
{
|
||||
Vector3 returnCurrent = Vector3.Zero;
|
||||
if (!CurrentValue.ApproxEquals(TargetValue, 0.01f))
|
||||
{
|
||||
Vector3 origTarget = TargetValue; // DEBUG
|
||||
Vector3 origCurrVal = CurrentValue; // DEBUG
|
||||
|
||||
// Addition = (desiredVector - currentAppliedVector) / secondsItShouldTakeToComplete
|
||||
Vector3 addAmount = (TargetValue - CurrentValue)/TimeScale * timeStep;
|
||||
CurrentValue += addAmount;
|
||||
returnCurrent = CurrentValue;
|
||||
|
||||
// The desired value reduces to zero when also reduces the difference with current.
|
||||
float decayFactor = (1.0f / TargetValueDecayTimeScale) * timeStep;
|
||||
TargetValue *= (1f - decayFactor);
|
||||
|
||||
Vector3 frictionFactor = Vector3.Zero;
|
||||
frictionFactor = (Vector3.One / FrictionTimescale) * timeStep;
|
||||
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
|
||||
{
|
||||
// Difference between what we have and target is small. Motor is done.
|
||||
CurrentValue = Vector3.Zero;
|
||||
TargetValue = Vector3.Zero;
|
||||
|
||||
MDetailLog("{0},BSVMotor.Step,zero,{1},curr={2},target={3},ret={4}",
|
||||
BSScene.DetailLogZero, UseName, TargetValue, CurrentValue, returnCurrent);
|
||||
|
||||
}
|
||||
return returnCurrent;
|
||||
}
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format("<{0},curr={1},targ={2},decayTS={3},frictTS={4}>",
|
||||
UseName, CurrentValue, TargetValue, TargetValueDecayTimeScale, FrictionTimescale);
|
||||
}
|
||||
}
|
||||
|
||||
public class BSFMotor : BSMotor
|
||||
{
|
||||
public float TimeScale { get; set; }
|
||||
public float DecayTimeScale { get; set; }
|
||||
public float Friction { get; set; }
|
||||
public float Efficiency { get; set; }
|
||||
|
||||
public float Target { get; private set; }
|
||||
public float CurrentValue { get; private set; }
|
||||
|
||||
public BSFMotor(string useName, float timeScale, float decayTimescale, float friction, float efficiency)
|
||||
: base(useName)
|
||||
{
|
||||
}
|
||||
public void SetCurrent(float target)
|
||||
{
|
||||
}
|
||||
public void SetTarget(float target)
|
||||
{
|
||||
}
|
||||
public float Step(float timeStep)
|
||||
{
|
||||
return 0f;
|
||||
}
|
||||
}
|
||||
public class BSPIDMotor : BSMotor
|
||||
{
|
||||
// TODO: write and use this one
|
||||
public BSPIDMotor(string useName)
|
||||
: base(useName)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -342,13 +342,12 @@ public sealed class BSPrim : BSPhysObject
|
|||
// TODO: check for out of bounds
|
||||
|
||||
// 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)
|
||||
{
|
||||
PhysicsScene.TaintedObject(inTaintTime, "BSPrim.PositionSanityCheck:belowTerrain", delegate()
|
||||
{
|
||||
// Apply upforce and overcome gravity.
|
||||
ForceVelocity = ForceVelocity + upForce - PhysicsScene.DefaultGravity;
|
||||
});
|
||||
// Apply upforce and overcome gravity.
|
||||
AddForce(upForce - PhysicsScene.DefaultGravity, false, inTaintTime);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -39,23 +39,10 @@ using log4net;
|
|||
using OpenMetaverse;
|
||||
|
||||
// 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
|
||||
// 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
|
||||
// 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
|
||||
// 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?
|
||||
// Check terrain size. 128 or 127?
|
||||
// Raycast
|
||||
|
@ -234,6 +221,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
|||
if (m_physicsLoggingEnabled)
|
||||
{
|
||||
PhysicsLogging = new Logging.LogWriter(m_physicsLoggingDir, m_physicsLoggingPrefix, m_physicsLoggingFileMinutes);
|
||||
PhysicsLogging.ErrorLogger = m_log; // for DEBUG. Let's the logger output error messages.
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -308,6 +296,13 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
|||
// Do any replacements in the parameters
|
||||
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; } ),
|
||||
|
||||
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) => { return s.m_params[0].defaultFriction; },
|
||||
(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,p,l,v) => { s.m_params[0].defaultRestitution = v; } ),
|
||||
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) => { return s.m_params[0].collisionMargin; },
|
||||
(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,p,l,v) => { s.m_params[0].terrainImplementation = v; } ),
|
||||
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) => { return s.m_params[0].terrainFriction; },
|
||||
(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) => { return s.m_params[0].terrainRestitution; },
|
||||
(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.",
|
||||
0.2f,
|
||||
(s,cf,p,v) => { s.m_params[0].avatarFriction = cf.GetFloat(p, v); },
|
||||
(s) => { return s.m_params[0].avatarFriction; },
|
||||
(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.",
|
||||
10f,
|
||||
0.99f,
|
||||
(s,cf,p,v) => { s.m_params[0].avatarStandingFriction = cf.GetFloat(p, v); },
|
||||
(s) => { return s.m_params[0].avatarStandingFriction; },
|
||||
(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,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)",
|
||||
0f,
|
||||
|
|
|
@ -93,7 +93,7 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys
|
|||
{
|
||||
m_mapInfo.Ptr = BulletSimAPI.CreateHeightMapInfo2(PhysicsScene.World.ptr, m_mapInfo.ID,
|
||||
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
|
||||
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.
|
||||
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.
|
||||
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
|
||||
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);
|
||||
m_groundPlane = new BulletBody(BSScene.GROUNDPLANE_ID,
|
||||
BulletSimAPI.CreateBodyWithDefaultMotionState2(groundPlaneShape.ptr, BSScene.GROUNDPLANE_ID,
|
||||
|
@ -165,17 +164,22 @@ public sealed class BSTerrainManager
|
|||
// Release all the terrain we have allocated
|
||||
public void ReleaseTerrain()
|
||||
{
|
||||
foreach (KeyValuePair<Vector3, BSTerrainPhys> kvp in m_terrains)
|
||||
lock (m_terrains)
|
||||
{
|
||||
kvp.Value.Dispose();
|
||||
foreach (KeyValuePair<Vector3, BSTerrainPhys> kvp in m_terrains)
|
||||
{
|
||||
kvp.Value.Dispose();
|
||||
}
|
||||
m_terrains.Clear();
|
||||
}
|
||||
m_terrains.Clear();
|
||||
}
|
||||
|
||||
// The simulator wants to set a new heightmap for the terrain.
|
||||
public void SetTerrain(float[] 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)
|
||||
{
|
||||
|
@ -211,6 +215,7 @@ public sealed class BSTerrainManager
|
|||
// terrain shape is created and added to the body.
|
||||
// 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.)
|
||||
// Called during taint-time.
|
||||
private void UpdateTerrain(uint id, float[] heightMap,
|
||||
Vector3 minCoords, Vector3 maxCoords, bool inTaintTime)
|
||||
{
|
||||
|
@ -220,7 +225,7 @@ public sealed class BSTerrainManager
|
|||
// Find high and low points of passed heightmap.
|
||||
// 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
|
||||
// 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 maxZ = float.MinValue;
|
||||
foreach (float height in heightMap)
|
||||
|
@ -238,15 +243,15 @@ public sealed class BSTerrainManager
|
|||
|
||||
Vector3 terrainRegionBase = new Vector3(minCoords.X, minCoords.Y, 0f);
|
||||
|
||||
BSTerrainPhys terrainPhys;
|
||||
if (m_terrains.TryGetValue(terrainRegionBase, out terrainPhys))
|
||||
lock (m_terrains)
|
||||
{
|
||||
// There is already a terrain in this spot. Free the old and build the new.
|
||||
DetailLog("{0},UpdateTerrain:UpdateExisting,call,id={1},base={2},minC={3},maxC={4}",
|
||||
BSScene.DetailLogZero, id, terrainRegionBase, minCoords, minCoords);
|
||||
|
||||
PhysicsScene.TaintedObject(inTaintTime, "BSScene.UpdateTerrain:UpdateExisting", delegate()
|
||||
BSTerrainPhys terrainPhys;
|
||||
if (m_terrains.TryGetValue(terrainRegionBase, out terrainPhys))
|
||||
{
|
||||
// There is already a terrain in this spot. Free the old and build the new.
|
||||
DetailLog("{0},UpdateTerrain:UpdateExisting,call,id={1},base={2},minC={3},maxC={4}",
|
||||
BSScene.DetailLogZero, id, terrainRegionBase, minCoords, minCoords);
|
||||
|
||||
// Remove old terrain from the collection
|
||||
m_terrains.Remove(terrainRegionBase);
|
||||
// Release any physical memory it may be using.
|
||||
|
@ -271,35 +276,24 @@ public sealed class BSTerrainManager
|
|||
// I hate doing this, but just bail
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
// We don't know about this terrain so either we are creating a new terrain or
|
||||
// our mega-prim child is giving us a new terrain to add to the phys world
|
||||
|
||||
// if this is a child terrain, calculate a unique terrain id
|
||||
uint newTerrainID = id;
|
||||
if (newTerrainID >= BSScene.CHILDTERRAIN_ID)
|
||||
newTerrainID = ++m_terrainCount;
|
||||
|
||||
float[] heightMapX = heightMap;
|
||||
Vector3 minCoordsX = minCoords;
|
||||
Vector3 maxCoordsX = maxCoords;
|
||||
|
||||
DetailLog("{0},UpdateTerrain:NewTerrain,call,id={1}, minC={2}, maxC={3}",
|
||||
BSScene.DetailLogZero, newTerrainID, minCoords, minCoords);
|
||||
|
||||
// Code that must happen at taint-time
|
||||
PhysicsScene.TaintedObject(inTaintTime, "BSScene.UpdateTerrain:NewTerrain", delegate()
|
||||
}
|
||||
else
|
||||
{
|
||||
DetailLog("{0},UpdateTerrain:NewTerrain,taint,baseX={1},baseY={2}",
|
||||
BSScene.DetailLogZero, minCoordsX.X, minCoordsX.Y);
|
||||
// We don't know about this terrain so either we are creating a new terrain or
|
||||
// our mega-prim child is giving us a new terrain to add to the phys world
|
||||
|
||||
// if this is a child terrain, calculate a unique terrain id
|
||||
uint newTerrainID = id;
|
||||
if (newTerrainID >= BSScene.CHILDTERRAIN_ID)
|
||||
newTerrainID = ++m_terrainCount;
|
||||
|
||||
DetailLog("{0},UpdateTerrain:NewTerrain,taint,newID={1},minCoord={2},maxCoord={3}",
|
||||
BSScene.DetailLogZero, newTerrainID, minCoords, minCoords);
|
||||
BSTerrainPhys newTerrainPhys = BuildPhysicalTerrain(terrainRegionBase, id, heightMap, minCoords, maxCoords);
|
||||
m_terrains.Add(terrainRegionBase, newTerrainPhys);
|
||||
|
||||
m_terrainModified = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -349,6 +343,7 @@ public sealed class BSTerrainManager
|
|||
// with the same parameters as last time.
|
||||
if (!m_terrainModified && lastHeightTX == tX && lastHeightTY == tY)
|
||||
return lastHeight;
|
||||
m_terrainModified = false;
|
||||
|
||||
lastHeightTX = tX;
|
||||
lastHeightTY = tY;
|
||||
|
@ -358,19 +353,19 @@ public sealed class BSTerrainManager
|
|||
int offsetY = ((int)(tY / (int)DefaultRegionSize.Y)) * (int)DefaultRegionSize.Y;
|
||||
Vector3 terrainBaseXYZ = new Vector3(offsetX, offsetY, 0f);
|
||||
|
||||
BSTerrainPhys physTerrain;
|
||||
if (m_terrains.TryGetValue(terrainBaseXYZ, out physTerrain))
|
||||
lock (m_terrains)
|
||||
{
|
||||
ret = physTerrain.GetHeightAtXYZ(loc - terrainBaseXYZ);
|
||||
DetailLog("{0},BSTerrainManager.GetTerrainHeightAtXYZ,loc={1},base={2},height={3}",
|
||||
BSScene.DetailLogZero, loc, terrainBaseXYZ, ret);
|
||||
BSTerrainPhys physTerrain;
|
||||
if (m_terrains.TryGetValue(terrainBaseXYZ, out physTerrain))
|
||||
{
|
||||
ret = physTerrain.GetHeightAtXYZ(loc - terrainBaseXYZ);
|
||||
}
|
||||
else
|
||||
{
|
||||
PhysicsScene.Logger.ErrorFormat("{0} GetTerrainHeightAtXY: terrain not found: region={1}, x={2}, y={3}",
|
||||
LogHeader, PhysicsScene.RegionName, tX, tY);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PhysicsScene.Logger.ErrorFormat("{0} GetTerrainHeightAtXY: terrain not found: region={1}, x={2}, y={3}",
|
||||
LogHeader, PhysicsScene.RegionName, tX, tY);
|
||||
}
|
||||
m_terrainModified = false;
|
||||
lastHeight = ret;
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -217,8 +217,6 @@ public sealed class BSTerrainMesh : BSTerrainPhys
|
|||
}
|
||||
}
|
||||
verticesCount = verticesCount / 3;
|
||||
physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,completeVerts,verCount={1}",
|
||||
BSScene.DetailLogZero, verticesCount);
|
||||
|
||||
for (int yy = 0; yy < sizeY; yy++)
|
||||
{
|
||||
|
@ -235,8 +233,6 @@ public sealed class BSTerrainMesh : BSTerrainPhys
|
|||
indicesCount += 6;
|
||||
}
|
||||
}
|
||||
physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,completeIndices,indCount={1}", // DEEBUG DEBUG DEBUG
|
||||
LogHeader, indicesCount); // DEBUG
|
||||
ret = true;
|
||||
}
|
||||
catch (Exception e)
|
||||
|
|
|
@ -287,6 +287,8 @@ public struct ConfigurationParameters
|
|||
public float terrainFriction;
|
||||
public float terrainHitFraction;
|
||||
public float terrainRestitution;
|
||||
public float terrainCollisionMargin;
|
||||
|
||||
public float avatarFriction;
|
||||
public float avatarStandingFriction;
|
||||
public float avatarDensity;
|
||||
|
@ -296,6 +298,8 @@ public struct ConfigurationParameters
|
|||
public float avatarCapsuleHeight;
|
||||
public float avatarContactProcessingThreshold;
|
||||
|
||||
public float vehicleAngularDamping;
|
||||
|
||||
public float maxPersistantManifoldPoolSize;
|
||||
public float maxCollisionAlgorithmPoolSize;
|
||||
public float shouldDisableContactPoolDynamicAllocation;
|
||||
|
@ -481,6 +485,9 @@ public static extern IntPtr BuildNativeShape2(IntPtr world, ShapeData shapeData)
|
|||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
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]
|
||||
public static extern IntPtr BuildCapsuleShape2(IntPtr world, float radius, float height, Vector3 scale);
|
||||
|
||||
|
|
|
@ -221,10 +221,10 @@
|
|||
; to false if you have compatibility problems.
|
||||
;CacheSculptMaps = true
|
||||
|
||||
; Choose one of the physics engines below
|
||||
; OpenDynamicsEngine is by some distance the most developed physics engine
|
||||
; basicphysics effectively does not model physics at all, making all objects phantom
|
||||
|
||||
; Choose one of the physics engines below.
|
||||
; OpenDynamicsEngine is by some distance the most developed physics engine.
|
||||
; 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 = basicphysics
|
||||
;physics = POS
|
||||
|
@ -908,15 +908,18 @@
|
|||
|
||||
[BulletSim]
|
||||
; World parameters
|
||||
DefaultFriction = 0.50
|
||||
DefaultFriction = 0.20
|
||||
DefaultDensity = 10.000006836
|
||||
DefaultRestitution = 0.0
|
||||
Gravity = -9.80665
|
||||
|
||||
TerrainFriction = 0.50
|
||||
TerrainHitFriction = 0.8
|
||||
TerrainFriction = 0.30
|
||||
TerrainHitFraction = 0.8
|
||||
TerrainRestitution = 0
|
||||
TerrainCollisionMargin = 0.04
|
||||
|
||||
AvatarFriction = 0.2
|
||||
AvatarStandingFriction = 0.99
|
||||
AvatarRestitution = 0.0
|
||||
AvatarDensity = 60.0
|
||||
AvatarCapsuleWidth = 0.6
|
||||
|
@ -930,27 +933,15 @@
|
|||
LinearDamping = 0.0
|
||||
AngularDamping = 0.0
|
||||
DeactivationTime = 0.2
|
||||
LinearSleepingThreshold = 0.8
|
||||
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
|
||||
CollisionMargin = 0.04
|
||||
|
||||
; Linkset constraint parameters
|
||||
LinkImplementation = 1 ; 0=constraint, 1=compound
|
||||
LinkConstraintUseFrameOffset = False
|
||||
LinkConstraintEnableTransMotor = True
|
||||
LinkConstraintTransMotorMaxVel = 5.0
|
||||
LinkConstraintTransMotorMaxForce = 0.1
|
||||
|
||||
|
||||
; Whether to mesh sculpties
|
||||
MeshSculptedPrim = true
|
||||
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue