diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index c23ccd5834..2e6b2dad90 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -263,7 +263,7 @@ public class BSCharacter : BSPhysObject // A version of the sanity check that also makes sure a new position value is // pushed back to the physics engine. This routine would be used by anyone // who is not already pushing the value. - private bool PositionSanityCheck2(bool atTaintTime) + private bool PositionSanityCheck2(bool inTaintTime) { bool ret = false; if (PositionSanityCheck()) @@ -275,7 +275,7 @@ public class BSCharacter : BSPhysObject DetailLog("{0},BSCharacter.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation); BulletSimAPI.SetObjectTranslation(PhysicsScene.WorldID, LocalID, _position, _orientation); }; - if (atTaintTime) + if (inTaintTime) sanityOperation(); else PhysicsScene.TaintedObject("BSCharacter.PositionSanityCheck", sanityOperation); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index 20db4de9ad..b84ccdccce 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs @@ -160,6 +160,31 @@ public class BSLinkset return ret; } + // When physical properties are changed the linkset needs to recalculate + // its internal properties. + // May be called at runtime or taint-time (just pass the appropriate flag). + public void Refresh(BSPhysObject requestor, bool inTaintTime) + { + // If there are no children, there can't be any constraints to recompute + if (!HasAnyChildren) + return; + + // Only the root does the recomputation + if (IsRoot(requestor)) + { + BSScene.TaintCallback refreshOperation = delegate() + { + RecomputeLinksetConstraintVariables(); + DetailLog("{0},BSLinkset.Refresh,complete,rBody={1}", + LinksetRoot.LocalID, LinksetRoot.BSBody.ptr.ToString("X")); + }; + if (inTaintTime) + refreshOperation(); + else + PhysicsScene.TaintedObject("BSLinkSet.Refresh", refreshOperation); + } + } + // The object is going dynamic (physical). Do any setup necessary // for a dynamic linkset. // Only the state of the passed object can be modified. The rest of the linkset @@ -182,24 +207,19 @@ public class BSLinkset return false; } - // When physical properties are changed the linkset needs to recalculate - // its internal properties. - // Called at runtime. - public void Refresh(BSPhysObject requestor) + // If the software is handling the movement of all the objects in a linkset + // (like if one doesn't use constraints for static linksets), this is called + // when an update for the root of the linkset is received. + // Called at taint-time!! + public void UpdateProperties(BSPhysObject physObject) { - // If there are no children, there can't be any constraints to recompute - if (!HasAnyChildren) - return; - - // Only the root does the recomputation - if (IsRoot(requestor)) + // The root local properties have been updated. Apply to the children if appropriate. + if (IsRoot(physObject) && HasAnyChildren) { - PhysicsScene.TaintedObject("BSLinkSet.Refresh", delegate() + if (!physObject.IsPhysical) { - RecomputeLinksetConstraintVariables(); - DetailLog("{0},BSLinkset.Refresh,complete,rBody={1}", - LinksetRoot.LocalID, LinksetRoot.BSBody.ptr.ToString("X")); - }); + // TODO: implement software linkset update for static object linksets + } } } @@ -236,9 +256,8 @@ public class BSLinkset return ret; } - // Routine used when rebuilding the body of the root of the linkset - // This is called after RemoveAllLinksToRoot() to restore all the constraints. - // This is called when the root body has been changed. + // Companion to RemoveBodyDependencies(). If RemoveBodyDependencies() returns 'true', + // this routine will restore the removed constraints. // Called at taint-time!! public void RestoreBodyDependencies(BSPrim child) { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index d408be0b5b..b26f0491a1 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -327,7 +327,7 @@ public sealed class BSPrim : BSPhysObject // A version of the sanity check that also makes sure a new position value is // pushed back to the physics engine. This routine would be used by anyone // who is not already pushing the value. - private bool PositionSanityCheck2(bool atTaintTime) + private bool PositionSanityCheck2(bool inTaintTime) { bool ret = false; if (PositionSanityCheck()) @@ -339,7 +339,7 @@ public sealed class BSPrim : BSPhysObject DetailLog("{0},BSPrim.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation); BulletSimAPI.SetObjectTranslation(PhysicsScene.WorldID, LocalID, _position, _orientation); }; - if (atTaintTime) + if (inTaintTime) sanityOperation(); else PhysicsScene.TaintedObject("BSPrim.PositionSanityCheck", sanityOperation); @@ -583,7 +583,7 @@ public sealed class BSPrim : BSPhysObject // Set up the object physicalness (does gravity and collisions move this object) MakeDynamic(IsStatic); - // Update vehicle specific parameters + // Update vehicle specific parameters (after MakeDynamic() so can change physical parameters) _vehicle.Refresh(); // Arrange for collision events if the simulator wants them @@ -606,7 +606,7 @@ public sealed class BSPrim : BSPhysObject // Recompute any linkset parameters. // When going from non-physical to physical, this re-enables the constraints that // had been automatically disabled when the mass was set to zero. - Linkset.Refresh(this); + Linkset.Refresh(this, true); DetailLog("{0},BSPrim.UpdatePhysicalParameters,exit,static={1},solid={2},mass={3},collide={4},cf={5:X},body={6},shape={7}", LocalID, IsStatic, IsSolid, _mass, SubscribedEvents(), CurrentCollisionFlags, BSBody, BSShape); @@ -1322,6 +1322,8 @@ public sealed class BSPrim : BSPhysObject PositionSanityCheck2(true); + Linkset.UpdateProperties(this); + DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}", LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 33ac1160e3..50091ccb1d 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -39,7 +39,6 @@ using log4net; using OpenMetaverse; // TODOs for BulletSim (for BSScene, BSPrim, BSCharacter and BulletSim) -// Move all logic out of the C++ code and into the C# code for easier future modifications. // Test sculpties (verified that they don't work) // Compute physics FPS reasonably // Based on material, set density and friction @@ -493,7 +492,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters int numSubSteps = 0; // DEBUG - DetailLog("{0},BSScene.Simulate,beforeStep,ntaimts={1},step={2}", DetailLogZero, numTaints, m_simulationStep); + // DetailLog("{0},BSScene.Simulate,beforeStep,ntaimts={1},step={2}", DetailLogZero, numTaints, m_simulationStep); try { @@ -503,8 +502,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters out updatedEntityCount, out updatedEntitiesPtr, out collidersCount, out collidersPtr); if (PhysicsLogging.Enabled) simTime = Util.EnvironmentTickCountSubtract(beforeTime); - DetailLog("{0},Simulate,call, nTaints={1}, simTime={2}, substeps={3}, updates={4}, colliders={5}", - DetailLogZero, numTaints, simTime, numSubSteps, updatedEntityCount, collidersCount); + DetailLog("{0},Simulate,call, frame={1}, nTaints={2}, simTime={3}, substeps={4}, updates={5}, colliders={6}", + DetailLogZero, m_simulationStep, numTaints, simTime, numSubSteps, updatedEntityCount, collidersCount); } catch (Exception e) { @@ -855,7 +854,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters (s) => { return s.NumericBool(s.ShouldForceSimplePrimMeshing); }, (s,p,l,v) => { s.ShouldForceSimplePrimMeshing = s.BoolNumeric(v); } ), new ParameterDefn("UseHullsForPhysicalObjects", "If true, create hulls for physical objects", - ConfigurationParameters.numericFalse, + ConfigurationParameters.numericTrue, (s,cf,p,v) => { s.ShouldUseHullsForPhysicalObjects = cf.GetBoolean(p, s.BoolNumeric(v)); }, (s) => { return s.NumericBool(s.ShouldUseHullsForPhysicalObjects); }, (s,p,l,v) => { s.ShouldUseHullsForPhysicalObjects = s.BoolNumeric(v); } ), diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index e619b48fe2..d5e21720df 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -67,8 +67,8 @@ public class BSShapeCollection : IDisposable public DateTime lastReferenced; } - private Dictionary Meshes = new Dictionary(); - private Dictionary Hulls = new Dictionary(); + private Dictionary Meshes = new Dictionary(); + private Dictionary Hulls = new Dictionary(); private Dictionary Bodies = new Dictionary(); public BSShapeCollection(BSScene physScene) @@ -121,7 +121,7 @@ public class BSShapeCollection : IDisposable // Track another user of a body // We presume the caller has allocated the body. // Bodies only have one user so the reference count is either 1 or 0. - public void ReferenceBody(BulletBody body, bool atTaintTime) + public void ReferenceBody(BulletBody body, bool inTaintTime) { lock (m_collectionActivityLock) { @@ -147,7 +147,7 @@ public class BSShapeCollection : IDisposable body.ID, body); } }; - if (atTaintTime) + if (inTaintTime) createOperation(); else PhysicsScene.TaintedObject("BSShapeCollection.ReferenceBody", createOperation); @@ -272,7 +272,7 @@ public class BSShapeCollection : IDisposable // Release the usage of a shape. // The collisionObject is released since it is a copy of the real collision shape. - public void DereferenceShape(BulletShape shape, bool atTaintTime, ShapeDestructionCallback shapeCallback) + public void DereferenceShape(BulletShape shape, bool inTaintTime, ShapeDestructionCallback shapeCallback) { if (shape.ptr == IntPtr.Zero) return; @@ -294,14 +294,14 @@ public class BSShapeCollection : IDisposable if (shape.ptr != IntPtr.Zero & shape.isNativeShape) { DetailLog("{0},BSShapeCollection.DereferenceShape,deleteNativeShape,ptr={1},taintTime={2}", - BSScene.DetailLogZero, shape.ptr.ToString("X"), atTaintTime); + BSScene.DetailLogZero, shape.ptr.ToString("X"), inTaintTime); if (shapeCallback != null) shapeCallback(shape); BulletSimAPI.DeleteCollisionShape2(PhysicsScene.World.ptr, shape.ptr); } break; } }; - if (atTaintTime) + if (inTaintTime) { lock (m_collectionActivityLock) { @@ -441,7 +441,7 @@ public class BSShapeCollection : IDisposable // Native shapes are always built independently. newShape = new BulletShape(BulletSimAPI.BuildNativeShape2(PhysicsScene.World.ptr, shapeData), shapeType); - newShape.shapeKey = (ulong)shapeKey; + newShape.shapeKey = (System.UInt64)shapeKey; newShape.isNativeShape = true; // Don't need to do a 'ReferenceShape()' here because native shapes are not tracked. @@ -461,7 +461,7 @@ public class BSShapeCollection : IDisposable BulletShape newShape = new BulletShape(IntPtr.Zero); float lod; - ulong newMeshKey = ComputeShapeKey(shapeData, pbs, out lod); + System.UInt64 newMeshKey = ComputeShapeKey(shapeData, pbs, out lod); // if this new shape is the same as last time, don't recreate the mesh if (newMeshKey == prim.BSShape.shapeKey && prim.BSShape.type == ShapeData.PhysicsShapeType.SHAPE_MESH) @@ -484,7 +484,7 @@ public class BSShapeCollection : IDisposable return true; // 'true' means a new shape has been added to this prim } - private BulletShape CreatePhysicalMesh(string objName, ulong newMeshKey, PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) + private BulletShape CreatePhysicalMesh(string objName, System.UInt64 newMeshKey, PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) { IMesh meshData = null; IntPtr meshPtr; @@ -531,7 +531,7 @@ public class BSShapeCollection : IDisposable BulletShape newShape; float lod; - ulong newHullKey = ComputeShapeKey(shapeData, pbs, out lod); + System.UInt64 newHullKey = ComputeShapeKey(shapeData, pbs, out lod); // if the hull hasn't changed, don't rebuild it if (newHullKey == prim.BSShape.shapeKey && prim.BSShape.type == ShapeData.PhysicsShapeType.SHAPE_HULL) @@ -554,7 +554,7 @@ public class BSShapeCollection : IDisposable } List m_hulls; - private BulletShape CreatePhysicalHull(string objName, ulong newHullKey, PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) + private BulletShape CreatePhysicalHull(string objName, System.UInt64 newHullKey, PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) { IntPtr hullPtr; @@ -667,7 +667,7 @@ public class BSShapeCollection : IDisposable // Create a hash of all the shape parameters to be used as a key // for this particular shape. - private ulong ComputeShapeKey(ShapeData shapeData, PrimitiveBaseShape pbs, out float retLod) + private System.UInt64 ComputeShapeKey(ShapeData shapeData, PrimitiveBaseShape pbs, out float retLod) { // level of detail based on size and type of the object float lod = PhysicsScene.MeshLOD; @@ -680,10 +680,10 @@ public class BSShapeCollection : IDisposable lod = PhysicsScene.MeshMegaPrimLOD; retLod = lod; - return (ulong)pbs.GetMeshKey(shapeData.Size, lod); + return pbs.GetMeshKey(shapeData.Size, lod); } // For those who don't want the LOD - private ulong ComputeShapeKey(ShapeData shapeData, PrimitiveBaseShape pbs) + private System.UInt64 ComputeShapeKey(ShapeData shapeData, PrimitiveBaseShape pbs) { float lod; return ComputeShapeKey(shapeData, pbs, out lod); @@ -717,6 +717,7 @@ public class BSShapeCollection : IDisposable if (mustRebuild || forceRebuild) { + // Free any old body DereferenceBody(prim.BSBody, true, bodyCallback); BulletBody aBody; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs index 70aa429fc3..2808603bcf 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs @@ -201,10 +201,10 @@ public class BSTerrainManager // The 'doNow' boolean says whether to do all the unmanaged activities right now (like when // calling this routine from initialization or taint-time routines) or whether to delay // all the unmanaged activities to taint-time. - private void UpdateOrCreateTerrain(uint id, float[] heightMap, Vector3 minCoords, Vector3 maxCoords, bool atTaintTime) + private void UpdateOrCreateTerrain(uint id, float[] heightMap, Vector3 minCoords, Vector3 maxCoords, bool inTaintTime) { - DetailLog("{0},BSTerrainManager.UpdateOrCreateTerrain,call,minC={1},maxC={2},atTaintTime={3}", - BSScene.DetailLogZero, minCoords, maxCoords, atTaintTime); + DetailLog("{0},BSTerrainManager.UpdateOrCreateTerrain,call,minC={1},maxC={2},inTaintTime={3}", + BSScene.DetailLogZero, minCoords, maxCoords, inTaintTime); float minZ = float.MaxValue; float maxZ = float.MinValue; @@ -320,7 +320,9 @@ public class BSTerrainManager BulletSimAPI.SetRestitution2(mapInfo.terrainBody.ptr, PhysicsScene.Params.terrainRestitution); BulletSimAPI.SetCollisionFlags2(mapInfo.terrainBody.ptr, CollisionFlags.CF_STATIC_OBJECT); - BulletSimAPI.SetMassProps2(mapInfo.terrainBody.ptr, 0f, Vector3.Zero); + float terrainMass = 1000; + Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(mapInfo.terrainBody.ptr, terrainMass); + BulletSimAPI.SetMassProps2(mapInfo.terrainBody.ptr, terrainMass, localInertia); BulletSimAPI.UpdateInertiaTensor2(mapInfo.terrainBody.ptr); // Return the new terrain to the world of physical objects @@ -342,7 +344,7 @@ public class BSTerrainManager // There is the option to do the changes now (we're already in 'taint time'), or // to do the Bullet operations later. - if (atTaintTime) + if (inTaintTime) rebuildOperation(); else PhysicsScene.TaintedObject("BSScene.UpdateOrCreateTerrain:UpdateExisting", rebuildOperation); @@ -381,7 +383,7 @@ public class BSTerrainManager }; // If already in taint-time, just call Bullet. Otherwise queue the operations for the safe time. - if (atTaintTime) + if (inTaintTime) createOperation(); else PhysicsScene.TaintedObject("BSScene.UpdateOrCreateTerrain:NewTerrain", createOperation); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index 7a60afbf21..e23fe5ad7b 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs @@ -101,9 +101,8 @@ public struct BulletShape } public IntPtr ptr; public ShapeData.PhysicsShapeType type; - public ulong shapeKey; + public System.UInt64 shapeKey; public bool isNativeShape; - // Hulls have an underlying mesh. A pointer to it is hidden here. public override string ToString() { StringBuilder buff = new StringBuilder();