Merge commit '8bf0a9f85dda4b1831630b65620d5c6868196c11' into careminster
Conflicts: OpenSim/Region/Framework/Scenes/SceneObjectPart.csavinationmerge
commit
fc5711fa7a
|
@ -4649,9 +4649,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
PhysicsShapeType,
|
PhysicsShapeType,
|
||||||
m_localId);
|
m_localId);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.ErrorFormat("[SCENE]: AddToPhysics object {0} failed: {1}", m_uuid, ex.Message);
|
m_log.ErrorFormat("[SCENE]: caught exception meshing object {0}. Object set to phantom. e={1}", m_uuid, e);
|
||||||
pa = null;
|
pa = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin
|
||||||
|
|
||||||
public PhysicsScene GetScene(string sceneIdentifier)
|
public PhysicsScene GetScene(string sceneIdentifier)
|
||||||
{
|
{
|
||||||
return new BasicScene(sceneIdentifier);
|
return new BasicScene(GetName(), sceneIdentifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetName()
|
public string GetName()
|
||||||
|
|
|
@ -49,8 +49,10 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin
|
||||||
|
|
||||||
//protected internal string sceneIdentifier;
|
//protected internal string sceneIdentifier;
|
||||||
|
|
||||||
public BasicScene(string _sceneIdentifier)
|
public BasicScene(string engineType, string _sceneIdentifier)
|
||||||
{
|
{
|
||||||
|
EngineType = engineType;
|
||||||
|
Name = EngineType + "/" + _sceneIdentifier;
|
||||||
//sceneIdentifier = _sceneIdentifier;
|
//sceneIdentifier = _sceneIdentifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -327,6 +327,12 @@ public override void RemoveChildShapeFromCompoundShape(BulletShape shape, Bullet
|
||||||
BSAPICPP.RemoveChildShapeFromCompoundShape2(shapeu.ptr, removeShapeu.ptr);
|
BSAPICPP.RemoveChildShapeFromCompoundShape2(shapeu.ptr, removeShapeu.ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void UpdateChildTransform(BulletShape pShape, int childIndex, Vector3 pos, Quaternion rot, bool shouldRecalculateLocalAabb)
|
||||||
|
{
|
||||||
|
BulletShapeUnman shapeu = pShape as BulletShapeUnman;
|
||||||
|
BSAPICPP.UpdateChildTransform2(shapeu.ptr, childIndex, pos, rot, shouldRecalculateLocalAabb);
|
||||||
|
}
|
||||||
|
|
||||||
public override void RecalculateCompoundShapeLocalAabb(BulletShape shape)
|
public override void RecalculateCompoundShapeLocalAabb(BulletShape shape)
|
||||||
{
|
{
|
||||||
BulletShapeUnman shapeu = shape as BulletShapeUnman;
|
BulletShapeUnman shapeu = shape as BulletShapeUnman;
|
||||||
|
@ -1356,6 +1362,9 @@ public static extern IntPtr RemoveChildShapeFromCompoundShapeIndex2(IntPtr cShap
|
||||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||||
public static extern void RemoveChildShapeFromCompoundShape2(IntPtr cShape, IntPtr removeShape);
|
public static extern void RemoveChildShapeFromCompoundShape2(IntPtr cShape, IntPtr removeShape);
|
||||||
|
|
||||||
|
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||||
|
public static extern void UpdateChildTransform2(IntPtr pShape, int childIndex, Vector3 pos, Quaternion rot, bool shouldRecalculateLocalAabb);
|
||||||
|
|
||||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||||
public static extern void RecalculateCompoundShapeLocalAabb2(IntPtr cShape);
|
public static extern void RecalculateCompoundShapeLocalAabb2(IntPtr cShape);
|
||||||
|
|
||||||
|
|
|
@ -1212,6 +1212,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
||||||
|
|
||||||
public override BulletShape GetChildShapeFromCompoundShapeIndex(BulletShape cShape, int indx) { /* TODO */ return null; }
|
public override BulletShape GetChildShapeFromCompoundShapeIndex(BulletShape cShape, int indx) { /* TODO */ return null; }
|
||||||
public override void RemoveChildShapeFromCompoundShape(BulletShape cShape, BulletShape removeShape) { /* TODO */ }
|
public override void RemoveChildShapeFromCompoundShape(BulletShape cShape, BulletShape removeShape) { /* TODO */ }
|
||||||
|
public override void UpdateChildTransform(BulletShape pShape, int childIndex, Vector3 pos, Quaternion rot, bool shouldRecalculateLocalAabb) { /* TODO */ }
|
||||||
|
|
||||||
public override BulletShape CreateGroundPlaneShape(uint pLocalId, float pheight, float pcollisionMargin)
|
public override BulletShape CreateGroundPlaneShape(uint pLocalId, float pheight, float pcollisionMargin)
|
||||||
{
|
{
|
||||||
|
|
|
@ -342,6 +342,8 @@ public abstract BulletShape RemoveChildShapeFromCompoundShapeIndex(BulletShape c
|
||||||
|
|
||||||
public abstract void RemoveChildShapeFromCompoundShape(BulletShape cShape, BulletShape removeShape);
|
public abstract void RemoveChildShapeFromCompoundShape(BulletShape cShape, BulletShape removeShape);
|
||||||
|
|
||||||
|
public abstract void UpdateChildTransform(BulletShape pShape, int childIndex, Vector3 pos, Quaternion rot, bool shouldRecalculateLocalAabb);
|
||||||
|
|
||||||
public abstract void RecalculateCompoundShapeLocalAabb(BulletShape cShape);
|
public abstract void RecalculateCompoundShapeLocalAabb(BulletShape cShape);
|
||||||
|
|
||||||
public abstract BulletShape DuplicateCollisionShape(BulletWorld sim, BulletShape srcShape, uint id);
|
public abstract BulletShape DuplicateCollisionShape(BulletWorld sim, BulletShape srcShape, uint id);
|
||||||
|
|
|
@ -328,6 +328,10 @@ public sealed class BSCharacter : BSPhysObject
|
||||||
public override bool Selected {
|
public override bool Selected {
|
||||||
set { _selected = value; }
|
set { _selected = value; }
|
||||||
}
|
}
|
||||||
|
public override bool IsSelected
|
||||||
|
{
|
||||||
|
get { return _selected; }
|
||||||
|
}
|
||||||
public override void CrossingFailure() { return; }
|
public override void CrossingFailure() { return; }
|
||||||
public override void link(PhysicsActor obj) { return; }
|
public override void link(PhysicsActor obj) { return; }
|
||||||
public override void delink() { return; }
|
public override void delink() { return; }
|
||||||
|
|
|
@ -108,10 +108,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
private float m_VhoverEfficiency = 0f;
|
private float m_VhoverEfficiency = 0f;
|
||||||
private float m_VhoverTimescale = 0f;
|
private float m_VhoverTimescale = 0f;
|
||||||
private float m_VhoverTargetHeight = -1.0f; // if <0 then no hover, else its the current target height
|
private float m_VhoverTargetHeight = -1.0f; // if <0 then no hover, else its the current target height
|
||||||
private float m_VehicleBuoyancy = 0f; //KF: m_VehicleBuoyancy is set by VEHICLE_BUOYANCY for a vehicle.
|
|
||||||
// Modifies gravity. Slider between -1 (double-gravity) and 1 (full anti-gravity)
|
// Modifies gravity. Slider between -1 (double-gravity) and 1 (full anti-gravity)
|
||||||
// KF: So far I have found no good method to combine a script-requested .Z velocity and gravity.
|
private float m_VehicleBuoyancy = 0f;
|
||||||
// Therefore only m_VehicleBuoyancy=1 (0g) will use the script-requested .Z velocity.
|
private Vector3 m_VehicleGravity = Vector3.Zero; // Gravity computed when buoyancy set
|
||||||
|
|
||||||
//Attractor properties
|
//Attractor properties
|
||||||
private BSVMotor m_verticalAttractionMotor = new BSVMotor("VerticalAttraction");
|
private BSVMotor m_verticalAttractionMotor = new BSVMotor("VerticalAttraction");
|
||||||
|
@ -124,17 +123,38 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
static readonly float PIOverFour = ((float)Math.PI) / 4f;
|
static readonly float PIOverFour = ((float)Math.PI) / 4f;
|
||||||
static readonly float PIOverTwo = ((float)Math.PI) / 2f;
|
static readonly float PIOverTwo = ((float)Math.PI) / 2f;
|
||||||
|
|
||||||
|
// For debugging, flags to turn on and off individual corrections.
|
||||||
|
private bool enableAngularVerticalAttraction = true;
|
||||||
|
private bool enableAngularDeflection = true;
|
||||||
|
private bool enableAngularBanking = true;
|
||||||
|
|
||||||
public BSDynamics(BSScene myScene, BSPrim myPrim)
|
public BSDynamics(BSScene myScene, BSPrim myPrim)
|
||||||
{
|
{
|
||||||
PhysicsScene = myScene;
|
PhysicsScene = myScene;
|
||||||
Prim = myPrim;
|
Prim = myPrim;
|
||||||
Type = Vehicle.TYPE_NONE;
|
Type = Vehicle.TYPE_NONE;
|
||||||
|
SetupVehicleDebugging();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stopgap debugging enablement. Allows source level debugging but still checking
|
||||||
|
// in changes by making enablement of debugging flags from INI file.
|
||||||
|
public void SetupVehicleDebugging()
|
||||||
|
{
|
||||||
|
enableAngularVerticalAttraction = true;
|
||||||
|
enableAngularDeflection = true;
|
||||||
|
enableAngularBanking = true;
|
||||||
|
if (BSParam.VehicleDebuggingEnabled != ConfigurationParameters.numericFalse)
|
||||||
|
{
|
||||||
|
enableAngularVerticalAttraction = false;
|
||||||
|
enableAngularDeflection = false;
|
||||||
|
enableAngularBanking = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return 'true' if this vehicle is doing vehicle things
|
// Return 'true' if this vehicle is doing vehicle things
|
||||||
public bool IsActive
|
public bool IsActive
|
||||||
{
|
{
|
||||||
get { return Type != Vehicle.TYPE_NONE && Prim.IsPhysical; }
|
get { return (Type != Vehicle.TYPE_NONE && !Prim.IsStatic); }
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Vehicle parameter setting
|
#region Vehicle parameter setting
|
||||||
|
@ -168,6 +188,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
break;
|
break;
|
||||||
case Vehicle.BUOYANCY:
|
case Vehicle.BUOYANCY:
|
||||||
m_VehicleBuoyancy = ClampInRange(-1f, pValue, 1f);
|
m_VehicleBuoyancy = ClampInRange(-1f, pValue, 1f);
|
||||||
|
m_VehicleGravity = Prim.ComputeGravity(m_VehicleBuoyancy);
|
||||||
break;
|
break;
|
||||||
case Vehicle.HOVER_EFFICIENCY:
|
case Vehicle.HOVER_EFFICIENCY:
|
||||||
m_VhoverEfficiency = ClampInRange(0f, pValue, 1f);
|
m_VhoverEfficiency = ClampInRange(0f, pValue, 1f);
|
||||||
|
@ -540,12 +561,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
1f);
|
1f);
|
||||||
m_angularMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging)
|
m_angularMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging)
|
||||||
|
|
||||||
|
/* Not implemented
|
||||||
m_verticalAttractionMotor = new BSVMotor("VerticalAttraction", m_verticalAttractionTimescale,
|
m_verticalAttractionMotor = new BSVMotor("VerticalAttraction", m_verticalAttractionTimescale,
|
||||||
BSMotor.Infinite, BSMotor.InfiniteVector,
|
BSMotor.Infinite, BSMotor.InfiniteVector,
|
||||||
m_verticalAttractionEfficiency);
|
m_verticalAttractionEfficiency);
|
||||||
// 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)
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
#endregion // Vehicle parameter setting
|
#endregion // Vehicle parameter setting
|
||||||
|
|
||||||
|
@ -571,15 +594,18 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
// Vehicles report collision events so we know when it's on the ground
|
// Vehicles report collision events so we know when it's on the ground
|
||||||
PhysicsScene.PE.AddToCollisionFlags(Prim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS);
|
PhysicsScene.PE.AddToCollisionFlags(Prim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS);
|
||||||
|
|
||||||
Vector3 localInertia = PhysicsScene.PE.CalculateLocalInertia(Prim.PhysShape, m_vehicleMass);
|
Prim.Inertia = PhysicsScene.PE.CalculateLocalInertia(Prim.PhysShape, m_vehicleMass);
|
||||||
PhysicsScene.PE.SetMassProps(Prim.PhysBody, m_vehicleMass, localInertia);
|
PhysicsScene.PE.SetMassProps(Prim.PhysBody, m_vehicleMass, Prim.Inertia);
|
||||||
PhysicsScene.PE.UpdateInertiaTensor(Prim.PhysBody);
|
PhysicsScene.PE.UpdateInertiaTensor(Prim.PhysBody);
|
||||||
|
|
||||||
Vector3 grav = PhysicsScene.DefaultGravity * (1f - Prim.Buoyancy);
|
// Set the gravity for the vehicle depending on the buoyancy
|
||||||
PhysicsScene.PE.SetGravity(Prim.PhysBody, grav);
|
// TODO: what should be done if prim and vehicle buoyancy differ?
|
||||||
|
m_VehicleGravity = Prim.ComputeGravity(m_VehicleBuoyancy);
|
||||||
|
// The actual vehicle gravity is set to zero in Bullet so we can do all the application of same.
|
||||||
|
PhysicsScene.PE.SetGravity(Prim.PhysBody, Vector3.Zero);
|
||||||
|
|
||||||
VDetailLog("{0},BSDynamics.Refresh,mass={1},frict={2},inert={3},aDamp={4}",
|
VDetailLog("{0},BSDynamics.Refresh,mass={1},frict={2},inert={3},aDamp={4},grav={5}",
|
||||||
Prim.LocalID, m_vehicleMass, friction, localInertia, angularDamping);
|
Prim.LocalID, m_vehicleMass, friction, Prim.Inertia, angularDamping, m_VehicleGravity);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -619,6 +645,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
private Vector3 m_knownPosition;
|
private Vector3 m_knownPosition;
|
||||||
private Vector3 m_knownVelocity;
|
private Vector3 m_knownVelocity;
|
||||||
private Vector3 m_knownForce;
|
private Vector3 m_knownForce;
|
||||||
|
private Vector3 m_knownForceImpulse;
|
||||||
private Quaternion m_knownOrientation;
|
private Quaternion m_knownOrientation;
|
||||||
private Vector3 m_knownRotationalVelocity;
|
private Vector3 m_knownRotationalVelocity;
|
||||||
private Vector3 m_knownRotationalForce;
|
private Vector3 m_knownRotationalForce;
|
||||||
|
@ -627,12 +654,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
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_knownChangedForce = 1 << 2;
|
private const int m_knownChangedForce = 1 << 2;
|
||||||
private const int m_knownChangedOrientation = 1 << 3;
|
private const int m_knownChangedForceImpulse = 1 << 3;
|
||||||
private const int m_knownChangedRotationalVelocity = 1 << 4;
|
private const int m_knownChangedOrientation = 1 << 4;
|
||||||
private const int m_knownChangedRotationalForce = 1 << 5;
|
private const int m_knownChangedRotationalVelocity = 1 << 5;
|
||||||
private const int m_knownChangedTerrainHeight = 1 << 6;
|
private const int m_knownChangedRotationalForce = 1 << 6;
|
||||||
private const int m_knownChangedWaterLevel = 1 << 7;
|
private const int m_knownChangedTerrainHeight = 1 << 7;
|
||||||
private const int m_knownChangedForwardVelocity = 1 << 8;
|
private const int m_knownChangedWaterLevel = 1 << 8;
|
||||||
|
private const int m_knownChangedForwardVelocity = 1 << 9;
|
||||||
|
|
||||||
private void ForgetKnownVehicleProperties()
|
private void ForgetKnownVehicleProperties()
|
||||||
{
|
{
|
||||||
|
@ -653,21 +681,29 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
if ((m_knownChanged & m_knownChangedVelocity) != 0)
|
if ((m_knownChanged & m_knownChangedVelocity) != 0)
|
||||||
{
|
{
|
||||||
Prim.ForceVelocity = m_knownVelocity;
|
Prim.ForceVelocity = m_knownVelocity;
|
||||||
PhysicsScene.PE.SetInterpolationLinearVelocity(Prim.PhysBody, VehicleVelocity);
|
// Fake out Bullet by making it think the velocity is the same as last time.
|
||||||
|
// Bullet does a bunch of smoothing for changing parameters.
|
||||||
|
// Since the vehicle is demanding this setting, we override Bullet's smoothing
|
||||||
|
// by telling Bullet the value was the same last time.
|
||||||
|
PhysicsScene.PE.SetInterpolationLinearVelocity(Prim.PhysBody, m_knownVelocity);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((m_knownChanged & m_knownChangedForce) != 0)
|
if ((m_knownChanged & m_knownChangedForce) != 0)
|
||||||
Prim.AddForce((Vector3)m_knownForce, false, true);
|
Prim.AddForce((Vector3)m_knownForce, false /*pushForce*/, true /*inTaintTime*/);
|
||||||
|
|
||||||
|
if ((m_knownChanged & m_knownChangedForceImpulse) != 0)
|
||||||
|
Prim.AddForceImpulse((Vector3)m_knownForceImpulse, false /*pushforce*/, true /*inTaintTime*/);
|
||||||
|
|
||||||
if ((m_knownChanged & m_knownChangedRotationalVelocity) != 0)
|
if ((m_knownChanged & m_knownChangedRotationalVelocity) != 0)
|
||||||
{
|
{
|
||||||
Prim.ForceRotationalVelocity = m_knownRotationalVelocity;
|
Prim.ForceRotationalVelocity = m_knownRotationalVelocity;
|
||||||
// Fake out Bullet by making it think the velocity is the same as last time.
|
|
||||||
PhysicsScene.PE.SetInterpolationAngularVelocity(Prim.PhysBody, m_knownRotationalVelocity);
|
PhysicsScene.PE.SetInterpolationAngularVelocity(Prim.PhysBody, m_knownRotationalVelocity);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((m_knownChanged & m_knownChangedRotationalForce) != 0)
|
if ((m_knownChanged & m_knownChangedRotationalForce) != 0)
|
||||||
Prim.AddAngularForce((Vector3)m_knownRotationalForce, false, true);
|
{
|
||||||
|
Prim.AddAngularForce((Vector3)m_knownRotationalForce, false /*pushForce*/, true /*inTaintTime*/);
|
||||||
|
}
|
||||||
|
|
||||||
// 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.
|
||||||
|
@ -757,16 +793,27 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void VehicleAddForce(Vector3 aForce)
|
private void VehicleAddForce(Vector3 pForce)
|
||||||
{
|
{
|
||||||
if ((m_knownHas & m_knownChangedForce) == 0)
|
if ((m_knownHas & m_knownChangedForce) == 0)
|
||||||
{
|
{
|
||||||
m_knownForce = Vector3.Zero;
|
m_knownForce = Vector3.Zero;
|
||||||
}
|
|
||||||
m_knownForce += aForce;
|
|
||||||
m_knownChanged |= m_knownChangedForce;
|
|
||||||
m_knownHas |= m_knownChangedForce;
|
m_knownHas |= m_knownChangedForce;
|
||||||
}
|
}
|
||||||
|
m_knownForce += pForce;
|
||||||
|
m_knownChanged |= m_knownChangedForce;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void VehicleAddForceImpulse(Vector3 pImpulse)
|
||||||
|
{
|
||||||
|
if ((m_knownHas & m_knownChangedForceImpulse) == 0)
|
||||||
|
{
|
||||||
|
m_knownForceImpulse = Vector3.Zero;
|
||||||
|
m_knownHas |= m_knownChangedForceImpulse;
|
||||||
|
}
|
||||||
|
m_knownForceImpulse += pImpulse;
|
||||||
|
m_knownChanged |= m_knownChangedForceImpulse;
|
||||||
|
}
|
||||||
|
|
||||||
private Vector3 VehicleRotationalVelocity
|
private Vector3 VehicleRotationalVelocity
|
||||||
{
|
{
|
||||||
|
@ -845,85 +892,91 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
PhysicsScene.PE.DumpRigidBody(PhysicsScene.World, Prim.PhysBody);
|
PhysicsScene.PE.DumpRigidBody(PhysicsScene.World, Prim.PhysBody);
|
||||||
|
|
||||||
VDetailLog("{0},BSDynamics.Step,done,pos={1}, force={2},velocity={3},angvel={4}",
|
VDetailLog("{0},BSDynamics.Step,done,pos={1}, force={2},velocity={3},angvel={4}",
|
||||||
Prim.LocalID, VehiclePosition, Prim.Force, VehicleVelocity, VehicleRotationalVelocity);
|
Prim.LocalID, VehiclePosition, m_knownForce, VehicleVelocity, VehicleRotationalVelocity);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply the effect of the linear motor and other linear motions (like hover and float).
|
// Apply the effect of the linear motor and other linear motions (like hover and float).
|
||||||
private void MoveLinear(float pTimestep)
|
private void MoveLinear(float pTimestep)
|
||||||
{
|
{
|
||||||
Vector3 linearMotorContribution = m_linearMotor.Step(pTimestep);
|
ComputeLinearVelocity(pTimestep);
|
||||||
|
|
||||||
// The movement computed in the linear motor is relative to the vehicle
|
ComputeLinearTerrainHeightCorrection(pTimestep);
|
||||||
// coordinates. Rotate the movement to world coordinates.
|
|
||||||
linearMotorContribution *= VehicleOrientation;
|
|
||||||
// All the contributions after this are world relative (mostly Z modifications)
|
|
||||||
|
|
||||||
// ==================================================================
|
ComputeLinearHover(pTimestep);
|
||||||
// Buoyancy: force to overcome gravity.
|
|
||||||
// m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g;
|
|
||||||
// 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 hoverContribution = ComputeLinearHover(pTimestep);
|
|
||||||
|
|
||||||
ComputeLinearBlockingEndPoint(pTimestep);
|
ComputeLinearBlockingEndPoint(pTimestep);
|
||||||
|
|
||||||
Vector3 limitMotorUpContribution = ComputeLinearMotorUp(pTimestep);
|
ComputeLinearMotorUp(pTimestep);
|
||||||
|
|
||||||
// ==================================================================
|
ApplyGravity(pTimestep);
|
||||||
Vector3 newVelocity = linearMotorContribution
|
|
||||||
+ terrainHeightContribution
|
|
||||||
+ hoverContribution
|
|
||||||
+ limitMotorUpContribution;
|
|
||||||
|
|
||||||
Vector3 newForce = buoyancyContribution;
|
|
||||||
|
|
||||||
// If not changing some axis, reduce out velocity
|
// If not changing some axis, reduce out velocity
|
||||||
|
if ((m_flags & (VehicleFlag.NO_X | VehicleFlag.NO_Y | VehicleFlag.NO_Z)) != 0)
|
||||||
|
{
|
||||||
|
Vector3 vel = VehicleVelocity;
|
||||||
if ((m_flags & (VehicleFlag.NO_X)) != 0)
|
if ((m_flags & (VehicleFlag.NO_X)) != 0)
|
||||||
newVelocity.X = 0;
|
vel.X = 0;
|
||||||
if ((m_flags & (VehicleFlag.NO_Y)) != 0)
|
if ((m_flags & (VehicleFlag.NO_Y)) != 0)
|
||||||
newVelocity.Y = 0;
|
vel.Y = 0;
|
||||||
if ((m_flags & (VehicleFlag.NO_Z)) != 0)
|
if ((m_flags & (VehicleFlag.NO_Z)) != 0)
|
||||||
newVelocity.Z = 0;
|
vel.Z = 0;
|
||||||
|
VehicleVelocity = vel;
|
||||||
|
}
|
||||||
|
|
||||||
// ==================================================================
|
// ==================================================================
|
||||||
// Clamp high or low velocities
|
// Clamp high or low velocities
|
||||||
float newVelocityLengthSq = newVelocity.LengthSquared();
|
float newVelocityLengthSq = VehicleVelocity.LengthSquared();
|
||||||
if (newVelocityLengthSq > 1000f)
|
if (newVelocityLengthSq > 1000f)
|
||||||
{
|
{
|
||||||
newVelocity /= newVelocity.Length();
|
VehicleVelocity /= VehicleVelocity.Length();
|
||||||
newVelocity *= 1000f;
|
VehicleVelocity *= 1000f;
|
||||||
}
|
}
|
||||||
else if (newVelocityLengthSq < 0.001f)
|
else if (newVelocityLengthSq < 0.001f)
|
||||||
newVelocity = Vector3.Zero;
|
VehicleVelocity = Vector3.Zero;
|
||||||
|
|
||||||
// ==================================================================
|
VDetailLog("{0}, MoveLinear,done,isColl={1},newVel={2}", Prim.LocalID, Prim.IsColliding, VehicleVelocity );
|
||||||
// Stuff new linear velocity into the vehicle.
|
|
||||||
// Since the velocity is just being set, it is not scaled by pTimeStep. Bullet will do that for us.
|
|
||||||
VehicleVelocity = newVelocity;
|
|
||||||
|
|
||||||
// Other linear forces are applied as forces.
|
|
||||||
Vector3 totalDownForce = newForce * m_vehicleMass;
|
|
||||||
if (!totalDownForce.ApproxEquals(Vector3.Zero, 0.01f))
|
|
||||||
{
|
|
||||||
VehicleAddForce(totalDownForce);
|
|
||||||
}
|
|
||||||
|
|
||||||
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()
|
} // end MoveLinear()
|
||||||
|
|
||||||
public Vector3 ComputeLinearTerrainHeightCorrection(float pTimestep)
|
public void ComputeLinearVelocity(float pTimestep)
|
||||||
|
{
|
||||||
|
Vector3 linearMotorStep = m_linearMotor.Step(pTimestep);
|
||||||
|
|
||||||
|
// The movement computed in the linear motor is relative to the vehicle
|
||||||
|
// coordinates. Rotate the movement to world coordinates.
|
||||||
|
Vector3 linearMotorVelocity = linearMotorStep * VehicleOrientation;
|
||||||
|
|
||||||
|
// If we're a ground vehicle, don't loose any Z action (like gravity acceleration).
|
||||||
|
float mixFactor = 1f; // 1 means use all linear motor Z value, 0 means use all existing Z
|
||||||
|
if ((m_flags & VehicleFlag.LIMIT_MOTOR_UP) != 0)
|
||||||
|
{
|
||||||
|
if (!Prim.IsColliding)
|
||||||
|
{
|
||||||
|
// If a ground vehicle and not on the ground, I want gravity effect
|
||||||
|
mixFactor = 0.2f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// I'm not a ground vehicle but don't totally loose the effect of the environment
|
||||||
|
mixFactor = 0.8f;
|
||||||
|
}
|
||||||
|
linearMotorVelocity.Z = mixFactor * linearMotorVelocity.Z + (1f - mixFactor) * VehicleVelocity.Z;
|
||||||
|
|
||||||
|
// What we want to contribute to the vehicle's existing velocity
|
||||||
|
Vector3 linearMotorForce = linearMotorVelocity - VehicleVelocity;
|
||||||
|
|
||||||
|
// Act against the inertia of the vehicle
|
||||||
|
linearMotorForce *= m_vehicleMass;
|
||||||
|
|
||||||
|
VehicleAddForceImpulse(linearMotorForce * pTimestep);
|
||||||
|
|
||||||
|
VDetailLog("{0}, MoveLinear,velocity,vehVel={1},step={2},stepVel={3},mix={4},force={5}",
|
||||||
|
Prim.LocalID, VehicleVelocity, linearMotorStep, linearMotorVelocity, mixFactor, linearMotorForce);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ComputeLinearTerrainHeightCorrection(float pTimestep)
|
||||||
{
|
{
|
||||||
Vector3 ret = Vector3.Zero;
|
|
||||||
// If below the terrain, move us above the ground a little.
|
// If below the terrain, move us above the ground a little.
|
||||||
// TODO: Consider taking the rotated size of the object or possibly casting a ray.
|
// TODO: Consider taking the rotated size of the object or possibly casting a ray.
|
||||||
if (VehiclePosition.Z < GetTerrainHeight(VehiclePosition))
|
if (VehiclePosition.Z < GetTerrainHeight(VehiclePosition))
|
||||||
|
@ -935,13 +988,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
VDetailLog("{0}, MoveLinear,terrainHeight,terrainHeight={1},pos={2}",
|
VDetailLog("{0}, MoveLinear,terrainHeight,terrainHeight={1},pos={2}",
|
||||||
Prim.LocalID, GetTerrainHeight(VehiclePosition), VehiclePosition);
|
Prim.LocalID, GetTerrainHeight(VehiclePosition), VehiclePosition);
|
||||||
}
|
}
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector3 ComputeLinearHover(float pTimestep)
|
public void ComputeLinearHover(float pTimestep)
|
||||||
{
|
{
|
||||||
Vector3 ret = Vector3.Zero;
|
|
||||||
|
|
||||||
// m_VhoverEfficiency: 0=bouncy, 1=totally damped
|
// m_VhoverEfficiency: 0=bouncy, 1=totally damped
|
||||||
// m_VhoverTimescale: time to achieve height
|
// m_VhoverTimescale: time to achieve height
|
||||||
if ((m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0)
|
if ((m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0)
|
||||||
|
@ -974,23 +1024,26 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
Vector3 pos = VehiclePosition;
|
Vector3 pos = VehiclePosition;
|
||||||
pos.Z = m_VhoverTargetHeight;
|
pos.Z = m_VhoverTargetHeight;
|
||||||
VehiclePosition = pos;
|
VehiclePosition = pos;
|
||||||
|
|
||||||
|
VDetailLog("{0}, MoveLinear,hover,pos={1},lockHoverHeight", Prim.LocalID, pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Error is positive if below the target and negative if above.
|
// Error is positive if below the target and negative if above.
|
||||||
float verticalError = m_VhoverTargetHeight - VehiclePosition.Z;
|
float verticalError = m_VhoverTargetHeight - VehiclePosition.Z;
|
||||||
float verticalCorrectionVelocity = verticalError / m_VhoverTimescale;
|
float verticalCorrectionVelocity = verticalError / m_VhoverTimescale * pTimestep;
|
||||||
|
|
||||||
// TODO: implement m_VhoverEfficiency correctly
|
// TODO: implement m_VhoverEfficiency correctly
|
||||||
ret = new Vector3(0f, 0f, verticalCorrectionVelocity);
|
VehicleAddForceImpulse(new Vector3(0f, 0f, verticalCorrectionVelocity));
|
||||||
|
|
||||||
|
VDetailLog("{0}, MoveLinear,hover,pos={1},eff={2},hoverTS={3},height={4},target={5},err={6},corrVel={7}",
|
||||||
|
Prim.LocalID, VehiclePosition, m_VhoverEfficiency,
|
||||||
|
m_VhoverTimescale, m_VhoverHeight, m_VhoverTargetHeight,
|
||||||
|
verticalError, verticalCorrectionVelocity);
|
||||||
}
|
}
|
||||||
|
|
||||||
VDetailLog("{0}, MoveLinear,hover,pos={1},eff={2},hoverTS={3},height={4},target={5},ret={6}",
|
|
||||||
Prim.LocalID, VehiclePosition, m_VhoverEfficiency, m_VhoverTimescale, m_VhoverHeight, m_VhoverTargetHeight, ret);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool ComputeLinearBlockingEndPoint(float pTimestep)
|
public bool ComputeLinearBlockingEndPoint(float pTimestep)
|
||||||
|
@ -1045,30 +1098,67 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
// TODO: this code is wrong. Also, what should it do for boats (height from water)?
|
// 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
|
// This is just using the ground and a general collision check. Should really be using
|
||||||
// a downward raycast to find what is below.
|
// a downward raycast to find what is below.
|
||||||
public Vector3 ComputeLinearMotorUp(float pTimestep)
|
public void ComputeLinearMotorUp(float pTimestep)
|
||||||
{
|
{
|
||||||
Vector3 ret = Vector3.Zero;
|
Vector3 ret = Vector3.Zero;
|
||||||
float distanceAboveGround = 0f;
|
|
||||||
|
|
||||||
if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0)
|
if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0)
|
||||||
{
|
{
|
||||||
|
// This code tries to decide if the object is not on the ground and then pushing down
|
||||||
|
/*
|
||||||
float targetHeight = Type == Vehicle.TYPE_BOAT ? GetWaterLevel(VehiclePosition) : GetTerrainHeight(VehiclePosition);
|
float targetHeight = Type == Vehicle.TYPE_BOAT ? GetWaterLevel(VehiclePosition) : GetTerrainHeight(VehiclePosition);
|
||||||
distanceAboveGround = VehiclePosition.Z - targetHeight;
|
distanceAboveGround = VehiclePosition.Z - targetHeight;
|
||||||
// Not colliding if the vehicle is off the ground
|
// Not colliding if the vehicle is off the ground
|
||||||
if (!Prim.IsColliding)
|
if (!Prim.IsColliding)
|
||||||
{
|
{
|
||||||
// downForce = new Vector3(0, 0, -distanceAboveGround / m_bankingTimescale);
|
// downForce = new Vector3(0, 0, -distanceAboveGround / m_bankingTimescale);
|
||||||
ret = new Vector3(0, 0, -distanceAboveGround);
|
VehicleVelocity += new Vector3(0, 0, -distanceAboveGround);
|
||||||
}
|
}
|
||||||
// TODO: this calculation is wrong. From the description at
|
// TODO: this calculation is wrong. From the description at
|
||||||
// (http://wiki.secondlife.com/wiki/Category:LSL_Vehicle), the downForce
|
// (http://wiki.secondlife.com/wiki/Category:LSL_Vehicle), the downForce
|
||||||
// has a decay factor. This says this force should
|
// has a decay factor. This says this force should
|
||||||
// be computed with a motor.
|
// be computed with a motor.
|
||||||
// TODO: add interaction with banking.
|
// TODO: add interaction with banking.
|
||||||
}
|
|
||||||
VDetailLog("{0}, MoveLinear,limitMotorUp,distAbove={1},colliding={2},ret={3}",
|
VDetailLog("{0}, MoveLinear,limitMotorUp,distAbove={1},colliding={2},ret={3}",
|
||||||
Prim.LocalID, distanceAboveGround, Prim.IsColliding, ret);
|
Prim.LocalID, distanceAboveGround, Prim.IsColliding, ret);
|
||||||
return ret;
|
*/
|
||||||
|
|
||||||
|
// Another approach is to measure if we're going up. If going up and not colliding,
|
||||||
|
// the vehicle is in the air. Fix that by pushing down.
|
||||||
|
if (!Prim.IsColliding && VehicleVelocity.Z > 0.1)
|
||||||
|
{
|
||||||
|
// Get rid of any of the velocity vector that is pushing us up.
|
||||||
|
VehicleVelocity += new Vector3(0, 0, -VehicleVelocity.Z);
|
||||||
|
|
||||||
|
// If we're pointed up into the air, we should nose down
|
||||||
|
Vector3 pointingDirection = Vector3.UnitX * VehicleOrientation;
|
||||||
|
// The rotation around the Y axis is pitch up or down
|
||||||
|
if (pointingDirection.Y > 0.01f)
|
||||||
|
{
|
||||||
|
float angularCorrectionForce = -(float)Math.Asin(pointingDirection.Y);
|
||||||
|
Vector3 angularCorrectionVector = new Vector3(0f, angularCorrectionForce, 0f);
|
||||||
|
// Rotate into world coordinates and apply to vehicle
|
||||||
|
angularCorrectionVector *= VehicleOrientation;
|
||||||
|
VehicleAddAngularForce(angularCorrectionVector);
|
||||||
|
VDetailLog("{0}, MoveLinear,limitMotorUp,newVel={1},pntDir={2},corrFrc={3},aCorr={4}",
|
||||||
|
Prim.LocalID, VehicleVelocity, pointingDirection, angularCorrectionForce, angularCorrectionVector);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
VDetailLog("{0}, MoveLinear,limitMotorUp,newVel={1},pntDir={2}",
|
||||||
|
Prim.LocalID, VehicleVelocity, pointingDirection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplyGravity(float pTimeStep)
|
||||||
|
{
|
||||||
|
Vector3 appliedGravity = m_VehicleGravity * m_vehicleMass;
|
||||||
|
VehicleAddForce(appliedGravity);
|
||||||
|
|
||||||
|
VDetailLog("{0}, MoveLinear,applyGravity,vehGrav={1},appliedForce-{2}",
|
||||||
|
Prim.LocalID, m_VehicleGravity, appliedGravity);
|
||||||
}
|
}
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
|
@ -1088,6 +1178,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
// for preventing ground vehicles with large linear deflection, like bumper cars,
|
// for preventing ground vehicles with large linear deflection, like bumper cars,
|
||||||
// from climbing their linear deflection into the sky.
|
// from climbing their linear deflection into the sky.
|
||||||
// That is, NO_DEFLECTION_UP says angular motion should not add any pitch or roll movement
|
// That is, NO_DEFLECTION_UP says angular motion should not add any pitch or roll movement
|
||||||
|
// TODO: This is here because this is where ODE put it but documentation says it
|
||||||
|
// is a linear effect. Where should this check go?
|
||||||
if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0)
|
if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0)
|
||||||
{
|
{
|
||||||
angularMotorContribution.X = 0f;
|
angularMotorContribution.X = 0f;
|
||||||
|
@ -1179,7 +1271,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
Vector3 ret = Vector3.Zero;
|
Vector3 ret = Vector3.Zero;
|
||||||
|
|
||||||
// If vertical attaction timescale is reasonable
|
// If vertical attaction timescale is reasonable
|
||||||
if (m_verticalAttractionTimescale < m_verticalAttractionCutoff)
|
if (enableAngularVerticalAttraction && 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;
|
||||||
|
@ -1230,7 +1322,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
// this creates an over-correction and then wabbling as the target is overshot.
|
// this creates an over-correction and then wabbling as the target is overshot.
|
||||||
// TODO: rethink how the different correction computations inter-relate.
|
// TODO: rethink how the different correction computations inter-relate.
|
||||||
|
|
||||||
if (m_angularDeflectionEfficiency != 0 && VehicleVelocity != Vector3.Zero)
|
if (enableAngularDeflection && m_angularDeflectionEfficiency != 0 && VehicleForwardSpeed > 0.2)
|
||||||
{
|
{
|
||||||
// The direction the vehicle is moving
|
// The direction the vehicle is moving
|
||||||
Vector3 movingDirection = VehicleVelocity;
|
Vector3 movingDirection = VehicleVelocity;
|
||||||
|
@ -1303,7 +1395,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
{
|
{
|
||||||
Vector3 ret = Vector3.Zero;
|
Vector3 ret = Vector3.Zero;
|
||||||
|
|
||||||
if (m_bankingEfficiency != 0 && m_verticalAttractionTimescale < m_verticalAttractionCutoff)
|
if (enableAngularBanking && m_bankingEfficiency != 0 && m_verticalAttractionTimescale < m_verticalAttractionCutoff)
|
||||||
{
|
{
|
||||||
// Rotate a UnitZ vector (pointing up) to how the vehicle is oriented.
|
// Rotate a UnitZ vector (pointing up) to how the vehicle is oriented.
|
||||||
// As the vehicle rolls to the right or left, the Y value will increase from
|
// As the vehicle rolls to the right or left, the Y value will increase from
|
||||||
|
|
|
@ -152,6 +152,7 @@ public abstract class BSLinkset
|
||||||
if (IsRoot(child))
|
if (IsRoot(child))
|
||||||
{
|
{
|
||||||
// Cannot remove the root from a linkset.
|
// Cannot remove the root from a linkset.
|
||||||
|
child.PositionDisplacement = OMV.Vector3.Zero;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
RemoveChildFromLinkset(child);
|
RemoveChildFromLinkset(child);
|
||||||
|
@ -159,6 +160,7 @@ public abstract class BSLinkset
|
||||||
}
|
}
|
||||||
|
|
||||||
// The child is down to a linkset of just itself
|
// The child is down to a linkset of just itself
|
||||||
|
child.PositionDisplacement = OMV.Vector3.Zero;
|
||||||
return BSLinkset.Factory(PhysicsScene, child);
|
return BSLinkset.Factory(PhysicsScene, child);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -310,7 +312,7 @@ public abstract class BSLinkset
|
||||||
|
|
||||||
foreach (BSPhysObject bp in m_children)
|
foreach (BSPhysObject bp in m_children)
|
||||||
{
|
{
|
||||||
com += bp.Position * bp.RawMass;
|
com += bp.Position;
|
||||||
}
|
}
|
||||||
com /= (m_children.Count + 1);
|
com /= (m_children.Count + 1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,23 +40,33 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
// removed from the linkset.
|
// removed from the linkset.
|
||||||
sealed class BSLinksetCompoundInfo : BSLinksetInfo
|
sealed class BSLinksetCompoundInfo : BSLinksetInfo
|
||||||
{
|
{
|
||||||
public OMV.Vector3 OffsetPos;
|
public int Index;
|
||||||
|
public OMV.Vector3 OffsetFromRoot;
|
||||||
|
public OMV.Vector3 OffsetFromCenterOfMass;
|
||||||
public OMV.Quaternion OffsetRot;
|
public OMV.Quaternion OffsetRot;
|
||||||
public BSLinksetCompoundInfo(OMV.Vector3 p, OMV.Quaternion r)
|
public BSLinksetCompoundInfo(int indx, OMV.Vector3 p, OMV.Quaternion r)
|
||||||
{
|
{
|
||||||
OffsetPos = p;
|
Index = indx;
|
||||||
|
OffsetFromRoot = p;
|
||||||
|
OffsetFromCenterOfMass = p;
|
||||||
OffsetRot = r;
|
OffsetRot = r;
|
||||||
}
|
}
|
||||||
public override void Clear()
|
public override void Clear()
|
||||||
{
|
{
|
||||||
OffsetPos = OMV.Vector3.Zero;
|
Index = 0;
|
||||||
|
OffsetFromRoot = OMV.Vector3.Zero;
|
||||||
|
OffsetFromCenterOfMass = OMV.Vector3.Zero;
|
||||||
OffsetRot = OMV.Quaternion.Identity;
|
OffsetRot = OMV.Quaternion.Identity;
|
||||||
}
|
}
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
StringBuilder buff = new StringBuilder();
|
StringBuilder buff = new StringBuilder();
|
||||||
buff.Append("<p=");
|
buff.Append("<i=");
|
||||||
buff.Append(OffsetPos.ToString());
|
buff.Append(Index.ToString());
|
||||||
|
buff.Append(",p=");
|
||||||
|
buff.Append(OffsetFromRoot.ToString());
|
||||||
|
buff.Append(",m=");
|
||||||
|
buff.Append(OffsetFromCenterOfMass.ToString());
|
||||||
buff.Append(",r=");
|
buff.Append(",r=");
|
||||||
buff.Append(OffsetRot.ToString());
|
buff.Append(OffsetRot.ToString());
|
||||||
buff.Append(">");
|
buff.Append(">");
|
||||||
|
@ -170,6 +180,8 @@ public sealed class BSLinksetCompound : BSLinkset
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 'physicalUpdate' is true if these changes came directly from the physics engine. Don't need to rebuild then.
|
||||||
|
// Called at taint-time.
|
||||||
public override void UpdateProperties(BSPhysObject updated, bool physicalUpdate)
|
public override void UpdateProperties(BSPhysObject updated, bool physicalUpdate)
|
||||||
{
|
{
|
||||||
// The user moving a child around requires the rebuilding of the linkset compound shape
|
// The user moving a child around requires the rebuilding of the linkset compound shape
|
||||||
|
@ -182,6 +194,7 @@ public sealed class BSLinksetCompound : BSLinkset
|
||||||
&& !physicalUpdate
|
&& !physicalUpdate
|
||||||
&& PhysicsScene.TerrainManager.IsWithinKnownTerrain(LinksetRoot.RawPosition))
|
&& PhysicsScene.TerrainManager.IsWithinKnownTerrain(LinksetRoot.RawPosition))
|
||||||
{
|
{
|
||||||
|
// TODO: replace this with are calculation of the child prim's orientation and pos.
|
||||||
updated.LinksetInfo = null;
|
updated.LinksetInfo = null;
|
||||||
ScheduleRebuild(updated);
|
ScheduleRebuild(updated);
|
||||||
}
|
}
|
||||||
|
@ -230,7 +243,7 @@ public sealed class BSLinksetCompound : BSLinkset
|
||||||
if (inTaintTime)
|
if (inTaintTime)
|
||||||
{
|
{
|
||||||
OMV.Vector3 oldPos = child.RawPosition;
|
OMV.Vector3 oldPos = child.RawPosition;
|
||||||
child.ForcePosition = LinksetRoot.RawPosition + lci.OffsetPos;
|
child.ForcePosition = LinksetRoot.RawPosition + lci.OffsetFromRoot;
|
||||||
child.ForceOrientation = LinksetRoot.RawOrientation * lci.OffsetRot;
|
child.ForceOrientation = LinksetRoot.RawOrientation * lci.OffsetRot;
|
||||||
DetailLog("{0},BSLinksetCompound.RecomputeChildWorldPosition,oldPos={1},lci={2},newPos={3}",
|
DetailLog("{0},BSLinksetCompound.RecomputeChildWorldPosition,oldPos={1},lci={2},newPos={3}",
|
||||||
child.LocalID, oldPos, lci, child.RawPosition);
|
child.LocalID, oldPos, lci, child.RawPosition);
|
||||||
|
@ -238,7 +251,7 @@ public sealed class BSLinksetCompound : BSLinkset
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// TaintedObject is not used here so the raw position is set now and not at taint-time.
|
// TaintedObject is not used here so the raw position is set now and not at taint-time.
|
||||||
child.Position = LinksetRoot.RawPosition + lci.OffsetPos;
|
child.Position = LinksetRoot.RawPosition + lci.OffsetFromRoot;
|
||||||
child.Orientation = LinksetRoot.RawOrientation * lci.OffsetRot;
|
child.Orientation = LinksetRoot.RawOrientation * lci.OffsetRot;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -306,6 +319,7 @@ public sealed class BSLinksetCompound : BSLinkset
|
||||||
// Constraint linksets are rebuilt every time.
|
// Constraint linksets are rebuilt every time.
|
||||||
// Note that this works for rebuilding just the root after a linkset is taken apart.
|
// Note that this works for rebuilding just the root after a linkset is taken apart.
|
||||||
// Called at taint time!!
|
// Called at taint time!!
|
||||||
|
private bool disableCOM = true; // disable until we get this debugged
|
||||||
private void RecomputeLinksetCompound()
|
private void RecomputeLinksetCompound()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -316,10 +330,34 @@ public sealed class BSLinksetCompound : BSLinkset
|
||||||
// Cause the root shape to be rebuilt as a compound object with just the root in it
|
// Cause the root shape to be rebuilt as a compound object with just the root in it
|
||||||
LinksetRoot.ForceBodyShapeRebuild(true);
|
LinksetRoot.ForceBodyShapeRebuild(true);
|
||||||
|
|
||||||
|
// The center of mass for the linkset is the geometric center of the group.
|
||||||
|
// Compute a displacement for each component so it is relative to the center-of-mass.
|
||||||
|
// Bullet presumes an object's origin (relative <0,0,0>) is its center-of-mass
|
||||||
|
OMV.Vector3 centerOfMass;
|
||||||
|
OMV.Vector3 centerDisplacement = OMV.Vector3.Zero;
|
||||||
|
if (disableCOM) // DEBUG DEBUG
|
||||||
|
{ // DEBUG DEBUG
|
||||||
|
centerOfMass = LinksetRoot.RawPosition; // DEBUG DEBUG
|
||||||
|
LinksetRoot.PositionDisplacement = OMV.Vector3.Zero;
|
||||||
|
} // DEBUG DEBUG
|
||||||
|
else
|
||||||
|
{
|
||||||
|
centerOfMass = ComputeLinksetGeometricCenter();
|
||||||
|
centerDisplacement = centerOfMass - LinksetRoot.RawPosition;
|
||||||
|
|
||||||
|
// Since we're displacing the center of the shape, we need to move the body in the world
|
||||||
|
LinksetRoot.PositionDisplacement = centerDisplacement;
|
||||||
|
|
||||||
|
PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, 0, -centerDisplacement, OMV.Quaternion.Identity, false);
|
||||||
|
DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,COM,com={1},rootPos={2},centerDisp={3}",
|
||||||
|
LinksetRoot.LocalID, centerOfMass, LinksetRoot.RawPosition, centerDisplacement);
|
||||||
|
}
|
||||||
|
|
||||||
DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,start,rBody={1},rShape={2},numChildren={3}",
|
DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,start,rBody={1},rShape={2},numChildren={3}",
|
||||||
LinksetRoot.LocalID, LinksetRoot.PhysBody, LinksetRoot.PhysShape, NumberOfChildren);
|
LinksetRoot.LocalID, LinksetRoot.PhysBody, LinksetRoot.PhysShape, NumberOfChildren);
|
||||||
|
|
||||||
// Add a shape for each of the other children in the linkset
|
// Add a shape for each of the other children in the linkset
|
||||||
|
int memberIndex = 1;
|
||||||
ForEachMember(delegate(BSPhysObject cPrim)
|
ForEachMember(delegate(BSPhysObject cPrim)
|
||||||
{
|
{
|
||||||
if (!IsRoot(cPrim))
|
if (!IsRoot(cPrim))
|
||||||
|
@ -331,19 +369,21 @@ public sealed class BSLinksetCompound : BSLinkset
|
||||||
BSLinksetCompoundInfo lci = cPrim.LinksetInfo as BSLinksetCompoundInfo;
|
BSLinksetCompoundInfo lci = cPrim.LinksetInfo as BSLinksetCompoundInfo;
|
||||||
if (lci == null)
|
if (lci == null)
|
||||||
{
|
{
|
||||||
// Each child position and rotation is given relative to the root.
|
// Each child position and rotation is given relative to the center-of-mass.
|
||||||
OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation);
|
OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation);
|
||||||
OMV.Vector3 displacementPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation;
|
OMV.Vector3 displacementFromRoot = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation;
|
||||||
|
OMV.Vector3 displacementFromCOM = displacementFromRoot - centerDisplacement;
|
||||||
OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation;
|
OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation;
|
||||||
|
|
||||||
// Save relative position for recomputing child's world position after moving linkset.
|
// Save relative position for recomputing child's world position after moving linkset.
|
||||||
lci = new BSLinksetCompoundInfo(displacementPos, displacementRot);
|
lci = new BSLinksetCompoundInfo(memberIndex, displacementFromCOM, displacementRot);
|
||||||
|
lci.OffsetFromRoot = displacementFromRoot;
|
||||||
cPrim.LinksetInfo = lci;
|
cPrim.LinksetInfo = lci;
|
||||||
DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,creatingRelPos,lci={1}", cPrim.LocalID, lci);
|
DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,creatingRelPos,lci={1}", cPrim.LocalID, lci);
|
||||||
}
|
}
|
||||||
|
|
||||||
DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addMemberToShape,mID={1},mShape={2},dispPos={3},dispRot={4}",
|
DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addMemberToShape,mID={1},mShape={2},lci={3}",
|
||||||
LinksetRoot.LocalID, cPrim.LocalID, cPrim.PhysShape, lci.OffsetPos, lci.OffsetRot);
|
LinksetRoot.LocalID, cPrim.LocalID, cPrim.PhysShape, lci);
|
||||||
|
|
||||||
if (cPrim.PhysShape.isNativeShape)
|
if (cPrim.PhysShape.isNativeShape)
|
||||||
{
|
{
|
||||||
|
@ -359,7 +399,7 @@ public sealed class BSLinksetCompound : BSLinkset
|
||||||
PhysicsScene.Shapes.CreateGeomMeshOrHull(cPrim, null);
|
PhysicsScene.Shapes.CreateGeomMeshOrHull(cPrim, null);
|
||||||
BulletShape newShape = cPrim.PhysShape;
|
BulletShape newShape = cPrim.PhysShape;
|
||||||
cPrim.PhysShape = saveShape;
|
cPrim.PhysShape = saveShape;
|
||||||
PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, newShape, lci.OffsetPos, lci.OffsetRot);
|
PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, newShape, lci.OffsetFromCenterOfMass, lci.OffsetRot);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -371,8 +411,10 @@ public sealed class BSLinksetCompound : BSLinkset
|
||||||
PhysicsScene.Logger.ErrorFormat("{0} Rebuilt sharable shape when building linkset! Region={1}, primID={2}, shape={3}",
|
PhysicsScene.Logger.ErrorFormat("{0} Rebuilt sharable shape when building linkset! Region={1}, primID={2}, shape={3}",
|
||||||
LogHeader, PhysicsScene.RegionName, cPrim.LocalID, cPrim.PhysShape);
|
LogHeader, PhysicsScene.RegionName, cPrim.LocalID, cPrim.PhysShape);
|
||||||
}
|
}
|
||||||
PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, cPrim.PhysShape, lci.OffsetPos, lci.OffsetRot);
|
PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, cPrim.PhysShape, lci.OffsetFromCenterOfMass, lci.OffsetRot);
|
||||||
}
|
}
|
||||||
|
lci.Index = memberIndex;
|
||||||
|
memberIndex++;
|
||||||
}
|
}
|
||||||
return false; // 'false' says to move onto the next child in the list
|
return false; // 'false' says to move onto the next child in the list
|
||||||
});
|
});
|
||||||
|
|
|
@ -80,6 +80,7 @@ public static class BSParam
|
||||||
public static float AvatarStepForceFactor { get; private set; }
|
public static float AvatarStepForceFactor { get; private set; }
|
||||||
|
|
||||||
public static float VehicleAngularDamping { get; private set; }
|
public static float VehicleAngularDamping { get; private set; }
|
||||||
|
public static float VehicleDebuggingEnabled { get; private set; }
|
||||||
|
|
||||||
public static float LinksetImplementation { get; private set; }
|
public static float LinksetImplementation { get; private set; }
|
||||||
public static float LinkConstraintUseFrameOffset { get; private set; }
|
public static float LinkConstraintUseFrameOffset { get; private set; }
|
||||||
|
@ -427,6 +428,11 @@ public static class BSParam
|
||||||
(s,cf,p,v) => { VehicleAngularDamping = cf.GetFloat(p, v); },
|
(s,cf,p,v) => { VehicleAngularDamping = cf.GetFloat(p, v); },
|
||||||
(s) => { return VehicleAngularDamping; },
|
(s) => { return VehicleAngularDamping; },
|
||||||
(s,p,l,v) => { VehicleAngularDamping = v; } ),
|
(s,p,l,v) => { VehicleAngularDamping = v; } ),
|
||||||
|
new ParameterDefn("VehicleDebuggingEnable", "Turn on/off vehicle debugging",
|
||||||
|
ConfigurationParameters.numericFalse,
|
||||||
|
(s,cf,p,v) => { VehicleDebuggingEnabled = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); },
|
||||||
|
(s) => { return VehicleDebuggingEnabled; },
|
||||||
|
(s,p,l,v) => { VehicleDebuggingEnabled = v; } ),
|
||||||
|
|
||||||
new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)",
|
new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)",
|
||||||
0f,
|
0f,
|
||||||
|
|
|
@ -73,6 +73,8 @@ public abstract class BSPhysObject : PhysicsActor
|
||||||
|
|
||||||
// A linkset of just me
|
// A linkset of just me
|
||||||
Linkset = BSLinkset.Factory(PhysicsScene, this);
|
Linkset = BSLinkset.Factory(PhysicsScene, this);
|
||||||
|
PositionDisplacement = OMV.Vector3.Zero;
|
||||||
|
|
||||||
LastAssetBuildFailed = false;
|
LastAssetBuildFailed = false;
|
||||||
|
|
||||||
// Default material type
|
// Default material type
|
||||||
|
@ -135,6 +137,7 @@ public abstract class BSPhysObject : PhysicsActor
|
||||||
public virtual OMV.Vector3 Scale { get; set; }
|
public virtual OMV.Vector3 Scale { get; set; }
|
||||||
public abstract bool IsSolid { get; }
|
public abstract bool IsSolid { get; }
|
||||||
public abstract bool IsStatic { get; }
|
public abstract bool IsStatic { get; }
|
||||||
|
public abstract bool IsSelected { get; }
|
||||||
|
|
||||||
// Materialness
|
// Materialness
|
||||||
public MaterialAttributes.Material Material { get; private set; }
|
public MaterialAttributes.Material Material { get; private set; }
|
||||||
|
@ -156,6 +159,14 @@ public abstract class BSPhysObject : PhysicsActor
|
||||||
public abstract OMV.Vector3 RawPosition { get; set; }
|
public abstract OMV.Vector3 RawPosition { get; set; }
|
||||||
public abstract OMV.Vector3 ForcePosition { get; set; }
|
public abstract OMV.Vector3 ForcePosition { get; set; }
|
||||||
|
|
||||||
|
// Position is what the simulator thinks the positions of the prim is.
|
||||||
|
// Because Bullet needs the zero coordinate to be the center of mass of the linkset,
|
||||||
|
// sometimes it is necessary to displace the position the physics engine thinks
|
||||||
|
// the position is. PositionDisplacement must be added and removed from the
|
||||||
|
// position as the simulator position is stored and fetched from the physics
|
||||||
|
// engine.
|
||||||
|
public virtual OMV.Vector3 PositionDisplacement { get; set; }
|
||||||
|
|
||||||
public abstract OMV.Quaternion RawOrientation { get; set; }
|
public abstract OMV.Quaternion RawOrientation { get; set; }
|
||||||
public abstract OMV.Quaternion ForceOrientation { get; set; }
|
public abstract OMV.Quaternion ForceOrientation { get; set; }
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,7 @@ public class BSPlugin : IPhysicsPlugin
|
||||||
{
|
{
|
||||||
if (_mScene == null)
|
if (_mScene == null)
|
||||||
{
|
{
|
||||||
_mScene = new BSScene(sceneIdentifier);
|
_mScene = new BSScene(GetName(), sceneIdentifier);
|
||||||
}
|
}
|
||||||
return (_mScene);
|
return (_mScene);
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,10 @@ public sealed class BSPrim : BSPhysObject
|
||||||
private bool _grabbed;
|
private bool _grabbed;
|
||||||
private bool _isSelected;
|
private bool _isSelected;
|
||||||
private bool _isVolumeDetect;
|
private bool _isVolumeDetect;
|
||||||
|
|
||||||
|
// _position is what the simulator thinks the positions of the prim is.
|
||||||
private OMV.Vector3 _position;
|
private OMV.Vector3 _position;
|
||||||
|
|
||||||
private float _mass; // the mass of this object
|
private float _mass; // the mass of this object
|
||||||
private float _density;
|
private float _density;
|
||||||
private OMV.Vector3 _force;
|
private OMV.Vector3 _force;
|
||||||
|
@ -204,6 +207,10 @@ public sealed class BSPrim : BSPhysObject
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public override bool IsSelected
|
||||||
|
{
|
||||||
|
get { return _isSelected; }
|
||||||
|
}
|
||||||
public override void CrossingFailure() { return; }
|
public override void CrossingFailure() { return; }
|
||||||
|
|
||||||
// link me to the specified parent
|
// link me to the specified parent
|
||||||
|
@ -290,7 +297,7 @@ public sealed class BSPrim : BSPhysObject
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// don't do the GetObjectPosition for root elements because this function is called a zillion times.
|
// don't do the GetObjectPosition for root elements because this function is called a zillion times.
|
||||||
// _position = PhysicsScene.PE.GetObjectPosition2(PhysicsScene.World, BSBody);
|
// _position = PhysicsScene.PE.GetObjectPosition2(PhysicsScene.World, BSBody) - PositionDisplacement;
|
||||||
return _position;
|
return _position;
|
||||||
}
|
}
|
||||||
set {
|
set {
|
||||||
|
@ -316,18 +323,37 @@ public sealed class BSPrim : BSPhysObject
|
||||||
}
|
}
|
||||||
public override OMV.Vector3 ForcePosition {
|
public override OMV.Vector3 ForcePosition {
|
||||||
get {
|
get {
|
||||||
_position = PhysicsScene.PE.GetPosition(PhysBody);
|
_position = PhysicsScene.PE.GetPosition(PhysBody) - PositionDisplacement;
|
||||||
return _position;
|
return _position;
|
||||||
}
|
}
|
||||||
set {
|
set {
|
||||||
_position = value;
|
_position = value;
|
||||||
if (PhysBody.HasPhysicalBody)
|
if (PhysBody.HasPhysicalBody)
|
||||||
{
|
{
|
||||||
PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation);
|
PhysicsScene.PE.SetTranslation(PhysBody, _position + PositionDisplacement, _orientation);
|
||||||
ActivateIfPhysical(false);
|
ActivateIfPhysical(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Override to have position displacement immediately update the physical position.
|
||||||
|
// A feeble attempt to keep the sim and physical positions in sync
|
||||||
|
// Must be called at taint time.
|
||||||
|
public override OMV.Vector3 PositionDisplacement
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return base.PositionDisplacement;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
base.PositionDisplacement = value;
|
||||||
|
PhysicsScene.TaintedObject(PhysicsScene.InTaintTime, "BSPrim.setPosition", delegate()
|
||||||
|
{
|
||||||
|
if (PhysBody.HasPhysicalBody)
|
||||||
|
PhysicsScene.PE.SetTranslation(PhysBody, _position + base.PositionDisplacement, _orientation);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check that the current position is sane and, if not, modify the position to make it so.
|
// Check that the current position is sane and, if not, modify the position to make it so.
|
||||||
// Check for being below terrain and being out of bounds.
|
// Check for being below terrain and being out of bounds.
|
||||||
|
@ -336,7 +362,7 @@ public sealed class BSPrim : BSPhysObject
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(_position))
|
if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(RawPosition))
|
||||||
{
|
{
|
||||||
// The physical object is out of the known/simulated area.
|
// The physical object is out of the known/simulated area.
|
||||||
// Upper levels of code will handle the transition to other areas so, for
|
// Upper levels of code will handle the transition to other areas so, for
|
||||||
|
@ -350,8 +376,11 @@ public sealed class BSPrim : BSPhysObject
|
||||||
{
|
{
|
||||||
DetailLog("{0},BSPrim.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight);
|
DetailLog("{0},BSPrim.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight);
|
||||||
float targetHeight = terrainHeight + (Size.Z / 2f);
|
float targetHeight = terrainHeight + (Size.Z / 2f);
|
||||||
// Upforce proportional to the distance away from the terrain. Correct the error in 1 sec.
|
// If the object is below ground it just has to be moved up because pushing will
|
||||||
upForce.Z = (terrainHeight - RawPosition.Z) * 1f;
|
// not get it through the terrain
|
||||||
|
_position.Z = targetHeight;
|
||||||
|
if (!inTaintTime)
|
||||||
|
ForcePosition = _position;
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -363,20 +392,15 @@ public sealed class BSPrim : BSPhysObject
|
||||||
{
|
{
|
||||||
// Upforce proportional to the distance away from the water. Correct the error in 1 sec.
|
// Upforce proportional to the distance away from the water. Correct the error in 1 sec.
|
||||||
upForce.Z = (waterHeight - RawPosition.Z) * 1f;
|
upForce.Z = (waterHeight - RawPosition.Z) * 1f;
|
||||||
ret = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The above code computes a force to apply to correct any out-of-bounds problems. Apply same.
|
|
||||||
// TODO: This should be intergrated with a geneal physics action mechanism.
|
|
||||||
// TODO: This should be moderated with PID'ness.
|
|
||||||
if (ret)
|
|
||||||
{
|
|
||||||
// Apply upforce and overcome gravity.
|
// Apply upforce and overcome gravity.
|
||||||
OMV.Vector3 correctionForce = upForce - PhysicsScene.DefaultGravity;
|
OMV.Vector3 correctionForce = upForce - PhysicsScene.DefaultGravity;
|
||||||
DetailLog("{0},BSPrim.PositionSanityCheck,applyForce,pos={1},upForce={2},correctionForce={3}", LocalID, _position, upForce, correctionForce);
|
DetailLog("{0},BSPrim.PositionSanityCheck,applyForce,pos={1},upForce={2},correctionForce={3}", LocalID, _position, upForce, correctionForce);
|
||||||
AddForce(correctionForce, false, inTaintTime);
|
AddForce(correctionForce, false, inTaintTime);
|
||||||
|
ret = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -410,7 +434,7 @@ public sealed class BSPrim : BSPhysObject
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
OMV.Vector3 grav = ComputeGravity();
|
OMV.Vector3 grav = ComputeGravity(Buoyancy);
|
||||||
|
|
||||||
if (inWorld)
|
if (inWorld)
|
||||||
{
|
{
|
||||||
|
@ -445,12 +469,12 @@ public sealed class BSPrim : BSPhysObject
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return what gravity should be set to this very moment
|
// Return what gravity should be set to this very moment
|
||||||
private OMV.Vector3 ComputeGravity()
|
public OMV.Vector3 ComputeGravity(float buoyancy)
|
||||||
{
|
{
|
||||||
OMV.Vector3 ret = PhysicsScene.DefaultGravity;
|
OMV.Vector3 ret = PhysicsScene.DefaultGravity;
|
||||||
|
|
||||||
if (!IsStatic)
|
if (!IsStatic)
|
||||||
ret *= (1f - Buoyancy);
|
ret *= (1f - buoyancy);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -586,6 +610,7 @@ public sealed class BSPrim : BSPhysObject
|
||||||
_velocity = value;
|
_velocity = value;
|
||||||
if (PhysBody.HasPhysicalBody)
|
if (PhysBody.HasPhysicalBody)
|
||||||
{
|
{
|
||||||
|
DetailLog("{0},BSPrim.ForceVelocity,taint,vel={1}", LocalID, _velocity);
|
||||||
PhysicsScene.PE.SetLinearVelocity(PhysBody, _velocity);
|
PhysicsScene.PE.SetLinearVelocity(PhysBody, _velocity);
|
||||||
ActivateIfPhysical(false);
|
ActivateIfPhysical(false);
|
||||||
}
|
}
|
||||||
|
@ -650,12 +675,7 @@ public sealed class BSPrim : BSPhysObject
|
||||||
|
|
||||||
PhysicsScene.TaintedObject("BSPrim.setOrientation", delegate()
|
PhysicsScene.TaintedObject("BSPrim.setOrientation", delegate()
|
||||||
{
|
{
|
||||||
if (PhysBody.HasPhysicalBody)
|
ForceOrientation = _orientation;
|
||||||
{
|
|
||||||
// _position = PhysicsScene.PE.GetObjectPosition(PhysicsScene.World, BSBody);
|
|
||||||
// DetailLog("{0},BSPrim.setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation);
|
|
||||||
PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -670,7 +690,8 @@ public sealed class BSPrim : BSPhysObject
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
_orientation = value;
|
_orientation = value;
|
||||||
PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation);
|
if (PhysBody.HasPhysicalBody)
|
||||||
|
PhysicsScene.PE.SetTranslation(PhysBody, _position + PositionDisplacement, _orientation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public override int PhysicsActorType {
|
public override int PhysicsActorType {
|
||||||
|
@ -809,7 +830,7 @@ public sealed class BSPrim : BSPhysObject
|
||||||
// PhysicsScene.PE.ClearAllForces(BSBody);
|
// PhysicsScene.PE.ClearAllForces(BSBody);
|
||||||
|
|
||||||
// For good measure, make sure the transform is set through to the motion state
|
// For good measure, make sure the transform is set through to the motion state
|
||||||
PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation);
|
PhysicsScene.PE.SetTranslation(PhysBody, _position + PositionDisplacement, _orientation);
|
||||||
|
|
||||||
// Center of mass is at the center of the object
|
// Center of mass is at the center of the object
|
||||||
// DEBUG DEBUG PhysicsScene.PE.SetCenterOfMassByPosRot(Linkset.LinksetRoot.PhysBody, _position, _orientation);
|
// DEBUG DEBUG PhysicsScene.PE.SetCenterOfMassByPosRot(Linkset.LinksetRoot.PhysBody, _position, _orientation);
|
||||||
|
@ -1153,7 +1174,9 @@ public sealed class BSPrim : BSPhysObject
|
||||||
// This added force will only last the next simulation tick.
|
// This added force will only last the next simulation tick.
|
||||||
public void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) {
|
public void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) {
|
||||||
// for an object, doesn't matter if force is a pushforce or not
|
// for an object, doesn't matter if force is a pushforce or not
|
||||||
if (!IsStatic && force.IsFinite())
|
if (!IsStatic)
|
||||||
|
{
|
||||||
|
if (force.IsFinite())
|
||||||
{
|
{
|
||||||
float magnitude = force.Length();
|
float magnitude = force.Length();
|
||||||
if (magnitude > BSParam.MaxAddForceMagnitude)
|
if (magnitude > BSParam.MaxAddForceMagnitude)
|
||||||
|
@ -1178,10 +1201,45 @@ public sealed class BSPrim : BSPhysObject
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_log.WarnFormat("{0}: Got a NaN force applied to a prim. LocalID={1}", LogHeader, LocalID);
|
m_log.WarnFormat("{0}: AddForce: Got a NaN force applied to a prim. LocalID={1}", LogHeader, LocalID);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddForceImpulse(OMV.Vector3 impulse, bool pushforce, bool inTaintTime) {
|
||||||
|
// for an object, doesn't matter if force is a pushforce or not
|
||||||
|
if (!IsStatic)
|
||||||
|
{
|
||||||
|
if (impulse.IsFinite())
|
||||||
|
{
|
||||||
|
float magnitude = impulse.Length();
|
||||||
|
if (magnitude > BSParam.MaxAddForceMagnitude)
|
||||||
|
{
|
||||||
|
// Force has a limit
|
||||||
|
impulse = impulse / magnitude * BSParam.MaxAddForceMagnitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
// DetailLog("{0},BSPrim.addForceImpulse,call,impulse={1}", LocalID, impulse);
|
||||||
|
OMV.Vector3 addImpulse = impulse;
|
||||||
|
PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddImpulse", delegate()
|
||||||
|
{
|
||||||
|
// Bullet adds this impulse immediately to the velocity
|
||||||
|
DetailLog("{0},BSPrim.addForceImpulse,taint,impulseforce={1}", LocalID, addImpulse);
|
||||||
|
if (PhysBody.HasPhysicalBody)
|
||||||
|
{
|
||||||
|
PhysicsScene.PE.ApplyCentralImpulse(PhysBody, addImpulse);
|
||||||
|
ActivateIfPhysical(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_log.WarnFormat("{0}: AddForceImpulse: Got a NaN impulse applied to a prim. LocalID={1}", LogHeader, LocalID);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override void AddAngularForce(OMV.Vector3 force, bool pushforce) {
|
public override void AddAngularForce(OMV.Vector3 force, bool pushforce) {
|
||||||
AddAngularForce(force, pushforce, false);
|
AddAngularForce(force, pushforce, false);
|
||||||
|
@ -1561,21 +1619,6 @@ public sealed class BSPrim : BSPhysObject
|
||||||
|
|
||||||
// The physics engine says that properties have updated. Update same and inform
|
// The physics engine says that properties have updated. Update same and inform
|
||||||
// the world that things have changed.
|
// the world that things have changed.
|
||||||
// TODO: do we really need to check for changed? Maybe just copy values and call RequestPhysicsterseUpdate()
|
|
||||||
enum UpdatedProperties {
|
|
||||||
Position = 1 << 0,
|
|
||||||
Rotation = 1 << 1,
|
|
||||||
Velocity = 1 << 2,
|
|
||||||
Acceleration = 1 << 3,
|
|
||||||
RotationalVel = 1 << 4
|
|
||||||
}
|
|
||||||
|
|
||||||
const float ROTATION_TOLERANCE = 0.01f;
|
|
||||||
const float VELOCITY_TOLERANCE = 0.001f;
|
|
||||||
const float POSITION_TOLERANCE = 0.05f;
|
|
||||||
const float ACCELERATION_TOLERANCE = 0.01f;
|
|
||||||
const float ROTATIONAL_VELOCITY_TOLERANCE = 0.01f;
|
|
||||||
|
|
||||||
public override void UpdateProperties(EntityProperties entprop)
|
public override void UpdateProperties(EntityProperties entprop)
|
||||||
{
|
{
|
||||||
// Updates only for individual prims and for the root object of a linkset.
|
// Updates only for individual prims and for the root object of a linkset.
|
||||||
|
@ -1588,7 +1631,8 @@ public sealed class BSPrim : BSPhysObject
|
||||||
entprop.RotationalVelocity = OMV.Vector3.Zero;
|
entprop.RotationalVelocity = OMV.Vector3.Zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assign directly to the local variables so the normal set action does not happen
|
// Assign directly to the local variables so the normal set actions do not happen
|
||||||
|
entprop.Position -= PositionDisplacement;
|
||||||
_position = entprop.Position;
|
_position = entprop.Position;
|
||||||
_orientation = entprop.Rotation;
|
_orientation = entprop.Rotation;
|
||||||
_velocity = entprop.Velocity;
|
_velocity = entprop.Velocity;
|
||||||
|
|
|
@ -167,11 +167,16 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
public bool VehiclePhysicalLoggingEnabled { get; private set; }
|
public bool VehiclePhysicalLoggingEnabled { get; private set; }
|
||||||
|
|
||||||
#region Construction and Initialization
|
#region Construction and Initialization
|
||||||
public BSScene(string identifier)
|
public BSScene(string engineType, string identifier)
|
||||||
{
|
{
|
||||||
m_initialized = false;
|
m_initialized = false;
|
||||||
// we are passed the name of the region we're working for.
|
|
||||||
|
// The name of the region we're working for is passed to us. Keep for identification.
|
||||||
RegionName = identifier;
|
RegionName = identifier;
|
||||||
|
|
||||||
|
// Set identifying variables in the PhysicsScene interface.
|
||||||
|
EngineType = engineType;
|
||||||
|
Name = EngineType + "/" + RegionName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Initialise(IMesher meshmerizer, IConfigSource config)
|
public override void Initialise(IMesher meshmerizer, IConfigSource config)
|
||||||
|
@ -486,6 +491,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
ProcessTaints();
|
ProcessTaints();
|
||||||
|
|
||||||
// Some of the physical objects requre individual, pre-step calls
|
// Some of the physical objects requre individual, pre-step calls
|
||||||
|
// (vehicles and avatar movement, in particular)
|
||||||
TriggerPreStepEvent(timeStep);
|
TriggerPreStepEvent(timeStep);
|
||||||
|
|
||||||
// the prestep actions might have added taints
|
// the prestep actions might have added taints
|
||||||
|
|
|
@ -906,7 +906,7 @@ public sealed class BSShapeCollection : IDisposable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// While we figure out the real problem, stick a simple native shape on the object.
|
// While we figure out the real problem, stick in a simple box for the object.
|
||||||
BulletShape fillinShape =
|
BulletShape fillinShape =
|
||||||
BuildPhysicalNativeShape(prim, BSPhysicsShapeType.SHAPE_BOX, FixedShapeKey.KEY_BOX);
|
BuildPhysicalNativeShape(prim, BSPhysicsShapeType.SHAPE_BOX, FixedShapeKey.KEY_BOX);
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
CURRENT PRIORITIES
|
CURRENT PRIORITIES
|
||||||
=================================================
|
=================================================
|
||||||
Avatars walking up stairs (HALF DONE)
|
Nebadon vehicles turning funny in arena
|
||||||
Vehicle movement on terrain smoothness
|
|
||||||
limitMotorUp calibration (more down?)
|
limitMotorUp calibration (more down?)
|
||||||
|
Vehicle angular vertical attraction
|
||||||
|
Vehicle angular deflection
|
||||||
Preferred orientation angular correction fix
|
Preferred orientation angular correction fix
|
||||||
|
vehicle angular banking
|
||||||
|
Avatars walking up stairs (HALF DONE)
|
||||||
|
Radius of the capsule affects ability to climb edges.
|
||||||
|
Vehicle movement on terrain smoothness
|
||||||
Surfboard go wonky when turning
|
Surfboard go wonky when turning
|
||||||
Angular motor direction is global coordinates rather than local coordinates?
|
Angular motor direction is global coordinates rather than local coordinates?
|
||||||
Boats float low in the water
|
Boats float low in the water (DONE)
|
||||||
Avatar movement
|
Avatar movement
|
||||||
flying into a wall doesn't stop avatar who keeps appearing to move through the obstacle (DONE)
|
flying into a wall doesn't stop avatar who keeps appearing to move through the obstacle (DONE)
|
||||||
walking up stairs is not calibrated correctly (stairs out of Kepler cabin)
|
walking up stairs is not calibrated correctly (stairs out of Kepler cabin)
|
||||||
|
@ -33,19 +38,15 @@ CRASHES
|
||||||
|
|
||||||
VEHICLES TODO LIST:
|
VEHICLES TODO LIST:
|
||||||
=================================================
|
=================================================
|
||||||
Angular motor direction is global coordinates rather than local coordinates
|
|
||||||
Border crossing with linked vehicle causes crash
|
Border crossing with linked vehicle causes crash
|
||||||
Vehicles (Move smoothly)
|
Vehicles (Move smoothly)
|
||||||
Add vehicle collisions so IsColliding is properly reported.
|
|
||||||
Needed for banking, limitMotorUp, movementLimiting, ...
|
|
||||||
VehicleAddForce is not scaled by the simulation step but it is only
|
|
||||||
applied for one step. Should it be scaled?
|
|
||||||
Some vehicles should not be able to turn if no speed or off ground.
|
Some vehicles should not be able to turn if no speed or off ground.
|
||||||
Cannot edit/move a vehicle being ridden: it jumps back to the origional position.
|
Cannot edit/move a vehicle being ridden: it jumps back to the origional position.
|
||||||
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.
|
Happens on terrain and any other mesh object. Flat cubes are much smoother.
|
||||||
This has been reduced but not eliminated.
|
This has been reduced but not eliminated.
|
||||||
Implement referenceFrame for all the motion routines.
|
Implement referenceFrame for all the motion routines.
|
||||||
|
For limitMotorUp, use raycast down to find if vehicle is in the air.
|
||||||
Angular motion around Z moves the vehicle in world Z and not vehicle Z in ODE.
|
Angular motion around Z moves the vehicle in world Z and not vehicle Z in ODE.
|
||||||
Verify that angular motion specified around Z moves in the vehicle coordinates.
|
Verify that angular motion specified around Z moves in the vehicle coordinates.
|
||||||
Verify llGetVel() is returning a smooth and good value for vehicle movement.
|
Verify llGetVel() is returning a smooth and good value for vehicle movement.
|
||||||
|
@ -54,14 +55,13 @@ Implement function efficiency for lineaar and angular motion.
|
||||||
After getting off a vehicle, the root prim is phantom (can be walked through)
|
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
|
Need to force a position update for the root prim after compound shape destruction
|
||||||
Linkset explosion after three "rides" on Nebadon lite vehicle (LinksetConstraint)
|
Linkset explosion after three "rides" on Nebadon lite vehicle (LinksetConstraint)
|
||||||
For limitMotorUp, use raycast down to find if vehicle is in the air.
|
|
||||||
Remove vehicle angular velocity zeroing in BSPrim.UpdateProperties().
|
Remove vehicle angular velocity zeroing in BSPrim.UpdateProperties().
|
||||||
A kludge that isn't fixing the real problem of Bullet adding extra motion.
|
A kludge that isn't fixing the real problem of Bullet adding extra motion.
|
||||||
Incorporate inter-relationship of angular corrections. For instance, angularDeflection
|
Incorporate inter-relationship of angular corrections. For instance, angularDeflection
|
||||||
and angularMotorUp will compute same X or Y correction. When added together
|
and angularMotorUp will compute same X or Y correction. When added together
|
||||||
creates over-correction and over-shoot and wabbling.
|
creates over-correction and over-shoot and wabbling.
|
||||||
|
|
||||||
BULLETSIM TODO LIST:
|
GENERAL TODO LIST:
|
||||||
=================================================
|
=================================================
|
||||||
Implement an avatar mesh shape. The Bullet capsule is way too limited.
|
Implement an avatar mesh shape. The Bullet capsule is way too limited.
|
||||||
Consider just hand creating a vertex/index array in a new BSShapeAvatar.
|
Consider just hand creating a vertex/index array in a new BSShapeAvatar.
|
||||||
|
@ -121,11 +121,9 @@ LinksetCompound: when one of the children changes orientation (like tires
|
||||||
Verify/think through scripts in children of linksets. What do they reference
|
Verify/think through scripts in children of linksets. What do they reference
|
||||||
and return when getting position, velocity, ...
|
and return when getting position, velocity, ...
|
||||||
Confirm constraint linksets still work after making all the changes for compound linksets.
|
Confirm constraint linksets still work after making all the changes for compound linksets.
|
||||||
|
Use PostTaint callback to do rebuilds for constraint linksets to reduce rebuilding
|
||||||
Add 'changed' flag or similar to reduce the number of times a linkset is rebuilt.
|
Add 'changed' flag or similar to reduce the number of times a linkset is rebuilt.
|
||||||
For compound linksets, add ability to remove or reposition individual child shapes.
|
For compound linksets, add ability to remove or reposition individual child shapes.
|
||||||
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, ...
|
|
||||||
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.
|
||||||
REALLY bad for very large physical linksets (freezes the sim for many seconds).
|
REALLY bad for very large physical linksets (freezes the sim for many seconds).
|
||||||
|
@ -138,25 +136,21 @@ MORE
|
||||||
Use the HACD convex hull routine in Bullet rather than the C# version.
|
Use the HACD convex hull routine in Bullet rather than the C# version.
|
||||||
Do we need to do convex hulls all the time? Can complex meshes be left meshes?
|
Do we need to do convex hulls all the time? Can complex meshes be left meshes?
|
||||||
There is some problem with meshes and collisions
|
There is some problem with meshes and collisions
|
||||||
Test avatar walking up stairs. How does compare with SL.
|
Hulls are not as detailed as meshes. Hulled vehicles insides are different shape.
|
||||||
Radius of the capsule affects ability to climb edges.
|
|
||||||
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.
|
||||||
Use a different capsule shape for avatar when sitting
|
Use a different capsule shape for avatar when sitting
|
||||||
LL uses a pyrimidal shape scaled by the avatar's bounding box
|
LL uses a pyrimidal shape scaled by the avatar's bounding box
|
||||||
http://wiki.secondlife.com/wiki/File:Avmeshforms.png
|
http://wiki.secondlife.com/wiki/File:Avmeshforms.png
|
||||||
|
|
||||||
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 whether 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
|
||||||
Performance measurement and changes to make quicker.
|
Performance measurement and changes to make quicker.
|
||||||
Implement detailed physics stats (GetStats()).
|
Implement detailed physics stats (GetStats()).
|
||||||
|
|
||||||
Measure performance improvement from hulls
|
Measure performance improvement from hulls
|
||||||
Test not using ghost objects for volume detect implementation.
|
Test not using ghost objects for volume detect implementation.
|
||||||
Performance of closures and delegates for taint processing
|
Performance of closures and delegates for taint processing
|
||||||
|
@ -164,9 +158,7 @@ Performance of closures and delegates for taint processing
|
||||||
Is any slowdown introduced by the existing implementation significant?
|
Is any slowdown introduced by the existing implementation significant?
|
||||||
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
|
||||||
|
|
||||||
Physics Arena central pyramid: why is one side permiable?
|
Physics Arena central pyramid: why is one side permiable?
|
||||||
|
|
||||||
In SL, perfect spheres don't seem to have rolling friction. Add special case.
|
In SL, perfect spheres don't seem to have rolling friction. Add special case.
|
||||||
Enforce physical parameter min/max:
|
Enforce physical parameter min/max:
|
||||||
Gravity: [-1, 28]
|
Gravity: [-1, 28]
|
||||||
|
@ -178,6 +170,8 @@ Avatar attachments have no mass? http://forums-archive.secondlife.com/54/f0/3179
|
||||||
|
|
||||||
INTERNAL IMPROVEMENT/CLEANUP
|
INTERNAL IMPROVEMENT/CLEANUP
|
||||||
=================================================
|
=================================================
|
||||||
|
Can the 'inTaintTime' flag be cleaned up and used? For instance, a call to
|
||||||
|
BSScene.TaintedObject() could immediately execute the callback if already in taint time.
|
||||||
Create the physical wrapper classes (BulletBody, BulletShape) by methods on
|
Create the physical wrapper classes (BulletBody, BulletShape) by methods on
|
||||||
BSAPITemplate and make their actual implementation Bullet engine specific.
|
BSAPITemplate and make their actual implementation Bullet engine specific.
|
||||||
For the short term, just call the existing functions in ShapeCollection.
|
For the short term, just call the existing functions in ShapeCollection.
|
||||||
|
@ -197,22 +191,19 @@ Generalize Dynamics and PID with standardized motors.
|
||||||
Generalize Linkset and vehicles into PropertyManagers
|
Generalize Linkset and vehicles into PropertyManagers
|
||||||
Methods for Refresh, RemoveBodyDependencies, RestoreBodyDependencies
|
Methods for Refresh, RemoveBodyDependencies, RestoreBodyDependencies
|
||||||
Potentially add events for shape destruction, etc.
|
Potentially add events for shape destruction, etc.
|
||||||
Complete implemention of preStepActions
|
Better mechanism for resetting linkset set and vehicle parameters when body rebuilt.
|
||||||
Replace vehicle step call with prestep event.
|
BSPrim.CreateGeomAndObject is kludgy with the callbacks, etc.
|
||||||
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)
|
||||||
Linkset implementation using manual prim movement.
|
Linkset implementation using manual prim movement.
|
||||||
LinkablePrim class? Would that simplify/centralize the linkset logic?
|
LinkablePrim class? Would that simplify/centralize the linkset logic?
|
||||||
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
|
|
||||||
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()
|
||||||
Should taints check for existance or activeness of target?
|
Should taints check for existance or activeness of target?
|
||||||
When destroying linksets/etc, taints can be generated for objects that are
|
When destroying linksets/etc, taints can be generated for objects that are
|
||||||
actually gone when the taint happens. Crashes don't happen because the taint closure
|
actually gone when the taint happens. Crashes don't happen because the taint closure
|
||||||
keeps the object from being freed, but that is just an accident.
|
keeps the object from being freed, but that is just an accident.
|
||||||
Possibly have and 'active' flag that is checked by the taint processor?
|
Possibly have an 'active' flag that is checked by the taint processor?
|
||||||
Parameters for physics logging should be moved from BSScene to BSParam (at least boolean ones)
|
Parameters for physics logging should be moved from BSScene to BSParam (at least boolean ones)
|
||||||
Can some of the physical wrapper classes (BulletBody, BulletWorld, BulletShape) be 'sealed'?
|
Can some of the physical wrapper classes (BulletBody, BulletWorld, BulletShape) be 'sealed'?
|
||||||
There are TOO MANY interfaces from BulletSim core to Bullet itself
|
There are TOO MANY interfaces from BulletSim core to Bullet itself
|
||||||
|
@ -282,3 +273,18 @@ Redo BulletSimAPI to allow native C# implementation of Bullet option (DONE)
|
||||||
Meshes rendering as bounding boxes (DONE)
|
Meshes rendering as bounding boxes (DONE)
|
||||||
(Resolution: Added test for mesh/sculpties in native shapes so it didn't think it was a box)
|
(Resolution: Added test for mesh/sculpties in native shapes so it didn't think it was a box)
|
||||||
llMoveToTarget (Resolution: added simple motor to update the position.)
|
llMoveToTarget (Resolution: added simple motor to update the position.)
|
||||||
|
Angular motor direction is global coordinates rather than local coordinates (DONE)
|
||||||
|
Add vehicle collisions so IsColliding is properly reported. (DONE)
|
||||||
|
Needed for banking, limitMotorUp, movementLimiting, ...
|
||||||
|
(Resolution: added CollisionFlags.BS_VEHICLE_COLLISION and code to use it)
|
||||||
|
VehicleAddForce is not scaled by the simulation step but it is only
|
||||||
|
applied for one step. Should it be scaled? (DONE)
|
||||||
|
(Resolution: use force for timed things, Impulse for immediate, non-timed things)
|
||||||
|
Complete implemention of preStepActions (DONE)
|
||||||
|
Replace vehicle step call with prestep event.
|
||||||
|
Is there a need for postStepActions? postStepTaints?
|
||||||
|
Disable activity of passive linkset children. (DONE)
|
||||||
|
Since the linkset is a compound object, the old prims are left lying
|
||||||
|
around and need to be phantomized so they don't collide, ...
|
||||||
|
Remove HeightmapInfo from terrain specification (DONE)
|
||||||
|
Since C++ code does not need terrain height, this structure et al are not needed.
|
|
@ -97,13 +97,20 @@ namespace OpenSim.Region.Physics.Manager
|
||||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Name of this scene. Useful in debug messages to distinguish one OdeScene instance from another.
|
/// A unique identifying string for this instance of the physics engine.
|
||||||
|
/// Useful in debug messages to distinguish one OdeScene instance from another.
|
||||||
|
/// Usually set to include the region name that the physics engine is acting for.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Name { get; protected set; }
|
public string Name { get; protected set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A string identifying the family of this physics engine. Most common values returned
|
||||||
|
/// are "OpenDynamicsEngine" and "BulletSim" but others are possible.
|
||||||
|
/// </summary>
|
||||||
|
public string EngineType { get; protected set; }
|
||||||
|
|
||||||
// The only thing that should register for this event is the SceneGraph
|
// The only thing that should register for this event is the SceneGraph
|
||||||
// Anything else could cause problems.
|
// Anything else could cause problems.
|
||||||
|
|
||||||
public event physicsCrash OnPhysicsCrash;
|
public event physicsCrash OnPhysicsCrash;
|
||||||
|
|
||||||
public static PhysicsScene Null
|
public static PhysicsScene Null
|
||||||
|
|
|
@ -72,7 +72,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
// http://opensimulator.org/mantis/view.php?id=2750).
|
// http://opensimulator.org/mantis/view.php?id=2750).
|
||||||
d.InitODE();
|
d.InitODE();
|
||||||
|
|
||||||
m_scene = new OdeScene(sceneIdentifier);
|
m_scene = new OdeScene(GetName(), sceneIdentifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
return m_scene;
|
return m_scene;
|
||||||
|
|
|
@ -526,11 +526,12 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
/// These settings need to be tweaked 'exactly' right or weird stuff happens.
|
/// These settings need to be tweaked 'exactly' right or weird stuff happens.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param value="name">Name of the scene. Useful in debug messages.</param>
|
/// <param value="name">Name of the scene. Useful in debug messages.</param>
|
||||||
public OdeScene(string name)
|
public OdeScene(string engineType, string name)
|
||||||
{
|
{
|
||||||
m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType.ToString() + "." + name);
|
m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType.ToString() + "." + name);
|
||||||
|
|
||||||
Name = name;
|
Name = name;
|
||||||
|
EngineType = engineType;
|
||||||
|
|
||||||
nearCallback = near;
|
nearCallback = near;
|
||||||
triCallback = TriCallback;
|
triCallback = TriCallback;
|
||||||
|
|
|
@ -49,7 +49,7 @@ namespace OpenSim.Region.Physics.POSPlugin
|
||||||
|
|
||||||
public PhysicsScene GetScene(string sceneIdentifier)
|
public PhysicsScene GetScene(string sceneIdentifier)
|
||||||
{
|
{
|
||||||
return new POSScene(sceneIdentifier);
|
return new POSScene(GetName(), sceneIdentifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetName()
|
public string GetName()
|
||||||
|
|
|
@ -43,8 +43,10 @@ namespace OpenSim.Region.Physics.POSPlugin
|
||||||
|
|
||||||
//protected internal string sceneIdentifier;
|
//protected internal string sceneIdentifier;
|
||||||
|
|
||||||
public POSScene(String _sceneIdentifier)
|
public POSScene(string engineType, String _sceneIdentifier)
|
||||||
{
|
{
|
||||||
|
EngineType = engineType;
|
||||||
|
Name = EngineType + "/" + _sceneIdentifier;
|
||||||
//sceneIdentifier = _sceneIdentifier;
|
//sceneIdentifier = _sceneIdentifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -254,11 +254,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
wComm.DeliverMessage(ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.Name, m_host.UUID, message);
|
wComm.DeliverMessage(ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.Name, m_host.UUID, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns of the function is allowed. Throws a script exception if not allowed.
|
||||||
public void CheckThreatLevel(ThreatLevel level, string function)
|
public void CheckThreatLevel(ThreatLevel level, string function)
|
||||||
{
|
{
|
||||||
if (!m_OSFunctionsEnabled)
|
if (!m_OSFunctionsEnabled)
|
||||||
OSSLError(String.Format("{0} permission denied. All OS functions are disabled.", function)); // throws
|
OSSLError(String.Format("{0} permission denied. All OS functions are disabled.", function)); // throws
|
||||||
|
|
||||||
|
string reasonWhyNot = CheckThreatLevelTest(level, function);
|
||||||
|
if (!String.IsNullOrEmpty(reasonWhyNot))
|
||||||
|
{
|
||||||
|
OSSLError(reasonWhyNot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check to see if function is allowed. Returns an empty string if function permitted
|
||||||
|
// or a string explaining why this function can't be used.
|
||||||
|
private string CheckThreatLevelTest(ThreatLevel level, string function)
|
||||||
|
{
|
||||||
if (!m_FunctionPerms.ContainsKey(function))
|
if (!m_FunctionPerms.ContainsKey(function))
|
||||||
{
|
{
|
||||||
FunctionPerms perms = new FunctionPerms();
|
FunctionPerms perms = new FunctionPerms();
|
||||||
|
@ -338,10 +350,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
{
|
{
|
||||||
// Allow / disallow by threat level
|
// Allow / disallow by threat level
|
||||||
if (level > m_MaxThreatLevel)
|
if (level > m_MaxThreatLevel)
|
||||||
OSSLError(
|
return
|
||||||
String.Format(
|
String.Format(
|
||||||
"{0} permission denied. Allowed threat level is {1} but function threat level is {2}.",
|
"{0} permission denied. Allowed threat level is {1} but function threat level is {2}.",
|
||||||
function, m_MaxThreatLevel, level));
|
function, m_MaxThreatLevel, level);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -351,7 +363,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
if (m_FunctionPerms[function].AllowedOwners.Contains(m_host.OwnerID))
|
if (m_FunctionPerms[function].AllowedOwners.Contains(m_host.OwnerID))
|
||||||
{
|
{
|
||||||
// prim owner is in the list of allowed owners
|
// prim owner is in the list of allowed owners
|
||||||
return;
|
return String.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
UUID ownerID = m_item.OwnerID;
|
UUID ownerID = m_item.OwnerID;
|
||||||
|
@ -363,7 +375,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
|
|
||||||
if (land.LandData.GroupID == m_item.GroupID && land.LandData.GroupID != UUID.Zero)
|
if (land.LandData.GroupID == m_item.GroupID && land.LandData.GroupID != UUID.Zero)
|
||||||
{
|
{
|
||||||
return;
|
return String.Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -374,7 +386,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
|
|
||||||
if (land.LandData.OwnerID == ownerID)
|
if (land.LandData.OwnerID == ownerID)
|
||||||
{
|
{
|
||||||
return;
|
return String.Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -384,7 +396,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
//Only Estate Managers may use the function
|
//Only Estate Managers may use the function
|
||||||
if (World.RegionInfo.EstateSettings.IsEstateManagerOrOwner(ownerID) && World.RegionInfo.EstateSettings.EstateOwner != ownerID)
|
if (World.RegionInfo.EstateSettings.IsEstateManagerOrOwner(ownerID) && World.RegionInfo.EstateSettings.EstateOwner != ownerID)
|
||||||
{
|
{
|
||||||
return;
|
return String.Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -393,25 +405,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
{
|
{
|
||||||
if (World.RegionInfo.EstateSettings.EstateOwner == ownerID)
|
if (World.RegionInfo.EstateSettings.EstateOwner == ownerID)
|
||||||
{
|
{
|
||||||
return;
|
return String.Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_FunctionPerms[function].AllowedCreators.Contains(m_item.CreatorID))
|
if (!m_FunctionPerms[function].AllowedCreators.Contains(m_item.CreatorID))
|
||||||
OSSLError(
|
return(
|
||||||
String.Format("{0} permission denied. Script creator is not in the list of users allowed to execute this function and prim owner also has no permission.",
|
String.Format("{0} permission denied. Script creator is not in the list of users allowed to execute this function and prim owner also has no permission.",
|
||||||
function));
|
function));
|
||||||
|
|
||||||
if (m_item.CreatorID != ownerID)
|
if (m_item.CreatorID != ownerID)
|
||||||
{
|
{
|
||||||
if ((m_item.CurrentPermissions & (uint)PermissionMask.Modify) != 0)
|
if ((m_item.CurrentPermissions & (uint)PermissionMask.Modify) != 0)
|
||||||
OSSLError(
|
return String.Format("{0} permission denied. Script permissions error.", function);
|
||||||
String.Format("{0} permission denied. Script permissions error.",
|
|
||||||
function));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return String.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void OSSLDeprecated(string function, string replacement)
|
internal void OSSLDeprecated(string function, string replacement)
|
||||||
|
@ -1567,6 +1578,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string osGetPhysicsEngineType()
|
||||||
|
{
|
||||||
|
// High because it can be used to target attacks to known weaknesses
|
||||||
|
// This would allow a new class of griefer scripts that don't even
|
||||||
|
// require their user to know what they are doing (see script
|
||||||
|
// kiddie)
|
||||||
|
// Because it would be nice if scripts didn't blow up if the information
|
||||||
|
// about the physics engine, this function returns an empty string if
|
||||||
|
// the user does not have permission to see it. This as opposed to
|
||||||
|
// throwing an exception.
|
||||||
|
m_host.AddScriptLPS(1);
|
||||||
|
string ret = String.Empty;
|
||||||
|
if (String.IsNullOrEmpty(CheckThreatLevelTest(ThreatLevel.High, "osGetPhysicsEngineType")))
|
||||||
|
{
|
||||||
|
if (m_ScriptEngine.World.PhysicsScene != null)
|
||||||
|
{
|
||||||
|
ret = m_ScriptEngine.World.PhysicsScene.EngineType;
|
||||||
|
// An old physics engine might have an uninitialized engine type
|
||||||
|
if (ret == null)
|
||||||
|
ret = "unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
public string osGetSimulatorVersion()
|
public string osGetSimulatorVersion()
|
||||||
{
|
{
|
||||||
// High because it can be used to target attacks to known weaknesses
|
// High because it can be used to target attacks to known weaknesses
|
||||||
|
|
|
@ -259,6 +259,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
|
||||||
|
|
||||||
string osGetScriptEngineName();
|
string osGetScriptEngineName();
|
||||||
string osGetSimulatorVersion();
|
string osGetSimulatorVersion();
|
||||||
|
string osGetPhysicsEngineType();
|
||||||
Object osParseJSONNew(string JSON);
|
Object osParseJSONNew(string JSON);
|
||||||
Hashtable osParseJSON(string JSON);
|
Hashtable osParseJSON(string JSON);
|
||||||
|
|
||||||
|
|
|
@ -420,6 +420,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
|
||||||
return m_OSSL_Functions.osGetScriptEngineName();
|
return m_OSSL_Functions.osGetScriptEngineName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string osGetPhysicsEngineType()
|
||||||
|
{
|
||||||
|
return m_OSSL_Functions.osGetPhysicsEngineType();
|
||||||
|
}
|
||||||
|
|
||||||
public string osGetSimulatorVersion()
|
public string osGetSimulatorVersion()
|
||||||
{
|
{
|
||||||
return m_OSSL_Functions.osGetSimulatorVersion();
|
return m_OSSL_Functions.osGetSimulatorVersion();
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue