BulletSim: add clock and change logic for taint processing a little

so taints check if they are not in simulation time and execute
immediately if not.
BulletSim2017
Robert Adams 2017-08-28 15:23:32 -07:00
parent 05b8ead8b2
commit 5c36561424
5 changed files with 62 additions and 27 deletions

View File

@ -496,8 +496,8 @@ public sealed class BSCharacter : BSPhysObject
public override OMV.Vector3 ForceVelocity { public override OMV.Vector3 ForceVelocity {
get { return RawVelocity; } get { return RawVelocity; }
set { set {
PhysScene.AssertInTaintTime("BSCharacter.ForceVelocity"); PhysScene.AssertNotInSimulationTime("BSCharacter.ForceVelocity");
DetailLog("{0}: BSCharacter.ForceVelocity.set = {1}", LocalID, value); DetailLog("{0},BSCharacter.ForceVelocity.set={1}", LocalID, value);
RawVelocity = Util.ClampV(value, BSParam.MaxLinearVelocity); RawVelocity = Util.ClampV(value, BSParam.MaxLinearVelocity);
PhysScene.PE.SetLinearVelocity(PhysBody, RawVelocity); PhysScene.PE.SetLinearVelocity(PhysBody, RawVelocity);
@ -638,7 +638,7 @@ public sealed class BSCharacter : BSPhysObject
public override float ForceBuoyancy { public override float ForceBuoyancy {
get { return _buoyancy; } get { return _buoyancy; }
set { set {
PhysScene.AssertInTaintTime("BSCharacter.ForceBuoyancy"); PhysScene.AssertNotInSimulationTime("BSCharacter.ForceBuoyancy");
_buoyancy = value; _buoyancy = value;
DetailLog("{0},BSCharacter.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy); DetailLog("{0},BSCharacter.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy);

View File

@ -790,7 +790,7 @@ public class BSPrim : BSPhysObject
public override OMV.Vector3 ForceVelocity { public override OMV.Vector3 ForceVelocity {
get { return RawVelocity; } get { return RawVelocity; }
set { set {
PhysScene.AssertInTaintTime("BSPrim.ForceVelocity"); PhysScene.AssertNotInSimulationTime("BSPrim.ForceVelocity");
RawVelocity = Util.ClampV(value, BSParam.MaxLinearVelocity); RawVelocity = Util.ClampV(value, BSParam.MaxLinearVelocity);
if (PhysBody.HasPhysicalBody) if (PhysBody.HasPhysicalBody)

View File

@ -128,6 +128,9 @@ namespace OpenSim.Region.PhysicsModule.BulletS
// Not guaranteed to be correct all the time (don't depend on this) but good for debugging. // Not guaranteed to be correct all the time (don't depend on this) but good for debugging.
public bool InTaintTime { get; private set; } public bool InTaintTime { get; private set; }
// Flag that is true when the simulator is active and shouldn't be touched
public bool InSimulationTime { get; private set; }
// Pinned memory used to pass step information between managed and unmanaged // Pinned memory used to pass step information between managed and unmanaged
internal int m_maxCollisionsPerFrame; internal int m_maxCollisionsPerFrame;
internal CollisionDesc[] m_collisionArray; internal CollisionDesc[] m_collisionArray;
@ -344,6 +347,7 @@ namespace OpenSim.Region.PhysicsModule.BulletS
// Put some informational messages into the log file. // Put some informational messages into the log file.
m_log.InfoFormat("{0} Linksets implemented with {1}", LogHeader, (BSLinkset.LinksetImplementation)BSParam.LinksetImplementation); m_log.InfoFormat("{0} Linksets implemented with {1}", LogHeader, (BSLinkset.LinksetImplementation)BSParam.LinksetImplementation);
InSimulationTime = false;
InTaintTime = false; InTaintTime = false;
m_initialized = true; m_initialized = true;
@ -658,21 +662,21 @@ namespace OpenSim.Region.PhysicsModule.BulletS
int beforeTime = Util.EnvironmentTickCount(); int beforeTime = Util.EnvironmentTickCount();
int simTime = 0; int simTime = 0;
int numTaints = _taintOperations.Count; InTaintTime = true;
InTaintTime = true; // Only used for debugging so locking is not necessary.
// update the prim states while we know the physics engine is not busy // update the prim states while we know the physics engine is not busy
ProcessTaints(); int numTaints = ProcessTaints();
// Some of the physical objects requre individual, pre-step calls // Some of the physical objects requre individual, pre-step calls
// (vehicles and avatar movement, in particular) // (vehicles and avatar movement, in particular)
TriggerPreStepEvent(timeStep); TriggerPreStepEvent(timeStep);
// the prestep actions might have added taints // the prestep actions might have added taints
numTaints += _taintOperations.Count; numTaints += ProcessTaints();
ProcessTaints();
InTaintTime = false; // Only used for debugging so locking is not necessary. lock (_taintLock)
{
InSimulationTime = true;
}
// The following causes the unmanaged code to output ALL the values found in ALL the objects in the world. // The following causes the unmanaged code to output ALL the values found in ALL the objects in the world.
// Only enable this in a limited test world with few objects. // Only enable this in a limited test world with few objects.
@ -700,6 +704,18 @@ namespace OpenSim.Region.PhysicsModule.BulletS
if (PhysicsMetricDumpFrames != 0 && ((m_simulationStep % PhysicsMetricDumpFrames) == 0)) if (PhysicsMetricDumpFrames != 0 && ((m_simulationStep % PhysicsMetricDumpFrames) == 0))
PE.DumpPhysicsStatistics(World); PE.DumpPhysicsStatistics(World);
lock (_taintLock)
{
InTaintTime = false;
InSimulationTime = false;
}
// Some actors want to know when the simulation step is complete.
TriggerPostStepEvent(timeStep);
// In case there were any parameter updates that happened during the simulation step
numTaints += ProcessTaints();
// Get a value for 'now' so all the collision and update routines don't have to get their own. // Get a value for 'now' so all the collision and update routines don't have to get their own.
SimulationNowTime = Util.EnvironmentTickCount(); SimulationNowTime = Util.EnvironmentTickCount();
@ -748,9 +764,6 @@ namespace OpenSim.Region.PhysicsModule.BulletS
} }
} }
// Some actors want to know when the simulation step is complete.
TriggerPostStepEvent(timeStep);
simTime = Util.EnvironmentTickCountSubtract(beforeTime); simTime = Util.EnvironmentTickCountSubtract(beforeTime);
if (PhysicsLogging.Enabled) if (PhysicsLogging.Enabled)
{ {
@ -1090,6 +1103,15 @@ namespace OpenSim.Region.PhysicsModule.BulletS
{ {
if (!m_initialized) return; if (!m_initialized) return;
lock (_taintLock) {
if (inTaintTime || !InSimulationTime) {
pCallback();
}
else {
_taintOperations.Add(new TaintCallbackEntry(pOriginator, pIdent, pCallback));
}
}
/*
if (inTaintTime) if (inTaintTime)
pCallback(); pCallback();
else else
@ -1099,6 +1121,7 @@ namespace OpenSim.Region.PhysicsModule.BulletS
_taintOperations.Add(new TaintCallbackEntry(pOriginator, pIdent, pCallback)); _taintOperations.Add(new TaintCallbackEntry(pOriginator, pIdent, pCallback));
} }
} }
*/
} }
private void TriggerPreStepEvent(float timeStep) private void TriggerPreStepEvent(float timeStep)
@ -1120,14 +1143,19 @@ namespace OpenSim.Region.PhysicsModule.BulletS
// When someone tries to change a property on a BSPrim or BSCharacter, the object queues // When someone tries to change a property on a BSPrim or BSCharacter, the object queues
// a callback into itself to do the actual property change. That callback is called // a callback into itself to do the actual property change. That callback is called
// here just before the physics engine is called to step the simulation. // here just before the physics engine is called to step the simulation.
public void ProcessTaints() // Returns the number of taints processed
public int ProcessTaints()
{ {
ProcessRegularTaints(); int ret = 0;
ProcessPostTaintTaints(); ret += ProcessRegularTaints();
ret += ProcessPostTaintTaints();
return ret;
} }
private void ProcessRegularTaints() // Returns the number of taints processed
private int ProcessRegularTaints()
{ {
int ret = 0;
if (m_initialized && _taintOperations.Count > 0) // save allocating new list if there is nothing to process if (m_initialized && _taintOperations.Count > 0) // save allocating new list if there is nothing to process
{ {
// swizzle a new list into the list location so we can process what's there // swizzle a new list into the list location so we can process what's there
@ -1144,6 +1172,7 @@ namespace OpenSim.Region.PhysicsModule.BulletS
{ {
DetailLog("{0},BSScene.ProcessTaints,doTaint,id={1}", tcbe.originator, tcbe.ident); // DEBUG DEBUG DEBUG DetailLog("{0},BSScene.ProcessTaints,doTaint,id={1}", tcbe.originator, tcbe.ident); // DEBUG DEBUG DEBUG
tcbe.callback(); tcbe.callback();
ret++;
} }
catch (Exception e) catch (Exception e)
{ {
@ -1152,6 +1181,7 @@ namespace OpenSim.Region.PhysicsModule.BulletS
} }
oldList.Clear(); oldList.Clear();
} }
return ret;
} }
// Schedule an update to happen after all the regular taints are processed. // Schedule an update to happen after all the regular taints are processed.
@ -1170,8 +1200,10 @@ namespace OpenSim.Region.PhysicsModule.BulletS
} }
// Taints that happen after the normal taint processing but before the simulation step. // Taints that happen after the normal taint processing but before the simulation step.
private void ProcessPostTaintTaints() // Returns the number of taints processed
private int ProcessPostTaintTaints()
{ {
int ret = 0;
if (m_initialized && _postTaintOperations.Count > 0) if (m_initialized && _postTaintOperations.Count > 0)
{ {
Dictionary<string, TaintCallbackEntry> oldList; Dictionary<string, TaintCallbackEntry> oldList;
@ -1187,6 +1219,7 @@ namespace OpenSim.Region.PhysicsModule.BulletS
{ {
DetailLog("{0},BSScene.ProcessPostTaintTaints,doTaint,id={1}", DetailLogZero, kvp.Key); // DEBUG DEBUG DEBUG DetailLog("{0},BSScene.ProcessPostTaintTaints,doTaint,id={1}", DetailLogZero, kvp.Key); // DEBUG DEBUG DEBUG
kvp.Value.callback(); kvp.Value.callback();
ret++;
} }
catch (Exception e) catch (Exception e)
{ {
@ -1195,18 +1228,19 @@ namespace OpenSim.Region.PhysicsModule.BulletS
} }
oldList.Clear(); oldList.Clear();
} }
return ret;
} }
// Only used for debugging. Does not change state of anything so locking is not necessary. // Verify that things are being diddled when the physics engine is not running.
public bool AssertInTaintTime(string whereFrom) public bool AssertNotInSimulationTime(string whereFrom)
{ {
if (!InTaintTime) if (InSimulationTime)
{ {
DetailLog("{0},BSScene.AssertInTaintTime,NOT IN TAINT TIME,Region={1},Where={2}", DetailLogZero, RegionName, whereFrom); DetailLog("{0},BSScene.AssertInTaintTime,IN SIMULATION TIME,Region={1},Where={2}", DetailLogZero, RegionName, whereFrom);
m_log.ErrorFormat("{0} NOT IN TAINT TIME!! Region={1}, Where={2}", LogHeader, RegionName, whereFrom); m_log.ErrorFormat("{0} IN SIMULATION TIME!! Region={1}, Where={2}", LogHeader, RegionName, whereFrom);
// Util.PrintCallStack(DetailLog); // Util.PrintCallStack(DetailLog);
} }
return InTaintTime; return InSimulationTime;
} }
#endregion // Taints #endregion // Taints

View File

@ -75,7 +75,7 @@ public sealed class BSShapeCollection : IDisposable
// Called at taint-time. // Called at taint-time.
public bool GetBodyAndShape(bool forceRebuild, BulletWorld sim, BSPhysObject prim, PhysicalDestructionCallback bodyCallback) public bool GetBodyAndShape(bool forceRebuild, BulletWorld sim, BSPhysObject prim, PhysicalDestructionCallback bodyCallback)
{ {
m_physicsScene.AssertInTaintTime("BSShapeCollection.GetBodyAndShape"); m_physicsScene.AssertNotInSimulationTime("BSShapeCollection.GetBodyAndShape");
bool ret = false; bool ret = false;
@ -344,7 +344,7 @@ public sealed class BSShapeCollection : IDisposable
if (!body.HasPhysicalBody) if (!body.HasPhysicalBody)
return; return;
m_physicsScene.AssertInTaintTime("BSShapeCollection.DereferenceBody"); m_physicsScene.AssertNotInSimulationTime("BSShapeCollection.DereferenceBody");
lock (m_collectionActivityLock) lock (m_collectionActivityLock)
{ {

View File

@ -100,6 +100,7 @@ public class BulletBody
} }
} }
// Handle to btCollisionObject - a shape that can be added to a btRidgidBody
public class BulletShape public class BulletShape
{ {
public BulletShape() public BulletShape()