diff options
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSScene.cs')
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 90 |
1 files changed, 61 insertions, 29 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index aaed7de..2c3c481 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | |||
@@ -39,7 +39,6 @@ using log4net; | |||
39 | using OpenMetaverse; | 39 | using OpenMetaverse; |
40 | 40 | ||
41 | // TODOs for BulletSim (for BSScene, BSPrim, BSCharacter and BulletSim) | 41 | // TODOs for BulletSim (for BSScene, BSPrim, BSCharacter and BulletSim) |
42 | // Move all logic out of the C++ code and into the C# code for easier future modifications. | ||
43 | // Test sculpties (verified that they don't work) | 42 | // Test sculpties (verified that they don't work) |
44 | // Compute physics FPS reasonably | 43 | // Compute physics FPS reasonably |
45 | // Based on material, set density and friction | 44 | // Based on material, set density and friction |
@@ -90,10 +89,6 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
90 | // let my minuions use my logger | 89 | // let my minuions use my logger |
91 | public ILog Logger { get { return m_log; } } | 90 | public ILog Logger { get { return m_log; } } |
92 | 91 | ||
93 | // If non-zero, the number of simulation steps between calls to the physics | ||
94 | // engine to output detailed physics stats. Debug logging level must be on also. | ||
95 | private int m_detailedStatsStep = 0; | ||
96 | |||
97 | public IMesher mesher; | 92 | public IMesher mesher; |
98 | // Level of Detail values kept as float because that's what the Meshmerizer wants | 93 | // Level of Detail values kept as float because that's what the Meshmerizer wants |
99 | public float MeshLOD { get; private set; } | 94 | public float MeshLOD { get; private set; } |
@@ -112,6 +107,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
112 | private float m_fixedTimeStep; | 107 | private float m_fixedTimeStep; |
113 | private long m_simulationStep = 0; | 108 | private long m_simulationStep = 0; |
114 | public long SimulationStep { get { return m_simulationStep; } } | 109 | public long SimulationStep { get { return m_simulationStep; } } |
110 | private int m_taintsToProcessPerStep; | ||
115 | 111 | ||
116 | // A value of the time now so all the collision and update routines do not have to get their own | 112 | // A value of the time now so all the collision and update routines do not have to get their own |
117 | // Set to 'now' just before all the prims and actors are called for collisions and updates | 113 | // Set to 'now' just before all the prims and actors are called for collisions and updates |
@@ -131,6 +127,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
131 | 127 | ||
132 | public bool ShouldMeshSculptedPrim { get; private set; } // cause scuplted prims to get meshed | 128 | public bool ShouldMeshSculptedPrim { get; private set; } // cause scuplted prims to get meshed |
133 | public bool ShouldForceSimplePrimMeshing { get; private set; } // if a cube or sphere, let Bullet do internal shapes | 129 | public bool ShouldForceSimplePrimMeshing { get; private set; } // if a cube or sphere, let Bullet do internal shapes |
130 | public bool ShouldUseHullsForPhysicalObjects { get; private set; } // 'true' if should create hulls for physical objects | ||
134 | 131 | ||
135 | public float PID_D { get; private set; } // derivative | 132 | public float PID_D { get; private set; } // derivative |
136 | public float PID_P { get; private set; } // proportional | 133 | public float PID_P { get; private set; } // proportional |
@@ -254,7 +251,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
254 | 251 | ||
255 | // The bounding box for the simulated world. The origin is 0,0,0 unless we're | 252 | // The bounding box for the simulated world. The origin is 0,0,0 unless we're |
256 | // a child in a mega-region. | 253 | // a child in a mega-region. |
257 | // Turns out that Bullet really doesn't care about the extents of the simulated | 254 | // Bullet actually doesn't care about the extents of the simulated |
258 | // area. It tracks active objects no matter where they are. | 255 | // area. It tracks active objects no matter where they are. |
259 | Vector3 worldExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionHeight); | 256 | Vector3 worldExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionHeight); |
260 | 257 | ||
@@ -331,7 +328,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
331 | // Called directly from unmanaged code so don't do much | 328 | // Called directly from unmanaged code so don't do much |
332 | private void BulletLoggerPhysLog(string msg) | 329 | private void BulletLoggerPhysLog(string msg) |
333 | { | 330 | { |
334 | PhysicsLogging.Write("[BULLETS UNMANAGED]:" + msg); | 331 | DetailLog("[BULLETS UNMANAGED]:" + msg); |
335 | } | 332 | } |
336 | 333 | ||
337 | public override void Dispose() | 334 | public override void Dispose() |
@@ -494,8 +491,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
494 | m_simulationStep++; | 491 | m_simulationStep++; |
495 | int numSubSteps = 0; | 492 | int numSubSteps = 0; |
496 | 493 | ||
497 | // Sometimes needed for debugging to find out what happened before the step | 494 | // DEBUG |
498 | // PhysicsLogging.Flush(); | 495 | // DetailLog("{0},BSScene.Simulate,beforeStep,ntaimts={1},step={2}", DetailLogZero, numTaints, m_simulationStep); |
499 | 496 | ||
500 | try | 497 | try |
501 | { | 498 | { |
@@ -505,8 +502,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
505 | out updatedEntityCount, out updatedEntitiesPtr, out collidersCount, out collidersPtr); | 502 | out updatedEntityCount, out updatedEntitiesPtr, out collidersCount, out collidersPtr); |
506 | 503 | ||
507 | if (PhysicsLogging.Enabled) simTime = Util.EnvironmentTickCountSubtract(beforeTime); | 504 | if (PhysicsLogging.Enabled) simTime = Util.EnvironmentTickCountSubtract(beforeTime); |
508 | DetailLog("{0},Simulate,call, nTaints={1}, simTime={2}, substeps={3}, updates={4}, colliders={5}", | 505 | DetailLog("{0},Simulate,call, frame={1}, nTaints={2}, simTime={3}, substeps={4}, updates={5}, colliders={6}", |
509 | DetailLogZero, numTaints, simTime, numSubSteps, updatedEntityCount, collidersCount); | 506 | DetailLogZero, m_simulationStep, numTaints, simTime, numSubSteps, updatedEntityCount, collidersCount); |
510 | } | 507 | } |
511 | catch (Exception e) | 508 | catch (Exception e) |
512 | { | 509 | { |
@@ -582,19 +579,11 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
582 | } | 579 | } |
583 | } | 580 | } |
584 | 581 | ||
585 | // If enabled, call into the physics engine to dump statistics | ||
586 | if (m_detailedStatsStep > 0) | ||
587 | { | ||
588 | if ((m_simulationStep % m_detailedStatsStep) == 0) | ||
589 | { | ||
590 | BulletSimAPI.DumpBulletStatistics(); | ||
591 | } | ||
592 | } | ||
593 | |||
594 | // The physics engine returns the number of milliseconds it simulated this call. | 582 | // The physics engine returns the number of milliseconds it simulated this call. |
595 | // These are summed and normalized to one second and divided by 1000 to give the reported physics FPS. | 583 | // These are summed and normalized to one second and divided by 1000 to give the reported physics FPS. |
596 | // Since Bullet normally does 5 or 6 substeps, this will normally sum to about 60 FPS. | 584 | // We multiply by 45 to give a recognizable running rate (45 or less). |
597 | return numSubSteps * m_fixedTimeStep * 1000; | 585 | return numSubSteps * m_fixedTimeStep * 1000 * 45; |
586 | // return timeStep * 1000 * 45; | ||
598 | } | 587 | } |
599 | 588 | ||
600 | // Something has collided | 589 | // Something has collided |
@@ -617,7 +606,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
617 | BSPhysObject collidee = null; | 606 | BSPhysObject collidee = null; |
618 | PhysObjects.TryGetValue(collidingWith, out collidee); | 607 | PhysObjects.TryGetValue(collidingWith, out collidee); |
619 | 608 | ||
620 | DetailLog("{0},BSScene.SendCollision,collide,id={1},with={2}", DetailLogZero, localID, collidingWith); | 609 | // DetailLog("{0},BSScene.SendCollision,collide,id={1},with={2}", DetailLogZero, localID, collidingWith); |
621 | 610 | ||
622 | if (collider.Collide(collidingWith, collidee, collidePoint, collideNormal, penetration)) | 611 | if (collider.Collide(collidingWith, collidee, collidePoint, collideNormal, penetration)) |
623 | { | 612 | { |
@@ -704,6 +693,35 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
704 | if (_taintedObjects.Count > 0) // save allocating new list if there is nothing to process | 693 | if (_taintedObjects.Count > 0) // save allocating new list if there is nothing to process |
705 | { | 694 | { |
706 | // swizzle a new list into the list location so we can process what's there | 695 | // swizzle a new list into the list location so we can process what's there |
696 | int taintCount = m_taintsToProcessPerStep; | ||
697 | TaintCallbackEntry oneCallback = new TaintCallbackEntry(); | ||
698 | while (_taintedObjects.Count > 0 && taintCount-- > 0) | ||
699 | { | ||
700 | bool gotOne = false; | ||
701 | lock (_taintLock) | ||
702 | { | ||
703 | if (_taintedObjects.Count > 0) | ||
704 | { | ||
705 | oneCallback = _taintedObjects[0]; | ||
706 | _taintedObjects.RemoveAt(0); | ||
707 | gotOne = true; | ||
708 | } | ||
709 | } | ||
710 | if (gotOne) | ||
711 | { | ||
712 | try | ||
713 | { | ||
714 | DetailLog("{0},BSScene.ProcessTaints,doTaint,id={1}", DetailLogZero, oneCallback.ident); // DEBUG DEBUG DEBUG | ||
715 | oneCallback.callback(); | ||
716 | } | ||
717 | catch (Exception e) | ||
718 | { | ||
719 | m_log.ErrorFormat("{0}: ProcessTaints: {1}: Exception: {2}", LogHeader, oneCallback.ident, e); | ||
720 | } | ||
721 | } | ||
722 | } | ||
723 | /* | ||
724 | // swizzle a new list into the list location so we can process what's there | ||
707 | List<TaintCallbackEntry> oldList; | 725 | List<TaintCallbackEntry> oldList; |
708 | lock (_taintLock) | 726 | lock (_taintLock) |
709 | { | 727 | { |
@@ -715,6 +733,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
715 | { | 733 | { |
716 | try | 734 | try |
717 | { | 735 | { |
736 | DetailLog("{0},BSScene.ProcessTaints,doTaint,id={1}", DetailLogZero, tcbe.ident); // DEBUG DEBUG DEBUG | ||
718 | tcbe.callback(); | 737 | tcbe.callback(); |
719 | } | 738 | } |
720 | catch (Exception e) | 739 | catch (Exception e) |
@@ -723,6 +742,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
723 | } | 742 | } |
724 | } | 743 | } |
725 | oldList.Clear(); | 744 | oldList.Clear(); |
745 | */ | ||
726 | } | 746 | } |
727 | } | 747 | } |
728 | 748 | ||
@@ -834,6 +854,11 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
834 | (s,cf,p,v) => { s.ShouldForceSimplePrimMeshing = cf.GetBoolean(p, s.BoolNumeric(v)); }, | 854 | (s,cf,p,v) => { s.ShouldForceSimplePrimMeshing = cf.GetBoolean(p, s.BoolNumeric(v)); }, |
835 | (s) => { return s.NumericBool(s.ShouldForceSimplePrimMeshing); }, | 855 | (s) => { return s.NumericBool(s.ShouldForceSimplePrimMeshing); }, |
836 | (s,p,l,v) => { s.ShouldForceSimplePrimMeshing = s.BoolNumeric(v); } ), | 856 | (s,p,l,v) => { s.ShouldForceSimplePrimMeshing = s.BoolNumeric(v); } ), |
857 | new ParameterDefn("UseHullsForPhysicalObjects", "If true, create hulls for physical objects", | ||
858 | ConfigurationParameters.numericTrue, | ||
859 | (s,cf,p,v) => { s.ShouldUseHullsForPhysicalObjects = cf.GetBoolean(p, s.BoolNumeric(v)); }, | ||
860 | (s) => { return s.NumericBool(s.ShouldUseHullsForPhysicalObjects); }, | ||
861 | (s,p,l,v) => { s.ShouldUseHullsForPhysicalObjects = s.BoolNumeric(v); } ), | ||
837 | 862 | ||
838 | new ParameterDefn("MeshLevelOfDetail", "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)", | 863 | new ParameterDefn("MeshLevelOfDetail", "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)", |
839 | 8f, | 864 | 8f, |
@@ -876,6 +901,11 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
876 | (s,cf,p,v) => { s.m_maxUpdatesPerFrame = cf.GetInt(p, (int)v); }, | 901 | (s,cf,p,v) => { s.m_maxUpdatesPerFrame = cf.GetInt(p, (int)v); }, |
877 | (s) => { return (float)s.m_maxUpdatesPerFrame; }, | 902 | (s) => { return (float)s.m_maxUpdatesPerFrame; }, |
878 | (s,p,l,v) => { s.m_maxUpdatesPerFrame = (int)v; } ), | 903 | (s,p,l,v) => { s.m_maxUpdatesPerFrame = (int)v; } ), |
904 | new ParameterDefn("MaxTaintsToProcessPerStep", "Number of update taints to process before each simulation step", | ||
905 | 100f, | ||
906 | (s,cf,p,v) => { s.m_taintsToProcessPerStep = cf.GetInt(p, (int)v); }, | ||
907 | (s) => { return (float)s.m_taintsToProcessPerStep; }, | ||
908 | (s,p,l,v) => { s.m_taintsToProcessPerStep = (int)v; } ), | ||
879 | new ParameterDefn("MaxObjectMass", "Maximum object mass (10000.01)", | 909 | new ParameterDefn("MaxObjectMass", "Maximum object mass (10000.01)", |
880 | 10000.01f, | 910 | 10000.01f, |
881 | (s,cf,p,v) => { s.MaximumObjectMass = cf.GetFloat(p, v); }, | 911 | (s,cf,p,v) => { s.MaximumObjectMass = cf.GetFloat(p, v); }, |
@@ -1070,12 +1100,12 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
1070 | (s) => { return s.m_params[0].linkConstraintTransMotorMaxForce; }, | 1100 | (s) => { return s.m_params[0].linkConstraintTransMotorMaxForce; }, |
1071 | (s,p,l,v) => { s.m_params[0].linkConstraintTransMotorMaxForce = v; } ), | 1101 | (s,p,l,v) => { s.m_params[0].linkConstraintTransMotorMaxForce = v; } ), |
1072 | new ParameterDefn("LinkConstraintCFM", "Amount constraint can be violated. 0=no violation, 1=infinite. Default=0.1", | 1102 | new ParameterDefn("LinkConstraintCFM", "Amount constraint can be violated. 0=no violation, 1=infinite. Default=0.1", |
1073 | 0.1f, | 1103 | 0.001f, |
1074 | (s,cf,p,v) => { s.m_params[0].linkConstraintCFM = cf.GetFloat(p, v); }, | 1104 | (s,cf,p,v) => { s.m_params[0].linkConstraintCFM = cf.GetFloat(p, v); }, |
1075 | (s) => { return s.m_params[0].linkConstraintCFM; }, | 1105 | (s) => { return s.m_params[0].linkConstraintCFM; }, |
1076 | (s,p,l,v) => { s.m_params[0].linkConstraintCFM = v; } ), | 1106 | (s,p,l,v) => { s.m_params[0].linkConstraintCFM = v; } ), |
1077 | new ParameterDefn("LinkConstraintERP", "Amount constraint is corrected each tick. 0=none, 1=all. Default = 0.2", | 1107 | new ParameterDefn("LinkConstraintERP", "Amount constraint is corrected each tick. 0=none, 1=all. Default = 0.2", |
1078 | 0.2f, | 1108 | 0.8f, |
1079 | (s,cf,p,v) => { s.m_params[0].linkConstraintERP = cf.GetFloat(p, v); }, | 1109 | (s,cf,p,v) => { s.m_params[0].linkConstraintERP = cf.GetFloat(p, v); }, |
1080 | (s) => { return s.m_params[0].linkConstraintERP; }, | 1110 | (s) => { return s.m_params[0].linkConstraintERP; }, |
1081 | (s,p,l,v) => { s.m_params[0].linkConstraintERP = v; } ), | 1111 | (s,p,l,v) => { s.m_params[0].linkConstraintERP = v; } ), |
@@ -1085,11 +1115,11 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
1085 | (s) => { return s.m_params[0].linkConstraintSolverIterations; }, | 1115 | (s) => { return s.m_params[0].linkConstraintSolverIterations; }, |
1086 | (s,p,l,v) => { s.m_params[0].linkConstraintSolverIterations = v; } ), | 1116 | (s,p,l,v) => { s.m_params[0].linkConstraintSolverIterations = v; } ), |
1087 | 1117 | ||
1088 | new ParameterDefn("DetailedStats", "Frames between outputting detailed phys stats. (0 is off)", | 1118 | new ParameterDefn("LogPhysicsStatisticsFrames", "Frames between outputting detailed phys stats. (0 is off)", |
1089 | 0f, | 1119 | 0f, |
1090 | (s,cf,p,v) => { s.m_detailedStatsStep = cf.GetInt(p, (int)v); }, | 1120 | (s,cf,p,v) => { s.m_params[0].physicsLoggingFrames = cf.GetInt(p, (int)v); }, |
1091 | (s) => { return (float)s.m_detailedStatsStep; }, | 1121 | (s) => { return (float)s.m_params[0].physicsLoggingFrames; }, |
1092 | (s,p,l,v) => { s.m_detailedStatsStep = (int)v; } ), | 1122 | (s,p,l,v) => { s.m_params[0].physicsLoggingFrames = (int)v; } ), |
1093 | }; | 1123 | }; |
1094 | 1124 | ||
1095 | // Convert a boolean to our numeric true and false values | 1125 | // Convert a boolean to our numeric true and false values |
@@ -1270,6 +1300,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
1270 | public void DetailLog(string msg, params Object[] args) | 1300 | public void DetailLog(string msg, params Object[] args) |
1271 | { | 1301 | { |
1272 | PhysicsLogging.Write(msg, args); | 1302 | PhysicsLogging.Write(msg, args); |
1303 | // Add the Flush() if debugging crashes to get all the messages written out. | ||
1304 | // PhysicsLogging.Flush(); | ||
1273 | } | 1305 | } |
1274 | // used to fill in the LocalID when there isn't one | 1306 | // used to fill in the LocalID when there isn't one |
1275 | public const string DetailLogZero = "0000000000"; | 1307 | public const string DetailLogZero = "0000000000"; |