BulletSim: add post taint taints and post step taints. The post taints operation is most useful and is used by linksets to build and rebuild only once before the simulation step.
parent
2f25f70316
commit
9568f24c26
|
@ -171,7 +171,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private Object _taintLock = new Object(); // lock for using the next object
|
private Object _taintLock = new Object(); // lock for using the next object
|
||||||
private List<TaintCallbackEntry> _taintedObjects;
|
private List<TaintCallbackEntry> _taintOperations;
|
||||||
|
private Dictionary<string, TaintCallbackEntry> _postTaintOperations;
|
||||||
|
private List<TaintCallbackEntry> _postStepOperations;
|
||||||
|
|
||||||
// A pointer to an instance if this structure is passed to the C++ code
|
// A pointer to an instance if this structure is passed to the C++ code
|
||||||
// Used to pass basic configuration values to the unmanaged code.
|
// Used to pass basic configuration values to the unmanaged code.
|
||||||
|
@ -203,7 +205,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
public override void Initialise(IMesher meshmerizer, IConfigSource config)
|
public override void Initialise(IMesher meshmerizer, IConfigSource config)
|
||||||
{
|
{
|
||||||
mesher = meshmerizer;
|
mesher = meshmerizer;
|
||||||
_taintedObjects = new List<TaintCallbackEntry>();
|
_taintOperations = new List<TaintCallbackEntry>();
|
||||||
|
_postTaintOperations = new Dictionary<string, TaintCallbackEntry>();
|
||||||
|
_postStepOperations = new List<TaintCallbackEntry>();
|
||||||
PhysObjects = new Dictionary<uint, BSPhysObject>();
|
PhysObjects = new Dictionary<uint, BSPhysObject>();
|
||||||
Shapes = new BSShapeCollection(this);
|
Shapes = new BSShapeCollection(this);
|
||||||
|
|
||||||
|
@ -475,23 +479,21 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
if (!m_initialized) return 5.0f;
|
if (!m_initialized) return 5.0f;
|
||||||
|
|
||||||
// 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
|
||||||
int numTaints = _taintedObjects.Count;
|
int numTaints = _taintOperations.Count;
|
||||||
ProcessTaints();
|
ProcessTaints();
|
||||||
|
|
||||||
// Some of the prims operate with special vehicle properties
|
// Some of the prims operate with special vehicle properties
|
||||||
ProcessVehicles(timeStep);
|
ProcessVehicles(timeStep);
|
||||||
numTaints += _taintedObjects.Count;
|
numTaints += _taintOperations.Count;
|
||||||
ProcessTaints(); // the vehicles might have added taints
|
ProcessTaints(); // the vehicles might have added taints
|
||||||
|
|
||||||
// step the physical world one interval
|
// step the physical world one interval
|
||||||
m_simulationStep++;
|
m_simulationStep++;
|
||||||
int numSubSteps = 0;
|
int numSubSteps = 0;
|
||||||
|
|
||||||
// DEBUG
|
|
||||||
// DetailLog("{0},BSScene.Simulate,beforeStep,ntaimts={1},step={2}", DetailLogZero, numTaints, m_simulationStep);
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
// DumpVehicles(); // DEBUG
|
||||||
if (PhysicsLogging.Enabled) beforeTime = Util.EnvironmentTickCount();
|
if (PhysicsLogging.Enabled) beforeTime = Util.EnvironmentTickCount();
|
||||||
|
|
||||||
numSubSteps = BulletSimAPI.PhysicsStep2(World.ptr, timeStep, m_maxSubSteps, m_fixedTimeStep,
|
numSubSteps = BulletSimAPI.PhysicsStep2(World.ptr, timeStep, m_maxSubSteps, m_fixedTimeStep,
|
||||||
|
@ -500,6 +502,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
if (PhysicsLogging.Enabled) simTime = Util.EnvironmentTickCountSubtract(beforeTime);
|
if (PhysicsLogging.Enabled) simTime = Util.EnvironmentTickCountSubtract(beforeTime);
|
||||||
DetailLog("{0},Simulate,call, frame={1}, nTaints={2}, simTime={3}, substeps={4}, updates={5}, colliders={6}",
|
DetailLog("{0},Simulate,call, frame={1}, nTaints={2}, simTime={3}, substeps={4}, updates={5}, colliders={6}",
|
||||||
DetailLogZero, m_simulationStep, numTaints, simTime, numSubSteps, updatedEntityCount, collidersCount);
|
DetailLogZero, m_simulationStep, numTaints, simTime, numSubSteps, updatedEntityCount, collidersCount);
|
||||||
|
// DumpVehicles(); // DEBUG
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
@ -579,6 +582,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
// Only enable this in a limited test world with few objects.
|
// Only enable this in a limited test world with few objects.
|
||||||
// BulletSimAPI.DumpAllInfo2(World.ptr); // DEBUG DEBUG DEBUG
|
// BulletSimAPI.DumpAllInfo2(World.ptr); // DEBUG DEBUG DEBUG
|
||||||
|
|
||||||
|
ProcessPostStepTaints();
|
||||||
|
|
||||||
// The physics engine returns the number of milliseconds it simulated this call.
|
// The physics engine returns the number of milliseconds it simulated this call.
|
||||||
// These are summed and normalized to one second and divided by 1000 to give the reported physics FPS.
|
// These are summed and normalized to one second and divided by 1000 to give the reported physics FPS.
|
||||||
// We multiply by 55 to give a recognizable running rate (55 or less).
|
// We multiply by 55 to give a recognizable running rate (55 or less).
|
||||||
|
@ -670,6 +675,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
|
|
||||||
public override bool IsThreaded { get { return false; } }
|
public override bool IsThreaded { get { return false; } }
|
||||||
|
|
||||||
|
#region Taints
|
||||||
|
|
||||||
// Calls to the PhysicsActors can't directly call into the physics engine
|
// Calls to the PhysicsActors can't directly call into the physics engine
|
||||||
// because it might be busy. We delay changes to a known time.
|
// because it might be busy. We delay changes to a known time.
|
||||||
// We rely on C#'s closure to save and restore the context for the delegate.
|
// We rely on C#'s closure to save and restore the context for the delegate.
|
||||||
|
@ -679,7 +686,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
|
|
||||||
lock (_taintLock)
|
lock (_taintLock)
|
||||||
{
|
{
|
||||||
_taintedObjects.Add(new TaintCallbackEntry(ident, callback));
|
_taintOperations.Add(new TaintCallbackEntry(ident, callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -690,19 +697,25 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
// 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()
|
public void ProcessTaints()
|
||||||
{
|
{
|
||||||
if (_taintedObjects.Count > 0) // save allocating new list if there is nothing to process
|
ProcessRegularTaints();
|
||||||
|
ProcessPostTaintTaints();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ProcessRegularTaints()
|
||||||
|
{
|
||||||
|
if (_taintOperations.Count > 0) // save allocating new list if there is nothing to process
|
||||||
{
|
{
|
||||||
int taintCount = m_taintsToProcessPerStep;
|
int taintCount = m_taintsToProcessPerStep;
|
||||||
TaintCallbackEntry oneCallback = new TaintCallbackEntry();
|
TaintCallbackEntry oneCallback = new TaintCallbackEntry();
|
||||||
while (_taintedObjects.Count > 0 && taintCount-- > 0)
|
while (_taintOperations.Count > 0 && taintCount-- > 0)
|
||||||
{
|
{
|
||||||
bool gotOne = false;
|
bool gotOne = false;
|
||||||
lock (_taintLock)
|
lock (_taintLock)
|
||||||
{
|
{
|
||||||
if (_taintedObjects.Count > 0)
|
if (_taintOperations.Count > 0)
|
||||||
{
|
{
|
||||||
oneCallback = _taintedObjects[0];
|
oneCallback = _taintOperations[0];
|
||||||
_taintedObjects.RemoveAt(0);
|
_taintOperations.RemoveAt(0);
|
||||||
gotOne = true;
|
gotOne = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -746,6 +759,89 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Schedule an update to happen after all the regular taints are processed.
|
||||||
|
// Note that new requests for the same operation ("ident") for the same object ("ID")
|
||||||
|
// will replace any previous operation by the same object.
|
||||||
|
public void PostTaintObject(String ident, uint ID, TaintCallback callback)
|
||||||
|
{
|
||||||
|
if (!m_initialized) return;
|
||||||
|
|
||||||
|
lock (_taintLock)
|
||||||
|
{
|
||||||
|
_postTaintOperations[ident] = new TaintCallbackEntry(ident + "-" + ID.ToString(), callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ProcessPostTaintTaints()
|
||||||
|
{
|
||||||
|
if (_postTaintOperations.Count > 0)
|
||||||
|
{
|
||||||
|
Dictionary<string, TaintCallbackEntry> oldList;
|
||||||
|
lock (_taintLock)
|
||||||
|
{
|
||||||
|
oldList = _postTaintOperations;
|
||||||
|
_postTaintOperations = new Dictionary<string, TaintCallbackEntry>();
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (KeyValuePair<string,TaintCallbackEntry> kvp in oldList)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
DetailLog("{0},BSScene.ProcessPostTaintTaints,doTaint,id={1}", DetailLogZero, kvp.Key); // DEBUG DEBUG DEBUG
|
||||||
|
kvp.Value.callback();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
m_log.ErrorFormat("{0}: ProcessPostTaintTaints: {1}: Exception: {2}", LogHeader, kvp.Key, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
oldList.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PostStepTaintObject(String ident, TaintCallback callback)
|
||||||
|
{
|
||||||
|
if (!m_initialized) return;
|
||||||
|
|
||||||
|
lock (_taintLock)
|
||||||
|
{
|
||||||
|
_postStepOperations.Add(new TaintCallbackEntry(ident, callback));
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ProcessPostStepTaints()
|
||||||
|
{
|
||||||
|
if (_postStepOperations.Count > 0)
|
||||||
|
{
|
||||||
|
List<TaintCallbackEntry> oldList;
|
||||||
|
lock (_taintLock)
|
||||||
|
{
|
||||||
|
oldList = _postStepOperations;
|
||||||
|
_postStepOperations = new List<TaintCallbackEntry>();
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (TaintCallbackEntry tcbe in oldList)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
DetailLog("{0},BSScene.ProcessPostStepTaints,doTaint,id={1}", DetailLogZero, tcbe.ident); // DEBUG DEBUG DEBUG
|
||||||
|
tcbe.callback();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
m_log.ErrorFormat("{0}: ProcessPostStepTaints: {1}: Exception: {2}", LogHeader, tcbe.ident, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
oldList.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion // Taints
|
||||||
|
|
||||||
#region Vehicles
|
#region Vehicles
|
||||||
|
|
||||||
public void VehicleInSceneTypeChanged(BSPrim vehic, Vehicle newType)
|
public void VehicleInSceneTypeChanged(BSPrim vehic, Vehicle newType)
|
||||||
|
@ -1006,7 +1102,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
(s,cf,p,v) => { s.m_params[0].ccdSweptSphereRadius = cf.GetFloat(p, v); },
|
(s,cf,p,v) => { s.m_params[0].ccdSweptSphereRadius = cf.GetFloat(p, v); },
|
||||||
(s) => { return s.m_params[0].ccdSweptSphereRadius; },
|
(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); } ),
|
(s,o,v) => { BulletSimAPI.SetCcdSweptSphereRadius2(o.BSBody.ptr, v); } ),
|
||||||
new ParameterDefn("ContactProcessingThreshold", "Distance between contacts before doing collision check" ,
|
new ParameterDefn("ContactProcessingThreshold", "Distance between contacts before doing collision check" ,
|
||||||
0.1f,
|
0.1f,
|
||||||
(s,cf,p,v) => { s.m_params[0].contactProcessingThreshold = cf.GetFloat(p, v); },
|
(s,cf,p,v) => { s.m_params[0].contactProcessingThreshold = cf.GetFloat(p, v); },
|
||||||
|
@ -1128,12 +1224,12 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
(s) => { return s.m_params[0].linkConstraintTransMotorMaxForce; },
|
(s) => { return s.m_params[0].linkConstraintTransMotorMaxForce; },
|
||||||
(s,p,l,v) => { s.m_params[0].linkConstraintTransMotorMaxForce = v; } ),
|
(s,p,l,v) => { s.m_params[0].linkConstraintTransMotorMaxForce = v; } ),
|
||||||
new ParameterDefn("LinkConstraintCFM", "Amount constraint can be violated. 0=no violation, 1=infinite. Default=0.1",
|
new ParameterDefn("LinkConstraintCFM", "Amount constraint can be violated. 0=no violation, 1=infinite. Default=0.1",
|
||||||
0.001f,
|
0.1f,
|
||||||
(s,cf,p,v) => { s.m_params[0].linkConstraintCFM = cf.GetFloat(p, v); },
|
(s,cf,p,v) => { s.m_params[0].linkConstraintCFM = cf.GetFloat(p, v); },
|
||||||
(s) => { return s.m_params[0].linkConstraintCFM; },
|
(s) => { return s.m_params[0].linkConstraintCFM; },
|
||||||
(s,p,l,v) => { s.m_params[0].linkConstraintCFM = v; } ),
|
(s,p,l,v) => { s.m_params[0].linkConstraintCFM = v; } ),
|
||||||
new ParameterDefn("LinkConstraintERP", "Amount constraint is corrected each tick. 0=none, 1=all. Default = 0.2",
|
new ParameterDefn("LinkConstraintERP", "Amount constraint is corrected each tick. 0=none, 1=all. Default = 0.2",
|
||||||
0.8f,
|
0.1f,
|
||||||
(s,cf,p,v) => { s.m_params[0].linkConstraintERP = cf.GetFloat(p, v); },
|
(s,cf,p,v) => { s.m_params[0].linkConstraintERP = cf.GetFloat(p, v); },
|
||||||
(s) => { return s.m_params[0].linkConstraintERP; },
|
(s) => { return s.m_params[0].linkConstraintERP; },
|
||||||
(s,p,l,v) => { s.m_params[0].linkConstraintERP = v; } ),
|
(s,p,l,v) => { s.m_params[0].linkConstraintERP = v; } ),
|
||||||
|
@ -1326,6 +1422,16 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
|
|
||||||
#endregion Runtime settable parameters
|
#endregion Runtime settable parameters
|
||||||
|
|
||||||
|
// Debugging routine for dumping detailed physical information for vehicle prims
|
||||||
|
private void DumpVehicles()
|
||||||
|
{
|
||||||
|
foreach (BSPrim prim in m_vehicles)
|
||||||
|
{
|
||||||
|
BulletSimAPI.DumpRigidBody2(World.ptr, prim.BSBody.ptr);
|
||||||
|
BulletSimAPI.DumpCollisionShape2(World.ptr, prim.BSShape.ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Invoke the detailed logger and output something if it's enabled.
|
// Invoke the detailed logger and output something if it's enabled.
|
||||||
public void DetailLog(string msg, params Object[] args)
|
public void DetailLog(string msg, params Object[] args)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue