aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSScene.cs')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSScene.cs163
1 files changed, 97 insertions, 66 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
index 7017194..a4a8794 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27using System; 27using System;
28using System.Collections.Generic; 28using System.Collections.Generic;
29using System.Linq;
29using System.Reflection; 30using System.Reflection;
30using System.Runtime.InteropServices; 31using System.Runtime.InteropServices;
31using System.Text; 32using System.Text;
@@ -81,14 +82,13 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
81 internal long m_simulationStep = 0; 82 internal long m_simulationStep = 0;
82 internal float NominalFrameRate { get; set; } 83 internal float NominalFrameRate { get; set; }
83 public long SimulationStep { get { return m_simulationStep; } } 84 public long SimulationStep { get { return m_simulationStep; } }
84 internal int m_taintsToProcessPerStep;
85 internal float LastTimeStep { get; private set; } 85 internal float LastTimeStep { get; private set; }
86 86
87 // Physical objects can register for prestep or poststep events 87 // Physical objects can register for prestep or poststep events
88 public delegate void PreStepAction(float timeStep); 88 public delegate void PreStepAction(float timeStep);
89 public delegate void PostStepAction(float timeStep); 89 public delegate void PostStepAction(float timeStep);
90 public event PreStepAction BeforeStep; 90 public event PreStepAction BeforeStep;
91 public event PreStepAction AfterStep; 91 public event PostStepAction AfterStep;
92 92
93 // A value of the time now so all the collision and update routines do not have to get their own 93 // A value of the time now so all the collision and update routines do not have to get their own
94 // Set to 'now' just before all the prims and actors are called for collisions and updates 94 // Set to 'now' just before all the prims and actors are called for collisions and updates
@@ -161,17 +161,22 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
161 private int m_physicsLoggingFileMinutes; 161 private int m_physicsLoggingFileMinutes;
162 private bool m_physicsLoggingDoFlush; 162 private bool m_physicsLoggingDoFlush;
163 private bool m_physicsPhysicalDumpEnabled; 163 private bool m_physicsPhysicalDumpEnabled;
164 public float PhysicsMetricDumpFrames { get; set; } 164 public int PhysicsMetricDumpFrames { get; set; }
165 // 'true' of the vehicle code is to log lots of details 165 // 'true' of the vehicle code is to log lots of details
166 public bool VehicleLoggingEnabled { get; private set; } 166 public bool VehicleLoggingEnabled { get; private set; }
167 public bool VehiclePhysicalLoggingEnabled { get; private set; } 167 public bool VehiclePhysicalLoggingEnabled { get; private set; }
168 168
169 #region Construction and Initialization 169 #region Construction and Initialization
170 public BSScene(string identifier) 170 public BSScene(string engineType, string identifier)
171 { 171 {
172 m_initialized = false; 172 m_initialized = false;
173 // we are passed the name of the region we're working for. 173
174 // The name of the region we're working for is passed to us. Keep for identification.
174 RegionName = identifier; 175 RegionName = identifier;
176
177 // Set identifying variables in the PhysicsScene interface.
178 EngineType = engineType;
179 Name = EngineType + "/" + RegionName;
175 } 180 }
176 181
177 public override void Initialise(IMesher meshmerizer, IConfigSource config) 182 public override void Initialise(IMesher meshmerizer, IConfigSource config)
@@ -311,6 +316,10 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
311 break; 316 break;
312 case "bulletxna": 317 case "bulletxna":
313 ret = new BSAPIXNA(engineName, this); 318 ret = new BSAPIXNA(engineName, this);
319 // Disable some features that are not implemented in BulletXNA
320 m_log.InfoFormat("{0} Disabling some physics features not implemented by BulletXNA", LogHeader);
321 BSParam.ShouldUseBulletHACD = false;
322 BSParam.ShouldUseSingleConvexHullForPrims = false;
314 break; 323 break;
315 } 324 }
316 325
@@ -382,12 +391,14 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
382 if (!m_initialized) return null; 391 if (!m_initialized) return null;
383 392
384 BSCharacter actor = new BSCharacter(localID, avName, this, position, size, isFlying); 393 BSCharacter actor = new BSCharacter(localID, avName, this, position, size, isFlying);
385 lock (PhysObjects) PhysObjects.Add(localID, actor); 394 lock (PhysObjects)
395 PhysObjects.Add(localID, actor);
386 396
387 // TODO: Remove kludge someday. 397 // TODO: Remove kludge someday.
388 // We must generate a collision for avatars whether they collide or not. 398 // We must generate a collision for avatars whether they collide or not.
389 // This is required by OpenSim to update avatar animations, etc. 399 // This is required by OpenSim to update avatar animations, etc.
390 lock (m_avatars) m_avatars.Add(actor); 400 lock (m_avatars)
401 m_avatars.Add(actor);
391 402
392 return actor; 403 return actor;
393 } 404 }
@@ -403,9 +414,11 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
403 { 414 {
404 try 415 try
405 { 416 {
406 lock (PhysObjects) PhysObjects.Remove(actor.LocalID); 417 lock (PhysObjects)
418 PhysObjects.Remove(bsactor.LocalID);
407 // Remove kludge someday 419 // Remove kludge someday
408 lock (m_avatars) m_avatars.Remove(bsactor); 420 lock (m_avatars)
421 m_avatars.Remove(bsactor);
409 } 422 }
410 catch (Exception e) 423 catch (Exception e)
411 { 424 {
@@ -414,13 +427,18 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
414 bsactor.Destroy(); 427 bsactor.Destroy();
415 // bsactor.dispose(); 428 // bsactor.dispose();
416 } 429 }
430 else
431 {
432 m_log.ErrorFormat("{0}: Requested to remove avatar that is not a BSCharacter. ID={1}, type={2}",
433 LogHeader, actor.LocalID, actor.GetType().Name);
434 }
417 } 435 }
418 436
419 public override void RemovePrim(PhysicsActor prim) 437 public override void RemovePrim(PhysicsActor prim)
420 { 438 {
421 if (!m_initialized) return; 439 if (!m_initialized) return;
422 440
423 BSPrim bsprim = prim as BSPrim; 441 BSPhysObject bsprim = prim as BSPhysObject;
424 if (bsprim != null) 442 if (bsprim != null)
425 { 443 {
426 DetailLog("{0},RemovePrim,call", bsprim.LocalID); 444 DetailLog("{0},RemovePrim,call", bsprim.LocalID);
@@ -449,9 +467,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
449 467
450 if (!m_initialized) return null; 468 if (!m_initialized) return null;
451 469
452 DetailLog("{0},AddPrimShape,call", localID); 470 // DetailLog("{0},BSScene.AddPrimShape,call", localID);
453 471
454 BSPrim prim = new BSPrim(localID, primName, this, position, size, rotation, pbs, isPhysical); 472 BSPhysObject prim = new BSPrimLinkable(localID, primName, this, position, size, rotation, pbs, isPhysical);
455 lock (PhysObjects) PhysObjects.Add(localID, prim); 473 lock (PhysObjects) PhysObjects.Add(localID, prim);
456 return prim; 474 return prim;
457 } 475 }
@@ -486,6 +504,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
486 ProcessTaints(); 504 ProcessTaints();
487 505
488 // Some of the physical objects requre individual, pre-step calls 506 // Some of the physical objects requre individual, pre-step calls
507 // (vehicles and avatar movement, in particular)
489 TriggerPreStepEvent(timeStep); 508 TriggerPreStepEvent(timeStep);
490 509
491 // the prestep actions might have added taints 510 // the prestep actions might have added taints
@@ -527,7 +546,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
527 collidersCount = 0; 546 collidersCount = 0;
528 } 547 }
529 548
530 if ((m_simulationStep % PhysicsMetricDumpFrames) == 0) 549 if (PhysicsMetricDumpFrames != 0 && ((m_simulationStep % PhysicsMetricDumpFrames) == 0))
531 PE.DumpPhysicsStatistics(World); 550 PE.DumpPhysicsStatistics(World);
532 551
533 // Get a value for 'now' so all the collision and update routines don't have to get their own. 552 // Get a value for 'now' so all the collision and update routines don't have to get their own.
@@ -543,8 +562,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
543 uint cB = m_collisionArray[ii].bID; 562 uint cB = m_collisionArray[ii].bID;
544 Vector3 point = m_collisionArray[ii].point; 563 Vector3 point = m_collisionArray[ii].point;
545 Vector3 normal = m_collisionArray[ii].normal; 564 Vector3 normal = m_collisionArray[ii].normal;
546 SendCollision(cA, cB, point, normal, 0.01f); 565 float penetration = m_collisionArray[ii].penetration;
547 SendCollision(cB, cA, point, -normal, 0.01f); 566 SendCollision(cA, cB, point, normal, penetration);
567 SendCollision(cB, cA, point, -normal, penetration);
548 } 568 }
549 } 569 }
550 570
@@ -682,7 +702,21 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
682 702
683 public override Dictionary<uint, float> GetTopColliders() 703 public override Dictionary<uint, float> GetTopColliders()
684 { 704 {
685 return new Dictionary<uint, float>(); 705 Dictionary<uint, float> topColliders;
706
707 lock (PhysObjects)
708 {
709 foreach (KeyValuePair<uint, BSPhysObject> kvp in PhysObjects)
710 {
711 kvp.Value.ComputeCollisionScore();
712 }
713
714 List<BSPhysObject> orderedPrims = new List<BSPhysObject>(PhysObjects.Values);
715 orderedPrims.OrderByDescending(p => p.CollisionScore);
716 topColliders = orderedPrims.Take(25).ToDictionary(p => p.LocalID, p => p.CollisionScore);
717 }
718
719 return topColliders;
686 } 720 }
687 721
688 public override bool IsThreaded { get { return false; } } 722 public override bool IsThreaded { get { return false; } }
@@ -694,8 +728,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
694 // TriggerPreStepEvent 728 // TriggerPreStepEvent
695 // DoOneTimeTaints 729 // DoOneTimeTaints
696 // Step() 730 // Step()
697 // ProcessAndForwardCollisions 731 // ProcessAndSendToSimulatorCollisions
698 // ProcessAndForwardPropertyUpdates 732 // ProcessAndSendToSimulatorPropertyUpdates
699 // TriggerPostStepEvent 733 // TriggerPostStepEvent
700 734
701 // Calls to the PhysicsActors can't directly call into the physics engine 735 // Calls to the PhysicsActors can't directly call into the physics engine
@@ -733,7 +767,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
733 767
734 private void TriggerPostStepEvent(float timeStep) 768 private void TriggerPostStepEvent(float timeStep)
735 { 769 {
736 PreStepAction actions = AfterStep; 770 PostStepAction actions = AfterStep;
737 if (actions != null) 771 if (actions != null)
738 actions(timeStep); 772 actions(timeStep);
739 773
@@ -825,15 +859,13 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
825 { 859 {
826 DetailLog("{0},BSScene.AssertInTaintTime,NOT IN TAINT TIME,Region={1},Where={2}", DetailLogZero, RegionName, whereFrom); 860 DetailLog("{0},BSScene.AssertInTaintTime,NOT IN TAINT TIME,Region={1},Where={2}", DetailLogZero, RegionName, whereFrom);
827 m_log.ErrorFormat("{0} NOT IN TAINT TIME!! Region={1}, Where={2}", LogHeader, RegionName, whereFrom); 861 m_log.ErrorFormat("{0} NOT IN TAINT TIME!! Region={1}, Where={2}", LogHeader, RegionName, whereFrom);
828 Util.PrintCallStack(DetailLog); 862 // Util.PrintCallStack(DetailLog);
829 } 863 }
830 return InTaintTime; 864 return InTaintTime;
831 } 865 }
832 866
833 #endregion // Taints 867 #endregion // Taints
834 868
835 #region INI and command line parameter processing
836
837 #region IPhysicsParameters 869 #region IPhysicsParameters
838 // Get the list of parameters this physics engine supports 870 // Get the list of parameters this physics engine supports
839 public PhysParameterEntry[] GetParameterList() 871 public PhysParameterEntry[] GetParameterList()
@@ -848,64 +880,65 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
848 // will use the next time since it's pinned and shared memory. 880 // will use the next time since it's pinned and shared memory.
849 // Some of the values require calling into the physics engine to get the new 881 // Some of the values require calling into the physics engine to get the new
850 // value activated ('terrainFriction' for instance). 882 // value activated ('terrainFriction' for instance).
851 public bool SetPhysicsParameter(string parm, float val, uint localID) 883 public bool SetPhysicsParameter(string parm, string val, uint localID)
852 { 884 {
853 bool ret = false; 885 bool ret = false;
854 BSParam.ParameterDefn theParam; 886
887 BSParam.ParameterDefnBase theParam;
855 if (BSParam.TryGetParameter(parm, out theParam)) 888 if (BSParam.TryGetParameter(parm, out theParam))
856 { 889 {
857 theParam.setter(this, parm, localID, val); 890 // Set the value in the C# code
891 theParam.SetValue(this, val);
892
893 // Optionally set the parameter in the unmanaged code
894 if (theParam.HasSetOnObject)
895 {
896 // update all the localIDs specified
897 // If the local ID is APPLY_TO_NONE, just change the default value
898 // If the localID is APPLY_TO_ALL change the default value and apply the new value to all the lIDs
899 // If the localID is a specific object, apply the parameter change to only that object
900 List<uint> objectIDs = new List<uint>();
901 switch (localID)
902 {
903 case PhysParameterEntry.APPLY_TO_NONE:
904 // This will cause a call into the physical world if some operation is specified (SetOnObject).
905 objectIDs.Add(TERRAIN_ID);
906 TaintedUpdateParameter(parm, objectIDs, val);
907 break;
908 case PhysParameterEntry.APPLY_TO_ALL:
909 lock (PhysObjects) objectIDs = new List<uint>(PhysObjects.Keys);
910 TaintedUpdateParameter(parm, objectIDs, val);
911 break;
912 default:
913 // setting only one localID
914 objectIDs.Add(localID);
915 TaintedUpdateParameter(parm, objectIDs, val);
916 break;
917 }
918 }
919
858 ret = true; 920 ret = true;
859 } 921 }
860 return ret; 922 return ret;
861 } 923 }
862 924
863 // update all the localIDs specified
864 // If the local ID is APPLY_TO_NONE, just change the default value
865 // If the localID is APPLY_TO_ALL change the default value and apply the new value to all the lIDs
866 // If the localID is a specific object, apply the parameter change to only that object
867 internal delegate void AssignVal(float x);
868 internal void UpdateParameterObject(AssignVal setDefault, string parm, uint localID, float val)
869 {
870 List<uint> objectIDs = new List<uint>();
871 switch (localID)
872 {
873 case PhysParameterEntry.APPLY_TO_NONE:
874 setDefault(val); // setting only the default value
875 // This will cause a call into the physical world if some operation is specified (SetOnObject).
876 objectIDs.Add(TERRAIN_ID);
877 TaintedUpdateParameter(parm, objectIDs, val);
878 break;
879 case PhysParameterEntry.APPLY_TO_ALL:
880 setDefault(val); // setting ALL also sets the default value
881 lock (PhysObjects) objectIDs = new List<uint>(PhysObjects.Keys);
882 TaintedUpdateParameter(parm, objectIDs, val);
883 break;
884 default:
885 // setting only one localID
886 objectIDs.Add(localID);
887 TaintedUpdateParameter(parm, objectIDs, val);
888 break;
889 }
890 }
891
892 // schedule the actual updating of the paramter to when the phys engine is not busy 925 // schedule the actual updating of the paramter to when the phys engine is not busy
893 private void TaintedUpdateParameter(string parm, List<uint> lIDs, float val) 926 private void TaintedUpdateParameter(string parm, List<uint> lIDs, string val)
894 { 927 {
895 float xval = val; 928 string xval = val;
896 List<uint> xlIDs = lIDs; 929 List<uint> xlIDs = lIDs;
897 string xparm = parm; 930 string xparm = parm;
898 TaintedObject("BSScene.UpdateParameterSet", delegate() { 931 TaintedObject("BSScene.UpdateParameterSet", delegate() {
899 BSParam.ParameterDefn thisParam; 932 BSParam.ParameterDefnBase thisParam;
900 if (BSParam.TryGetParameter(xparm, out thisParam)) 933 if (BSParam.TryGetParameter(xparm, out thisParam))
901 { 934 {
902 if (thisParam.onObject != null) 935 if (thisParam.HasSetOnObject)
903 { 936 {
904 foreach (uint lID in xlIDs) 937 foreach (uint lID in xlIDs)
905 { 938 {
906 BSPhysObject theObject = null; 939 BSPhysObject theObject = null;
907 PhysObjects.TryGetValue(lID, out theObject); 940 if (PhysObjects.TryGetValue(lID, out theObject))
908 thisParam.onObject(this, theObject, xval); 941 thisParam.SetOnObject(this, theObject);
909 } 942 }
910 } 943 }
911 } 944 }
@@ -914,14 +947,14 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
914 947
915 // Get parameter. 948 // Get parameter.
916 // Return 'false' if not able to get the parameter. 949 // Return 'false' if not able to get the parameter.
917 public bool GetPhysicsParameter(string parm, out float value) 950 public bool GetPhysicsParameter(string parm, out string value)
918 { 951 {
919 float val = 0f; 952 string val = String.Empty;
920 bool ret = false; 953 bool ret = false;
921 BSParam.ParameterDefn theParam; 954 BSParam.ParameterDefnBase theParam;
922 if (BSParam.TryGetParameter(parm, out theParam)) 955 if (BSParam.TryGetParameter(parm, out theParam))
923 { 956 {
924 val = theParam.getter(this); 957 val = theParam.GetValue(this);
925 ret = true; 958 ret = true;
926 } 959 }
927 value = val; 960 value = val;
@@ -930,8 +963,6 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
930 963
931 #endregion IPhysicsParameters 964 #endregion IPhysicsParameters
932 965
933 #endregion Runtime settable parameters
934
935 // Invoke the detailed logger and output something if it's enabled. 966 // Invoke the detailed logger and output something if it's enabled.
936 public void DetailLog(string msg, params Object[] args) 967 public void DetailLog(string msg, params Object[] args)
937 { 968 {