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
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
|
* The quotations from http://wiki.secondlife.com/wiki/Linden_Vehicle_Tutorial
|
||||||
/* RA: June 14, 2011. Copied from ODEDynamics.cs and converted to
|
* are Copyright (c) 2009 Linden Research, Inc and are used under their license
|
||||||
* call the BulletSim system.
|
* of Creative Commons Attribution-Share Alike 3.0
|
||||||
*/
|
* (http://creativecommons.org/licenses/by-sa/3.0/).
|
||||||
/* 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.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
@ -111,7 +100,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
private float m_bankingEfficiency = 0;
|
private float m_bankingEfficiency = 0;
|
||||||
private float m_bankingMix = 0;
|
private float m_bankingMix = 0;
|
||||||
private float m_bankingTimescale = 0;
|
private float m_bankingTimescale = 0;
|
||||||
private Vector3 m_lastBanking = Vector3.Zero;
|
|
||||||
|
|
||||||
//Hover and Buoyancy properties
|
//Hover and Buoyancy properties
|
||||||
private float m_VhoverHeight = 0f;
|
private float m_VhoverHeight = 0f;
|
||||||
|
@ -126,7 +114,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
//Attractor properties
|
//Attractor properties
|
||||||
private BSVMotor m_verticalAttractionMotor = new BSVMotor("VerticalAttraction");
|
private BSVMotor m_verticalAttractionMotor = new BSVMotor("VerticalAttraction");
|
||||||
private float m_verticalAttractionEfficiency = 1.0f; // damped
|
private float m_verticalAttractionEfficiency = 1.0f; // damped
|
||||||
private float m_verticalAttractionTimescale = 600f; // Timescale > 500 means no vert attractor.
|
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)
|
public BSDynamics(BSScene myScene, BSPrim myPrim)
|
||||||
{
|
{
|
||||||
|
@ -329,7 +319,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
m_bankingEfficiency = 0;
|
m_bankingEfficiency = 0;
|
||||||
m_bankingTimescale = 1000;
|
m_bankingTimescale = 1000;
|
||||||
m_bankingMix = 1;
|
m_bankingMix = 1;
|
||||||
m_lastBanking = Vector3.Zero;
|
|
||||||
|
|
||||||
m_referenceFrame = Quaternion.Identity;
|
m_referenceFrame = Quaternion.Identity;
|
||||||
m_flags = (VehicleFlag)0;
|
m_flags = (VehicleFlag)0;
|
||||||
|
@ -364,7 +353,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
m_bankingEfficiency = 0;
|
m_bankingEfficiency = 0;
|
||||||
m_bankingTimescale = 10;
|
m_bankingTimescale = 10;
|
||||||
m_bankingMix = 1;
|
m_bankingMix = 1;
|
||||||
m_lastBanking = Vector3.Zero;
|
|
||||||
|
|
||||||
m_referenceFrame = Quaternion.Identity;
|
m_referenceFrame = Quaternion.Identity;
|
||||||
m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY
|
m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY
|
||||||
|
@ -374,6 +362,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
m_flags |= (VehicleFlag.NO_DEFLECTION_UP
|
m_flags |= (VehicleFlag.NO_DEFLECTION_UP
|
||||||
| VehicleFlag.LIMIT_ROLL_ONLY
|
| VehicleFlag.LIMIT_ROLL_ONLY
|
||||||
| VehicleFlag.LIMIT_MOTOR_UP);
|
| VehicleFlag.LIMIT_MOTOR_UP);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case Vehicle.TYPE_CAR:
|
case Vehicle.TYPE_CAR:
|
||||||
m_linearMotorDirection = Vector3.Zero;
|
m_linearMotorDirection = Vector3.Zero;
|
||||||
|
@ -403,7 +392,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
m_bankingEfficiency = -0.2f;
|
m_bankingEfficiency = -0.2f;
|
||||||
m_bankingMix = 1;
|
m_bankingMix = 1;
|
||||||
m_bankingTimescale = 1;
|
m_bankingTimescale = 1;
|
||||||
m_lastBanking = Vector3.Zero;
|
|
||||||
|
|
||||||
m_referenceFrame = Quaternion.Identity;
|
m_referenceFrame = Quaternion.Identity;
|
||||||
m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY
|
m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY
|
||||||
|
@ -442,7 +430,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
m_bankingEfficiency = -0.3f;
|
m_bankingEfficiency = -0.3f;
|
||||||
m_bankingMix = 0.8f;
|
m_bankingMix = 0.8f;
|
||||||
m_bankingTimescale = 1;
|
m_bankingTimescale = 1;
|
||||||
m_lastBanking = Vector3.Zero;
|
|
||||||
|
|
||||||
m_referenceFrame = Quaternion.Identity;
|
m_referenceFrame = Quaternion.Identity;
|
||||||
m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY
|
m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY
|
||||||
|
@ -481,7 +468,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
m_bankingEfficiency = 1;
|
m_bankingEfficiency = 1;
|
||||||
m_bankingMix = 0.7f;
|
m_bankingMix = 0.7f;
|
||||||
m_bankingTimescale = 2;
|
m_bankingTimescale = 2;
|
||||||
m_lastBanking = Vector3.Zero;
|
|
||||||
|
|
||||||
m_referenceFrame = Quaternion.Identity;
|
m_referenceFrame = Quaternion.Identity;
|
||||||
m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY
|
m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY
|
||||||
|
@ -520,7 +506,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
m_bankingEfficiency = 0;
|
m_bankingEfficiency = 0;
|
||||||
m_bankingMix = 0.7f;
|
m_bankingMix = 0.7f;
|
||||||
m_bankingTimescale = 5;
|
m_bankingTimescale = 5;
|
||||||
m_lastBanking = Vector3.Zero;
|
|
||||||
|
|
||||||
m_referenceFrame = Quaternion.Identity;
|
m_referenceFrame = Quaternion.Identity;
|
||||||
|
|
||||||
|
@ -554,8 +539,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
// Z goes away and we keep X and Y
|
// Z goes away and we keep X and Y
|
||||||
m_verticalAttractionMotor.FrictionTimescale = new Vector3(BSMotor.Infinite, BSMotor.Infinite, 0.1f);
|
m_verticalAttractionMotor.FrictionTimescale = new Vector3(BSMotor.Infinite, BSMotor.Infinite, 0.1f);
|
||||||
m_verticalAttractionMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging)
|
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.
|
// Some of the properties of this prim may have changed.
|
||||||
|
@ -577,15 +560,23 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
float angularDamping = PhysicsScene.Params.vehicleAngularDamping;
|
float angularDamping = PhysicsScene.Params.vehicleAngularDamping;
|
||||||
BulletSimAPI.SetAngularDamping2(Prim.PhysBody.ptr, angularDamping);
|
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
|
// DEBUG DEBUG DEBUG: use uniform inertia to smooth movement added by Bullet
|
||||||
// Vector3 localInertia = new Vector3(1f, 1f, 1f);
|
// 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.SetMassProps2(Prim.PhysBody.ptr, m_vehicleMass, localInertia);
|
||||||
BulletSimAPI.UpdateInertiaTensor2(Prim.PhysBody.ptr);
|
BulletSimAPI.UpdateInertiaTensor2(Prim.PhysBody.ptr);
|
||||||
|
|
||||||
VDetailLog("{0},BSDynamics.Refresh,frict={1},inert={2},aDamp={3}",
|
VDetailLog("{0},BSDynamics.Refresh,frict={1},inert={2},aDamp={3}",
|
||||||
Prim.LocalID, friction, localInertia, angularDamping);
|
Prim.LocalID, friction, localInertia, angularDamping);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BulletSimAPI.RemoveFromCollisionFlags2(Prim.PhysBody.ptr, CollisionFlags.BS_VEHICLE_COLLISIONS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool RemoveBodyDependencies(BSPhysObject prim)
|
public bool RemoveBodyDependencies(BSPhysObject prim)
|
||||||
|
@ -618,13 +609,18 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
private float? m_knownWaterLevel;
|
private float? m_knownWaterLevel;
|
||||||
private Vector3? m_knownPosition;
|
private Vector3? m_knownPosition;
|
||||||
private Vector3? m_knownVelocity;
|
private Vector3? m_knownVelocity;
|
||||||
|
private Vector3 m_knownForce;
|
||||||
private Quaternion? m_knownOrientation;
|
private Quaternion? m_knownOrientation;
|
||||||
private Vector3? m_knownRotationalVelocity;
|
private Vector3? m_knownRotationalVelocity;
|
||||||
|
private Vector3 m_knownRotationalForce;
|
||||||
|
private float? m_knownForwardSpeed;
|
||||||
|
|
||||||
private const int m_knownChangedPosition = 1 << 0;
|
private const int m_knownChangedPosition = 1 << 0;
|
||||||
private const int m_knownChangedVelocity = 1 << 1;
|
private const int m_knownChangedVelocity = 1 << 1;
|
||||||
private const int m_knownChangedOrientation = 1 << 2;
|
private const int m_knownChangedForce = 1 << 2;
|
||||||
private const int m_knownChangedRotationalVelocity = 1 << 3;
|
private const int m_knownChangedOrientation = 1 << 3;
|
||||||
|
private const int m_knownChangedRotationalVelocity = 1 << 4;
|
||||||
|
private const int m_knownChangedRotationalForce = 1 << 5;
|
||||||
|
|
||||||
private void ForgetKnownVehicleProperties()
|
private void ForgetKnownVehicleProperties()
|
||||||
{
|
{
|
||||||
|
@ -632,8 +628,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
m_knownWaterLevel = null;
|
m_knownWaterLevel = null;
|
||||||
m_knownPosition = null;
|
m_knownPosition = null;
|
||||||
m_knownVelocity = null;
|
m_knownVelocity = null;
|
||||||
|
m_knownForce = Vector3.Zero;
|
||||||
m_knownOrientation = null;
|
m_knownOrientation = null;
|
||||||
m_knownRotationalVelocity = null;
|
m_knownRotationalVelocity = null;
|
||||||
|
m_knownRotationalForce = Vector3.Zero;
|
||||||
|
m_knownForwardSpeed = null;
|
||||||
m_knownChanged = 0;
|
m_knownChanged = 0;
|
||||||
}
|
}
|
||||||
private void PushKnownChanged()
|
private void PushKnownChanged()
|
||||||
|
@ -645,12 +644,22 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
if ((m_knownChanged & m_knownChangedOrientation) != 0)
|
if ((m_knownChanged & m_knownChangedOrientation) != 0)
|
||||||
Prim.ForceOrientation = VehicleOrientation;
|
Prim.ForceOrientation = VehicleOrientation;
|
||||||
if ((m_knownChanged & m_knownChangedVelocity) != 0)
|
if ((m_knownChanged & m_knownChangedVelocity) != 0)
|
||||||
|
{
|
||||||
Prim.ForceVelocity = VehicleVelocity;
|
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)
|
if ((m_knownChanged & m_knownChangedRotationalVelocity) != 0)
|
||||||
{
|
{
|
||||||
Prim.ForceRotationalVelocity = VehicleRotationalVelocity;
|
Prim.ForceRotationalVelocity = VehicleRotationalVelocity;
|
||||||
|
// Fake out Bullet by making it think the velocity is the same as last time.
|
||||||
BulletSimAPI.SetInterpolationAngularVelocity2(Prim.PhysBody.ptr, VehicleRotationalVelocity);
|
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
|
// 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.
|
// an UpdateProperties event to send the changes up to the simulator.
|
||||||
BulletSimAPI.PushUpdate2(Prim.PhysBody.ptr);
|
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
|
private Vector3 VehicleRotationalVelocity
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
@ -734,6 +749,21 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
m_knownChanged |= m_knownChangedRotationalVelocity;
|
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
|
#endregion // Known vehicle value functions
|
||||||
|
|
||||||
// One step of the vehicle properties for the next 'pTimestep' seconds.
|
// One step of the vehicle properties for the next 'pTimestep' seconds.
|
||||||
|
@ -769,10 +799,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
linearMotorContribution *= VehicleOrientation;
|
linearMotorContribution *= VehicleOrientation;
|
||||||
|
|
||||||
// ==================================================================
|
// ==================================================================
|
||||||
// Gravity and Buoyancy
|
// Buoyancy: force to overcome gravity.
|
||||||
// There is some gravity, make a gravity force vector that is applied after object velocity.
|
|
||||||
// m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g;
|
// m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g;
|
||||||
Vector3 grav = Prim.PhysicsScene.DefaultGravity * (1f - m_VehicleBuoyancy);
|
// 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);
|
Vector3 terrainHeightContribution = ComputeLinearTerrainHeightCorrection(pTimestep);
|
||||||
|
|
||||||
|
@ -797,14 +827,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
newVelocity.Z = 0;
|
newVelocity.Z = 0;
|
||||||
|
|
||||||
// ==================================================================
|
// ==================================================================
|
||||||
// Clamp REALLY high or low velocities
|
// Clamp high or low velocities
|
||||||
float newVelocityLengthSq = newVelocity.LengthSquared();
|
float newVelocityLengthSq = newVelocity.LengthSquared();
|
||||||
if (newVelocityLengthSq > 1e6f)
|
// if (newVelocityLengthSq > 1e6f)
|
||||||
|
if (newVelocityLengthSq > 1000f)
|
||||||
{
|
{
|
||||||
newVelocity /= newVelocity.Length();
|
newVelocity /= newVelocity.Length();
|
||||||
newVelocity *= 1000f;
|
newVelocity *= 1000f;
|
||||||
}
|
}
|
||||||
else if (newVelocityLengthSq < 1e-6f)
|
// else if (newVelocityLengthSq < 1e-6f)
|
||||||
|
else if (newVelocityLengthSq < 0.001f)
|
||||||
newVelocity = Vector3.Zero;
|
newVelocity = Vector3.Zero;
|
||||||
|
|
||||||
// ==================================================================
|
// ==================================================================
|
||||||
|
@ -813,15 +845,18 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
VehicleVelocity = newVelocity;
|
VehicleVelocity = newVelocity;
|
||||||
|
|
||||||
// Other linear forces are applied as forces.
|
// Other linear forces are applied as forces.
|
||||||
Vector3 totalDownForce = grav * m_vehicleMass * pTimestep;
|
Vector3 totalDownForce = buoyancyContribution * m_vehicleMass;
|
||||||
if (totalDownForce != Vector3.Zero)
|
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}",
|
VDetailLog("{0}, MoveLinear,done,newVel={1},totDown={2},IsColliding={3}",
|
||||||
Prim.LocalID, newVelocity, totalDownForce,
|
Prim.LocalID, newVelocity, totalDownForce, Prim.IsColliding);
|
||||||
linearMotorContribution, terrainHeightContribution, hoverContribution, limitMotorUpContribution
|
VDetailLog("{0}, MoveLinear,done,linContrib={1},terrContrib={2},hoverContrib={3},limitContrib={4},buoyContrib={5}",
|
||||||
|
Prim.LocalID,
|
||||||
|
linearMotorContribution, terrainHeightContribution, hoverContribution,
|
||||||
|
limitMotorUpContribution, buoyancyContribution
|
||||||
);
|
);
|
||||||
|
|
||||||
} // end MoveLinear()
|
} // end MoveLinear()
|
||||||
|
@ -947,16 +982,19 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
// vehicle no longer experiences collisions. The decay timescale is the same as
|
// vehicle no longer experiences collisions. The decay timescale is the same as
|
||||||
// VEHICLE_BANKING_TIMESCALE. This is to help prevent ground vehicles from steering
|
// VEHICLE_BANKING_TIMESCALE. This is to help prevent ground vehicles from steering
|
||||||
// when they are in mid jump.
|
// 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)
|
public Vector3 ComputeLinearMotorUp(float pTimestep)
|
||||||
{
|
{
|
||||||
Vector3 ret = Vector3.Zero;
|
Vector3 ret = Vector3.Zero;
|
||||||
|
|
||||||
if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0)
|
if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0)
|
||||||
{
|
{
|
||||||
// If the vehicle is motoring into the sky, get it going back down.
|
// If the vehicle is motoring into the sky, get it going back down.
|
||||||
// float distanceAboveGround = pos.Z - Math.Max(GetTerrainHeight(pos), GetWaterLevel(pos));
|
|
||||||
float distanceAboveGround = VehiclePosition.Z - GetTerrainHeight(VehiclePosition);
|
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) * pTimestep);
|
||||||
// downForce = new Vector3(0, 0, -distanceAboveGround / m_bankingTimescale);
|
// downForce = new Vector3(0, 0, -distanceAboveGround / m_bankingTimescale);
|
||||||
|
@ -977,8 +1015,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
// Apply the effect of the angular motor.
|
// Apply the effect of the angular motor.
|
||||||
// The 'contribution' is how much angular correction velocity each function wants.
|
// The 'contribution' is how much angular correction velocity each function wants.
|
||||||
// All the contributions are added together and the orientation of the vehicle
|
// All the contributions are added together and the resulting velocity is
|
||||||
// is changed by all the contributed corrections.
|
// set directly on the vehicle.
|
||||||
private void MoveAngular(float pTimestep)
|
private void MoveAngular(float pTimestep)
|
||||||
{
|
{
|
||||||
// The user wants how many radians per second angular change?
|
// The user wants how many radians per second angular change?
|
||||||
|
@ -1001,7 +1039,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
|
|
||||||
Vector3 deflectionContribution = ComputeAngularDeflection();
|
Vector3 deflectionContribution = ComputeAngularDeflection();
|
||||||
|
|
||||||
Vector3 bankingContribution = ComputeAngularBanking(angularMotorContribution.Z);
|
Vector3 bankingContribution = ComputeAngularBanking();
|
||||||
|
|
||||||
// ==================================================================
|
// ==================================================================
|
||||||
m_lastVertAttractor = verticalAttractionContribution;
|
m_lastVertAttractor = verticalAttractionContribution;
|
||||||
|
@ -1013,11 +1051,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
+ bankingContribution;
|
+ 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))
|
if (!m_lastAngularCorrection.ApproxEquals(Vector3.Zero, 0.01f))
|
||||||
{
|
{
|
||||||
Vector3 scaledCorrection = m_lastAngularCorrection * pTimestep;
|
Vector3 scaledCorrection = m_lastAngularCorrection * pTimestep;
|
||||||
|
|
||||||
VehicleRotationalVelocity = scaledCorrection;
|
VehicleRotationalVelocity = scaledCorrection;
|
||||||
|
|
||||||
VDetailLog("{0}, MoveAngular,done,nonZero,angMotorContrib={1},vertAttrContrib={2},bankContrib={3},deflectContrib={4},totalContrib={5},scaledCorr={6}",
|
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
|
else
|
||||||
{
|
{
|
||||||
// The vehicle is not adding anything velocity wise.
|
// The vehicle is not adding anything angular wise.
|
||||||
VehicleRotationalVelocity = Vector3.Zero;
|
VehicleRotationalVelocity = Vector3.Zero;
|
||||||
VDetailLog("{0}, MoveAngular,done,zero", Prim.LocalID);
|
VDetailLog("{0}, MoveAngular,done,zero", Prim.LocalID);
|
||||||
}
|
}
|
||||||
|
@ -1060,19 +1098,26 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
torqueFromOffset.Y = 0;
|
torqueFromOffset.Y = 0;
|
||||||
if (float.IsNaN(torqueFromOffset.Z))
|
if (float.IsNaN(torqueFromOffset.Z))
|
||||||
torqueFromOffset.Z = 0;
|
torqueFromOffset.Z = 0;
|
||||||
torqueFromOffset *= m_vehicleMass;
|
|
||||||
Prim.ApplyTorqueImpulse(torqueFromOffset, true);
|
VehicleAddAngularForce(torqueFromOffset * m_vehicleMass);
|
||||||
VDetailLog("{0}, BSDynamic.MoveAngular,motorOffset,applyTorqueImpulse={1}", Prim.LocalID, torqueFromOffset);
|
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()
|
public Vector3 ComputeAngularVerticalAttraction()
|
||||||
{
|
{
|
||||||
Vector3 ret = Vector3.Zero;
|
Vector3 ret = Vector3.Zero;
|
||||||
|
|
||||||
// If vertical attaction timescale is reasonable and we applied an angular force last time...
|
// If vertical attaction timescale is reasonable and we applied an angular force last time...
|
||||||
if (m_verticalAttractionTimescale < 500)
|
if (m_verticalAttractionTimescale < m_verticalAttractionCutoff)
|
||||||
{
|
{
|
||||||
// Take a vector pointing up and convert it from world to vehicle relative coords.
|
// Take a vector pointing up and convert it from world to vehicle relative coords.
|
||||||
Vector3 verticalError = Vector3.UnitZ * VehicleOrientation;
|
Vector3 verticalError = Vector3.UnitZ * VehicleOrientation;
|
||||||
|
@ -1097,91 +1142,121 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
ret.Y = - verticalError.X;
|
ret.Y = - verticalError.X;
|
||||||
ret.Z = 0f;
|
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;
|
Vector3 unscaledContrib = ret;
|
||||||
ret /= m_verticalAttractionTimescale;
|
ret /= m_verticalAttractionTimescale;
|
||||||
// This returns the angular correction desired. Timestep is added later.
|
|
||||||
// ret *= pTimestep;
|
|
||||||
|
|
||||||
// apply efficiency
|
VDetailLog("{0}, MoveAngular,verticalAttraction,,verticalError={1},unscaled={2},vertForce={3},eff={4},vertAttr={5}",
|
||||||
Vector3 preEfficiencyContrib = ret;
|
Prim.LocalID, verticalError, unscaledContrib, vertForce, m_verticalAttractionEfficiency, 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);
|
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the angular correction to correct the direction the vehicle is pointing to be
|
// Return the angular correction to correct the direction the vehicle is pointing to be
|
||||||
// the direction is should want to be pointing.
|
// 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()
|
public Vector3 ComputeAngularDeflection()
|
||||||
{
|
{
|
||||||
Vector3 ret = Vector3.Zero;
|
Vector3 ret = Vector3.Zero;
|
||||||
|
return ret; // DEBUG DEBUG DEBUG debug one force at a time
|
||||||
|
|
||||||
if (m_angularDeflectionEfficiency != 0)
|
if (m_angularDeflectionEfficiency != 0)
|
||||||
{
|
{
|
||||||
// Where the vehicle should want to point relative to the vehicle
|
// The direction the vehicle is moving
|
||||||
Vector3 preferredDirection = Vector3.UnitX * m_referenceFrame;
|
Vector3 movingDirection = VehicleVelocity;
|
||||||
|
movingDirection.Normalize();
|
||||||
|
|
||||||
// Where the vehicle is pointing relative to the vehicle.
|
// The direction the vehicle is pointing
|
||||||
Vector3 currentDirection = Vector3.UnitX * Quaternion.Add(VehicleOrientation, m_referenceFrame);
|
Vector3 pointingDirection = Vector3.UnitX * VehicleOrientation;
|
||||||
|
pointingDirection.Normalize();
|
||||||
|
|
||||||
// Difference between where vehicle is pointing and where it should wish to point
|
// The difference between what is and what should be
|
||||||
Vector3 directionCorrection = preferredDirection - currentDirection;
|
Vector3 deflectionError = movingDirection - pointingDirection;
|
||||||
|
|
||||||
// Scale the correction by recovery timescale and efficiency
|
// 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}",
|
VDetailLog("{0}, MoveAngular,Deflection,movingDir={1},pointingDir={2},deflectError={3},ret={4}",
|
||||||
Prim.LocalID, preferredDirection, currentDirection, directionCorrection, ret);
|
Prim.LocalID, movingDirection, pointingDirection, deflectionError, ret);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return an angular change to tip the vehicle (around X axis) when turning (turned around Z).
|
// Return an angular change to rotate the vehicle around the Z axis when the vehicle
|
||||||
// Remembers the last banking value calculated and returns the difference needed this tick.
|
// is tipped around the X axis.
|
||||||
// TurningFactor is rate going left or right (pos=left, neg=right, scale=0..1).
|
// From http://wiki.secondlife.com/wiki/Linden_Vehicle_Tutorial:
|
||||||
public Vector3 ComputeAngularBanking(float turningFactor)
|
// 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 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
|
// TODO: there must be a better computation of the banking force.
|
||||||
float effSquared = (m_bankingEfficiency * m_bankingEfficiency);
|
float bankingTurnForce = turnComponent;
|
||||||
if (m_bankingEfficiency < 0)
|
|
||||||
effSquared *= -1; //Keep the negative!
|
|
||||||
|
|
||||||
float mix = Math.Abs(m_bankingMix);
|
// actual error = static turn error + dynamic turn error
|
||||||
// TODO: Must include reference frame.
|
float mixedBankingError = bankingTurnForce * (1f - m_bankingMix) + bankingTurnForce * m_bankingMix * VehicleForwardSpeed;
|
||||||
float forwardSpeed = VehicleVelocity.X;
|
// 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)
|
// Build the force vector to change rotation from what it is to what it should be
|
||||||
{
|
ret.Z = -mixedBankingError;
|
||||||
computedBanking.X = ClampInRange(-3f, turningFactor * (effSquared * mult), 3f);
|
|
||||||
|
// Don't do it all at once.
|
||||||
|
ret /= m_bankingTimescale;
|
||||||
|
|
||||||
|
VDetailLog("{0}, MoveAngular,Banking,rollComp={1},speed={2},turnComp={3},bankErr={4},mixedBankErr={5},ret={6}",
|
||||||
|
Prim.LocalID, rollComponents, VehicleForwardSpeed, turnComponent, bankingTurnForce, mixedBankingError, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 'computedBanking' is now how much banking that should be happening.
|
|
||||||
ret = computedBanking - m_lastBanking;
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
m_lastBanking = computedBanking;
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
*
|
*
|
||||||
|
@ -53,24 +53,19 @@ public struct MaterialAttributes
|
||||||
// Names must be in the order of the above enum.
|
// Names must be in the order of the above enum.
|
||||||
public static string[] MaterialNames = { "Stone", "Metal", "Glass", "Wood",
|
public static string[] MaterialNames = { "Stone", "Metal", "Glass", "Wood",
|
||||||
"Flesh", "Plastic", "Rubber", "Light", "Avatar" };
|
"Flesh", "Plastic", "Rubber", "Light", "Avatar" };
|
||||||
public static string[] MaterialAttribs = { "Density", "Friction", "Restitution",
|
public static string[] MaterialAttribs = { "Density", "Friction", "Restitution"};
|
||||||
"ccdMotionThreshold", "ccdSweptSphereRadius" };
|
|
||||||
|
|
||||||
public MaterialAttributes(string t, float d, float f, float r, float ccdM, float ccdS)
|
public MaterialAttributes(string t, float d, float f, float r)
|
||||||
{
|
{
|
||||||
type = t;
|
type = t;
|
||||||
density = d;
|
density = d;
|
||||||
friction = f;
|
friction = f;
|
||||||
restitution = r;
|
restitution = r;
|
||||||
ccdMotionThreshold = ccdM;
|
|
||||||
ccdSweptSphereRadius = ccdS;
|
|
||||||
}
|
}
|
||||||
public string type;
|
public string type;
|
||||||
public float density;
|
public float density;
|
||||||
public float friction;
|
public float friction;
|
||||||
public float restitution;
|
public float restitution;
|
||||||
public float ccdMotionThreshold;
|
|
||||||
public float ccdSweptSphereRadius;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class BSMaterials
|
public static class BSMaterials
|
||||||
|
@ -86,50 +81,49 @@ public static class BSMaterials
|
||||||
// This is where all the default material attributes are defined.
|
// This is where all the default material attributes are defined.
|
||||||
public static void InitializeFromDefaults(ConfigurationParameters parms)
|
public static void InitializeFromDefaults(ConfigurationParameters parms)
|
||||||
{
|
{
|
||||||
|
// Values from http://wiki.secondlife.com/wiki/PRIM_MATERIAL
|
||||||
// public static string[] MaterialNames = { "Stone", "Metal", "Glass", "Wood",
|
// public static string[] MaterialNames = { "Stone", "Metal", "Glass", "Wood",
|
||||||
// "Flesh", "Plastic", "Rubber", "Light", "Avatar" };
|
// "Flesh", "Plastic", "Rubber", "Light", "Avatar" };
|
||||||
float dFriction = parms.defaultFriction;
|
float dFriction = parms.defaultFriction;
|
||||||
float dRestitution = parms.defaultRestitution;
|
float dRestitution = parms.defaultRestitution;
|
||||||
float dDensity = parms.defaultDensity;
|
float dDensity = parms.defaultDensity;
|
||||||
float dCcdM = parms.ccdMotionThreshold;
|
|
||||||
float dCcdS = parms.ccdSweptSphereRadius;
|
|
||||||
Attributes[(int)MaterialAttributes.Material.Stone] =
|
Attributes[(int)MaterialAttributes.Material.Stone] =
|
||||||
new MaterialAttributes("stone",dDensity,dFriction,dRestitution, dCcdM, dCcdS);
|
new MaterialAttributes("stone",dDensity, 0.8f, 0.4f);
|
||||||
Attributes[(int)MaterialAttributes.Material.Metal] =
|
Attributes[(int)MaterialAttributes.Material.Metal] =
|
||||||
new MaterialAttributes("metal",dDensity,dFriction,dRestitution, dCcdM, dCcdS);
|
new MaterialAttributes("metal",dDensity, 0.3f, 0.4f);
|
||||||
Attributes[(int)MaterialAttributes.Material.Glass] =
|
Attributes[(int)MaterialAttributes.Material.Glass] =
|
||||||
new MaterialAttributes("glass",dDensity,dFriction,dRestitution, dCcdM, dCcdS);
|
new MaterialAttributes("glass",dDensity, 0.2f, 0.7f);
|
||||||
Attributes[(int)MaterialAttributes.Material.Wood] =
|
Attributes[(int)MaterialAttributes.Material.Wood] =
|
||||||
new MaterialAttributes("wood",dDensity,dFriction,dRestitution, dCcdM, dCcdS);
|
new MaterialAttributes("wood",dDensity, 0.6f, 0.5f);
|
||||||
Attributes[(int)MaterialAttributes.Material.Flesh] =
|
Attributes[(int)MaterialAttributes.Material.Flesh] =
|
||||||
new MaterialAttributes("flesh",dDensity,dFriction,dRestitution, dCcdM, dCcdS);
|
new MaterialAttributes("flesh",dDensity, 0.9f, 0.3f);
|
||||||
Attributes[(int)MaterialAttributes.Material.Plastic] =
|
Attributes[(int)MaterialAttributes.Material.Plastic] =
|
||||||
new MaterialAttributes("plastic",dDensity,dFriction,dRestitution, dCcdM, dCcdS);
|
new MaterialAttributes("plastic",dDensity, 0.4f, 0.7f);
|
||||||
Attributes[(int)MaterialAttributes.Material.Rubber] =
|
Attributes[(int)MaterialAttributes.Material.Rubber] =
|
||||||
new MaterialAttributes("rubber",dDensity,dFriction,dRestitution, dCcdM, dCcdS);
|
new MaterialAttributes("rubber",dDensity, 0.9f, 0.9f);
|
||||||
Attributes[(int)MaterialAttributes.Material.Light] =
|
Attributes[(int)MaterialAttributes.Material.Light] =
|
||||||
new MaterialAttributes("light",dDensity,dFriction,dRestitution, dCcdM, dCcdS);
|
new MaterialAttributes("light",dDensity, dFriction, dRestitution);
|
||||||
Attributes[(int)MaterialAttributes.Material.Avatar] =
|
Attributes[(int)MaterialAttributes.Material.Avatar] =
|
||||||
new MaterialAttributes("avatar",dDensity,dFriction,dRestitution, dCcdM, dCcdS);
|
new MaterialAttributes("avatar",60f, 0.2f, 0f);
|
||||||
|
|
||||||
Attributes[(int)MaterialAttributes.Material.Stone + (int)MaterialAttributes.Material.NumberOfTypes] =
|
Attributes[(int)MaterialAttributes.Material.Stone + (int)MaterialAttributes.Material.NumberOfTypes] =
|
||||||
new MaterialAttributes("stonePhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS);
|
new MaterialAttributes("stonePhysical",dDensity, 0.8f, 0.4f);
|
||||||
Attributes[(int)MaterialAttributes.Material.Metal + (int)MaterialAttributes.Material.NumberOfTypes] =
|
Attributes[(int)MaterialAttributes.Material.Metal + (int)MaterialAttributes.Material.NumberOfTypes] =
|
||||||
new MaterialAttributes("metalPhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS);
|
new MaterialAttributes("metalPhysical",dDensity, 0.8f, 0.4f);
|
||||||
Attributes[(int)MaterialAttributes.Material.Glass + (int)MaterialAttributes.Material.NumberOfTypes] =
|
Attributes[(int)MaterialAttributes.Material.Glass + (int)MaterialAttributes.Material.NumberOfTypes] =
|
||||||
new MaterialAttributes("glassPhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS);
|
new MaterialAttributes("glassPhysical",dDensity, 0.8f, 0.7f);
|
||||||
Attributes[(int)MaterialAttributes.Material.Wood + (int)MaterialAttributes.Material.NumberOfTypes] =
|
Attributes[(int)MaterialAttributes.Material.Wood + (int)MaterialAttributes.Material.NumberOfTypes] =
|
||||||
new MaterialAttributes("woodPhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS);
|
new MaterialAttributes("woodPhysical",dDensity, 0.8f, 0.5f);
|
||||||
Attributes[(int)MaterialAttributes.Material.Flesh + (int)MaterialAttributes.Material.NumberOfTypes] =
|
Attributes[(int)MaterialAttributes.Material.Flesh + (int)MaterialAttributes.Material.NumberOfTypes] =
|
||||||
new MaterialAttributes("fleshPhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS);
|
new MaterialAttributes("fleshPhysical",dDensity, 0.8f, 0.3f);
|
||||||
Attributes[(int)MaterialAttributes.Material.Plastic + (int)MaterialAttributes.Material.NumberOfTypes] =
|
Attributes[(int)MaterialAttributes.Material.Plastic + (int)MaterialAttributes.Material.NumberOfTypes] =
|
||||||
new MaterialAttributes("plasticPhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS);
|
new MaterialAttributes("plasticPhysical",dDensity, 0.8f, 0.7f);
|
||||||
Attributes[(int)MaterialAttributes.Material.Rubber + (int)MaterialAttributes.Material.NumberOfTypes] =
|
Attributes[(int)MaterialAttributes.Material.Rubber + (int)MaterialAttributes.Material.NumberOfTypes] =
|
||||||
new MaterialAttributes("rubberPhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS);
|
new MaterialAttributes("rubberPhysical",dDensity, 0.8f, 0.9f);
|
||||||
Attributes[(int)MaterialAttributes.Material.Light + (int)MaterialAttributes.Material.NumberOfTypes] =
|
Attributes[(int)MaterialAttributes.Material.Light + (int)MaterialAttributes.Material.NumberOfTypes] =
|
||||||
new MaterialAttributes("lightPhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS);
|
new MaterialAttributes("lightPhysical",dDensity, dFriction, dRestitution);
|
||||||
Attributes[(int)MaterialAttributes.Material.Avatar + (int)MaterialAttributes.Material.NumberOfTypes] =
|
Attributes[(int)MaterialAttributes.Material.Avatar + (int)MaterialAttributes.Material.NumberOfTypes] =
|
||||||
new MaterialAttributes("avatarPhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS);
|
new MaterialAttributes("avatarPhysical",60f, 0.2f, 0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Under the [BulletSim] section, one can change the individual material
|
// Under the [BulletSim] section, one can change the individual material
|
||||||
|
|
|
@ -1010,6 +1010,9 @@ public sealed class BSPrim : BSPhysObject
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// A torque impulse.
|
// 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)
|
public void ApplyTorqueImpulse(OMV.Vector3 impulse, bool inTaintTime)
|
||||||
{
|
{
|
||||||
OMV.Vector3 applyImpulse = impulse;
|
OMV.Vector3 applyImpulse = impulse;
|
||||||
|
@ -1396,7 +1399,7 @@ public sealed class BSPrim : BSPhysObject
|
||||||
_rotationalVelocity = entprop.RotationalVelocity;
|
_rotationalVelocity = entprop.RotationalVelocity;
|
||||||
|
|
||||||
// The sanity check can change the velocity and/or position.
|
// The sanity check can change the velocity and/or position.
|
||||||
if (PositionSanityCheck(true))
|
if (IsPhysical && PositionSanityCheck(true))
|
||||||
{
|
{
|
||||||
entprop.Position = _position;
|
entprop.Position = _position;
|
||||||
entprop.Velocity = _velocity;
|
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}",
|
DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},dir={3},vel={4},rotVel={5}",
|
||||||
LocalID, _position, _orientation, direction, _velocity, _rotationalVelocity);
|
LocalID, _position, _orientation, direction, _velocity, _rotationalVelocity);
|
||||||
|
|
||||||
// BulletSimAPI.DumpRigidBody2(PhysicsScene.World.ptr, BSBody.ptr); // DEBUG DEBUG DEBUG
|
|
||||||
|
|
||||||
base.RequestPhysicsterseUpdate();
|
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, MeshDesc> Meshes = new Dictionary<System.UInt64, MeshDesc>();
|
||||||
private Dictionary<System.UInt64, HullDesc> Hulls = new Dictionary<System.UInt64, HullDesc>();
|
private Dictionary<System.UInt64, HullDesc> Hulls = new Dictionary<System.UInt64, HullDesc>();
|
||||||
|
|
||||||
|
private bool DDetail = false;
|
||||||
|
|
||||||
public BSShapeCollection(BSScene physScene)
|
public BSShapeCollection(BSScene physScene)
|
||||||
{
|
{
|
||||||
PhysicsScene = 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()
|
public void Dispose()
|
||||||
|
@ -126,13 +133,13 @@ public sealed class BSShapeCollection : IDisposable
|
||||||
{
|
{
|
||||||
lock (m_collectionActivityLock)
|
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()
|
PhysicsScene.TaintedObject(inTaintTime, "BSShapeCollection.ReferenceBody", delegate()
|
||||||
{
|
{
|
||||||
if (!BulletSimAPI.IsInWorld2(body.ptr))
|
if (!BulletSimAPI.IsInWorld2(body.ptr))
|
||||||
{
|
{
|
||||||
BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, 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()
|
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);
|
body.ID, body, inTaintTime);
|
||||||
// If the caller needs to know the old body is going away, pass the event up.
|
// If the caller needs to know the old body is going away, pass the event up.
|
||||||
if (bodyCallback != null) bodyCallback(body);
|
if (bodyCallback != null) bodyCallback(body);
|
||||||
|
@ -157,7 +164,7 @@ public sealed class BSShapeCollection : IDisposable
|
||||||
if (BulletSimAPI.IsInWorld2(body.ptr))
|
if (BulletSimAPI.IsInWorld2(body.ptr))
|
||||||
{
|
{
|
||||||
BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, 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.
|
// 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.
|
// There is an existing instance of this mesh.
|
||||||
meshDesc.referenceCount++;
|
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);
|
BSScene.DetailLogZero, shape.shapeKey.ToString("X"), meshDesc.referenceCount);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -194,7 +201,7 @@ public sealed class BSShapeCollection : IDisposable
|
||||||
meshDesc.shapeKey = shape.shapeKey;
|
meshDesc.shapeKey = shape.shapeKey;
|
||||||
// We keep a reference to the underlying IMesh data so a hull can be built
|
// We keep a reference to the underlying IMesh data so a hull can be built
|
||||||
meshDesc.referenceCount = 1;
|
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);
|
BSScene.DetailLogZero, shape.shapeKey.ToString("X"), meshDesc.referenceCount);
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
|
@ -207,7 +214,7 @@ public sealed class BSShapeCollection : IDisposable
|
||||||
{
|
{
|
||||||
// There is an existing instance of this hull.
|
// There is an existing instance of this hull.
|
||||||
hullDesc.referenceCount++;
|
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);
|
BSScene.DetailLogZero, shape.shapeKey.ToString("X"), hullDesc.referenceCount);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -216,7 +223,7 @@ public sealed class BSShapeCollection : IDisposable
|
||||||
hullDesc.ptr = shape.ptr;
|
hullDesc.ptr = shape.ptr;
|
||||||
hullDesc.shapeKey = shape.shapeKey;
|
hullDesc.shapeKey = shape.shapeKey;
|
||||||
hullDesc.referenceCount = 1;
|
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);
|
BSScene.DetailLogZero, shape.shapeKey.ToString("X"), hullDesc.referenceCount);
|
||||||
ret = true;
|
ret = true;
|
||||||
|
|
||||||
|
@ -246,7 +253,7 @@ public sealed class BSShapeCollection : IDisposable
|
||||||
if (shape.isNativeShape)
|
if (shape.isNativeShape)
|
||||||
{
|
{
|
||||||
// Native shapes are not tracked and are released immediately
|
// 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);
|
BSScene.DetailLogZero, shape.ptr.ToString("X"), inTaintTime);
|
||||||
if (shapeCallback != null) shapeCallback(shape);
|
if (shapeCallback != null) shapeCallback(shape);
|
||||||
BulletSimAPI.DeleteCollisionShape2(PhysicsScene.World.ptr, shape.ptr);
|
BulletSimAPI.DeleteCollisionShape2(PhysicsScene.World.ptr, shape.ptr);
|
||||||
|
@ -286,7 +293,7 @@ public sealed class BSShapeCollection : IDisposable
|
||||||
if (shapeCallback != null) shapeCallback(shape);
|
if (shapeCallback != null) shapeCallback(shape);
|
||||||
meshDesc.lastReferenced = System.DateTime.Now;
|
meshDesc.lastReferenced = System.DateTime.Now;
|
||||||
Meshes[shape.shapeKey] = meshDesc;
|
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);
|
BSScene.DetailLogZero, shape, meshDesc.referenceCount);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -307,7 +314,7 @@ public sealed class BSShapeCollection : IDisposable
|
||||||
|
|
||||||
hullDesc.lastReferenced = System.DateTime.Now;
|
hullDesc.lastReferenced = System.DateTime.Now;
|
||||||
Hulls[shape.shapeKey] = hullDesc;
|
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);
|
BSScene.DetailLogZero, shape, hullDesc.referenceCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -325,13 +332,13 @@ public sealed class BSShapeCollection : IDisposable
|
||||||
// Failed the sanity check!!
|
// Failed the sanity check!!
|
||||||
PhysicsScene.Logger.ErrorFormat("{0} Attempt to free a compound shape that is not compound!! type={1}, ptr={2}",
|
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"));
|
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"));
|
BSScene.DetailLogZero, shape.type, shape.ptr.ToString("X"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int numChildren = BulletSimAPI.GetNumberOfCompoundChildren2(shape.ptr);
|
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--)
|
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)
|
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)
|
// an avatar capsule is close to a native shape (it is not shared)
|
||||||
ret = GetReferenceToNativeShape(prim, BSPhysicsShapeType.SHAPE_CAPSULE,
|
ret = GetReferenceToNativeShape(prim, BSPhysicsShapeType.SHAPE_CAPSULE,
|
||||||
FixedShapeKey.KEY_CAPSULE, shapeCallback);
|
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;
|
ret = true;
|
||||||
haveShape = true;
|
haveShape = true;
|
||||||
}
|
}
|
||||||
|
@ -420,7 +427,7 @@ public sealed class BSShapeCollection : IDisposable
|
||||||
if (!haveShape && prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_COMPOUND)
|
if (!haveShape && prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_COMPOUND)
|
||||||
{
|
{
|
||||||
ret = GetReferenceToCompoundShape(prim, shapeCallback);
|
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;
|
haveShape = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -465,7 +472,7 @@ public sealed class BSShapeCollection : IDisposable
|
||||||
{
|
{
|
||||||
ret = GetReferenceToNativeShape(prim, BSPhysicsShapeType.SHAPE_SPHERE,
|
ret = GetReferenceToNativeShape(prim, BSPhysicsShapeType.SHAPE_SPHERE,
|
||||||
FixedShapeKey.KEY_SPHERE, shapeCallback);
|
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);
|
prim.LocalID, forceRebuild, prim.PhysShape);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -479,7 +486,7 @@ public sealed class BSShapeCollection : IDisposable
|
||||||
{
|
{
|
||||||
ret = GetReferenceToNativeShape( prim, BSPhysicsShapeType.SHAPE_BOX,
|
ret = GetReferenceToNativeShape( prim, BSPhysicsShapeType.SHAPE_BOX,
|
||||||
FixedShapeKey.KEY_BOX, shapeCallback);
|
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);
|
prim.LocalID, forceRebuild, prim.PhysShape);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -504,13 +511,13 @@ public sealed class BSShapeCollection : IDisposable
|
||||||
{
|
{
|
||||||
// Update prim.BSShape to reference a hull of this shape.
|
// Update prim.BSShape to reference a hull of this shape.
|
||||||
ret = GetReferenceToHull(prim,shapeCallback);
|
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"));
|
prim.LocalID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ret = GetReferenceToMesh(prim, shapeCallback);
|
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"));
|
prim.LocalID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X"));
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -528,7 +535,7 @@ public sealed class BSShapeCollection : IDisposable
|
||||||
BulletShape newShape = BuildPhysicalNativeShape(prim, shapeType, shapeKey);
|
BulletShape newShape = BuildPhysicalNativeShape(prim, shapeType, shapeKey);
|
||||||
|
|
||||||
// Don't need to do a 'ReferenceShape()' here because native shapes are not shared.
|
// 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.LocalID, newShape, prim.Scale);
|
||||||
|
|
||||||
prim.PhysShape = newShape;
|
prim.PhysShape = newShape;
|
||||||
|
@ -554,7 +561,7 @@ public sealed class BSShapeCollection : IDisposable
|
||||||
newShape = new BulletShape(
|
newShape = new BulletShape(
|
||||||
BulletSimAPI.BuildCapsuleShape2(PhysicsScene.World.ptr, 1f, 1f, prim.Scale)
|
BulletSimAPI.BuildCapsuleShape2(PhysicsScene.World.ptr, 1f, 1f, prim.Scale)
|
||||||
, shapeType);
|
, 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
|
else
|
||||||
{
|
{
|
||||||
|
@ -589,7 +596,7 @@ public sealed class BSShapeCollection : IDisposable
|
||||||
if (newMeshKey == prim.PhysShape.shapeKey && prim.PhysShape.type == BSPhysicsShapeType.SHAPE_MESH)
|
if (newMeshKey == prim.PhysShape.shapeKey && prim.PhysShape.type == BSPhysicsShapeType.SHAPE_MESH)
|
||||||
return false;
|
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"));
|
prim.LocalID, prim.PhysShape.shapeKey.ToString("X"), newMeshKey.ToString("X"));
|
||||||
|
|
||||||
// Since we're recreating new, get rid of the reference to the previous shape
|
// 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)
|
if (newHullKey == prim.PhysShape.shapeKey && prim.PhysShape.type == BSPhysicsShapeType.SHAPE_HULL)
|
||||||
return false;
|
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"));
|
prim.LocalID, prim.PhysShape.shapeKey.ToString("X"), newHullKey.ToString("X"));
|
||||||
|
|
||||||
// Remove usage of the previous shape.
|
// 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.
|
// Create the shape for the root prim and add it to the compound shape. Cannot be a native shape.
|
||||||
CreateGeomMeshOrHull(prim, shapeCallback);
|
CreateGeomMeshOrHull(prim, shapeCallback);
|
||||||
BulletSimAPI.AddChildShapeToCompoundShape2(cShape.ptr, prim.PhysShape.ptr, OMV.Vector3.Zero, OMV.Quaternion.Identity);
|
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.LocalID, cShape, prim.PhysShape);
|
||||||
|
|
||||||
prim.PhysShape = cShape;
|
prim.PhysShape = cShape;
|
||||||
|
@ -935,13 +942,13 @@ public sealed class BSShapeCollection : IDisposable
|
||||||
{
|
{
|
||||||
bodyPtr = BulletSimAPI.CreateBodyFromShape2(sim.ptr, shape.ptr,
|
bodyPtr = BulletSimAPI.CreateBodyFromShape2(sim.ptr, shape.ptr,
|
||||||
prim.LocalID, prim.RawPosition, prim.RawOrientation);
|
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
|
else
|
||||||
{
|
{
|
||||||
bodyPtr = BulletSimAPI.CreateGhostFromShape2(sim.ptr, shape.ptr,
|
bodyPtr = BulletSimAPI.CreateGhostFromShape2(sim.ptr, shape.ptr,
|
||||||
prim.LocalID, prim.RawPosition, prim.RawOrientation);
|
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);
|
aBody = new BulletBody(prim.LocalID, bodyPtr);
|
||||||
|
|
||||||
|
|
|
@ -360,6 +360,7 @@ public enum CollisionFlags : uint
|
||||||
// Following used by BulletSim to control collisions and updates
|
// Following used by BulletSim to control collisions and updates
|
||||||
BS_SUBSCRIBE_COLLISION_EVENTS = 1 << 10,
|
BS_SUBSCRIBE_COLLISION_EVENTS = 1 << 10,
|
||||||
BS_FLOATS_ON_WATER = 1 << 11,
|
BS_FLOATS_ON_WATER = 1 << 11,
|
||||||
|
BS_VEHICLE_COLLISIONS = 1 << 12,
|
||||||
BS_NONE = 0,
|
BS_NONE = 0,
|
||||||
BS_ALL = 0xFFFFFFFF,
|
BS_ALL = 0xFFFFFFFF,
|
||||||
|
|
||||||
|
|
|
@ -6,14 +6,34 @@ CRASHES
|
||||||
Causes many errors. Doesn't stop after first error with box shape.
|
Causes many errors. Doesn't stop after first error with box shape.
|
||||||
Eventually crashes when deleting the object.
|
Eventually crashes when deleting the object.
|
||||||
|
|
||||||
BULLETSIM TODO LIST:
|
VEHICLES TODO LIST:
|
||||||
=================================================
|
=================================================
|
||||||
Neb car jiggling left and right
|
Neb car jiggling left and right
|
||||||
|
Happens on terrain and any other mesh object. Flat cubes are much smoother.
|
||||||
Vehicles (Move smoothly)
|
Vehicles (Move smoothly)
|
||||||
Light cycle falling over when driving
|
Add vehicle collisions so IsColliding is properly reported.
|
||||||
Light cycle not banking
|
Needed for banking, limitMotorUp, movementLimiting, ...
|
||||||
Do single prim vehicles don't seem to properly vehiclize.
|
Some vehicles should not be able to turn if no speed or off ground.
|
||||||
Gun sending shooter flying
|
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)
|
Collision margin (gap between physical objects lying on each other)
|
||||||
Boundry checking (crashes related to crossing boundry)
|
Boundry checking (crashes related to crossing boundry)
|
||||||
Add check for border edge position for avatars and objects.
|
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.
|
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.
|
Skeleton classes and table are in the sources but are not filled or used.
|
||||||
Add PID motor for avatar movement (slow to stop, ...)
|
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.
|
Find/remove avatar collision with ID=0.
|
||||||
Test avatar walking up stairs. How does compare with SL.
|
Test avatar walking up stairs. How does compare with SL.
|
||||||
Radius of the capsule affects ability to climb edges.
|
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.
|
Debounce avatar contact so legs don't keep folding up when standing.
|
||||||
Implement LSL physics controls. Like STATUS_ROTATE_X.
|
Implement LSL physics controls. Like STATUS_ROTATE_X.
|
||||||
Add border extensions to terrain to help region crossings and objects leaving region.
|
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
|
Speed up creation of large physical linksets
|
||||||
For instance, sitting in Neb's car (130 prims) takes several seconds to become physical
|
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?
|
Performance test with lots of avatars. Can BulletSim support a thousand?
|
||||||
Optimize collisions in C++: only send up to the object subscribed to collisions.
|
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)
|
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.
|
Implement 'top colliders' info.
|
||||||
Avatar jump
|
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.
|
Performance measurement and changes to make quicker.
|
||||||
Implement detailed physics stats (GetStats()).
|
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?
|
Is there are more efficient method of implementing pre and post step actions?
|
||||||
See http://www.codeproject.com/Articles/29922/Weak-Events-in-C
|
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?
|
Physics Arena central pyramid: why is one side permiable?
|
||||||
|
|
||||||
INTERNAL IMPROVEMENT/CLEANUP
|
INTERNAL IMPROVEMENT/CLEANUP
|
||||||
|
@ -85,33 +101,42 @@ Complete implemention of preStepActions
|
||||||
Replace vehicle step call with prestep event.
|
Replace vehicle step call with prestep event.
|
||||||
Is there a need for postStepActions? postStepTaints?
|
Is there a need for postStepActions? postStepTaints?
|
||||||
Implement linkset by setting position of children when root updated. (LinksetManual)
|
Implement linkset by setting position of children when root updated. (LinksetManual)
|
||||||
LinkablePrim class? Would that simplify/centralize the linkset logic?
|
|
||||||
Linkset implementation using manual prim movement.
|
Linkset implementation using manual prim movement.
|
||||||
Linkset implementation using compound shapes.
|
LinkablePrim class? Would that simplify/centralize the linkset logic?
|
||||||
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?
|
BSScene.UpdateParameterSet() is broken. How to set params on objects?
|
||||||
Remove HeightmapInfo from terrain specification.
|
Remove HeightmapInfo from terrain specification.
|
||||||
Since C++ code does not need terrain height, this structure et al are not needed.
|
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
|
Add floating motor for BS_FLOATS_ON_WATER so prim and avatar will
|
||||||
bob at the water level. BSPrim.PositionSanityCheck().
|
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
|
DONE DONE DONE DONE
|
||||||
=================================================
|
=================================================
|
||||||
Cleanup code in BSDynamics by using motors.
|
Cleanup code in BSDynamics by using motors. (Resolution: started)
|
||||||
Consider implementing terrain with a mesh rather than heightmap.
|
Consider implementing terrain with a mesh rather than heightmap. (Resolution: done)
|
||||||
Would have better and adjustable resolution.
|
Would have better and adjustable resolution.
|
||||||
NOTDONE: Build terrain mesh so heighmap is height of the center of the square meter.
|
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.
|
Resolution: NOT DONE: SL and ODE define meter square as being at one corner with one diagional.
|
||||||
Terrain as mesh.
|
Terrain as mesh. (Resolution: done)
|
||||||
How are static linksets seen by the physics engine?
|
How are static linksets seen by the physics engine?
|
||||||
A: they are not linked in physics. When moved, all the children are repositioned.
|
Resolution: 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: done)
|
||||||
Convert BSCharacter to use all API2
|
|
||||||
Avatar pushing difficult (too heavy?)
|
Avatar pushing difficult (too heavy?)
|
||||||
Use asset service passed to BulletSim to get sculptie bodies, etc.
|
Use asset service passed to BulletSim to get sculptie bodies, etc. (Resolution: done)
|
||||||
Vehicles (fix bouncing on terrain)
|
Remove old code in DLL (all non-API2 stuff). (Resolution: done)
|
||||||
Remove old code in DLL (all non-API2 stuff).
|
Measurements of mega-physical prim performance (with graph) (Resolution: done, email)
|
||||||
Measurements of mega-physical prim performance (with graph)
|
|
||||||
Debug Bullet internal stats output (why is timing all wrong?)
|
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>
|
<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-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" />
|
<dllmap os="!windows,osx" cpu="x86" dll="openjpeg-dotnet.dll" target="lib32/libopenjpeg-dotnet" />
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue