Merge branch 'master' of ssh://opensimulator.org/var/git/opensim
commit
4e622f6816
|
@ -24,21 +24,10 @@
|
|||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
||||
/* RA: June 14, 2011. Copied from ODEDynamics.cs and converted to
|
||||
* call the BulletSim system.
|
||||
*/
|
||||
/* Revised Aug, Sept 2009 by Kitto Flora. ODEDynamics.cs replaces
|
||||
* ODEVehicleSettings.cs. It and ODEPrim.cs are re-organised:
|
||||
* ODEPrim.cs contains methods dealing with Prim editing, Prim
|
||||
* characteristics and Kinetic motion.
|
||||
* ODEDynamics.cs contains methods dealing with Prim Physical motion
|
||||
* (dynamics) and the associated settings. Old Linear and angular
|
||||
* motors for dynamic motion have been replace with MoveLinear()
|
||||
* and MoveAngular(); 'Physical' is used only to switch ODE dynamic
|
||||
* simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_<other> is to
|
||||
* switch between 'VEHICLE' parameter use and general dynamics
|
||||
* settings use.
|
||||
* The quotations from http://wiki.secondlife.com/wiki/Linden_Vehicle_Tutorial
|
||||
* are Copyright (c) 2009 Linden Research, Inc and are used under their license
|
||||
* of Creative Commons Attribution-Share Alike 3.0
|
||||
* (http://creativecommons.org/licenses/by-sa/3.0/).
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
@ -111,7 +100,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
private float m_bankingEfficiency = 0;
|
||||
private float m_bankingMix = 0;
|
||||
private float m_bankingTimescale = 0;
|
||||
private Vector3 m_lastBanking = Vector3.Zero;
|
||||
|
||||
//Hover and Buoyancy properties
|
||||
private float m_VhoverHeight = 0f;
|
||||
|
@ -125,8 +113,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
|
||||
//Attractor properties
|
||||
private BSVMotor m_verticalAttractionMotor = new BSVMotor("VerticalAttraction");
|
||||
private float m_verticalAttractionEfficiency = 1.0f; // damped
|
||||
private float m_verticalAttractionTimescale = 600f; // Timescale > 500 means no vert attractor.
|
||||
private float m_verticalAttractionEfficiency = 1.0f; // damped
|
||||
private float m_verticalAttractionCutoff = 500f; // per the documentation
|
||||
// Timescale > cutoff means no vert attractor.
|
||||
private float m_verticalAttractionTimescale = 510f;
|
||||
|
||||
public BSDynamics(BSScene myScene, BSPrim myPrim)
|
||||
{
|
||||
|
@ -329,7 +319,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
m_bankingEfficiency = 0;
|
||||
m_bankingTimescale = 1000;
|
||||
m_bankingMix = 1;
|
||||
m_lastBanking = Vector3.Zero;
|
||||
|
||||
m_referenceFrame = Quaternion.Identity;
|
||||
m_flags = (VehicleFlag)0;
|
||||
|
@ -364,7 +353,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
m_bankingEfficiency = 0;
|
||||
m_bankingTimescale = 10;
|
||||
m_bankingMix = 1;
|
||||
m_lastBanking = Vector3.Zero;
|
||||
|
||||
m_referenceFrame = Quaternion.Identity;
|
||||
m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY
|
||||
|
@ -374,6 +362,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
m_flags |= (VehicleFlag.NO_DEFLECTION_UP
|
||||
| VehicleFlag.LIMIT_ROLL_ONLY
|
||||
| VehicleFlag.LIMIT_MOTOR_UP);
|
||||
|
||||
break;
|
||||
case Vehicle.TYPE_CAR:
|
||||
m_linearMotorDirection = Vector3.Zero;
|
||||
|
@ -403,7 +392,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
m_bankingEfficiency = -0.2f;
|
||||
m_bankingMix = 1;
|
||||
m_bankingTimescale = 1;
|
||||
m_lastBanking = Vector3.Zero;
|
||||
|
||||
m_referenceFrame = Quaternion.Identity;
|
||||
m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY
|
||||
|
@ -442,7 +430,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
m_bankingEfficiency = -0.3f;
|
||||
m_bankingMix = 0.8f;
|
||||
m_bankingTimescale = 1;
|
||||
m_lastBanking = Vector3.Zero;
|
||||
|
||||
m_referenceFrame = Quaternion.Identity;
|
||||
m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY
|
||||
|
@ -481,7 +468,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
m_bankingEfficiency = 1;
|
||||
m_bankingMix = 0.7f;
|
||||
m_bankingTimescale = 2;
|
||||
m_lastBanking = Vector3.Zero;
|
||||
|
||||
m_referenceFrame = Quaternion.Identity;
|
||||
m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY
|
||||
|
@ -520,7 +506,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
m_bankingEfficiency = 0;
|
||||
m_bankingMix = 0.7f;
|
||||
m_bankingTimescale = 5;
|
||||
m_lastBanking = Vector3.Zero;
|
||||
|
||||
m_referenceFrame = Quaternion.Identity;
|
||||
|
||||
|
@ -554,8 +539,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
// Z goes away and we keep X and Y
|
||||
m_verticalAttractionMotor.FrictionTimescale = new Vector3(BSMotor.Infinite, BSMotor.Infinite, 0.1f);
|
||||
m_verticalAttractionMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging)
|
||||
|
||||
// m_bankingMotor = new BSVMotor("BankingMotor", ...);
|
||||
}
|
||||
|
||||
// Some of the properties of this prim may have changed.
|
||||
|
@ -577,15 +560,23 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
float angularDamping = PhysicsScene.Params.vehicleAngularDamping;
|
||||
BulletSimAPI.SetAngularDamping2(Prim.PhysBody.ptr, angularDamping);
|
||||
|
||||
// Vehicles report collision events so we know when it's on the ground
|
||||
BulletSimAPI.AddToCollisionFlags2(Prim.PhysBody.ptr, CollisionFlags.BS_VEHICLE_COLLISIONS);
|
||||
|
||||
// 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);
|
||||
// Vector3 localInertia = new Vector3(m_vehicleMass, m_vehicleMass, m_vehicleMass);
|
||||
Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(Prim.PhysShape.ptr, m_vehicleMass);
|
||||
BulletSimAPI.SetMassProps2(Prim.PhysBody.ptr, m_vehicleMass, localInertia);
|
||||
BulletSimAPI.UpdateInertiaTensor2(Prim.PhysBody.ptr);
|
||||
|
||||
VDetailLog("{0},BSDynamics.Refresh,frict={1},inert={2},aDamp={3}",
|
||||
Prim.LocalID, friction, localInertia, angularDamping);
|
||||
}
|
||||
else
|
||||
{
|
||||
BulletSimAPI.RemoveFromCollisionFlags2(Prim.PhysBody.ptr, CollisionFlags.BS_VEHICLE_COLLISIONS);
|
||||
}
|
||||
}
|
||||
|
||||
public bool RemoveBodyDependencies(BSPhysObject prim)
|
||||
|
@ -618,13 +609,18 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
private float? m_knownWaterLevel;
|
||||
private Vector3? m_knownPosition;
|
||||
private Vector3? m_knownVelocity;
|
||||
private Vector3 m_knownForce;
|
||||
private Quaternion? m_knownOrientation;
|
||||
private Vector3? m_knownRotationalVelocity;
|
||||
private Vector3 m_knownRotationalForce;
|
||||
private float? m_knownForwardSpeed;
|
||||
|
||||
private const int m_knownChangedPosition = 1 << 0;
|
||||
private const int m_knownChangedVelocity = 1 << 1;
|
||||
private const int m_knownChangedOrientation = 1 << 2;
|
||||
private const int m_knownChangedRotationalVelocity = 1 << 3;
|
||||
private const int m_knownChangedForce = 1 << 2;
|
||||
private const int m_knownChangedOrientation = 1 << 3;
|
||||
private const int m_knownChangedRotationalVelocity = 1 << 4;
|
||||
private const int m_knownChangedRotationalForce = 1 << 5;
|
||||
|
||||
private void ForgetKnownVehicleProperties()
|
||||
{
|
||||
|
@ -632,8 +628,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
m_knownWaterLevel = null;
|
||||
m_knownPosition = null;
|
||||
m_knownVelocity = null;
|
||||
m_knownForce = Vector3.Zero;
|
||||
m_knownOrientation = null;
|
||||
m_knownRotationalVelocity = null;
|
||||
m_knownRotationalForce = Vector3.Zero;
|
||||
m_knownForwardSpeed = null;
|
||||
m_knownChanged = 0;
|
||||
}
|
||||
private void PushKnownChanged()
|
||||
|
@ -645,12 +644,22 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
if ((m_knownChanged & m_knownChangedOrientation) != 0)
|
||||
Prim.ForceOrientation = VehicleOrientation;
|
||||
if ((m_knownChanged & m_knownChangedVelocity) != 0)
|
||||
{
|
||||
Prim.ForceVelocity = VehicleVelocity;
|
||||
BulletSimAPI.SetInterpolationLinearVelocity2(Prim.PhysBody.ptr, VehicleVelocity);
|
||||
}
|
||||
if ((m_knownChanged & m_knownChangedForce) != 0)
|
||||
Prim.AddForce((Vector3)m_knownForce, false, true);
|
||||
|
||||
if ((m_knownChanged & m_knownChangedRotationalVelocity) != 0)
|
||||
{
|
||||
Prim.ForceRotationalVelocity = VehicleRotationalVelocity;
|
||||
// Fake out Bullet by making it think the velocity is the same as last time.
|
||||
BulletSimAPI.SetInterpolationAngularVelocity2(Prim.PhysBody.ptr, VehicleRotationalVelocity);
|
||||
}
|
||||
if ((m_knownChanged & m_knownChangedRotationalForce) != 0)
|
||||
Prim.AddAngularForce((Vector3)m_knownRotationalForce, false, true);
|
||||
|
||||
// If we set one of the values (ie, the physics engine didn't do it) we must force
|
||||
// an UpdateProperties event to send the changes up to the simulator.
|
||||
BulletSimAPI.PushUpdate2(Prim.PhysBody.ptr);
|
||||
|
@ -720,6 +729,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
}
|
||||
}
|
||||
|
||||
private void VehicleAddForce(Vector3 aForce)
|
||||
{
|
||||
m_knownForce += aForce;
|
||||
m_knownChanged |= m_knownChangedForce;
|
||||
}
|
||||
|
||||
private Vector3 VehicleRotationalVelocity
|
||||
{
|
||||
get
|
||||
|
@ -734,6 +749,21 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
m_knownChanged |= m_knownChangedRotationalVelocity;
|
||||
}
|
||||
}
|
||||
private void VehicleAddAngularForce(Vector3 aForce)
|
||||
{
|
||||
m_knownRotationalForce += aForce;
|
||||
m_knownChanged |= m_knownChangedRotationalForce;
|
||||
}
|
||||
private float VehicleForwardSpeed
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_knownForwardSpeed == null)
|
||||
m_knownForwardSpeed = (VehicleVelocity * Quaternion.Inverse(VehicleOrientation)).X;
|
||||
return (float)m_knownForwardSpeed;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion // Known vehicle value functions
|
||||
|
||||
// One step of the vehicle properties for the next 'pTimestep' seconds.
|
||||
|
@ -769,10 +799,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
linearMotorContribution *= VehicleOrientation;
|
||||
|
||||
// ==================================================================
|
||||
// Gravity and Buoyancy
|
||||
// There is some gravity, make a gravity force vector that is applied after object velocity.
|
||||
// Buoyancy: force to overcome gravity.
|
||||
// m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g;
|
||||
Vector3 grav = Prim.PhysicsScene.DefaultGravity * (1f - m_VehicleBuoyancy);
|
||||
// So, if zero, don't change anything (let gravity happen). If one, negate the effect of gravity.
|
||||
Vector3 buoyancyContribution = Prim.PhysicsScene.DefaultGravity * m_VehicleBuoyancy;
|
||||
|
||||
Vector3 terrainHeightContribution = ComputeLinearTerrainHeightCorrection(pTimestep);
|
||||
|
||||
|
@ -797,14 +827,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
newVelocity.Z = 0;
|
||||
|
||||
// ==================================================================
|
||||
// Clamp REALLY high or low velocities
|
||||
// Clamp high or low velocities
|
||||
float newVelocityLengthSq = newVelocity.LengthSquared();
|
||||
if (newVelocityLengthSq > 1e6f)
|
||||
// if (newVelocityLengthSq > 1e6f)
|
||||
if (newVelocityLengthSq > 1000f)
|
||||
{
|
||||
newVelocity /= newVelocity.Length();
|
||||
newVelocity *= 1000f;
|
||||
}
|
||||
else if (newVelocityLengthSq < 1e-6f)
|
||||
// else if (newVelocityLengthSq < 1e-6f)
|
||||
else if (newVelocityLengthSq < 0.001f)
|
||||
newVelocity = Vector3.Zero;
|
||||
|
||||
// ==================================================================
|
||||
|
@ -813,15 +845,18 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
VehicleVelocity = newVelocity;
|
||||
|
||||
// Other linear forces are applied as forces.
|
||||
Vector3 totalDownForce = grav * m_vehicleMass * pTimestep;
|
||||
if (totalDownForce != Vector3.Zero)
|
||||
Vector3 totalDownForce = buoyancyContribution * m_vehicleMass;
|
||||
if (!totalDownForce.ApproxEquals(Vector3.Zero, 0.01f))
|
||||
{
|
||||
Prim.AddForce(totalDownForce, false);
|
||||
VehicleAddForce(totalDownForce);
|
||||
}
|
||||
|
||||
VDetailLog("{0}, MoveLinear,done,newVel={1},totDown={2},linContrib={3},terrContrib={4},hoverContrib={5},limitContrib={6}",
|
||||
Prim.LocalID, newVelocity, totalDownForce,
|
||||
linearMotorContribution, terrainHeightContribution, hoverContribution, limitMotorUpContribution
|
||||
VDetailLog("{0}, MoveLinear,done,newVel={1},totDown={2},IsColliding={3}",
|
||||
Prim.LocalID, newVelocity, totalDownForce, Prim.IsColliding);
|
||||
VDetailLog("{0}, MoveLinear,done,linContrib={1},terrContrib={2},hoverContrib={3},limitContrib={4},buoyContrib={5}",
|
||||
Prim.LocalID,
|
||||
linearMotorContribution, terrainHeightContribution, hoverContribution,
|
||||
limitMotorUpContribution, buoyancyContribution
|
||||
);
|
||||
|
||||
} // end MoveLinear()
|
||||
|
@ -942,21 +977,24 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
}
|
||||
|
||||
// From http://wiki.secondlife.com/wiki/LlSetVehicleFlags :
|
||||
// Prevent ground vehicles from motoring into the sky.This flag has a subtle effect when
|
||||
// Prevent ground vehicles from motoring into the sky. This flag has a subtle effect when
|
||||
// used with conjunction with banking: the strength of the banking will decay when the
|
||||
// vehicle no longer experiences collisions. The decay timescale is the same as
|
||||
// VEHICLE_BANKING_TIMESCALE. This is to help prevent ground vehicles from steering
|
||||
// when they are in mid jump.
|
||||
// TODO: this code is wrong. Also, what should it do for boats?
|
||||
// TODO: this code is wrong. Also, what should it do for boats (height from water)?
|
||||
// This is just using the ground and a general collision check. Should really be using
|
||||
// a downward raycast to find what is below.
|
||||
public Vector3 ComputeLinearMotorUp(float pTimestep)
|
||||
{
|
||||
Vector3 ret = Vector3.Zero;
|
||||
|
||||
if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0)
|
||||
{
|
||||
// If the vehicle is motoring into the sky, get it going back down.
|
||||
// float distanceAboveGround = pos.Z - Math.Max(GetTerrainHeight(pos), GetWaterLevel(pos));
|
||||
float distanceAboveGround = VehiclePosition.Z - GetTerrainHeight(VehiclePosition);
|
||||
if (distanceAboveGround > 1f)
|
||||
// Not colliding if the vehicle is off the ground
|
||||
if (!Prim.IsColliding)
|
||||
{
|
||||
// downForce = new Vector3(0, 0, (-distanceAboveGround / m_bankingTimescale) * pTimestep);
|
||||
// downForce = new Vector3(0, 0, -distanceAboveGround / m_bankingTimescale);
|
||||
|
@ -977,8 +1015,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
// =======================================================================
|
||||
// Apply the effect of the angular motor.
|
||||
// The 'contribution' is how much angular correction velocity each function wants.
|
||||
// All the contributions are added together and the orientation of the vehicle
|
||||
// is changed by all the contributed corrections.
|
||||
// All the contributions are added together and the resulting velocity is
|
||||
// set directly on the vehicle.
|
||||
private void MoveAngular(float pTimestep)
|
||||
{
|
||||
// The user wants how many radians per second angular change?
|
||||
|
@ -1001,7 +1039,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
|
||||
Vector3 deflectionContribution = ComputeAngularDeflection();
|
||||
|
||||
Vector3 bankingContribution = ComputeAngularBanking(angularMotorContribution.Z);
|
||||
Vector3 bankingContribution = ComputeAngularBanking();
|
||||
|
||||
// ==================================================================
|
||||
m_lastVertAttractor = verticalAttractionContribution;
|
||||
|
@ -1013,11 +1051,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
+ bankingContribution;
|
||||
|
||||
// ==================================================================
|
||||
// The correction is applied to the current orientation.
|
||||
// Apply the correction velocity.
|
||||
// TODO: Should this be applied as an angular force (torque)?
|
||||
if (!m_lastAngularCorrection.ApproxEquals(Vector3.Zero, 0.01f))
|
||||
{
|
||||
Vector3 scaledCorrection = m_lastAngularCorrection * pTimestep;
|
||||
|
||||
VehicleRotationalVelocity = scaledCorrection;
|
||||
|
||||
VDetailLog("{0}, MoveAngular,done,nonZero,angMotorContrib={1},vertAttrContrib={2},bankContrib={3},deflectContrib={4},totalContrib={5},scaledCorr={6}",
|
||||
|
@ -1029,7 +1067,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
}
|
||||
else
|
||||
{
|
||||
// The vehicle is not adding anything velocity wise.
|
||||
// The vehicle is not adding anything angular wise.
|
||||
VehicleRotationalVelocity = Vector3.Zero;
|
||||
VDetailLog("{0}, MoveAngular,done,zero", Prim.LocalID);
|
||||
}
|
||||
|
@ -1060,19 +1098,26 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
torqueFromOffset.Y = 0;
|
||||
if (float.IsNaN(torqueFromOffset.Z))
|
||||
torqueFromOffset.Z = 0;
|
||||
torqueFromOffset *= m_vehicleMass;
|
||||
Prim.ApplyTorqueImpulse(torqueFromOffset, true);
|
||||
|
||||
VehicleAddAngularForce(torqueFromOffset * m_vehicleMass);
|
||||
VDetailLog("{0}, BSDynamic.MoveAngular,motorOffset,applyTorqueImpulse={1}", Prim.LocalID, torqueFromOffset);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// From http://wiki.secondlife.com/wiki/Linden_Vehicle_Tutorial:
|
||||
// Some vehicles, like boats, should always keep their up-side up. This can be done by
|
||||
// enabling the "vertical attractor" behavior that springs the vehicle's local z-axis to
|
||||
// the world z-axis (a.k.a. "up"). To take advantage of this feature you would set the
|
||||
// VEHICLE_VERTICAL_ATTRACTION_TIMESCALE to control the period of the spring frequency,
|
||||
// and then set the VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY to control the damping. An
|
||||
// efficiency of 0.0 will cause the spring to wobble around its equilibrium, while an
|
||||
// efficiency of 1.0 will cause the spring to reach its equilibrium with exponential decay.
|
||||
public Vector3 ComputeAngularVerticalAttraction()
|
||||
{
|
||||
Vector3 ret = Vector3.Zero;
|
||||
|
||||
// If vertical attaction timescale is reasonable and we applied an angular force last time...
|
||||
if (m_verticalAttractionTimescale < 500)
|
||||
if (m_verticalAttractionTimescale < m_verticalAttractionCutoff)
|
||||
{
|
||||
// Take a vector pointing up and convert it from world to vehicle relative coords.
|
||||
Vector3 verticalError = Vector3.UnitZ * VehicleOrientation;
|
||||
|
@ -1097,91 +1142,121 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
ret.Y = - verticalError.X;
|
||||
ret.Z = 0f;
|
||||
|
||||
// scale by the time scale and timestep
|
||||
// Scale the correction force by how far we're off from vertical.
|
||||
// Z error of one says little error. As Z gets smaller, the vehicle is leaning farther over.
|
||||
float clampedSqrZError = ClampInRange(0.01f, verticalError.Z * verticalError.Z, 1f);
|
||||
float vertForce = 1f / clampedSqrZError;
|
||||
|
||||
ret *= vertForce;
|
||||
|
||||
// Correction happens over a number of seconds.
|
||||
Vector3 unscaledContrib = ret;
|
||||
ret /= m_verticalAttractionTimescale;
|
||||
// This returns the angular correction desired. Timestep is added later.
|
||||
// ret *= pTimestep;
|
||||
|
||||
// apply efficiency
|
||||
Vector3 preEfficiencyContrib = ret;
|
||||
// TODO: implement efficiency.
|
||||
// Effenciency squared seems to give a more realistic effect
|
||||
float efficencySquared = m_verticalAttractionEfficiency * m_verticalAttractionEfficiency;
|
||||
// ret *= efficencySquared;
|
||||
|
||||
VDetailLog("{0}, MoveAngular,verticalAttraction,,verticalError={1},unscaled={2},preEff={3},eff={4},effSq={5},vertAttr={6}",
|
||||
Prim.LocalID, verticalError, unscaledContrib, preEfficiencyContrib,
|
||||
m_verticalAttractionEfficiency, efficencySquared,
|
||||
ret);
|
||||
VDetailLog("{0}, MoveAngular,verticalAttraction,,verticalError={1},unscaled={2},vertForce={3},eff={4},vertAttr={5}",
|
||||
Prim.LocalID, verticalError, unscaledContrib, vertForce, m_verticalAttractionEfficiency, ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Return the angular correction to correct the direction the vehicle is pointing to be
|
||||
// the direction is should want to be pointing.
|
||||
// The vehicle is moving in some direction and correct its orientation to it is pointing
|
||||
// in that direction.
|
||||
// TODO: implement reference frame.
|
||||
public Vector3 ComputeAngularDeflection()
|
||||
{
|
||||
Vector3 ret = Vector3.Zero;
|
||||
return ret; // DEBUG DEBUG DEBUG debug one force at a time
|
||||
|
||||
if (m_angularDeflectionEfficiency != 0)
|
||||
{
|
||||
// Where the vehicle should want to point relative to the vehicle
|
||||
Vector3 preferredDirection = Vector3.UnitX * m_referenceFrame;
|
||||
// The direction the vehicle is moving
|
||||
Vector3 movingDirection = VehicleVelocity;
|
||||
movingDirection.Normalize();
|
||||
|
||||
// Where the vehicle is pointing relative to the vehicle.
|
||||
Vector3 currentDirection = Vector3.UnitX * Quaternion.Add(VehicleOrientation, m_referenceFrame);
|
||||
// The direction the vehicle is pointing
|
||||
Vector3 pointingDirection = Vector3.UnitX * VehicleOrientation;
|
||||
pointingDirection.Normalize();
|
||||
|
||||
// Difference between where vehicle is pointing and where it should wish to point
|
||||
Vector3 directionCorrection = preferredDirection - currentDirection;
|
||||
// The difference between what is and what should be
|
||||
Vector3 deflectionError = movingDirection - pointingDirection;
|
||||
|
||||
// Scale the correction by recovery timescale and efficiency
|
||||
ret = directionCorrection * m_angularDeflectionEfficiency / m_angularDeflectionTimescale;
|
||||
ret = (-deflectionError * VehicleForwardSpeed) * m_angularDeflectionEfficiency;
|
||||
ret /= m_angularDeflectionTimescale;
|
||||
|
||||
VDetailLog("{0}, MoveAngular,Deflection,perfDir={1},currentDir={2},dirCorrection={3},ret={4}",
|
||||
Prim.LocalID, preferredDirection, currentDirection, directionCorrection, ret);
|
||||
VDetailLog("{0}, MoveAngular,Deflection,movingDir={1},pointingDir={2},deflectError={3},ret={4}",
|
||||
Prim.LocalID, movingDirection, pointingDirection, deflectionError, ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Return an angular change to tip the vehicle (around X axis) when turning (turned around Z).
|
||||
// Remembers the last banking value calculated and returns the difference needed this tick.
|
||||
// TurningFactor is rate going left or right (pos=left, neg=right, scale=0..1).
|
||||
public Vector3 ComputeAngularBanking(float turningFactor)
|
||||
// Return an angular change to rotate the vehicle around the Z axis when the vehicle
|
||||
// is tipped around the X axis.
|
||||
// From http://wiki.secondlife.com/wiki/Linden_Vehicle_Tutorial:
|
||||
// The vertical attractor feature must be enabled in order for the banking behavior to
|
||||
// function. The way banking works is this: a rotation around the vehicle's roll-axis will
|
||||
// produce a angular velocity around the yaw-axis, causing the vehicle to turn. The magnitude
|
||||
// of the yaw effect will be proportional to the
|
||||
// VEHICLE_BANKING_EFFICIENCY, the angle of the roll rotation, and sometimes the vehicle's
|
||||
// velocity along its preferred axis of motion.
|
||||
// The VEHICLE_BANKING_EFFICIENCY can vary between -1 and +1. When it is positive then any
|
||||
// positive rotation (by the right-hand rule) about the roll-axis will effect a
|
||||
// (negative) torque around the yaw-axis, making it turn to the right--that is the
|
||||
// vehicle will lean into the turn, which is how real airplanes and motorcycle's work.
|
||||
// Negating the banking coefficient will make it so that the vehicle leans to the
|
||||
// outside of the turn (not very "physical" but might allow interesting vehicles so why not?).
|
||||
// The VEHICLE_BANKING_MIX is a fake (i.e. non-physical) parameter that is useful for making
|
||||
// banking vehicles do what you want rather than what the laws of physics allow.
|
||||
// For example, consider a real motorcycle...it must be moving forward in order for
|
||||
// it to turn while banking, however video-game motorcycles are often configured
|
||||
// to turn in place when at a dead stop--because they are often easier to control
|
||||
// that way using the limited interface of the keyboard or game controller. The
|
||||
// VEHICLE_BANKING_MIX enables combinations of both realistic and non-realistic
|
||||
// banking by functioning as a slider between a banking that is correspondingly
|
||||
// totally static (0.0) and totally dynamic (1.0). By "static" we mean that the
|
||||
// banking effect depends only on the vehicle's rotation about its roll-axis compared
|
||||
// to "dynamic" where the banking is also proportional to its velocity along its
|
||||
// roll-axis. Finding the best value of the "mixture" will probably require trial and error.
|
||||
// The time it takes for the banking behavior to defeat a preexisting angular velocity about the
|
||||
// world z-axis is determined by the VEHICLE_BANKING_TIMESCALE. So if you want the vehicle to
|
||||
// bank quickly then give it a banking timescale of about a second or less, otherwise you can
|
||||
// make a sluggish vehicle by giving it a timescale of several seconds.
|
||||
public Vector3 ComputeAngularBanking()
|
||||
{
|
||||
Vector3 ret = Vector3.Zero;
|
||||
Vector3 computedBanking = Vector3.Zero;
|
||||
|
||||
if (m_bankingEfficiency != 0)
|
||||
if (m_bankingEfficiency != 0 && m_verticalAttractionTimescale < m_verticalAttractionCutoff)
|
||||
{
|
||||
Vector3 currentDirection = Vector3.UnitX * VehicleOrientation;
|
||||
// This works by rotating a unit vector to the orientation of the vehicle. The
|
||||
// roll (tilt) will be Y component of a tilting Z vector (zero for no tilt
|
||||
// up to one for full over).
|
||||
Vector3 rollComponents = Vector3.UnitZ * VehicleOrientation;
|
||||
|
||||
float mult = (m_bankingMix * m_bankingMix) * -1 * (m_bankingMix < 0 ? -1 : 1);
|
||||
// Figure out the yaw value for this much roll.
|
||||
float turnComponent = rollComponents.Y * rollComponents.Y * m_bankingEfficiency;
|
||||
// Keep the sign
|
||||
if (rollComponents.Y < 0f)
|
||||
turnComponent = -turnComponent;
|
||||
|
||||
//Use the square of the efficiency, as it looks much more how SL banking works
|
||||
float effSquared = (m_bankingEfficiency * m_bankingEfficiency);
|
||||
if (m_bankingEfficiency < 0)
|
||||
effSquared *= -1; //Keep the negative!
|
||||
// TODO: there must be a better computation of the banking force.
|
||||
float bankingTurnForce = turnComponent;
|
||||
|
||||
float mix = Math.Abs(m_bankingMix);
|
||||
// TODO: Must include reference frame.
|
||||
float forwardSpeed = VehicleVelocity.X;
|
||||
// actual error = static turn error + dynamic turn error
|
||||
float mixedBankingError = bankingTurnForce * (1f - m_bankingMix) + bankingTurnForce * m_bankingMix * VehicleForwardSpeed;
|
||||
// TODO: the banking effect should not go to infinity but what to limit it to?
|
||||
mixedBankingError = ClampInRange(-20f, mixedBankingError, 20f);
|
||||
|
||||
if (!Prim.IsColliding && forwardSpeed > mix)
|
||||
{
|
||||
computedBanking.X = ClampInRange(-3f, turningFactor * (effSquared * mult), 3f);
|
||||
}
|
||||
// Build the force vector to change rotation from what it is to what it should be
|
||||
ret.Z = -mixedBankingError;
|
||||
|
||||
// 'computedBanking' is now how much banking that should be happening.
|
||||
ret = computedBanking - m_lastBanking;
|
||||
// Don't do it all at once.
|
||||
ret /= m_bankingTimescale;
|
||||
|
||||
// Scale the correction by timescale and efficiency
|
||||
ret /= m_bankingTimescale * m_bankingEfficiency;
|
||||
|
||||
VDetailLog("{0}, MoveAngular,Banking,computedB={1},lastB={2},bEff={3},effSq={4},mult={5},mix={6},banking={7}",
|
||||
Prim.LocalID, computedBanking, m_lastBanking, m_bankingEfficiency, effSquared, mult, mix, ret);
|
||||
VDetailLog("{0}, MoveAngular,Banking,rollComp={1},speed={2},turnComp={3},bankErr={4},mixedBankErr={5},ret={6}",
|
||||
Prim.LocalID, rollComponents, VehicleForwardSpeed, turnComponent, bankingTurnForce, mixedBankingError, ret);
|
||||
}
|
||||
m_lastBanking = computedBanking;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,191 +1,185 @@
|
|||
/*
|
||||
* 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];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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"};
|
||||
|
||||
public MaterialAttributes(string t, float d, float f, float r)
|
||||
{
|
||||
type = t;
|
||||
density = d;
|
||||
friction = f;
|
||||
restitution = r;
|
||||
}
|
||||
public string type;
|
||||
public float density;
|
||||
public float friction;
|
||||
public float restitution;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
// Values from http://wiki.secondlife.com/wiki/PRIM_MATERIAL
|
||||
// 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;
|
||||
Attributes[(int)MaterialAttributes.Material.Stone] =
|
||||
new MaterialAttributes("stone",dDensity, 0.8f, 0.4f);
|
||||
Attributes[(int)MaterialAttributes.Material.Metal] =
|
||||
new MaterialAttributes("metal",dDensity, 0.3f, 0.4f);
|
||||
Attributes[(int)MaterialAttributes.Material.Glass] =
|
||||
new MaterialAttributes("glass",dDensity, 0.2f, 0.7f);
|
||||
Attributes[(int)MaterialAttributes.Material.Wood] =
|
||||
new MaterialAttributes("wood",dDensity, 0.6f, 0.5f);
|
||||
Attributes[(int)MaterialAttributes.Material.Flesh] =
|
||||
new MaterialAttributes("flesh",dDensity, 0.9f, 0.3f);
|
||||
Attributes[(int)MaterialAttributes.Material.Plastic] =
|
||||
new MaterialAttributes("plastic",dDensity, 0.4f, 0.7f);
|
||||
Attributes[(int)MaterialAttributes.Material.Rubber] =
|
||||
new MaterialAttributes("rubber",dDensity, 0.9f, 0.9f);
|
||||
Attributes[(int)MaterialAttributes.Material.Light] =
|
||||
new MaterialAttributes("light",dDensity, dFriction, dRestitution);
|
||||
Attributes[(int)MaterialAttributes.Material.Avatar] =
|
||||
new MaterialAttributes("avatar",60f, 0.2f, 0f);
|
||||
|
||||
Attributes[(int)MaterialAttributes.Material.Stone + (int)MaterialAttributes.Material.NumberOfTypes] =
|
||||
new MaterialAttributes("stonePhysical",dDensity, 0.8f, 0.4f);
|
||||
Attributes[(int)MaterialAttributes.Material.Metal + (int)MaterialAttributes.Material.NumberOfTypes] =
|
||||
new MaterialAttributes("metalPhysical",dDensity, 0.8f, 0.4f);
|
||||
Attributes[(int)MaterialAttributes.Material.Glass + (int)MaterialAttributes.Material.NumberOfTypes] =
|
||||
new MaterialAttributes("glassPhysical",dDensity, 0.8f, 0.7f);
|
||||
Attributes[(int)MaterialAttributes.Material.Wood + (int)MaterialAttributes.Material.NumberOfTypes] =
|
||||
new MaterialAttributes("woodPhysical",dDensity, 0.8f, 0.5f);
|
||||
Attributes[(int)MaterialAttributes.Material.Flesh + (int)MaterialAttributes.Material.NumberOfTypes] =
|
||||
new MaterialAttributes("fleshPhysical",dDensity, 0.8f, 0.3f);
|
||||
Attributes[(int)MaterialAttributes.Material.Plastic + (int)MaterialAttributes.Material.NumberOfTypes] =
|
||||
new MaterialAttributes("plasticPhysical",dDensity, 0.8f, 0.7f);
|
||||
Attributes[(int)MaterialAttributes.Material.Rubber + (int)MaterialAttributes.Material.NumberOfTypes] =
|
||||
new MaterialAttributes("rubberPhysical",dDensity, 0.8f, 0.9f);
|
||||
Attributes[(int)MaterialAttributes.Material.Light + (int)MaterialAttributes.Material.NumberOfTypes] =
|
||||
new MaterialAttributes("lightPhysical",dDensity, dFriction, dRestitution);
|
||||
Attributes[(int)MaterialAttributes.Material.Avatar + (int)MaterialAttributes.Material.NumberOfTypes] =
|
||||
new MaterialAttributes("avatarPhysical",60f, 0.2f, 0f);
|
||||
}
|
||||
|
||||
// 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];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1010,6 +1010,9 @@ public sealed class BSPrim : BSPhysObject
|
|||
});
|
||||
}
|
||||
// A torque impulse.
|
||||
// ApplyTorqueImpulse adds torque directly to the angularVelocity.
|
||||
// AddAngularForce accumulates the force and applied it to the angular velocity all at once.
|
||||
// Computed as: angularVelocity += impulse * inertia;
|
||||
public void ApplyTorqueImpulse(OMV.Vector3 impulse, bool inTaintTime)
|
||||
{
|
||||
OMV.Vector3 applyImpulse = impulse;
|
||||
|
@ -1396,7 +1399,7 @@ public sealed class BSPrim : BSPhysObject
|
|||
_rotationalVelocity = entprop.RotationalVelocity;
|
||||
|
||||
// The sanity check can change the velocity and/or position.
|
||||
if (PositionSanityCheck(true))
|
||||
if (IsPhysical && PositionSanityCheck(true))
|
||||
{
|
||||
entprop.Position = _position;
|
||||
entprop.Velocity = _velocity;
|
||||
|
@ -1410,8 +1413,6 @@ public sealed class BSPrim : BSPhysObject
|
|||
DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},dir={3},vel={4},rotVel={5}",
|
||||
LocalID, _position, _orientation, direction, _velocity, _rotationalVelocity);
|
||||
|
||||
// BulletSimAPI.DumpRigidBody2(PhysicsScene.World.ptr, BSBody.ptr); // DEBUG DEBUG DEBUG
|
||||
|
||||
base.RequestPhysicsterseUpdate();
|
||||
}
|
||||
/*
|
||||
|
|
|
@ -65,9 +65,16 @@ public sealed class BSShapeCollection : IDisposable
|
|||
private Dictionary<System.UInt64, MeshDesc> Meshes = new Dictionary<System.UInt64, MeshDesc>();
|
||||
private Dictionary<System.UInt64, HullDesc> Hulls = new Dictionary<System.UInt64, HullDesc>();
|
||||
|
||||
private bool DDetail = false;
|
||||
|
||||
public BSShapeCollection(BSScene physScene)
|
||||
{
|
||||
PhysicsScene = physScene;
|
||||
// Set the next to 'true' for very detailed shape update detailed logging (detailed details?)
|
||||
// While detailed debugging is still active, this is better than commenting out all the
|
||||
// DetailLog statements. When debugging slows down, this and the protected logging
|
||||
// statements can be commented/removed.
|
||||
DDetail = true;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
@ -126,13 +133,13 @@ public sealed class BSShapeCollection : IDisposable
|
|||
{
|
||||
lock (m_collectionActivityLock)
|
||||
{
|
||||
DetailLog("{0},BSShapeCollection.ReferenceBody,newBody,body={1}", body.ID, body);
|
||||
if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceBody,newBody,body={1}", body.ID, body);
|
||||
PhysicsScene.TaintedObject(inTaintTime, "BSShapeCollection.ReferenceBody", delegate()
|
||||
{
|
||||
if (!BulletSimAPI.IsInWorld2(body.ptr))
|
||||
{
|
||||
BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, body.ptr);
|
||||
DetailLog("{0},BSShapeCollection.ReferenceBody,addedToWorld,ref={1}", body.ID, body);
|
||||
if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceBody,addedToWorld,ref={1}", body.ID, body);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -149,7 +156,7 @@ public sealed class BSShapeCollection : IDisposable
|
|||
{
|
||||
PhysicsScene.TaintedObject(inTaintTime, "BSShapeCollection.DereferenceBody", delegate()
|
||||
{
|
||||
DetailLog("{0},BSShapeCollection.DereferenceBody,DestroyingBody,body={1},inTaintTime={2}",
|
||||
if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceBody,DestroyingBody,body={1},inTaintTime={2}",
|
||||
body.ID, body, inTaintTime);
|
||||
// If the caller needs to know the old body is going away, pass the event up.
|
||||
if (bodyCallback != null) bodyCallback(body);
|
||||
|
@ -157,7 +164,7 @@ public sealed class BSShapeCollection : IDisposable
|
|||
if (BulletSimAPI.IsInWorld2(body.ptr))
|
||||
{
|
||||
BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, body.ptr);
|
||||
DetailLog("{0},BSShapeCollection.DereferenceBody,removingFromWorld. Body={1}", body.ID, body);
|
||||
if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceBody,removingFromWorld. Body={1}", body.ID, body);
|
||||
}
|
||||
|
||||
// Zero any reference to the shape so it is not freed when the body is deleted.
|
||||
|
@ -184,7 +191,7 @@ public sealed class BSShapeCollection : IDisposable
|
|||
{
|
||||
// There is an existing instance of this mesh.
|
||||
meshDesc.referenceCount++;
|
||||
DetailLog("{0},BSShapeCollection.ReferenceShape,existingMesh,key={1},cnt={2}",
|
||||
if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceShape,existingMesh,key={1},cnt={2}",
|
||||
BSScene.DetailLogZero, shape.shapeKey.ToString("X"), meshDesc.referenceCount);
|
||||
}
|
||||
else
|
||||
|
@ -194,7 +201,7 @@ public sealed class BSShapeCollection : IDisposable
|
|||
meshDesc.shapeKey = shape.shapeKey;
|
||||
// We keep a reference to the underlying IMesh data so a hull can be built
|
||||
meshDesc.referenceCount = 1;
|
||||
DetailLog("{0},BSShapeCollection.ReferenceShape,newMesh,key={1},cnt={2}",
|
||||
if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceShape,newMesh,key={1},cnt={2}",
|
||||
BSScene.DetailLogZero, shape.shapeKey.ToString("X"), meshDesc.referenceCount);
|
||||
ret = true;
|
||||
}
|
||||
|
@ -207,7 +214,7 @@ public sealed class BSShapeCollection : IDisposable
|
|||
{
|
||||
// There is an existing instance of this hull.
|
||||
hullDesc.referenceCount++;
|
||||
DetailLog("{0},BSShapeCollection.ReferenceShape,existingHull,key={1},cnt={2}",
|
||||
if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceShape,existingHull,key={1},cnt={2}",
|
||||
BSScene.DetailLogZero, shape.shapeKey.ToString("X"), hullDesc.referenceCount);
|
||||
}
|
||||
else
|
||||
|
@ -216,7 +223,7 @@ public sealed class BSShapeCollection : IDisposable
|
|||
hullDesc.ptr = shape.ptr;
|
||||
hullDesc.shapeKey = shape.shapeKey;
|
||||
hullDesc.referenceCount = 1;
|
||||
DetailLog("{0},BSShapeCollection.ReferenceShape,newHull,key={1},cnt={2}",
|
||||
if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceShape,newHull,key={1},cnt={2}",
|
||||
BSScene.DetailLogZero, shape.shapeKey.ToString("X"), hullDesc.referenceCount);
|
||||
ret = true;
|
||||
|
||||
|
@ -246,7 +253,7 @@ public sealed class BSShapeCollection : IDisposable
|
|||
if (shape.isNativeShape)
|
||||
{
|
||||
// Native shapes are not tracked and are released immediately
|
||||
DetailLog("{0},BSShapeCollection.DereferenceShape,deleteNativeShape,ptr={1},taintTime={2}",
|
||||
if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceShape,deleteNativeShape,ptr={1},taintTime={2}",
|
||||
BSScene.DetailLogZero, shape.ptr.ToString("X"), inTaintTime);
|
||||
if (shapeCallback != null) shapeCallback(shape);
|
||||
BulletSimAPI.DeleteCollisionShape2(PhysicsScene.World.ptr, shape.ptr);
|
||||
|
@ -286,7 +293,7 @@ public sealed class BSShapeCollection : IDisposable
|
|||
if (shapeCallback != null) shapeCallback(shape);
|
||||
meshDesc.lastReferenced = System.DateTime.Now;
|
||||
Meshes[shape.shapeKey] = meshDesc;
|
||||
DetailLog("{0},BSShapeCollection.DereferenceMesh,shape={1},refCnt={2}",
|
||||
if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceMesh,shape={1},refCnt={2}",
|
||||
BSScene.DetailLogZero, shape, meshDesc.referenceCount);
|
||||
|
||||
}
|
||||
|
@ -307,7 +314,7 @@ public sealed class BSShapeCollection : IDisposable
|
|||
|
||||
hullDesc.lastReferenced = System.DateTime.Now;
|
||||
Hulls[shape.shapeKey] = hullDesc;
|
||||
DetailLog("{0},BSShapeCollection.DereferenceHull,shape={1},refCnt={2}",
|
||||
if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceHull,shape={1},refCnt={2}",
|
||||
BSScene.DetailLogZero, shape, hullDesc.referenceCount);
|
||||
}
|
||||
}
|
||||
|
@ -325,13 +332,13 @@ public sealed class BSShapeCollection : IDisposable
|
|||
// Failed the sanity check!!
|
||||
PhysicsScene.Logger.ErrorFormat("{0} Attempt to free a compound shape that is not compound!! type={1}, ptr={2}",
|
||||
LogHeader, shape.type, shape.ptr.ToString("X"));
|
||||
DetailLog("{0},BSShapeCollection.DereferenceCompound,notACompoundShape,type={1},ptr={2}",
|
||||
if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceCompound,notACompoundShape,type={1},ptr={2}",
|
||||
BSScene.DetailLogZero, shape.type, shape.ptr.ToString("X"));
|
||||
return;
|
||||
}
|
||||
|
||||
int numChildren = BulletSimAPI.GetNumberOfCompoundChildren2(shape.ptr);
|
||||
DetailLog("{0},BSShapeCollection.DereferenceCompound,shape={1},children={2}", BSScene.DetailLogZero, shape, numChildren);
|
||||
if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceCompound,shape={1},children={2}", BSScene.DetailLogZero, shape, numChildren);
|
||||
|
||||
for (int ii = numChildren - 1; ii >= 0; ii--)
|
||||
{
|
||||
|
@ -379,7 +386,7 @@ public sealed class BSShapeCollection : IDisposable
|
|||
}
|
||||
}
|
||||
|
||||
DetailLog("{0},BSShapeCollection.DereferenceAnonCollisionShape,shape={1}", BSScene.DetailLogZero, shapeInfo);
|
||||
if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceAnonCollisionShape,shape={1}", BSScene.DetailLogZero, shapeInfo);
|
||||
|
||||
if (shapeInfo.type != BSPhysicsShapeType.SHAPE_UNKNOWN)
|
||||
{
|
||||
|
@ -410,7 +417,7 @@ public sealed class BSShapeCollection : IDisposable
|
|||
// an avatar capsule is close to a native shape (it is not shared)
|
||||
ret = GetReferenceToNativeShape(prim, BSPhysicsShapeType.SHAPE_CAPSULE,
|
||||
FixedShapeKey.KEY_CAPSULE, shapeCallback);
|
||||
DetailLog("{0},BSShapeCollection.CreateGeom,avatarCapsule,shape={1}", prim.LocalID, prim.PhysShape);
|
||||
if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,avatarCapsule,shape={1}", prim.LocalID, prim.PhysShape);
|
||||
ret = true;
|
||||
haveShape = true;
|
||||
}
|
||||
|
@ -420,7 +427,7 @@ public sealed class BSShapeCollection : IDisposable
|
|||
if (!haveShape && prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_COMPOUND)
|
||||
{
|
||||
ret = GetReferenceToCompoundShape(prim, shapeCallback);
|
||||
DetailLog("{0},BSShapeCollection.CreateGeom,compoundShape,shape={1}", prim.LocalID, prim.PhysShape);
|
||||
if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,compoundShape,shape={1}", prim.LocalID, prim.PhysShape);
|
||||
haveShape = true;
|
||||
}
|
||||
|
||||
|
@ -465,7 +472,7 @@ public sealed class BSShapeCollection : IDisposable
|
|||
{
|
||||
ret = GetReferenceToNativeShape(prim, BSPhysicsShapeType.SHAPE_SPHERE,
|
||||
FixedShapeKey.KEY_SPHERE, shapeCallback);
|
||||
DetailLog("{0},BSShapeCollection.CreateGeom,sphere,force={1},shape={2}",
|
||||
if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,sphere,force={1},shape={2}",
|
||||
prim.LocalID, forceRebuild, prim.PhysShape);
|
||||
}
|
||||
}
|
||||
|
@ -479,7 +486,7 @@ public sealed class BSShapeCollection : IDisposable
|
|||
{
|
||||
ret = GetReferenceToNativeShape( prim, BSPhysicsShapeType.SHAPE_BOX,
|
||||
FixedShapeKey.KEY_BOX, shapeCallback);
|
||||
DetailLog("{0},BSShapeCollection.CreateGeom,box,force={1},shape={2}",
|
||||
if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,box,force={1},shape={2}",
|
||||
prim.LocalID, forceRebuild, prim.PhysShape);
|
||||
}
|
||||
}
|
||||
|
@ -504,13 +511,13 @@ public sealed class BSShapeCollection : IDisposable
|
|||
{
|
||||
// Update prim.BSShape to reference a hull of this shape.
|
||||
ret = GetReferenceToHull(prim,shapeCallback);
|
||||
DetailLog("{0},BSShapeCollection.CreateGeom,hull,shape={1},key={2}",
|
||||
if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,hull,shape={1},key={2}",
|
||||
prim.LocalID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = GetReferenceToMesh(prim, shapeCallback);
|
||||
DetailLog("{0},BSShapeCollection.CreateGeom,mesh,shape={1},key={2}",
|
||||
if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,mesh,shape={1},key={2}",
|
||||
prim.LocalID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X"));
|
||||
}
|
||||
return ret;
|
||||
|
@ -528,7 +535,7 @@ public sealed class BSShapeCollection : IDisposable
|
|||
BulletShape newShape = BuildPhysicalNativeShape(prim, shapeType, shapeKey);
|
||||
|
||||
// Don't need to do a 'ReferenceShape()' here because native shapes are not shared.
|
||||
DetailLog("{0},BSShapeCollection.AddNativeShapeToPrim,create,newshape={1},scale={2}",
|
||||
if (DDetail) DetailLog("{0},BSShapeCollection.AddNativeShapeToPrim,create,newshape={1},scale={2}",
|
||||
prim.LocalID, newShape, prim.Scale);
|
||||
|
||||
prim.PhysShape = newShape;
|
||||
|
@ -554,7 +561,7 @@ public sealed class BSShapeCollection : IDisposable
|
|||
newShape = new BulletShape(
|
||||
BulletSimAPI.BuildCapsuleShape2(PhysicsScene.World.ptr, 1f, 1f, prim.Scale)
|
||||
, shapeType);
|
||||
DetailLog("{0},BSShapeCollection.BuiletPhysicalNativeShape,capsule,scale={1}", prim.LocalID, prim.Scale);
|
||||
if (DDetail) DetailLog("{0},BSShapeCollection.BuiletPhysicalNativeShape,capsule,scale={1}", prim.LocalID, prim.Scale);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -589,7 +596,7 @@ public sealed class BSShapeCollection : IDisposable
|
|||
if (newMeshKey == prim.PhysShape.shapeKey && prim.PhysShape.type == BSPhysicsShapeType.SHAPE_MESH)
|
||||
return false;
|
||||
|
||||
DetailLog("{0},BSShapeCollection.GetReferenceToMesh,create,oldKey={1},newKey={2}",
|
||||
if (DDetail) DetailLog("{0},BSShapeCollection.GetReferenceToMesh,create,oldKey={1},newKey={2}",
|
||||
prim.LocalID, prim.PhysShape.shapeKey.ToString("X"), newMeshKey.ToString("X"));
|
||||
|
||||
// Since we're recreating new, get rid of the reference to the previous shape
|
||||
|
@ -662,7 +669,7 @@ public sealed class BSShapeCollection : IDisposable
|
|||
if (newHullKey == prim.PhysShape.shapeKey && prim.PhysShape.type == BSPhysicsShapeType.SHAPE_HULL)
|
||||
return false;
|
||||
|
||||
DetailLog("{0},BSShapeCollection.GetReferenceToHull,create,oldKey={1},newKey={2}",
|
||||
if (DDetail) DetailLog("{0},BSShapeCollection.GetReferenceToHull,create,oldKey={1},newKey={2}",
|
||||
prim.LocalID, prim.PhysShape.shapeKey.ToString("X"), newHullKey.ToString("X"));
|
||||
|
||||
// Remove usage of the previous shape.
|
||||
|
@ -808,7 +815,7 @@ public sealed class BSShapeCollection : IDisposable
|
|||
// Create the shape for the root prim and add it to the compound shape. Cannot be a native shape.
|
||||
CreateGeomMeshOrHull(prim, shapeCallback);
|
||||
BulletSimAPI.AddChildShapeToCompoundShape2(cShape.ptr, prim.PhysShape.ptr, OMV.Vector3.Zero, OMV.Quaternion.Identity);
|
||||
DetailLog("{0},BSShapeCollection.GetReferenceToCompoundShape,addRootPrim,compShape={1},rootShape={2}",
|
||||
if (DDetail) DetailLog("{0},BSShapeCollection.GetReferenceToCompoundShape,addRootPrim,compShape={1},rootShape={2}",
|
||||
prim.LocalID, cShape, prim.PhysShape);
|
||||
|
||||
prim.PhysShape = cShape;
|
||||
|
@ -935,13 +942,13 @@ public sealed class BSShapeCollection : IDisposable
|
|||
{
|
||||
bodyPtr = BulletSimAPI.CreateBodyFromShape2(sim.ptr, shape.ptr,
|
||||
prim.LocalID, prim.RawPosition, prim.RawOrientation);
|
||||
DetailLog("{0},BSShapeCollection.CreateBody,mesh,ptr={1}", prim.LocalID, bodyPtr.ToString("X"));
|
||||
if (DDetail) DetailLog("{0},BSShapeCollection.CreateBody,mesh,ptr={1}", prim.LocalID, bodyPtr.ToString("X"));
|
||||
}
|
||||
else
|
||||
{
|
||||
bodyPtr = BulletSimAPI.CreateGhostFromShape2(sim.ptr, shape.ptr,
|
||||
prim.LocalID, prim.RawPosition, prim.RawOrientation);
|
||||
DetailLog("{0},BSShapeCollection.CreateBody,ghost,ptr={1}", prim.LocalID, bodyPtr.ToString("X"));
|
||||
if (DDetail) DetailLog("{0},BSShapeCollection.CreateBody,ghost,ptr={1}", prim.LocalID, bodyPtr.ToString("X"));
|
||||
}
|
||||
aBody = new BulletBody(prim.LocalID, bodyPtr);
|
||||
|
||||
|
|
|
@ -360,6 +360,7 @@ public enum CollisionFlags : uint
|
|||
// Following used by BulletSim to control collisions and updates
|
||||
BS_SUBSCRIBE_COLLISION_EVENTS = 1 << 10,
|
||||
BS_FLOATS_ON_WATER = 1 << 11,
|
||||
BS_VEHICLE_COLLISIONS = 1 << 12,
|
||||
BS_NONE = 0,
|
||||
BS_ALL = 0xFFFFFFFF,
|
||||
|
||||
|
|
|
@ -6,14 +6,34 @@ CRASHES
|
|||
Causes many errors. Doesn't stop after first error with box shape.
|
||||
Eventually crashes when deleting the object.
|
||||
|
||||
BULLETSIM TODO LIST:
|
||||
VEHICLES TODO LIST:
|
||||
=================================================
|
||||
Neb car jiggling left and right
|
||||
Happens on terrain and any other mesh object. Flat cubes are much smoother.
|
||||
Vehicles (Move smoothly)
|
||||
Light cycle falling over when driving
|
||||
Light cycle not banking
|
||||
Do single prim vehicles don't seem to properly vehiclize.
|
||||
Gun sending shooter flying
|
||||
Add vehicle collisions so IsColliding is properly reported.
|
||||
Needed for banking, limitMotorUp, movementLimiting, ...
|
||||
Some vehicles should not be able to turn if no speed or off ground.
|
||||
For limitMotorUp, use raycast down to find if vehicle is in the air.
|
||||
Implement function efficiency for lineaar and angular motion.
|
||||
Should vehicle angular/linear movement friction happen after all the components
|
||||
or does it only apply to the basic movement?
|
||||
After getting off a vehicle, the root prim is phantom (can be walked through)
|
||||
Need to force a position update for the root prim after compound shape destruction
|
||||
Linkset explosion after three "rides" on Nebadon lite vehicle (LinksetConstraint)
|
||||
Implement referenceFrame for all the motion routines.
|
||||
Cannot edit/move a vehicle being ridden: it jumps back to the origional position.
|
||||
|
||||
BULLETSIM TODO LIST:
|
||||
=================================================
|
||||
Disable activity of passive linkset children.
|
||||
Since the linkset is a compound object, the old prims are left lying
|
||||
around and need to be phantomized so they don't collide, ...
|
||||
Scenes with hundred of thousands of static objects take a lot of physics CPU time.
|
||||
BSPrim.Force should set a continious force on the prim. The force should be
|
||||
applied each tick. Some limits?
|
||||
Single prim vehicles don't seem to properly vehiclize.
|
||||
Gun sending shooter flying.
|
||||
Collision margin (gap between physical objects lying on each other)
|
||||
Boundry checking (crashes related to crossing boundry)
|
||||
Add check for border edge position for avatars and objects.
|
||||
|
@ -28,10 +48,11 @@ Small physical objects do not interact correctly
|
|||
Add material type linkage and input all the material property definitions.
|
||||
Skeleton classes and table are in the sources but are not filled or used.
|
||||
Add PID motor for avatar movement (slow to stop, ...)
|
||||
Implement function efficiency for lineaar and angular motion.
|
||||
setForce should set a constant force. Different than AddImpulse.
|
||||
Implement raycast.
|
||||
Implement ShapeCollection.Dispose()
|
||||
Implement water as a plain so raycasting and collisions can happen with same.
|
||||
|
||||
After getting off a vehicle, the root prim is phantom (can be walked through)
|
||||
Need to force a position update for the root prim after compound shape destruction
|
||||
Find/remove avatar collision with ID=0.
|
||||
Test avatar walking up stairs. How does compare with SL.
|
||||
Radius of the capsule affects ability to climb edges.
|
||||
|
@ -39,19 +60,16 @@ Tune terrain/object friction to be closer to SL.
|
|||
Debounce avatar contact so legs don't keep folding up when standing.
|
||||
Implement LSL physics controls. Like STATUS_ROTATE_X.
|
||||
Add border extensions to terrain to help region crossings and objects leaving region.
|
||||
Linkset explosion after three "rides" on Nebadon lite vehicle (LinksetConstraint)
|
||||
|
||||
Speed up creation of large physical linksets
|
||||
For instance, sitting in Neb's car (130 prims) takes several seconds to become physical
|
||||
Performance test with lots of avatars. Can BulletSim support a thousand?
|
||||
Optimize collisions in C++: only send up to the object subscribed to collisions.
|
||||
Use collision subscription and remove the collsion(A,B) and collision(B,A)
|
||||
Check wheter SimMotionState needs large if statement (see TODO).
|
||||
Check whether SimMotionState needs large if statement (see TODO).
|
||||
|
||||
Implement 'top colliders' info.
|
||||
Avatar jump
|
||||
Implement meshes or just verify that they work.
|
||||
Do prim hash codes work for sculpties and meshes?
|
||||
Performance measurement and changes to make quicker.
|
||||
Implement detailed physics stats (GetStats()).
|
||||
|
||||
|
@ -67,8 +85,6 @@ Performance of closures and delegates for taint processing
|
|||
Is there are more efficient method of implementing pre and post step actions?
|
||||
See http://www.codeproject.com/Articles/29922/Weak-Events-in-C
|
||||
|
||||
Package Bullet source mods for Bullet internal stats output
|
||||
|
||||
Physics Arena central pyramid: why is one side permiable?
|
||||
|
||||
INTERNAL IMPROVEMENT/CLEANUP
|
||||
|
@ -85,33 +101,42 @@ Complete implemention of preStepActions
|
|||
Replace vehicle step call with prestep event.
|
||||
Is there a need for postStepActions? postStepTaints?
|
||||
Implement linkset by setting position of children when root updated. (LinksetManual)
|
||||
Linkset implementation using manual prim movement.
|
||||
LinkablePrim class? Would that simplify/centralize the linkset logic?
|
||||
Linkset implementation using manual prim movement.
|
||||
Linkset implementation using compound shapes.
|
||||
Compound shapes will need the LocalID in the shapes and collision
|
||||
processing to get it from there.
|
||||
BSScene.UpdateParameterSet() is broken. How to set params on objects?
|
||||
Remove HeightmapInfo from terrain specification.
|
||||
Since C++ code does not need terrain height, this structure et al are not needed.
|
||||
Add floating motor for BS_FLOATS_ON_WATER so prim and avatar will
|
||||
bob at the water level. BSPrim.PositionSanityCheck().
|
||||
|
||||
THREADING
|
||||
=================================================
|
||||
Do taint action immediately if not actually executing Bullet.
|
||||
Add lock around Bullet execution and just do taint actions if simulation is not happening.
|
||||
|
||||
DONE DONE DONE DONE
|
||||
=================================================
|
||||
Cleanup code in BSDynamics by using motors.
|
||||
Consider implementing terrain with a mesh rather than heightmap.
|
||||
Cleanup code in BSDynamics by using motors. (Resolution: started)
|
||||
Consider implementing terrain with a mesh rather than heightmap. (Resolution: done)
|
||||
Would have better and adjustable resolution.
|
||||
NOTDONE: Build terrain mesh so heighmap is height of the center of the square meter.
|
||||
SL and ODE define meter square as being at one corner with one diagional.
|
||||
Terrain as mesh.
|
||||
Build terrain mesh so heighmap is height of the center of the square meter.
|
||||
Resolution: NOT DONE: SL and ODE define meter square as being at one corner with one diagional.
|
||||
Terrain as mesh. (Resolution: done)
|
||||
How are static linksets seen by the physics engine?
|
||||
A: they are not linked in physics. When moved, all the children are repositioned.
|
||||
Remember to remove BSScene.DetailLog Refresh call.
|
||||
Convert BSCharacter to use all API2
|
||||
Resolution: they are not linked in physics. When moved, all the children are repositioned.
|
||||
Convert BSCharacter to use all API2 (Resolution: done)
|
||||
Avatar pushing difficult (too heavy?)
|
||||
Use asset service passed to BulletSim to get sculptie bodies, etc.
|
||||
Vehicles (fix bouncing on terrain)
|
||||
Remove old code in DLL (all non-API2 stuff).
|
||||
Measurements of mega-physical prim performance (with graph)
|
||||
Use asset service passed to BulletSim to get sculptie bodies, etc. (Resolution: done)
|
||||
Remove old code in DLL (all non-API2 stuff). (Resolution: done)
|
||||
Measurements of mega-physical prim performance (with graph) (Resolution: done, email)
|
||||
Debug Bullet internal stats output (why is timing all wrong?)
|
||||
Bullet stats logging only works with a single instance of Bullet (one region).
|
||||
Resolution: Bullet stats logging only works with a single instance of Bullet (one region).
|
||||
Implement meshes or just verify that they work. (Resolution: they do!)
|
||||
Do prim hash codes work for sculpties and meshes? (Resolution: yes)
|
||||
Linkset implementation using compound shapes. (Resolution: implemented LinksetCompound)
|
||||
Compound shapes will need the LocalID in the shapes and collision
|
||||
processing to get it from there.
|
||||
Light cycle falling over when driving (Resolution: implemented VerticalAttractor)
|
||||
Light cycle not banking (Resolution: It doesn't. Banking is roll adding yaw.)
|
||||
Package Bullet source mods for Bullet internal stats output
|
||||
(Resolution: move code into WorldData.h rather than relying on patches)
|
|
@ -1,5 +1,5 @@
|
|||
<configuration>
|
||||
<dllmap os="osx" dll="openjpeg-dotnet.dll" target="lib64/libopenjpeg-dotnet-2.1.5.0-dotnet-1.dylib" />
|
||||
<dllmap os="osx" dll="openjpeg-dotnet.dll" target="lib64/libopenjpeg-dotnet.dylib" />
|
||||
<dllmap os="!windows,osx" cpu="x86-64,ia64" dll="openjpeg-dotnet-x86_64.dll" target="lib64/libopenjpeg-dotnet-x86_64" />
|
||||
<dllmap os="!windows,osx" cpu="x86" dll="openjpeg-dotnet.dll" target="lib32/libopenjpeg-dotnet" />
|
||||
</configuration>
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue