Merge branch 'master' of ssh://opensimulator.org/var/git/opensim
commit
c846cefda9
|
@ -6428,8 +6428,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
|
||||
AgentRequestSit handlerAgentRequestSit = OnAgentRequestSit;
|
||||
if (handlerAgentRequestSit != null)
|
||||
handlerAgentRequestSit(this, agentRequestSit.AgentData.AgentID,
|
||||
agentRequestSit.TargetObject.TargetID, agentRequestSit.TargetObject.Offset);
|
||||
if (!(agentRequestSit.AgentData == null
|
||||
|| agentRequestSit.TargetObject == null
|
||||
|| agentRequestSit.TargetObject.TargetID == null
|
||||
|| agentRequestSit.TargetObject.Offset == null))
|
||||
{
|
||||
var sp = m_scene.GetScenePresence(agentRequestSit.AgentData.AgentID);
|
||||
if (sp == null || sp.ParentID != 0) // ignore packet if agent is already sitting
|
||||
return true;
|
||||
|
||||
handlerAgentRequestSit(this, agentRequestSit.AgentData.AgentID,
|
||||
agentRequestSit.TargetObject.TargetID, agentRequestSit.TargetObject.Offset);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -4050,9 +4050,9 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
rigidBody,
|
||||
m_localId);
|
||||
}
|
||||
catch
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[SCENE]: caught exception meshing object {0}. Object set to phantom.", m_uuid);
|
||||
m_log.ErrorFormat("[SCENE]: caught exception meshing object {0}. Object set to phantom. e={1}", m_uuid, e);
|
||||
pa = null;
|
||||
}
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin
|
|||
|
||||
public PhysicsScene GetScene(string sceneIdentifier)
|
||||
{
|
||||
return new BasicScene(sceneIdentifier);
|
||||
return new BasicScene(GetName(), sceneIdentifier);
|
||||
}
|
||||
|
||||
public string GetName()
|
||||
|
|
|
@ -49,8 +49,10 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin
|
|||
|
||||
//protected internal string sceneIdentifier;
|
||||
|
||||
public BasicScene(string _sceneIdentifier)
|
||||
public BasicScene(string engineType, string _sceneIdentifier)
|
||||
{
|
||||
EngineType = engineType;
|
||||
Name = EngineType + "/" + _sceneIdentifier;
|
||||
//sceneIdentifier = _sceneIdentifier;
|
||||
}
|
||||
|
||||
|
|
|
@ -202,7 +202,7 @@ private void BulletLoggerPhysLog(string msg)
|
|||
}
|
||||
|
||||
public override int PhysicsStep(BulletWorld world, float timeStep, int maxSubSteps, float fixedTimeStep,
|
||||
out int updatedEntityCount, out int collidersCount)
|
||||
out int updatedEntityCount, out int collidersCount)
|
||||
{
|
||||
BulletWorldUnman worldu = world as BulletWorldUnman;
|
||||
return BSAPICPP.PhysicsStep2(worldu.ptr, timeStep, maxSubSteps, fixedTimeStep, out updatedEntityCount, out collidersCount);
|
||||
|
@ -327,6 +327,12 @@ public override void RemoveChildShapeFromCompoundShape(BulletShape shape, Bullet
|
|||
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)
|
||||
{
|
||||
BulletShapeUnman shapeu = shape as BulletShapeUnman;
|
||||
|
@ -1356,6 +1362,9 @@ public static extern IntPtr RemoveChildShapeFromCompoundShapeIndex2(IntPtr cShap
|
|||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
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]
|
||||
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 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)
|
||||
{
|
||||
|
|
|
@ -342,6 +342,8 @@ public abstract BulletShape RemoveChildShapeFromCompoundShapeIndex(BulletShape c
|
|||
|
||||
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 BulletShape DuplicateCollisionShape(BulletWorld sim, BulletShape srcShape, uint id);
|
||||
|
|
|
@ -126,9 +126,9 @@ public sealed class BSCharacter : BSPhysObject
|
|||
DetailLog("{0},BSCharacter.Destroy", LocalID);
|
||||
PhysicsScene.TaintedObject("BSCharacter.destroy", delegate()
|
||||
{
|
||||
PhysicsScene.Shapes.DereferenceBody(PhysBody, true, null);
|
||||
PhysicsScene.Shapes.DereferenceBody(PhysBody, true /* inTaintTime */, null /* bodyCallback */);
|
||||
PhysBody.Clear();
|
||||
PhysicsScene.Shapes.DereferenceShape(PhysShape, true, null);
|
||||
PhysicsScene.Shapes.DereferenceShape(PhysShape, true /* inTaintTime */, null /* bodyCallback */);
|
||||
PhysShape.Clear();
|
||||
});
|
||||
}
|
||||
|
@ -328,6 +328,10 @@ public sealed class BSCharacter : BSPhysObject
|
|||
public override bool Selected {
|
||||
set { _selected = value; }
|
||||
}
|
||||
public override bool IsSelected
|
||||
{
|
||||
get { return _selected; }
|
||||
}
|
||||
public override void CrossingFailure() { return; }
|
||||
public override void link(PhysicsActor obj) { return; }
|
||||
public override void delink() { return; }
|
||||
|
|
|
@ -108,10 +108,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
private float m_VhoverEfficiency = 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_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)
|
||||
// KF: So far I have found no good method to combine a script-requested .Z velocity and gravity.
|
||||
// Therefore only m_VehicleBuoyancy=1 (0g) will use the script-requested .Z velocity.
|
||||
// Modifies gravity. Slider between -1 (double-gravity) and 1 (full anti-gravity)
|
||||
private float m_VehicleBuoyancy = 0f;
|
||||
private Vector3 m_VehicleGravity = Vector3.Zero; // Gravity computed when buoyancy set
|
||||
|
||||
//Attractor properties
|
||||
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 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)
|
||||
{
|
||||
PhysicsScene = myScene;
|
||||
Prim = myPrim;
|
||||
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
|
||||
public bool IsActive
|
||||
{
|
||||
get { return Type != Vehicle.TYPE_NONE && Prim.IsPhysical; }
|
||||
get { return (Type != Vehicle.TYPE_NONE && !Prim.IsStatic); }
|
||||
}
|
||||
|
||||
#region Vehicle parameter setting
|
||||
|
@ -168,6 +188,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
break;
|
||||
case Vehicle.BUOYANCY:
|
||||
m_VehicleBuoyancy = ClampInRange(-1f, pValue, 1f);
|
||||
m_VehicleGravity = Prim.ComputeGravity(m_VehicleBuoyancy);
|
||||
break;
|
||||
case Vehicle.HOVER_EFFICIENCY:
|
||||
m_VhoverEfficiency = ClampInRange(0f, pValue, 1f);
|
||||
|
@ -540,12 +561,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
1f);
|
||||
m_angularMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging)
|
||||
|
||||
/* Not implemented
|
||||
m_verticalAttractionMotor = new BSVMotor("VerticalAttraction", m_verticalAttractionTimescale,
|
||||
BSMotor.Infinite, BSMotor.InfiniteVector,
|
||||
m_verticalAttractionEfficiency);
|
||||
// Z goes away and we keep X and Y
|
||||
m_verticalAttractionMotor.FrictionTimescale = new Vector3(BSMotor.Infinite, BSMotor.Infinite, 0.1f);
|
||||
m_verticalAttractionMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging)
|
||||
*/
|
||||
}
|
||||
#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
|
||||
PhysicsScene.PE.AddToCollisionFlags(Prim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS);
|
||||
|
||||
Vector3 localInertia = PhysicsScene.PE.CalculateLocalInertia(Prim.PhysShape, m_vehicleMass);
|
||||
PhysicsScene.PE.SetMassProps(Prim.PhysBody, m_vehicleMass, localInertia);
|
||||
Prim.Inertia = PhysicsScene.PE.CalculateLocalInertia(Prim.PhysShape, m_vehicleMass);
|
||||
PhysicsScene.PE.SetMassProps(Prim.PhysBody, m_vehicleMass, Prim.Inertia);
|
||||
PhysicsScene.PE.UpdateInertiaTensor(Prim.PhysBody);
|
||||
|
||||
Vector3 grav = PhysicsScene.DefaultGravity * (1f - Prim.Buoyancy);
|
||||
PhysicsScene.PE.SetGravity(Prim.PhysBody, grav);
|
||||
// Set the gravity for the vehicle depending on the buoyancy
|
||||
// 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}",
|
||||
Prim.LocalID, m_vehicleMass, friction, localInertia, angularDamping);
|
||||
VDetailLog("{0},BSDynamics.Refresh,mass={1},frict={2},inert={3},aDamp={4},grav={5}",
|
||||
Prim.LocalID, m_vehicleMass, friction, Prim.Inertia, angularDamping, m_VehicleGravity);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -619,6 +645,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
private Vector3 m_knownPosition;
|
||||
private Vector3 m_knownVelocity;
|
||||
private Vector3 m_knownForce;
|
||||
private Vector3 m_knownForceImpulse;
|
||||
private Quaternion m_knownOrientation;
|
||||
private Vector3 m_knownRotationalVelocity;
|
||||
private Vector3 m_knownRotationalForce;
|
||||
|
@ -627,12 +654,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
private const int m_knownChangedPosition = 1 << 0;
|
||||
private const int m_knownChangedVelocity = 1 << 1;
|
||||
private const int m_knownChangedForce = 1 << 2;
|
||||
private const int m_knownChangedOrientation = 1 << 3;
|
||||
private const int m_knownChangedRotationalVelocity = 1 << 4;
|
||||
private const int m_knownChangedRotationalForce = 1 << 5;
|
||||
private const int m_knownChangedTerrainHeight = 1 << 6;
|
||||
private const int m_knownChangedWaterLevel = 1 << 7;
|
||||
private const int m_knownChangedForwardVelocity = 1 << 8;
|
||||
private const int m_knownChangedForceImpulse = 1 << 3;
|
||||
private const int m_knownChangedOrientation = 1 << 4;
|
||||
private const int m_knownChangedRotationalVelocity = 1 << 5;
|
||||
private const int m_knownChangedRotationalForce = 1 << 6;
|
||||
private const int m_knownChangedTerrainHeight = 1 << 7;
|
||||
private const int m_knownChangedWaterLevel = 1 << 8;
|
||||
private const int m_knownChangedForwardVelocity = 1 << 9;
|
||||
|
||||
private void ForgetKnownVehicleProperties()
|
||||
{
|
||||
|
@ -653,21 +681,29 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
if ((m_knownChanged & m_knownChangedVelocity) != 0)
|
||||
{
|
||||
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)
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
// an UpdateProperties event to send the changes up to the simulator.
|
||||
|
@ -757,15 +793,26 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
}
|
||||
}
|
||||
|
||||
private void VehicleAddForce(Vector3 aForce)
|
||||
private void VehicleAddForce(Vector3 pForce)
|
||||
{
|
||||
if ((m_knownHas & m_knownChangedForce) == 0)
|
||||
{
|
||||
m_knownForce = Vector3.Zero;
|
||||
m_knownHas |= m_knownChangedForce;
|
||||
}
|
||||
m_knownForce += aForce;
|
||||
m_knownForce += pForce;
|
||||
m_knownChanged |= m_knownChangedForce;
|
||||
m_knownHas |= 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
|
||||
|
@ -844,86 +891,92 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
if (PhysicsScene.VehiclePhysicalLoggingEnabled)
|
||||
PhysicsScene.PE.DumpRigidBody(PhysicsScene.World, Prim.PhysBody);
|
||||
|
||||
VDetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}",
|
||||
Prim.LocalID, VehiclePosition, Prim.Force, VehicleVelocity, VehicleRotationalVelocity);
|
||||
VDetailLog("{0},BSDynamics.Step,done,pos={1}, force={2},velocity={3},angvel={4}",
|
||||
Prim.LocalID, VehiclePosition, m_knownForce, VehicleVelocity, VehicleRotationalVelocity);
|
||||
}
|
||||
|
||||
// Apply the effect of the linear motor and other linear motions (like hover and float).
|
||||
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
|
||||
// coordinates. Rotate the movement to world coordinates.
|
||||
linearMotorContribution *= VehicleOrientation;
|
||||
// All the contributions after this are world relative (mostly Z modifications)
|
||||
ComputeLinearTerrainHeightCorrection(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);
|
||||
ComputeLinearHover(pTimestep);
|
||||
|
||||
ComputeLinearBlockingEndPoint(pTimestep);
|
||||
|
||||
Vector3 limitMotorUpContribution = ComputeLinearMotorUp(pTimestep);
|
||||
ComputeLinearMotorUp(pTimestep);
|
||||
|
||||
// ==================================================================
|
||||
Vector3 newVelocity = linearMotorContribution
|
||||
+ terrainHeightContribution
|
||||
+ hoverContribution
|
||||
+ limitMotorUpContribution;
|
||||
|
||||
Vector3 newForce = buoyancyContribution;
|
||||
ApplyGravity(pTimestep);
|
||||
|
||||
// If not changing some axis, reduce out velocity
|
||||
if ((m_flags & (VehicleFlag.NO_X)) != 0)
|
||||
newVelocity.X = 0;
|
||||
if ((m_flags & (VehicleFlag.NO_Y)) != 0)
|
||||
newVelocity.Y = 0;
|
||||
if ((m_flags & (VehicleFlag.NO_Z)) != 0)
|
||||
newVelocity.Z = 0;
|
||||
if ((m_flags & (VehicleFlag.NO_X | VehicleFlag.NO_Y | VehicleFlag.NO_Z)) != 0)
|
||||
{
|
||||
Vector3 vel = VehicleVelocity;
|
||||
if ((m_flags & (VehicleFlag.NO_X)) != 0)
|
||||
vel.X = 0;
|
||||
if ((m_flags & (VehicleFlag.NO_Y)) != 0)
|
||||
vel.Y = 0;
|
||||
if ((m_flags & (VehicleFlag.NO_Z)) != 0)
|
||||
vel.Z = 0;
|
||||
VehicleVelocity = vel;
|
||||
}
|
||||
|
||||
// ==================================================================
|
||||
// Clamp high or low velocities
|
||||
float newVelocityLengthSq = newVelocity.LengthSquared();
|
||||
float newVelocityLengthSq = VehicleVelocity.LengthSquared();
|
||||
if (newVelocityLengthSq > 1000f)
|
||||
{
|
||||
newVelocity /= newVelocity.Length();
|
||||
newVelocity *= 1000f;
|
||||
VehicleVelocity /= VehicleVelocity.Length();
|
||||
VehicleVelocity *= 1000f;
|
||||
}
|
||||
else if (newVelocityLengthSq < 0.001f)
|
||||
newVelocity = Vector3.Zero;
|
||||
VehicleVelocity = Vector3.Zero;
|
||||
|
||||
// ==================================================================
|
||||
// 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
|
||||
);
|
||||
VDetailLog("{0}, MoveLinear,done,isColl={1},newVel={2}", Prim.LocalID, Prim.IsColliding, VehicleVelocity );
|
||||
|
||||
} // 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.
|
||||
// TODO: Consider taking the rotated size of the object or possibly casting a ray.
|
||||
if (VehiclePosition.Z < GetTerrainHeight(VehiclePosition))
|
||||
|
@ -935,13 +988,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
VDetailLog("{0}, MoveLinear,terrainHeight,terrainHeight={1},pos={2}",
|
||||
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_VhoverTimescale: time to achieve height
|
||||
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;
|
||||
pos.Z = m_VhoverTargetHeight;
|
||||
VehiclePosition = pos;
|
||||
|
||||
VDetailLog("{0}, MoveLinear,hover,pos={1},lockHoverHeight", Prim.LocalID, pos);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Error is positive if below the target and negative if above.
|
||||
float verticalError = m_VhoverTargetHeight - VehiclePosition.Z;
|
||||
float verticalCorrectionVelocity = verticalError / m_VhoverTimescale;
|
||||
float verticalCorrectionVelocity = verticalError / m_VhoverTimescale * pTimestep;
|
||||
|
||||
// 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)
|
||||
|
@ -1045,30 +1098,67 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
// TODO: this code is wrong. Also, what should it do for boats (height from water)?
|
||||
// This is just using the ground and a general collision check. Should really be using
|
||||
// a downward raycast to find what is below.
|
||||
public Vector3 ComputeLinearMotorUp(float pTimestep)
|
||||
public void ComputeLinearMotorUp(float pTimestep)
|
||||
{
|
||||
Vector3 ret = Vector3.Zero;
|
||||
float distanceAboveGround = 0f;
|
||||
|
||||
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);
|
||||
distanceAboveGround = VehiclePosition.Z - targetHeight;
|
||||
// Not colliding if the vehicle is off the ground
|
||||
if (!Prim.IsColliding)
|
||||
{
|
||||
// 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
|
||||
// (http://wiki.secondlife.com/wiki/Category:LSL_Vehicle), the downForce
|
||||
// has a decay factor. This says this force should
|
||||
// be computed with a motor.
|
||||
// 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);
|
||||
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,
|
||||
// from climbing their linear deflection into the sky.
|
||||
// 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)
|
||||
{
|
||||
angularMotorContribution.X = 0f;
|
||||
|
@ -1179,7 +1271,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
Vector3 ret = Vector3.Zero;
|
||||
|
||||
// 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.
|
||||
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.
|
||||
// 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
|
||||
Vector3 movingDirection = VehicleVelocity;
|
||||
|
@ -1303,7 +1395,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
{
|
||||
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.
|
||||
// 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))
|
||||
{
|
||||
// Cannot remove the root from a linkset.
|
||||
child.PositionDisplacement = OMV.Vector3.Zero;
|
||||
return this;
|
||||
}
|
||||
RemoveChildFromLinkset(child);
|
||||
|
@ -159,6 +160,7 @@ public abstract class BSLinkset
|
|||
}
|
||||
|
||||
// The child is down to a linkset of just itself
|
||||
child.PositionDisplacement = OMV.Vector3.Zero;
|
||||
return BSLinkset.Factory(PhysicsScene, child);
|
||||
}
|
||||
|
||||
|
@ -310,7 +312,7 @@ public abstract class BSLinkset
|
|||
|
||||
foreach (BSPhysObject bp in m_children)
|
||||
{
|
||||
com += bp.Position * bp.RawMass;
|
||||
com += bp.Position;
|
||||
}
|
||||
com /= (m_children.Count + 1);
|
||||
}
|
||||
|
|
|
@ -40,23 +40,33 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
// removed from the linkset.
|
||||
sealed class BSLinksetCompoundInfo : BSLinksetInfo
|
||||
{
|
||||
public OMV.Vector3 OffsetPos;
|
||||
public int Index;
|
||||
public OMV.Vector3 OffsetFromRoot;
|
||||
public OMV.Vector3 OffsetFromCenterOfMass;
|
||||
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;
|
||||
}
|
||||
public override void Clear()
|
||||
{
|
||||
OffsetPos = OMV.Vector3.Zero;
|
||||
Index = 0;
|
||||
OffsetFromRoot = OMV.Vector3.Zero;
|
||||
OffsetFromCenterOfMass = OMV.Vector3.Zero;
|
||||
OffsetRot = OMV.Quaternion.Identity;
|
||||
}
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder buff = new StringBuilder();
|
||||
buff.Append("<p=");
|
||||
buff.Append(OffsetPos.ToString());
|
||||
buff.Append("<i=");
|
||||
buff.Append(Index.ToString());
|
||||
buff.Append(",p=");
|
||||
buff.Append(OffsetFromRoot.ToString());
|
||||
buff.Append(",m=");
|
||||
buff.Append(OffsetFromCenterOfMass.ToString());
|
||||
buff.Append(",r=");
|
||||
buff.Append(OffsetRot.ToString());
|
||||
buff.Append(">");
|
||||
|
@ -170,6 +180,8 @@ public sealed class BSLinksetCompound : BSLinkset
|
|||
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)
|
||||
{
|
||||
// The user moving a child around requires the rebuilding of the linkset compound shape
|
||||
|
@ -182,6 +194,7 @@ public sealed class BSLinksetCompound : BSLinkset
|
|||
&& !physicalUpdate
|
||||
&& PhysicsScene.TerrainManager.IsWithinKnownTerrain(LinksetRoot.RawPosition))
|
||||
{
|
||||
// TODO: replace this with are calculation of the child prim's orientation and pos.
|
||||
updated.LinksetInfo = null;
|
||||
ScheduleRebuild(updated);
|
||||
}
|
||||
|
@ -230,7 +243,7 @@ public sealed class BSLinksetCompound : BSLinkset
|
|||
if (inTaintTime)
|
||||
{
|
||||
OMV.Vector3 oldPos = child.RawPosition;
|
||||
child.ForcePosition = LinksetRoot.RawPosition + lci.OffsetPos;
|
||||
child.ForcePosition = LinksetRoot.RawPosition + lci.OffsetFromRoot;
|
||||
child.ForceOrientation = LinksetRoot.RawOrientation * lci.OffsetRot;
|
||||
DetailLog("{0},BSLinksetCompound.RecomputeChildWorldPosition,oldPos={1},lci={2},newPos={3}",
|
||||
child.LocalID, oldPos, lci, child.RawPosition);
|
||||
|
@ -238,7 +251,7 @@ public sealed class BSLinksetCompound : BSLinkset
|
|||
else
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
@ -306,6 +319,7 @@ public sealed class BSLinksetCompound : BSLinkset
|
|||
// Constraint linksets are rebuilt every time.
|
||||
// Note that this works for rebuilding just the root after a linkset is taken apart.
|
||||
// Called at taint time!!
|
||||
private bool disableCOM = true; // disable until we get this debugged
|
||||
private void RecomputeLinksetCompound()
|
||||
{
|
||||
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
|
||||
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}",
|
||||
LinksetRoot.LocalID, LinksetRoot.PhysBody, LinksetRoot.PhysShape, NumberOfChildren);
|
||||
|
||||
// Add a shape for each of the other children in the linkset
|
||||
int memberIndex = 1;
|
||||
ForEachMember(delegate(BSPhysObject cPrim)
|
||||
{
|
||||
if (!IsRoot(cPrim))
|
||||
|
@ -331,19 +369,21 @@ public sealed class BSLinksetCompound : BSLinkset
|
|||
BSLinksetCompoundInfo lci = cPrim.LinksetInfo as BSLinksetCompoundInfo;
|
||||
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.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;
|
||||
|
||||
// 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;
|
||||
DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,creatingRelPos,lci={1}", cPrim.LocalID, lci);
|
||||
}
|
||||
|
||||
DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addMemberToShape,mID={1},mShape={2},dispPos={3},dispRot={4}",
|
||||
LinksetRoot.LocalID, cPrim.LocalID, cPrim.PhysShape, lci.OffsetPos, lci.OffsetRot);
|
||||
DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addMemberToShape,mID={1},mShape={2},lci={3}",
|
||||
LinksetRoot.LocalID, cPrim.LocalID, cPrim.PhysShape, lci);
|
||||
|
||||
if (cPrim.PhysShape.isNativeShape)
|
||||
{
|
||||
|
@ -359,7 +399,7 @@ public sealed class BSLinksetCompound : BSLinkset
|
|||
PhysicsScene.Shapes.CreateGeomMeshOrHull(cPrim, null);
|
||||
BulletShape newShape = cPrim.PhysShape;
|
||||
cPrim.PhysShape = saveShape;
|
||||
PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, newShape, lci.OffsetPos, lci.OffsetRot);
|
||||
PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, newShape, lci.OffsetFromCenterOfMass, lci.OffsetRot);
|
||||
}
|
||||
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}",
|
||||
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
|
||||
});
|
||||
|
|
|
@ -80,6 +80,7 @@ public static class BSParam
|
|||
public static float AvatarStepForceFactor { 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 LinkConstraintUseFrameOffset { get; private set; }
|
||||
|
@ -427,6 +428,11 @@ public static class BSParam
|
|||
(s,cf,p,v) => { VehicleAngularDamping = cf.GetFloat(p, v); },
|
||||
(s) => { return VehicleAngularDamping; },
|
||||
(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)",
|
||||
0f,
|
||||
|
|
|
@ -73,6 +73,8 @@ public abstract class BSPhysObject : PhysicsActor
|
|||
|
||||
// A linkset of just me
|
||||
Linkset = BSLinkset.Factory(PhysicsScene, this);
|
||||
PositionDisplacement = OMV.Vector3.Zero;
|
||||
|
||||
LastAssetBuildFailed = false;
|
||||
|
||||
// Default material type
|
||||
|
@ -135,6 +137,7 @@ public abstract class BSPhysObject : PhysicsActor
|
|||
public virtual OMV.Vector3 Scale { get; set; }
|
||||
public abstract bool IsSolid { get; }
|
||||
public abstract bool IsStatic { get; }
|
||||
public abstract bool IsSelected { get; }
|
||||
|
||||
// Materialness
|
||||
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 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 ForceOrientation { get; set; }
|
||||
|
||||
|
@ -371,10 +382,13 @@ public abstract class BSPhysObject : PhysicsActor
|
|||
{
|
||||
string identifier = op + "-" + id.ToString();
|
||||
|
||||
// Clean out any existing action
|
||||
UnRegisterPreStepAction(op, id);
|
||||
lock (RegisteredActions)
|
||||
{
|
||||
// Clean out any existing action
|
||||
UnRegisterPreStepAction(op, id);
|
||||
|
||||
RegisteredActions[identifier] = actn;
|
||||
RegisteredActions[identifier] = actn;
|
||||
}
|
||||
PhysicsScene.BeforeStep += actn;
|
||||
DetailLog("{0},BSPhysObject.RegisterPreStepAction,id={1}", LocalID, identifier);
|
||||
}
|
||||
|
@ -384,22 +398,28 @@ public abstract class BSPhysObject : PhysicsActor
|
|||
{
|
||||
string identifier = op + "-" + id.ToString();
|
||||
bool removed = false;
|
||||
if (RegisteredActions.ContainsKey(identifier))
|
||||
lock (RegisteredActions)
|
||||
{
|
||||
PhysicsScene.BeforeStep -= RegisteredActions[identifier];
|
||||
RegisteredActions.Remove(identifier);
|
||||
removed = true;
|
||||
if (RegisteredActions.ContainsKey(identifier))
|
||||
{
|
||||
PhysicsScene.BeforeStep -= RegisteredActions[identifier];
|
||||
RegisteredActions.Remove(identifier);
|
||||
removed = true;
|
||||
}
|
||||
}
|
||||
DetailLog("{0},BSPhysObject.UnRegisterPreStepAction,id={1},removed={2}", LocalID, identifier, removed);
|
||||
}
|
||||
|
||||
protected void UnRegisterAllPreStepActions()
|
||||
{
|
||||
foreach (KeyValuePair<string, BSScene.PreStepAction> kvp in RegisteredActions)
|
||||
lock (RegisteredActions)
|
||||
{
|
||||
PhysicsScene.BeforeStep -= kvp.Value;
|
||||
foreach (KeyValuePair<string, BSScene.PreStepAction> kvp in RegisteredActions)
|
||||
{
|
||||
PhysicsScene.BeforeStep -= kvp.Value;
|
||||
}
|
||||
RegisteredActions.Clear();
|
||||
}
|
||||
RegisteredActions.Clear();
|
||||
DetailLog("{0},BSPhysObject.UnRegisterAllPreStepActions,", LocalID);
|
||||
}
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ public class BSPlugin : IPhysicsPlugin
|
|||
{
|
||||
if (_mScene == null)
|
||||
{
|
||||
_mScene = new BSScene(sceneIdentifier);
|
||||
_mScene = new BSScene(GetName(), sceneIdentifier);
|
||||
}
|
||||
return (_mScene);
|
||||
}
|
||||
|
|
|
@ -50,7 +50,10 @@ public sealed class BSPrim : BSPhysObject
|
|||
private bool _grabbed;
|
||||
private bool _isSelected;
|
||||
private bool _isVolumeDetect;
|
||||
|
||||
// _position is what the simulator thinks the positions of the prim is.
|
||||
private OMV.Vector3 _position;
|
||||
|
||||
private float _mass; // the mass of this object
|
||||
private float _density;
|
||||
private OMV.Vector3 _force;
|
||||
|
@ -169,6 +172,7 @@ public sealed class BSPrim : BSPhysObject
|
|||
public override PrimitiveBaseShape Shape {
|
||||
set {
|
||||
BaseShape = value;
|
||||
LastAssetBuildFailed = false;
|
||||
ForceBodyShapeRebuild(false);
|
||||
}
|
||||
}
|
||||
|
@ -178,7 +182,6 @@ public sealed class BSPrim : BSPhysObject
|
|||
|
||||
public override bool ForceBodyShapeRebuild(bool inTaintTime)
|
||||
{
|
||||
LastAssetBuildFailed = false;
|
||||
PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ForceBodyShapeRebuild", delegate()
|
||||
{
|
||||
_mass = CalculateMass(); // changing the shape changes the mass
|
||||
|
@ -204,6 +207,10 @@ public sealed class BSPrim : BSPhysObject
|
|||
}
|
||||
}
|
||||
}
|
||||
public override bool IsSelected
|
||||
{
|
||||
get { return _isSelected; }
|
||||
}
|
||||
public override void CrossingFailure() { return; }
|
||||
|
||||
// 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.
|
||||
// _position = PhysicsScene.PE.GetObjectPosition2(PhysicsScene.World, BSBody);
|
||||
// _position = PhysicsScene.PE.GetObjectPosition2(PhysicsScene.World, BSBody) - PositionDisplacement;
|
||||
return _position;
|
||||
}
|
||||
set {
|
||||
|
@ -316,18 +323,37 @@ public sealed class BSPrim : BSPhysObject
|
|||
}
|
||||
public override OMV.Vector3 ForcePosition {
|
||||
get {
|
||||
_position = PhysicsScene.PE.GetPosition(PhysBody);
|
||||
_position = PhysicsScene.PE.GetPosition(PhysBody) - PositionDisplacement;
|
||||
return _position;
|
||||
}
|
||||
set {
|
||||
_position = value;
|
||||
if (PhysBody.HasPhysicalBody)
|
||||
{
|
||||
PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation);
|
||||
PhysicsScene.PE.SetTranslation(PhysBody, _position + PositionDisplacement, _orientation);
|
||||
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 for being below terrain and being out of bounds.
|
||||
|
@ -336,7 +362,7 @@ public sealed class BSPrim : BSPhysObject
|
|||
{
|
||||
bool ret = false;
|
||||
|
||||
if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(_position))
|
||||
if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(RawPosition))
|
||||
{
|
||||
// The physical object is out of the known/simulated area.
|
||||
// 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);
|
||||
float targetHeight = terrainHeight + (Size.Z / 2f);
|
||||
// Upforce proportional to the distance away from the terrain. Correct the error in 1 sec.
|
||||
upForce.Z = (terrainHeight - RawPosition.Z) * 1f;
|
||||
// If the object is below ground it just has to be moved up because pushing will
|
||||
// not get it through the terrain
|
||||
_position.Z = targetHeight;
|
||||
if (inTaintTime)
|
||||
ForcePosition = _position;
|
||||
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.Z = (waterHeight - RawPosition.Z) * 1f;
|
||||
|
||||
// Apply upforce and overcome gravity.
|
||||
OMV.Vector3 correctionForce = upForce - PhysicsScene.DefaultGravity;
|
||||
DetailLog("{0},BSPrim.PositionSanityCheck,applyForce,pos={1},upForce={2},correctionForce={3}", LocalID, _position, upForce, correctionForce);
|
||||
AddForce(correctionForce, false, inTaintTime);
|
||||
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.
|
||||
OMV.Vector3 correctionForce = upForce - PhysicsScene.DefaultGravity;
|
||||
DetailLog("{0},BSPrim.PositionSanityCheck,applyForce,pos={1},upForce={2},correctionForce={3}", LocalID, _position, upForce, correctionForce);
|
||||
AddForce(correctionForce, false, inTaintTime);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -410,7 +434,7 @@ public sealed class BSPrim : BSPhysObject
|
|||
}
|
||||
else
|
||||
{
|
||||
OMV.Vector3 grav = ComputeGravity();
|
||||
OMV.Vector3 grav = ComputeGravity(Buoyancy);
|
||||
|
||||
if (inWorld)
|
||||
{
|
||||
|
@ -445,12 +469,12 @@ public sealed class BSPrim : BSPhysObject
|
|||
}
|
||||
|
||||
// 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;
|
||||
|
||||
if (!IsStatic)
|
||||
ret *= (1f - Buoyancy);
|
||||
ret *= (1f - buoyancy);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -586,6 +610,7 @@ public sealed class BSPrim : BSPhysObject
|
|||
_velocity = value;
|
||||
if (PhysBody.HasPhysicalBody)
|
||||
{
|
||||
DetailLog("{0},BSPrim.ForceVelocity,taint,vel={1}", LocalID, _velocity);
|
||||
PhysicsScene.PE.SetLinearVelocity(PhysBody, _velocity);
|
||||
ActivateIfPhysical(false);
|
||||
}
|
||||
|
@ -650,12 +675,7 @@ public sealed class BSPrim : BSPhysObject
|
|||
|
||||
PhysicsScene.TaintedObject("BSPrim.setOrientation", delegate()
|
||||
{
|
||||
if (PhysBody.HasPhysicalBody)
|
||||
{
|
||||
// _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);
|
||||
}
|
||||
ForceOrientation = _orientation;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -670,7 +690,8 @@ public sealed class BSPrim : BSPhysObject
|
|||
set
|
||||
{
|
||||
_orientation = value;
|
||||
PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation);
|
||||
if (PhysBody.HasPhysicalBody)
|
||||
PhysicsScene.PE.SetTranslation(PhysBody, _position + PositionDisplacement, _orientation);
|
||||
}
|
||||
}
|
||||
public override int PhysicsActorType {
|
||||
|
@ -809,7 +830,7 @@ public sealed class BSPrim : BSPhysObject
|
|||
// PhysicsScene.PE.ClearAllForces(BSBody);
|
||||
|
||||
// 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
|
||||
// DEBUG DEBUG PhysicsScene.PE.SetCenterOfMassByPosRot(Linkset.LinksetRoot.PhysBody, _position, _orientation);
|
||||
|
@ -1153,33 +1174,70 @@ public sealed class BSPrim : BSPhysObject
|
|||
// This added force will only last the next simulation tick.
|
||||
public void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) {
|
||||
// for an object, doesn't matter if force is a pushforce or not
|
||||
if (!IsStatic && force.IsFinite())
|
||||
if (!IsStatic)
|
||||
{
|
||||
float magnitude = force.Length();
|
||||
if (magnitude > BSParam.MaxAddForceMagnitude)
|
||||
if (force.IsFinite())
|
||||
{
|
||||
// Force has a limit
|
||||
force = force / magnitude * BSParam.MaxAddForceMagnitude;
|
||||
}
|
||||
|
||||
OMV.Vector3 addForce = force;
|
||||
// DetailLog("{0},BSPrim.addForce,call,force={1}", LocalID, addForce);
|
||||
|
||||
PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddForce", delegate()
|
||||
{
|
||||
// Bullet adds this central force to the total force for this tick
|
||||
DetailLog("{0},BSPrim.addForce,taint,force={1}", LocalID, addForce);
|
||||
if (PhysBody.HasPhysicalBody)
|
||||
float magnitude = force.Length();
|
||||
if (magnitude > BSParam.MaxAddForceMagnitude)
|
||||
{
|
||||
PhysicsScene.PE.ApplyCentralForce(PhysBody, addForce);
|
||||
ActivateIfPhysical(false);
|
||||
// Force has a limit
|
||||
force = force / magnitude * BSParam.MaxAddForceMagnitude;
|
||||
}
|
||||
});
|
||||
|
||||
OMV.Vector3 addForce = force;
|
||||
// DetailLog("{0},BSPrim.addForce,call,force={1}", LocalID, addForce);
|
||||
|
||||
PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddForce", delegate()
|
||||
{
|
||||
// Bullet adds this central force to the total force for this tick
|
||||
DetailLog("{0},BSPrim.addForce,taint,force={1}", LocalID, addForce);
|
||||
if (PhysBody.HasPhysicalBody)
|
||||
{
|
||||
PhysicsScene.PE.ApplyCentralForce(PhysBody, addForce);
|
||||
ActivateIfPhysical(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.WarnFormat("{0}: AddForce: Got a NaN force applied to a prim. LocalID={1}", LogHeader, LocalID);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
m_log.WarnFormat("{0}: Got a NaN force applied to a prim. LocalID={1}", LogHeader, LocalID);
|
||||
return;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1561,21 +1619,6 @@ public sealed class BSPrim : BSPhysObject
|
|||
|
||||
// The physics engine says that properties have updated. Update same and inform
|
||||
// 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)
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
_orientation = entprop.Rotation;
|
||||
_velocity = entprop.Velocity;
|
||||
|
|
|
@ -167,11 +167,16 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
|||
public bool VehiclePhysicalLoggingEnabled { get; private set; }
|
||||
|
||||
#region Construction and Initialization
|
||||
public BSScene(string identifier)
|
||||
public BSScene(string engineType, string identifier)
|
||||
{
|
||||
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;
|
||||
|
||||
// Set identifying variables in the PhysicsScene interface.
|
||||
EngineType = engineType;
|
||||
Name = EngineType + "/" + RegionName;
|
||||
}
|
||||
|
||||
public override void Initialise(IMesher meshmerizer, IConfigSource config)
|
||||
|
@ -382,12 +387,14 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
|||
if (!m_initialized) return null;
|
||||
|
||||
BSCharacter actor = new BSCharacter(localID, avName, this, position, size, isFlying);
|
||||
lock (PhysObjects) PhysObjects.Add(localID, actor);
|
||||
lock (PhysObjects)
|
||||
PhysObjects.Add(localID, actor);
|
||||
|
||||
// TODO: Remove kludge someday.
|
||||
// We must generate a collision for avatars whether they collide or not.
|
||||
// This is required by OpenSim to update avatar animations, etc.
|
||||
lock (m_avatars) m_avatars.Add(actor);
|
||||
lock (m_avatars)
|
||||
m_avatars.Add(actor);
|
||||
|
||||
return actor;
|
||||
}
|
||||
|
@ -403,9 +410,11 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
|||
{
|
||||
try
|
||||
{
|
||||
lock (PhysObjects) PhysObjects.Remove(actor.LocalID);
|
||||
lock (PhysObjects)
|
||||
PhysObjects.Remove(bsactor.LocalID);
|
||||
// Remove kludge someday
|
||||
lock (m_avatars) m_avatars.Remove(bsactor);
|
||||
lock (m_avatars)
|
||||
m_avatars.Remove(bsactor);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
@ -414,6 +423,11 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
|||
bsactor.Destroy();
|
||||
// bsactor.dispose();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.ErrorFormat("{0}: Requested to remove avatar that is not a BSCharacter. ID={1}, type={2}",
|
||||
LogHeader, actor.LocalID, actor.GetType().Name);
|
||||
}
|
||||
}
|
||||
|
||||
public override void RemovePrim(PhysicsActor prim)
|
||||
|
@ -486,6 +500,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
|||
ProcessTaints();
|
||||
|
||||
// Some of the physical objects requre individual, pre-step calls
|
||||
// (vehicles and avatar movement, in particular)
|
||||
TriggerPreStepEvent(timeStep);
|
||||
|
||||
// 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 =
|
||||
BuildPhysicalNativeShape(prim, BSPhysicsShapeType.SHAPE_BOX, FixedShapeKey.KEY_BOX);
|
||||
|
||||
|
|
|
@ -1,12 +1,17 @@
|
|||
CURRENT PRIORITIES
|
||||
=================================================
|
||||
Avatars walking up stairs (HALF DONE)
|
||||
Vehicle movement on terrain smoothness
|
||||
Nebadon vehicles turning funny in arena
|
||||
limitMotorUp calibration (more down?)
|
||||
Preferred orientation angular correction fix
|
||||
Vehicle angular vertical attraction
|
||||
Vehicle angular deflection
|
||||
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
|
||||
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
|
||||
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)
|
||||
|
@ -33,19 +38,15 @@ CRASHES
|
|||
|
||||
VEHICLES TODO LIST:
|
||||
=================================================
|
||||
Angular motor direction is global coordinates rather than local coordinates
|
||||
Border crossing with linked vehicle causes crash
|
||||
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.
|
||||
Cannot edit/move a vehicle being ridden: it jumps back to the origional position.
|
||||
Neb car jiggling left and right
|
||||
Happens on terrain and any other mesh object. Flat cubes are much smoother.
|
||||
This has been reduced but not eliminated.
|
||||
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.
|
||||
Verify that angular motion specified around Z moves in the vehicle coordinates.
|
||||
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)
|
||||
Need to force a position update for the root prim after compound shape destruction
|
||||
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().
|
||||
A kludge that isn't fixing the real problem of Bullet adding extra motion.
|
||||
Incorporate inter-relationship of angular corrections. For instance, angularDeflection
|
||||
and angularMotorUp will compute same X or Y correction. When added together
|
||||
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.
|
||||
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
|
||||
and return when getting position, velocity, ...
|
||||
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.
|
||||
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
|
||||
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).
|
||||
|
@ -138,25 +136,21 @@ MORE
|
|||
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?
|
||||
There is some problem with meshes and collisions
|
||||
Test avatar walking up stairs. How does compare with SL.
|
||||
Radius of the capsule affects ability to climb edges.
|
||||
Hulls are not as detailed as meshes. Hulled vehicles insides are different shape.
|
||||
Debounce avatar contact so legs don't keep folding up when standing.
|
||||
Implement LSL physics controls. Like STATUS_ROTATE_X.
|
||||
Add border extensions to terrain to help region crossings and objects leaving region.
|
||||
Use a different capsule shape for avatar when sitting
|
||||
LL uses a pyrimidal shape scaled by the avatar's bounding box
|
||||
http://wiki.secondlife.com/wiki/File:Avmeshforms.png
|
||||
|
||||
Performance test with lots of avatars. Can BulletSim support a thousand?
|
||||
Optimize collisions in C++: only send up to the object subscribed to collisions.
|
||||
Use collision subscription and remove the collsion(A,B) and collision(B,A)
|
||||
Check whether SimMotionState needs large if statement (see TODO).
|
||||
|
||||
Implement 'top colliders' info.
|
||||
Avatar jump
|
||||
Performance measurement and changes to make quicker.
|
||||
Implement detailed physics stats (GetStats()).
|
||||
|
||||
Measure performance improvement from hulls
|
||||
Test not using ghost objects for volume detect implementation.
|
||||
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 there are more efficient method of implementing pre and post step actions?
|
||||
See http://www.codeproject.com/Articles/29922/Weak-Events-in-C
|
||||
|
||||
Physics Arena central pyramid: why is one side permiable?
|
||||
|
||||
In SL, perfect spheres don't seem to have rolling friction. Add special case.
|
||||
Enforce physical parameter min/max:
|
||||
Gravity: [-1, 28]
|
||||
|
@ -178,6 +170,8 @@ Avatar attachments have no mass? http://forums-archive.secondlife.com/54/f0/3179
|
|||
|
||||
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
|
||||
BSAPITemplate and make their actual implementation Bullet engine specific.
|
||||
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
|
||||
Methods for Refresh, RemoveBodyDependencies, RestoreBodyDependencies
|
||||
Potentially add events for shape destruction, etc.
|
||||
Complete implemention of preStepActions
|
||||
Replace vehicle step call with prestep event.
|
||||
Is there a need for postStepActions? postStepTaints?
|
||||
Better mechanism for resetting linkset set and vehicle parameters when body rebuilt.
|
||||
BSPrim.CreateGeomAndObject is kludgy with the callbacks, etc.
|
||||
Implement linkset by setting position of children when root updated. (LinksetManual)
|
||||
Linkset implementation using manual prim movement.
|
||||
LinkablePrim class? Would that simplify/centralize the linkset logic?
|
||||
BSScene.UpdateParameterSet() is broken. How to set params on objects?
|
||||
Remove HeightmapInfo from terrain specification
|
||||
Since C++ code does not need terrain height, this structure et al are not needed.
|
||||
Add floating motor for BS_FLOATS_ON_WATER so prim and avatar will
|
||||
bob at the water level. BSPrim.PositionSanityCheck().
|
||||
bob at the water level. BSPrim.PositionSanityCheck()
|
||||
Should taints check for existance or activeness of target?
|
||||
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
|
||||
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)
|
||||
Can some of the physical wrapper classes (BulletBody, BulletWorld, BulletShape) be 'sealed'?
|
||||
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)
|
||||
(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.)
|
||||
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.
|
|
@ -62,13 +62,20 @@ namespace OpenSim.Region.Physics.Manager
|
|||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
/// <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>
|
||||
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
|
||||
// Anything else could cause problems.
|
||||
|
||||
public event physicsCrash OnPhysicsCrash;
|
||||
|
||||
public static PhysicsScene Null
|
||||
|
|
|
@ -72,7 +72,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
// http://opensimulator.org/mantis/view.php?id=2750).
|
||||
d.InitODE();
|
||||
|
||||
m_scene = new OdeScene(sceneIdentifier);
|
||||
m_scene = new OdeScene(GetName(), sceneIdentifier);
|
||||
}
|
||||
|
||||
return m_scene;
|
||||
|
|
|
@ -526,11 +526,12 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
/// These settings need to be tweaked 'exactly' right or weird stuff happens.
|
||||
/// </summary>
|
||||
/// <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);
|
||||
|
||||
Name = name;
|
||||
EngineType = engineType;
|
||||
|
||||
nearCallback = near;
|
||||
triCallback = TriCallback;
|
||||
|
|
|
@ -49,7 +49,7 @@ namespace OpenSim.Region.Physics.POSPlugin
|
|||
|
||||
public PhysicsScene GetScene(string sceneIdentifier)
|
||||
{
|
||||
return new POSScene(sceneIdentifier);
|
||||
return new POSScene(GetName(), sceneIdentifier);
|
||||
}
|
||||
|
||||
public string GetName()
|
||||
|
|
|
@ -43,8 +43,10 @@ namespace OpenSim.Region.Physics.POSPlugin
|
|||
|
||||
//protected internal string sceneIdentifier;
|
||||
|
||||
public POSScene(String _sceneIdentifier)
|
||||
public POSScene(string engineType, String _sceneIdentifier)
|
||||
{
|
||||
EngineType = engineType;
|
||||
Name = EngineType + "/" + _sceneIdentifier;
|
||||
//sceneIdentifier = _sceneIdentifier;
|
||||
}
|
||||
|
||||
|
|
|
@ -245,11 +245,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
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)
|
||||
{
|
||||
if (!m_OSFunctionsEnabled)
|
||||
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))
|
||||
{
|
||||
FunctionPerms perms = new FunctionPerms();
|
||||
|
@ -329,10 +341,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
{
|
||||
// Allow / disallow by threat level
|
||||
if (level > m_MaxThreatLevel)
|
||||
OSSLError(
|
||||
return
|
||||
String.Format(
|
||||
"{0} permission denied. Allowed threat level is {1} but function threat level is {2}.",
|
||||
function, m_MaxThreatLevel, level));
|
||||
function, m_MaxThreatLevel, level);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -342,7 +354,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
if (m_FunctionPerms[function].AllowedOwners.Contains(m_host.OwnerID))
|
||||
{
|
||||
// prim owner is in the list of allowed owners
|
||||
return;
|
||||
return String.Empty;
|
||||
}
|
||||
|
||||
UUID ownerID = m_item.OwnerID;
|
||||
|
@ -354,7 +366,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
|
||||
if (land.LandData.GroupID == m_item.GroupID && land.LandData.GroupID != UUID.Zero)
|
||||
{
|
||||
return;
|
||||
return String.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -365,7 +377,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
|
||||
if (land.LandData.OwnerID == ownerID)
|
||||
{
|
||||
return;
|
||||
return String.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -375,7 +387,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
//Only Estate Managers may use the function
|
||||
if (World.RegionInfo.EstateSettings.IsEstateManagerOrOwner(ownerID) && World.RegionInfo.EstateSettings.EstateOwner != ownerID)
|
||||
{
|
||||
return;
|
||||
return String.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -384,25 +396,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
{
|
||||
if (World.RegionInfo.EstateSettings.EstateOwner == ownerID)
|
||||
{
|
||||
return;
|
||||
return String.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
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.",
|
||||
function));
|
||||
|
||||
if (m_item.CreatorID != ownerID)
|
||||
{
|
||||
if ((m_item.CurrentPermissions & (uint)PermissionMask.Modify) != 0)
|
||||
OSSLError(
|
||||
String.Format("{0} permission denied. Script permissions error.",
|
||||
function));
|
||||
return String.Format("{0} permission denied. Script permissions error.", function);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return String.Empty;
|
||||
}
|
||||
|
||||
internal void OSSLDeprecated(string function, string replacement)
|
||||
|
@ -1558,6 +1569,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()
|
||||
{
|
||||
// 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 osGetSimulatorVersion();
|
||||
string osGetPhysicsEngineType();
|
||||
Object osParseJSONNew(string JSON);
|
||||
Hashtable osParseJSON(string JSON);
|
||||
|
||||
|
|
|
@ -420,6 +420,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
|
|||
return m_OSSL_Functions.osGetScriptEngineName();
|
||||
}
|
||||
|
||||
public string osGetPhysicsEngineType()
|
||||
{
|
||||
return m_OSSL_Functions.osGetPhysicsEngineType();
|
||||
}
|
||||
|
||||
public string 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