diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 7bc6b69e40..8e1171a481 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -114,17 +114,9 @@ public class BSCharacter : BSPhysObject PhysicsScene.TaintedObject("BSCharacter.create", delegate() { DetailLog("{0},BSCharacter.create,taint", LocalID); - PhysicsScene.Shapes.GetBodyAndShape(true, PhysicsScene.World, this, shapeData, null, null, null); - + PhysicsScene.Shapes.GetBodyAndShape(true, PhysicsScene.World, this, shapeData, null, null, null); + SetPhysicalProperties(); - - // Set the buoyancy for flying. This will be refactored when all the settings happen in C#. - // If not set at creation, the avatar will stop flying when created after crossing a region boundry. - ForceBuoyancy = _buoyancy; - - // This works here because CreateObject has already put the character into the physical world. - BulletSimAPI.SetCollisionFilterMask2(BSBody.ptr, - (uint)CollisionFilterGroups.AvatarFilter, (uint)CollisionFilterGroups.AvatarMask); }); return; } @@ -146,27 +138,32 @@ public class BSCharacter : BSPhysObject ZeroMotion(); - OMV.Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(BSShape.ptr, MassRaw); + OMV.Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(BSShape.ptr, MassRaw); BulletSimAPI.SetMassProps2(BSBody.ptr, MassRaw, localInertia); + ForcePosition = _position; // Set the velocity and compute the proper friction ForceVelocity = _velocity; - - BulletSimAPI.SetFriction2(BSBody.ptr, _currentFriction); BulletSimAPI.SetRestitution2(BSBody.ptr, PhysicsScene.Params.avatarRestitution); - BulletSimAPI.SetLocalScaling2(BSShape.ptr, Scale); BulletSimAPI.SetContactProcessingThreshold2(BSBody.ptr, PhysicsScene.Params.contactProcessingThreshold); - if (PhysicsScene.Params.ccdMotionThreshold > 0f) { BulletSimAPI.SetCcdMotionThreshold2(BSBody.ptr, PhysicsScene.Params.ccdMotionThreshold); BulletSimAPI.SetCcdSweepSphereRadius2(BSBody.ptr, PhysicsScene.Params.ccdSweptSphereRadius); - } - - BulletSimAPI.SetActivationState2(BSBody.ptr, (int)ActivationState.DISABLE_DEACTIVATION); + } + + BulletSimAPI.AddToCollisionFlags2(BSBody.ptr, CollisionFlags.CF_CHARACTER_OBJECT); BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, BSBody.ptr); + + BulletSimAPI.ForceActivationState2(BSBody.ptr, ActivationState.DISABLE_DEACTIVATION); + BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, BSBody.ptr); + + // Do this after the object has been added to the world + BulletSimAPI.SetCollisionFilterMask2(BSBody.ptr, + (uint)CollisionFilterGroups.AvatarFilter, + (uint)CollisionFilterGroups.AvatarMask); } public override void RequestPhysicsterseUpdate() @@ -174,9 +171,7 @@ public class BSCharacter : BSPhysObject base.RequestPhysicsterseUpdate(); } // No one calls this method so I don't know what it could possibly mean - public override bool Stopped { - get { return false; } - } + public override bool Stopped { get { return false; } } public override OMV.Vector3 Size { get { @@ -185,18 +180,14 @@ public class BSCharacter : BSPhysObject } set { - // When an avatar's size is set, only the height is changed - // and that really only depends on the radius. + // When an avatar's size is set, only the height is changed. _size = value; ComputeAvatarScale(_size); - - // TODO: something has to be done with the avatar's vertical position - ComputeAvatarVolumeAndMass(); PhysicsScene.TaintedObject("BSCharacter.setSize", delegate() { - BulletSimAPI.SetLocalScaling2(BSBody.ptr, Scale); + BulletSimAPI.SetLocalScaling2(BSShape.ptr, Scale); OMV.Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(BSBody.ptr, MassRaw); BulletSimAPI.SetMassProps2(BSBody.ptr, MassRaw, localInertia); }); @@ -300,7 +291,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 inTaintTime) + private bool PositionSanityCheck(bool inTaintTime) { bool ret = false; if (PositionSanityCheck()) @@ -378,14 +369,16 @@ public class BSCharacter : BSPhysObject } else { - if (_currentFriction == 999f) + if (_currentFriction != PhysicsScene.Params.avatarFriction) { _currentFriction = PhysicsScene.Params.avatarFriction; BulletSimAPI.SetFriction2(BSBody.ptr, _currentFriction); } } _velocity = value; + // Remember the set velocity so we can suppress the reduction by friction, ... _appliedVelocity = value; + BulletSimAPI.SetLinearVelocity2(BSBody.ptr, _velocity); BulletSimAPI.Activate2(BSBody.ptr, true); } @@ -590,7 +583,8 @@ public class BSCharacter : BSPhysObject // The 1.15 came from ODE but it seems to cause the avatar to float off the ground // Scale.Z = (_size.Z * 1.15f) - (Scale.X + Scale.Y); - newScale.Z = (_size.Z) - (Scale.X + Scale.Y); + // From the total height, remove the capsule half spheres that are at each end + newScale.Z = (size.Z) - (Math.Min(newScale.X, newScale.Y) * 2f); Scale = newScale; } @@ -621,7 +615,7 @@ public class BSCharacter : BSPhysObject _acceleration = entprop.Acceleration; _rotationalVelocity = entprop.RotationalVelocity; // Do some sanity checking for the avatar. Make sure it's above ground and inbounds. - PositionSanityCheck2(true); + PositionSanityCheck(true); // remember the current and last set values LastEntityProperties = CurrentEntityProperties; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 3421e309ed..b9e1908778 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -333,7 +333,7 @@ public sealed class BSPrim : BSPhysObject // just assign to "Position" because of potential call loops. BSScene.TaintCallback sanityOperation = delegate() { - DetailLog("{0},BSPrim.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation); + DetailLog("{0},BSPrim.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation); ForcePosition = _position; }; if (inTaintTime) @@ -822,7 +822,7 @@ public sealed class BSPrim : BSPhysObject set { _buoyancy = value; PhysicsScene.TaintedObject("BSPrim.setBuoyancy", delegate() - { + { ForceBuoyancy = _buoyancy; }); } @@ -1286,8 +1286,8 @@ public sealed class BSPrim : BSPhysObject 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; - + const float ROTATIONAL_VELOCITY_TOLERANCE = 0.01f; + public override void UpdateProperties(EntityProperties entprop) { /* @@ -1343,10 +1343,10 @@ public sealed class BSPrim : BSPhysObject _orientation = entprop.Rotation; _velocity = entprop.Velocity; _acceleration = entprop.Acceleration; - _rotationalVelocity = entprop.RotationalVelocity; - - // remember the current and last set values - LastEntityProperties = CurrentEntityProperties; + _rotationalVelocity = entprop.RotationalVelocity; + + // remember the current and last set values + LastEntityProperties = CurrentEntityProperties; CurrentEntityProperties = entprop; PositionSanityCheck(true); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 7998b08cfa..c6e8bc4da7 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -795,7 +795,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters delegate void ParamUser(BSScene scene, IConfig conf, string paramName, float val); delegate float ParamGet(BSScene scene); - delegate void ParamSet(BSScene scene, string paramName, uint localID, float val); + delegate void ParamSet(BSScene scene, string paramName, uint localID, float val); + delegate void SetOnObject(BSScene scene, BSPhysObject obj, float val); private struct ParameterDefn { @@ -804,7 +805,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters public float defaultValue; // default value if not specified anywhere else public ParamUser userParam; // get the value from the configuration file public ParamGet getter; // return the current value stored for this parameter - public ParamSet setter; // set the current value for this parameter + public ParamSet setter; // set the current value for this parameter + public SetOnObject onObject; // set the value on an object in the physical domain public ParameterDefn(string n, string d, float v, ParamUser u, ParamGet g, ParamSet s) { name = n; @@ -812,7 +814,18 @@ public class BSScene : PhysicsScene, IPhysicsParameters defaultValue = v; userParam = u; getter = g; - setter = s; + setter = s; + onObject = null; + } + public ParameterDefn(string n, string d, float v, ParamUser u, ParamGet g, ParamSet s, SetOnObject o) + { + name = n; + desc = d; + defaultValue = v; + userParam = u; + getter = g; + setter = s; + onObject = o; } } @@ -834,6 +847,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters // // The single letter parameters for the delegates are: // s = BSScene + // o = BSPhysObject // p = string parameter name // l = localID of referenced object // v = float value @@ -943,65 +957,74 @@ public class BSScene : PhysicsScene, IPhysicsParameters -9.80665f, (s,cf,p,v) => { s.m_params[0].gravity = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].gravity; }, - (s,p,l,v) => { s.m_params[0].gravity = v; s.TaintedUpdateParameter(p,l,v); } ), + (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].gravity, p, PhysParameterEntry.APPLY_TO_NONE, v); }, + (s,o,v) => { BulletSimAPI.SetGravity2(s.World.ptr, new Vector3(0f,0f,v)); } ), new ParameterDefn("LinearDamping", "Factor to damp linear movement per second (0.0 - 1.0)", 0f, (s,cf,p,v) => { s.m_params[0].linearDamping = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].linearDamping; }, - (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].linearDamping, p, l, v); } ), + (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].linearDamping, p, l, v); }, + (s,o,v) => { BulletSimAPI.SetDamping2(o.BSBody.ptr, v, v); } ), new ParameterDefn("AngularDamping", "Factor to damp angular movement per second (0.0 - 1.0)", 0f, (s,cf,p,v) => { s.m_params[0].angularDamping = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].angularDamping; }, - (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].angularDamping, p, l, v); } ), + (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].angularDamping, p, l, v); }, + (s,o,v) => { BulletSimAPI.SetDamping2(o.BSBody.ptr, v, v); } ), new ParameterDefn("DeactivationTime", "Seconds before considering an object potentially static", 0.2f, (s,cf,p,v) => { s.m_params[0].deactivationTime = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].deactivationTime; }, - (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].deactivationTime, p, l, v); } ), + (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].deactivationTime, p, l, v); }, + (s,o,v) => { BulletSimAPI.SetDeactivationTime2(o.BSBody.ptr, v); } ), new ParameterDefn("LinearSleepingThreshold", "Seconds to measure linear movement before considering static", 0.8f, (s,cf,p,v) => { s.m_params[0].linearSleepingThreshold = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].linearSleepingThreshold; }, - (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].linearSleepingThreshold, p, l, v); } ), + (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].linearSleepingThreshold, p, l, v); }, + (s,o,v) => { BulletSimAPI.SetSleepingThresholds2(o.BSBody.ptr, v, v); } ), new ParameterDefn("AngularSleepingThreshold", "Seconds to measure angular movement before considering static", 1.0f, (s,cf,p,v) => { s.m_params[0].angularSleepingThreshold = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].angularSleepingThreshold; }, - (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].angularSleepingThreshold, p, l, v); } ), + (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].angularSleepingThreshold, p, l, v); }, + (s,o,v) => { BulletSimAPI.SetSleepingThresholds2(o.BSBody.ptr, v, v); } ), new ParameterDefn("CcdMotionThreshold", "Continuious collision detection threshold (0 means no CCD)" , 0f, // set to zero to disable (s,cf,p,v) => { s.m_params[0].ccdMotionThreshold = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].ccdMotionThreshold; }, - (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].ccdMotionThreshold, p, l, v); } ), + (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].ccdMotionThreshold, p, l, v); }, + (s,o,v) => { BulletSimAPI.SetCcdMotionThreshold2(o.BSBody.ptr, v); } ), new ParameterDefn("CcdSweptSphereRadius", "Continuious collision detection test radius" , 0f, (s,cf,p,v) => { s.m_params[0].ccdSweptSphereRadius = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].ccdSweptSphereRadius; }, - (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].ccdSweptSphereRadius, p, l, v); } ), + (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].ccdSweptSphereRadius, p, l, v); }, + (s,o,v) => { BulletSimAPI.SetCcdSweepSphereRadius2(o.BSBody.ptr, v); } ), new ParameterDefn("ContactProcessingThreshold", "Distance between contacts before doing collision check" , 0.1f, (s,cf,p,v) => { s.m_params[0].contactProcessingThreshold = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].contactProcessingThreshold; }, - (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].contactProcessingThreshold, p, l, v); } ), + (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].contactProcessingThreshold, p, l, v); }, + (s,o,v) => { BulletSimAPI.SetContactProcessingThreshold2(o.BSBody.ptr, v); } ), new ParameterDefn("TerrainFriction", "Factor to reduce movement against terrain surface" , 0.5f, (s,cf,p,v) => { s.m_params[0].terrainFriction = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].terrainFriction; }, - (s,p,l,v) => { s.m_params[0].terrainFriction = v; s.TaintedUpdateParameter(p,l,v); } ), + (s,p,l,v) => { s.m_params[0].terrainFriction = v; /* TODO: set on real terrain */} ), new ParameterDefn("TerrainHitFraction", "Distance to measure hit collisions" , 0.8f, (s,cf,p,v) => { s.m_params[0].terrainHitFraction = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].terrainHitFraction; }, - (s,p,l,v) => { s.m_params[0].terrainHitFraction = v; s.TaintedUpdateParameter(p,l,v); } ), + (s,p,l,v) => { s.m_params[0].terrainHitFraction = v; /* TODO: set on real terrain */ } ), new ParameterDefn("TerrainRestitution", "Bouncyness" , 0f, (s,cf,p,v) => { s.m_params[0].terrainRestitution = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].terrainRestitution; }, - (s,p,l,v) => { s.m_params[0].terrainRestitution = v; s.TaintedUpdateParameter(p,l,v); } ), + (s,p,l,v) => { s.m_params[0].terrainRestitution = v; /* TODO: set on real terrain */ } ), new ParameterDefn("AvatarFriction", "Factor to reduce movement against an avatar. Changed on avatar recreation.", 0.2f, (s,cf,p,v) => { s.m_params[0].avatarFriction = cf.GetFloat(p, v); }, @@ -1228,58 +1251,55 @@ public class BSScene : PhysicsScene, IPhysicsParameters return ret; } - // check to see if we are updating a parameter for a particular or all of the prims - protected void UpdateParameterObject(ref float loc, string parm, uint localID, float val) - { - List operateOn; - lock (PhysObjects) operateOn = new List(PhysObjects.Keys); - UpdateParameterSet(operateOn, ref loc, parm, localID, val); - } - // update all the localIDs specified // If the local ID is APPLY_TO_NONE, just change the default value // If the localID is APPLY_TO_ALL change the default value and apply the new value to all the lIDs // If the localID is a specific object, apply the parameter change to only that object - protected void UpdateParameterSet(List lIDs, ref float defaultLoc, string parm, uint localID, float val) + protected void UpdateParameterObject(ref float defaultLoc, string parm, uint localID, float val) { + List objectIDs = new List(); switch (localID) { case PhysParameterEntry.APPLY_TO_NONE: defaultLoc = val; // setting only the default value + // This will cause a call into the physical world if some operation is specified (SetOnObject). + objectIDs.Add(TERRAIN_ID); + TaintedUpdateParameter(parm, objectIDs, val); break; - case PhysParameterEntry.APPLY_TO_ALL: + case PhysParameterEntry.APPLY_TO_ALL: defaultLoc = val; // setting ALL also sets the default value - /* - List objectIDs = lIDs; - string xparm = parm.ToLower(); - float xval = val; - TaintedObject("BSScene.UpdateParameterSet", delegate() { - foreach (uint lID in objectIDs) - { - BulletSimAPI.UpdateParameter(WorldID, lID, xparm, xval); - } - }); - */ + lock (PhysObjects) objectIDs = new List(PhysObjects.Keys); + TaintedUpdateParameter(parm, objectIDs, val); break; default: - // setting only one localID - TaintedUpdateParameter(parm, localID, val); + // setting only one localID + objectIDs.Add(localID); + TaintedUpdateParameter(parm, objectIDs, val); break; } } // schedule the actual updating of the paramter to when the phys engine is not busy - protected void TaintedUpdateParameter(string parm, uint localID, float val) + protected void TaintedUpdateParameter(string parm, List lIDs, float val) { - /* Settings in the C++ code are not working at the moment. TODO: fix the settings. - m_log.ErrorFormat("{0} Cannot change parameters of base objects. Someday it will be added.", LogHeader); - uint xlocalID = localID; - string xparm = parm.ToLower(); - float xval = val; - TaintedObject("BSScene.TaintedUpdateParameter", delegate() { - BulletSimAPI.UpdateParameter(WorldID, xlocalID, xparm, xval); + float xval = val; + List xlIDs = lIDs; + string xparm = parm; + TaintedObject("BSScene.UpdateParameterSet", delegate() { + ParameterDefn thisParam; + if (TryGetParameter(xparm, out thisParam)) + { + if (thisParam.onObject != null) + { + foreach (uint lID in xlIDs) + { + BSPhysObject theObject = null; + PhysObjects.TryGetValue(lID, out theObject); + thisParam.onObject(this, theObject, xval); + } + } + } }); - */ } // Get parameter. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index 5a77e5232b..bbfdac6e61 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -51,7 +51,7 @@ public class BSShapeCollection : IDisposable } // Description of a hull. - // Meshes and hulls have the same shape hash key but we only need hulls for efficient physical objects + // Meshes and hulls have the same shape hash key but we only need hulls for efficient collision calculations. private struct HullDesc { public IntPtr ptr; @@ -59,17 +59,9 @@ public class BSShapeCollection : IDisposable public DateTime lastReferenced; } - private struct BodyDesc - { - public IntPtr ptr; - // Bodies are only used once so reference count is always either one or zero - public int referenceCount; - public DateTime lastReferenced; - } - + // The sharable set of meshes and hulls. Indexed by their shape hash. private Dictionary Meshes = new Dictionary(); private Dictionary Hulls = new Dictionary(); - private Dictionary Bodies = new Dictionary(); public BSShapeCollection(BSScene physScene) { @@ -92,6 +84,10 @@ public class BSShapeCollection : IDisposable // First checks the shape and updates that if necessary then makes // sure the body is of the right type. // Return 'true' if either the body or the shape changed. + // 'shapeCallback' and 'bodyCallback' are, if non-null, functions called just before + // the current shape or body is destroyed. This allows the caller to remove any + // higher level dependencies on the shape or body. Mostly used for LinkSets to + // remove the physical constraints before the body is destroyed. // Called at taint-time!! public bool GetBodyAndShape(bool forceRebuild, BulletSim sim, BSPhysObject prim, ShapeData shapeData, PrimitiveBaseShape pbs, @@ -103,7 +99,8 @@ public class BSShapeCollection : IDisposable lock (m_collectionActivityLock) { // Do we have the correct geometry for this type of object? - // Updates prim.BSShape with information/pointers to requested shape + // Updates prim.BSShape with information/pointers to shape. + // CreateGeom returns 'true' of BSShape as changed to a new shape. bool newGeom = CreateGeom(forceRebuild, prim, shapeData, pbs, shapeCallback); // If we had to select a new shape geometry for the object, // rebuild the body around it. @@ -125,35 +122,19 @@ public class BSShapeCollection : IDisposable { lock (m_collectionActivityLock) { - BodyDesc bodyDesc; - if (Bodies.TryGetValue(body.ID, out bodyDesc)) + DetailLog("{0},BSShapeCollection.ReferenceBody,newBody", body.ID, body); + BSScene.TaintCallback createOperation = delegate() { - bodyDesc.referenceCount++; - DetailLog("{0},BSShapeCollection.ReferenceBody,existingBody,body={1},ref={2}", body.ID, body, bodyDesc.referenceCount); - } - else - { - // New entry - bodyDesc.ptr = body.ptr; - bodyDesc.referenceCount = 1; - DetailLog("{0},BSShapeCollection.ReferenceBody,newBody,ref={2}", - body.ID, body, bodyDesc.referenceCount); - BSScene.TaintCallback createOperation = delegate() + if (!BulletSimAPI.IsInWorld2(body.ptr)) { - if (!BulletSimAPI.IsInWorld2(body.ptr)) - { - BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, body.ptr); - DetailLog("{0},BSShapeCollection.ReferenceBody,addedToWorld,ref={1}", - body.ID, body); - } - }; - if (inTaintTime) - createOperation(); - else - PhysicsScene.TaintedObject("BSShapeCollection.ReferenceBody", createOperation); - } - bodyDesc.lastReferenced = System.DateTime.Now; - Bodies[body.ID] = bodyDesc; + BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, body.ptr); + DetailLog("{0},BSShapeCollection.ReferenceBody,addedToWorld,ref={1}", body.ID, body); + } + }; + if (inTaintTime) + createOperation(); + else + PhysicsScene.TaintedObject("BSShapeCollection.ReferenceBody", createOperation); } } @@ -166,43 +147,25 @@ public class BSShapeCollection : IDisposable lock (m_collectionActivityLock) { - BodyDesc bodyDesc; - if (Bodies.TryGetValue(body.ID, out bodyDesc)) + BSScene.TaintCallback removeOperation = delegate() { - bodyDesc.referenceCount--; - bodyDesc.lastReferenced = System.DateTime.Now; - Bodies[body.ID] = bodyDesc; - DetailLog("{0},BSShapeCollection.DereferenceBody,ref={1}", body.ID, bodyDesc.referenceCount); + DetailLog("{0},BSShapeCollection.DereferenceBody,DestroyingBody. ptr={1}, inTaintTime={2}", + body.ID, body.ptr.ToString("X"), inTaintTime); + // If the caller needs to know the old body is going away, pass the event up. + if (bodyCallback != null) bodyCallback(body); - // If body is no longer being used, free it -- bodies can never be shared. - if (bodyDesc.referenceCount == 0) - { - Bodies.Remove(body.ID); - BSScene.TaintCallback removeOperation = delegate() - { - DetailLog("{0},BSShapeCollection.DereferenceBody,DestroyingBody. ptr={1}, inTaintTime={2}", - body.ID, body.ptr.ToString("X"), inTaintTime); - // If the caller needs to know the old body is going away, pass the event up. - if (bodyCallback != null) bodyCallback(body); + // It may have already been removed from the world in which case the next is a NOOP. + BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, body.ptr); - // It may have already been removed from the world in which case the next is a NOOP. - BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, body.ptr); - - // Zero any reference to the shape so it is not freed when the body is deleted. - BulletSimAPI.SetCollisionShape2(PhysicsScene.World.ptr, body.ptr, IntPtr.Zero); - BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, body.ptr); - }; - // If already in taint-time, do the operations now. Otherwise queue for later. - if (inTaintTime) - removeOperation(); - else - PhysicsScene.TaintedObject("BSShapeCollection.DereferenceBody", removeOperation); - } - } + // Zero any reference to the shape so it is not freed when the body is deleted. + BulletSimAPI.SetCollisionShape2(PhysicsScene.World.ptr, body.ptr, IntPtr.Zero); + BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, body.ptr); + }; + // If already in taint-time, do the operations now. Otherwise queue for later. + if (inTaintTime) + removeOperation(); else - { - DetailLog("{0},BSShapeCollection.DereferenceBody,DID NOT FIND BODY", body.ID, bodyDesc.referenceCount); - } + PhysicsScene.TaintedObject("BSShapeCollection.DereferenceBody", removeOperation); } } @@ -271,7 +234,6 @@ 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 inTaintTime, ShapeDestructionCallback shapeCallback) { if (shape.ptr == IntPtr.Zero) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs index caf411e695..9743d948a6 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs @@ -334,7 +334,8 @@ public class BSTerrainManager // Make sure the new shape is processed. // BulletSimAPI.Activate2(mapInfo.terrainBody.ptr, true); - BulletSimAPI.ForceActivationState2(mapInfo.terrainBody.ptr, ActivationState.DISABLE_SIMULATION); + BulletSimAPI.ForceActivationState2(mapInfo.terrainBody.ptr, ActivationState.ISLAND_SLEEPING); + // BulletSimAPI.ForceActivationState2(mapInfo.terrainBody.ptr, ActivationState.DISABLE_SIMULATION); m_terrainModified = true; };