diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index a8517e60f3..967fa44978 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -6427,19 +6427,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP #endregion AgentRequestSit handlerAgentRequestSit = OnAgentRequestSit; - if (handlerAgentRequestSit != null) - 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); - } + if (handlerAgentRequestSit != null) + handlerAgentRequestSit(this, agentRequestSit.AgentData.AgentID, + agentRequestSit.TargetObject.TargetID, agentRequestSit.TargetObject.Offset); } return true; } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 232861e166..44e8fdf7c9 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -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; } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 0219540841..6979c33d11 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1954,6 +1954,10 @@ namespace OpenSim.Region.Framework.Scenes { if (ParentID != 0) { + var targetPart = m_scene.GetSceneObjectPart(targetID); + if (targetPart != null && targetPart.LocalId == ParentID) + return; // already sitting here, ignore + StandUp(); } diff --git a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs index 7ab2a03695..373c7e0015 100644 --- a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs +++ b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs @@ -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() diff --git a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs index f5826edd2c..c4b9117182 100644 --- a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs +++ b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs @@ -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; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs index 14de2ebb4e..ae54499716 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs @@ -166,7 +166,7 @@ public override BulletWorld Initialize(Vector3 maxPosition, ConfigurationParamet // If Debug logging level, enable logging from the unmanaged code m_DebugLogCallbackHandle = null; - if (BSScene.m_log.IsDebugEnabled || PhysicsScene.PhysicsLogging.Enabled) + if (BSScene.m_log.IsDebugEnabled && PhysicsScene.PhysicsLogging.Enabled) { BSScene.m_log.DebugFormat("{0}: Initialize: Setting debug callback for unmanaged code", BSScene.LogHeader); if (PhysicsScene.PhysicsLogging.Enabled) @@ -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); @@ -212,6 +212,19 @@ public override void Shutdown(BulletWorld world) { BulletWorldUnman worldu = world as BulletWorldUnman; BSAPICPP.Shutdown2(worldu.ptr); + + if (m_paramsHandle.IsAllocated) + { + m_paramsHandle.Free(); + } + if (m_collisionArrayPinnedHandle.IsAllocated) + { + m_collisionArrayPinnedHandle.Free(); + } + if (m_updateArrayPinnedHandle.IsAllocated) + { + m_updateArrayPinnedHandle.Free(); + } } public override bool PushUpdate(BulletBody obj) @@ -327,6 +340,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 +1375,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); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs index 0c7f31589f..b6ff52bf5b 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs @@ -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) { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs index 794ee17f2a..bc163eb946 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs @@ -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); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 939d38a5d3..a5fec87eed 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -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; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index c34c05a90a..e434412017 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -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; + private bool enableAngularDeflection; + private bool enableAngularBanking; + 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 = false; + enableAngularBanking = false; + 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,20 +645,24 @@ 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; + private Vector3 m_knownRotationalImpulse; private Vector3 m_knownForwardVelocity; // vehicle relative forward speed 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_knownChangedRotationalImpulse = 1 << 7; + private const int m_knownChangedTerrainHeight = 1 << 8; + private const int m_knownChangedWaterLevel = 1 << 9; + private const int m_knownChangedForwardVelocity = 1 <<10; private void ForgetKnownVehicleProperties() { @@ -653,21 +683,32 @@ 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_knownChangedRotationalImpulse) != 0) + Prim.ApplyTorqueImpulse((Vector3)m_knownRotationalImpulse, true /*inTaintTime*/); + 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 +798,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 @@ -796,6 +848,17 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_knownChanged |= m_knownChangedRotationalForce; m_knownHas |= m_knownChangedRotationalForce; } + private void VehicleAddRotationalImpulse(Vector3 pImpulse) + { + if ((m_knownHas & m_knownChangedRotationalImpulse) == 0) + { + m_knownRotationalImpulse = Vector3.Zero; + m_knownHas |= m_knownChangedRotationalImpulse; + } + m_knownRotationalImpulse += pImpulse; + m_knownChanged |= m_knownChangedRotationalImpulse; + } + // Vehicle relative forward velocity private Vector3 VehicleForwardVelocity { @@ -844,86 +907,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 +1004,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 +1040,42 @@ 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; + Vector3 hpos = VehiclePosition; + float verticalError = m_VhoverTargetHeight - hpos.Z; + float verticalCorrection = verticalError / m_VhoverTimescale; + verticalCorrection *= m_VhoverEfficiency; + + hpos.Z += verticalCorrection; + VehiclePosition = hpos; + + // Since we are hovering, we need to do the opposite of falling -- get rid of world Z + Vector3 vel = VehicleVelocity; + vel.Z = 0f; + VehicleVelocity = vel; + + /* float verticalCorrectionVelocity = verticalError / m_VhoverTimescale; + Vector3 verticalCorrection = new Vector3(0f, 0f, verticalCorrectionVelocity); + verticalCorrection *= m_vehicleMass; // TODO: implement m_VhoverEfficiency correctly - ret = new Vector3(0f, 0f, verticalCorrectionVelocity); + VehicleAddForceImpulse(verticalCorrection); + */ + + VDetailLog("{0}, MoveLinear,hover,pos={1},eff={2},hoverTS={3},height={4},target={5},err={6},corr={7}", + Prim.LocalID, VehiclePosition, m_VhoverEfficiency, + m_VhoverTimescale, m_VhoverHeight, m_VhoverTargetHeight, + verticalError, verticalCorrection); } - 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 +1130,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 +1210,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 +1303,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 +1354,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 +1427,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 diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index 756faedb21..cbd160fb81 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs @@ -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); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index bd03d31ce9..2dc89b51d3 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -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("
");
@@ -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,8 +194,12 @@ public sealed class BSLinksetCompound : BSLinkset
&& !physicalUpdate
&& PhysicsScene.TerrainManager.IsWithinKnownTerrain(LinksetRoot.RawPosition))
{
- updated.LinksetInfo = null;
- ScheduleRebuild(updated);
+ // TODO: replace this with are calculation of the child prim's orientation and pos.
+ // TODO: for the moment, don't rebuild the compound shape.
+ // This is often just the car turning its wheels. When we can just reorient the one
+ // member shape of the compound shape, the overhead of rebuilding won't be a problem.
+ // updated.LinksetInfo = null;
+ // ScheduleRebuild(updated);
}
}
@@ -230,7 +246,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 +254,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 +322,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 +333,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 +372,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 +402,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 +414,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
});
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
index 23d573fd65..862dbf6710 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
@@ -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; }
@@ -317,13 +318,13 @@ public static class BSParam
(s,p,l,v) => { s.UpdateParameterObject((x)=>{AngularSleepingThreshold=x;}, p, l, v); },
(s,o,v) => { s.PE.SetSleepingThresholds(o.PhysBody, v, v); } ),
new ParameterDefn("CcdMotionThreshold", "Continuious collision detection threshold (0 means no CCD)" ,
- 0f, // set to zero to disable
+ 0.3f, // set to zero to disable
(s,cf,p,v) => { CcdMotionThreshold = cf.GetFloat(p, v); },
(s) => { return CcdMotionThreshold; },
(s,p,l,v) => { s.UpdateParameterObject((x)=>{CcdMotionThreshold=x;}, p, l, v); },
(s,o,v) => { s.PE.SetCcdMotionThreshold(o.PhysBody, v); } ),
new ParameterDefn("CcdSweptSphereRadius", "Continuious collision detection test radius" ,
- 0f,
+ 0.2f,
(s,cf,p,v) => { CcdSweptSphereRadius = cf.GetFloat(p, v); },
(s) => { return CcdSweptSphereRadius; },
(s,p,l,v) => { s.UpdateParameterObject((x)=>{CcdSweptSphereRadius=x;}, p, l, v); },
@@ -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,
@@ -459,7 +465,7 @@ public static class BSParam
(s) => { return s.UnmanagedParams[0].shouldSplitSimulationIslands; },
(s,p,l,v) => { s.UnmanagedParams[0].shouldSplitSimulationIslands = v; } ),
new ParameterDefn("ShouldEnableFrictionCaching", "Enable friction computation caching",
- ConfigurationParameters.numericFalse,
+ ConfigurationParameters.numericTrue,
(s,cf,p,v) => { s.UnmanagedParams[0].shouldEnableFrictionCaching = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); },
(s) => { return s.UnmanagedParams[0].shouldEnableFrictionCaching; },
(s,p,l,v) => { s.UnmanagedParams[0].shouldEnableFrictionCaching = v; } ),
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
index e8575f60fe..821f470bd2 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
@@ -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