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

View File

@ -790,7 +790,7 @@ public class BSPrim : BSPhysObject
public override OMV.Vector3 ForceVelocity {
get { return RawVelocity; }
set {
PhysScene.AssertInTaintTime("BSPrim.ForceVelocity");
PhysScene.AssertNotInSimulationTime("BSPrim.ForceVelocity");
RawVelocity = Util.ClampV(value, BSParam.MaxLinearVelocity);
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.
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
internal int m_maxCollisionsPerFrame;
internal CollisionDesc[] m_collisionArray;
@ -344,6 +347,7 @@ namespace OpenSim.Region.PhysicsModule.BulletS
// Put some informational messages into the log file.
m_log.InfoFormat("{0} Linksets implemented with {1}", LogHeader, (BSLinkset.LinksetImplementation)BSParam.LinksetImplementation);
InSimulationTime = false;
InTaintTime = false;
m_initialized = true;
@ -658,21 +662,21 @@ namespace OpenSim.Region.PhysicsModule.BulletS
int beforeTime = Util.EnvironmentTickCount();
int simTime = 0;
int numTaints = _taintOperations.Count;
InTaintTime = true; // Only used for debugging so locking is not necessary.
InTaintTime = true;
// 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
// (vehicles and avatar movement, in particular)
TriggerPreStepEvent(timeStep);
// the prestep actions might have added taints
numTaints += _taintOperations.Count;
ProcessTaints();
numTaints += 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.
// 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))
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.
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);
if (PhysicsLogging.Enabled)
{
@ -1090,6 +1103,15 @@ namespace OpenSim.Region.PhysicsModule.BulletS
{
if (!m_initialized) return;
lock (_taintLock) {
if (inTaintTime || !InSimulationTime) {
pCallback();
}
else {
_taintOperations.Add(new TaintCallbackEntry(pOriginator, pIdent, pCallback));
}
}
/*
if (inTaintTime)
pCallback();
else
@ -1099,6 +1121,7 @@ namespace OpenSim.Region.PhysicsModule.BulletS
_taintOperations.Add(new TaintCallbackEntry(pOriginator, pIdent, pCallback));
}
}
*/
}
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
// 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.
public void ProcessTaints()
// Returns the number of taints processed
public int ProcessTaints()
{
ProcessRegularTaints();
ProcessPostTaintTaints();
int ret = 0;
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
{
// 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
tcbe.callback();
ret++;
}
catch (Exception e)
{
@ -1152,6 +1181,7 @@ namespace OpenSim.Region.PhysicsModule.BulletS
}
oldList.Clear();
}
return ret;
}
// 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.
private void ProcessPostTaintTaints()
// Returns the number of taints processed
private int ProcessPostTaintTaints()
{
int ret = 0;
if (m_initialized && _postTaintOperations.Count > 0)
{
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
kvp.Value.callback();
ret++;
}
catch (Exception e)
{
@ -1195,18 +1228,19 @@ namespace OpenSim.Region.PhysicsModule.BulletS
}
oldList.Clear();
}
return ret;
}
// Only used for debugging. Does not change state of anything so locking is not necessary.
public bool AssertInTaintTime(string whereFrom)
// Verify that things are being diddled when the physics engine is not running.
public bool AssertNotInSimulationTime(string whereFrom)
{
if (!InTaintTime)
if (InSimulationTime)
{
DetailLog("{0},BSScene.AssertInTaintTime,NOT IN TAINT TIME,Region={1},Where={2}", DetailLogZero, RegionName, whereFrom);
m_log.ErrorFormat("{0} NOT IN TAINT TIME!! Region={1}, Where={2}", LogHeader, RegionName, whereFrom);
DetailLog("{0},BSScene.AssertInTaintTime,IN SIMULATION TIME,Region={1},Where={2}", DetailLogZero, RegionName, whereFrom);
m_log.ErrorFormat("{0} IN SIMULATION TIME!! Region={1}, Where={2}", LogHeader, RegionName, whereFrom);
// Util.PrintCallStack(DetailLog);
}
return InTaintTime;
return InSimulationTime;
}
#endregion // Taints

View File

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