MezzanineEngine 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
physicsmanager.cpp
1 // © Copyright 2010 - 2014 BlackTopp Studios Inc.
2 /* This file is part of The Mezzanine Engine.
3 
4  The Mezzanine Engine is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  The Mezzanine Engine is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with The Mezzanine Engine. If not, see <http://www.gnu.org/licenses/>.
16 */
17 /* The original authors have included a copy of the license specified above in the
18  'Docs' folder. See 'gpl.txt'
19 */
20 /* We welcome the use of the Mezzanine engine to anyone, including companies who wish to
21  Build professional software and charge for their product.
22 
23  However there are some practical restrictions, so if your project involves
24  any of the following you should contact us and we will try to work something
25  out:
26  - DRM or Copy Protection of any kind(except Copyrights)
27  - Software Patents You Do Not Wish to Freely License
28  - Any Kind of Linking to Non-GPL licensed Works
29  - Are Currently In Violation of Another Copyright Holder's GPL License
30  - If You want to change our code and not add a few hundred MB of stuff to
31  your distribution
32 
33  These and other limitations could cause serious legal problems if you ignore
34  them, so it is best to simply contact us or the Free Software Foundation, if
35  you have any questions.
36 
37  Joseph Toppi - toppij@gmail.com
38  John Blackwood - makoenergy02@gmail.com
39 */
40 #ifndef _physicsphysicsmanager_cpp
41 #define _physicsphysicsmanager_cpp
42 
43 using namespace std;
44 
45 #include "Physics/physicsmanager.h"
46 #include "Physics/collision.h"
47 
48 #include "Physics/ghostproxy.h"
49 #include "Physics/rigidproxy.h"
50 #include "Physics/softproxy.h"
51 
52 #include "Graphics/graphicsmanager.h"
53 
54 // WorldObject Manager includes are here for the debug draw work unit dependency setting
55 #include "actormanager.h"
56 #include "areaeffectmanager.h"
57 #include "debrismanager.h"
58 
59 #include "stringtool.h"
60 #include "linegroup.h"
61 #include "vector3.h"
62 #include "worldtrigger.h"
63 #include "worldobject.h"
64 #include "crossplatform.h"
65 #include "entresol.h"
66 
67 #include "Physics/collisiondispatcher.h.cpp"
68 
69 #include <queue>
70 #include <algorithm>
71 
72 #include <btBulletDynamicsCommon.h>
73 #include <BulletSoftBody/btSoftRigidDynamicsWorld.h>
74 #include <BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h>
75 #include <BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h>
76 #include <BulletCollision/CollisionDispatch/btGhostObject.h>
77 
78 // This define is needed to avoid a declaration collision for uint64_t between a bullet typedef and the one in stdint.h
79 #define __PHYSICS_COMMON_H__ 1
80 
81 #ifdef WINDOWS
82 #include <BulletMultiThreaded/Win32ThreadSupport.h>
83 #else
84 #include <BulletMultiThreaded/PosixThreadSupport.h>
85 #endif
86 
87 #include <BulletMultiThreaded/btParallelConstraintSolver.h>
88 #include <BulletMultiThreaded/SpuGatheringCollisionDispatcher.h>
89 #include <BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.h>
90 
91 
92 namespace Mezzanine
93 {
94  /// @internal
95  /// @namespace Mezzanine::debug
96  /// @brief This namespace is for internal debugging tools. In general it shouldn't be used in game code.
97  /// @details This whole debug namespace is a dirty hack. This is where internal only classes and functions go
98  /// that can and maybe should be ommited from release builds
99  namespace debug
100  {
101  /// @internal
102  /// @class InternalDebugDrawer
103  /// @brief This is used to draw wireframse for the Physics subsystem
104  class InternalDebugDrawer : public btIDebugDraw
105  {
106  private:
107  /// @internal
108  /// @brief This stores the wireframe being used for rendering.
109  Mezzanine::LineGroup* WireFrame;
110  /// @internal
111  /// @brief This stores whether or not to render physics debug lines
112  /// @details This stores whether or not to render physics debud lines. 0 = Do not draw anything. 1 = Draw model wireframes.
113  /// Later we will add support for contact drawing, individual modeling drawing, etc...
114  int DebugDrawing;
115  public:
116  /// @internal
117  /// @brief Basic Constructor
119  /// @internal
120  /// @brief Destructor
121  virtual ~InternalDebugDrawer();
122 
123  /// @internal
124  /// @brief Clears data as necessary for updating debug geometry.
125  virtual void PrepareForUpdate();
126  /// @internal
127  /// @brief Copies all the line data to render buffers so they can be seen on screen.
128  virtual void FinalizeUpdate();
129 
130  /// @internal
131  /// @brief This will prepare a line segment for being drawn
132  /// @details This adds the points for a line to the internal list of points to be rendered.
133  /// @param from The first point of the line
134  /// @param to The second point of the line
135  /// @param color Currently ignored
136  virtual void drawLine(const btVector3& from,const btVector3& to,const btVector3& color);
137  /// @internal
138  /// @brief Currently Unused
139  /// @details Currently Unused
140  /// @param PointOnB Currently Unused
141  /// @param normalOnB Currently Unused
142  /// @param distance Currently Unused
143  /// @param lifeTime Currently Unused
144  /// @param color Currently Unused
145  virtual void drawContactPoint(const btVector3& PointOnB,const btVector3& normalOnB,btScalar distance,int lifeTime,const btVector3& color);
146  /// @internal
147  /// @brief Currently Unused
148  /// @details Currently Unused
149  /// @param location Currently Unused
150  /// @param textString Currently Unused
151  virtual void draw3dText(const btVector3& location, const char* textString);
152 
153  /// @internal
154  /// @brief This is used to decide how much the debug render should draw
155  /// @details Currently this accepts btIDebugDraw::DBG_NoDebug or btIDebugDraw::DBG_DrawWireframe and setting these will either start or stop
156  /// Wireframe rendering. All other btIDebugDraw values are ignored.
157  /// @param debugMode An Int which contains either btIDebugDraw::DBG_NoDebug or btIDebugDraw::DBG_DrawWireframe
158  virtual void setDebugMode(int debugMode);
159  /// @internal
160  /// @brief This will return the current debug mode.
161  /// @details Currently this can only return btIDebugDraw::DBG_NoDebug or btIDebugDraw::DBG_DrawWireframe
162  /// @return Returns the Current debug mode, currently either btIDebugDraw::DBG_NoDebug or btIDebugDraw::DBG_DrawWireframe
163  virtual int getDebugMode() const;
164 
165  /// @internal
166  /// @brief Used by the physics subsystem to report errors using the renderer
167  /// @details We *Believe* that this is used by the physics subsystem to report errors about rendering to the developer/user. As such, we
168  /// Have redirected all input from this function to the Entresol::Log function.
169  /// @param warningString We *Believe* These are messagesfrom the physics subsystem, and that this should not directly called otherwise
170  virtual void reportErrorWarning(const char* warningString);
171  };
172 
173  InternalDebugDrawer::InternalDebugDrawer()
174  {
175  this->DebugDrawing = Physics::DDM_NoDebug;
176  this->WireFrame = new Mezzanine::LineGroup();
177  }
178 
179  InternalDebugDrawer::~InternalDebugDrawer()
180  {
181  delete this->WireFrame;
182  }
183 
184  void InternalDebugDrawer::PrepareForUpdate()
185  {
186  if( this->WireFrame != NULL ) {
187  this->WireFrame->AddToWorld();
188  this->WireFrame->ClearLines();
189  }
190  }
191 
192  void InternalDebugDrawer::FinalizeUpdate()
193  {
194  if( this->WireFrame != NULL ) {
195  this->WireFrame->DrawLines();
196  }
197  }
198 
199  void InternalDebugDrawer::drawLine(const btVector3& from,const btVector3& to,const btVector3& color)
200  {
201  this->WireFrame->DrawLine( Vector3(from), Vector3(to), ColourValue(color.getX(),color.getY(),color.getZ()) );
202  }
203 
204  void InternalDebugDrawer::drawContactPoint(const btVector3& PointOnB,const btVector3& normalOnB,btScalar distance,int lifeTime,const btVector3& color)
205  {
206  }
207 
208  void InternalDebugDrawer::draw3dText(const btVector3& location,const char* textString)
209  {
210  }
211 
212  void InternalDebugDrawer::setDebugMode(int debugMode)
213  {
214  this->DebugDrawing = debugMode;
215  if( this->WireFrame != NULL ) {
216  if( this->DebugDrawing != Physics::DDM_NoDebug ) {
217  this->WireFrame->AddToWorld();
218  }else{
219  this->WireFrame->RemoveFromWorld();
220  }
221  }
222  }
223 
224  int InternalDebugDrawer::getDebugMode() const
225  {
226  return this->DebugDrawing;
227  }
228 
229  void InternalDebugDrawer::reportErrorWarning(const char* warningString)
230  {
231  String temp(warningString);
233  }
234  }// debug
235 
236  #ifdef GetObject
237  #undef GetObject
238  #endif
239  namespace Physics
240  {
241  ///////////////////////////////////////////////////////////
242  // SimulationWorkUnit functions
243 
244  SimulationWorkUnit::SimulationWorkUnit(const SimulationWorkUnit& Other)
245  { }
246 
247  SimulationWorkUnit& SimulationWorkUnit::operator=(const SimulationWorkUnit& Other)
248  { return *this; }
249 
250  SimulationWorkUnit::SimulationWorkUnit(PhysicsManager* Target) :
251  TargetManager(Target) { }
252 
254  { }
255 
256  ///////////////////////////////////////////////////////////////////////////////
257  // Utility
258 
260  {
261  if( this->TargetManager->SimulationIsPaused() )
262  return;
263 
264  this->TargetManager->ThreadResources = &CurrentThreadStorage;
265  Real FloatTime = this->TargetManager->TheEntresol->GetLastFrameTimeMilliseconds() * 0.001; // ©onvert from MilliSeconds to Seconds
266  //Real IdealStep = static_cast<Real>( this->TargetManager->TheEntresol->GetTargetFrameTimeMilliseconds() ) * 0.001;
267  //IdealStep /= this->TargetManager->SubstepModifier;
268  //IdealStep = ( IdealStep < 1.0/240.0 ? 1.0/240.0 : IdealStep );
269  int MaxSteps = ( FloatTime < this->TargetManager->StepSize ) ? 1 : int( FloatTime / this->TargetManager->StepSize ) + 1;
270  this->TargetManager->BulletDynamicsWorld->stepSimulation( FloatTime, MaxSteps, this->TargetManager->StepSize );
271  this->TargetManager->ThreadResources = NULL;
272  }
273 
274  ///////////////////////////////////////////////////////////
275  // SimulationMonopolyWorkUnit functions
276 
278  { }
279 
281  { return *this; }
282 
284  TargetManager(Target) { }
285 
287  { }
288 
289  ///////////////////////////////////////////////////////////////////////////////
290  // Utility
291 
293  {
294  // Do nothing
295  }
296 
298  {
299  return this->TargetManager->ThreadCount;
300  }
301 
303  {
304  if( this->TargetManager->SimulationIsPaused() )
305  return;
306 
307  this->TargetManager->ThreadResources = &CurrentThreadStorage;
308  Real FloatTime = this->TargetManager->TheEntresol->GetLastFrameTimeMilliseconds() * 0.001; // ©onvert from MilliSeconds to Seconds
309  //Real IdealStep = static_cast<Real>( this->TargetManager->TheEntresol->GetTargetFrameTimeMilliseconds() ) * 0.001;
310  //IdealStep /= this->TargetManager->SubstepModifier;
311  //IdealStep = ( IdealStep < 1.0/240.0 ? 1.0/240.0 : IdealStep );
312  int MaxSteps = ( FloatTime < this->TargetManager->StepSize ) ? 1 : int( FloatTime / this->TargetManager->StepSize ) + 1;
313  this->TargetManager->BulletDynamicsWorld->stepSimulation( FloatTime, MaxSteps, this->TargetManager->StepSize );
314  this->TargetManager->ThreadResources = NULL;
315  }
316 
317  ///////////////////////////////////////////////////////////
318  // WorldTriggerUpdate functions
319 
321  { }
322 
324  { return *this; }
325 
327  TargetManager(Target) { }
328 
330  { }
331 
332  ///////////////////////////////////////////////////////////////////////////////
333  // Utility
334 
336  {
337  // No real logging necessary
339  }
340 
341  ///////////////////////////////////////////////////////////
342  // DebugDrawWorkUnit functions
343 
345  { }
346 
348  { return *this; }
349 
351  TargetManager(Target) { }
352 
354  { }
355 
356  ///////////////////////////////////////////////////////////////////////////////
357  // Utility
358 
360  {
361  // No real logging necessary
362  debug::InternalDebugDrawer* Drawer = this->TargetManager->BulletDrawer;
363  if( Drawer && Drawer->getDebugMode() ) //this part is responsible for drawing the wireframes
364  {
365  Drawer->PrepareForUpdate();
366  this->TargetManager->BulletDynamicsWorld->debugDrawWorld();
367  Drawer->FinalizeUpdate();
368  }
369  }
370 
371  ///////////////////////////////////////////////////////////
372  // Physicsmanager functions
373 
375  SimulationPaused(false),
376  DebugRenderMode(0),
377  SubstepModifier(1),
378  ThreadCount(0),
379  StepSize(1.0/60.0),
380 
381  GhostCallback(NULL),
382  BulletSolverThreads(NULL),
383  BulletDispatcherThreads(NULL),
384  BulletBroadphase(NULL),
385  BulletCollisionConfiguration(NULL),
386  BulletDispatcher(NULL),
387  BulletSolver(NULL),
388  BulletDynamicsWorld(NULL),
389  BulletDrawer(NULL),
390 
391  SimulationWork(NULL),
392  WorldTriggerUpdateWork(NULL),
393  DebugDrawWork(NULL),
394  ThreadResources(NULL)
395  {
398  this->Construct(Info);
399  }
400 
402  SimulationPaused(false),
403  DebugRenderMode(0),
404  SubstepModifier(1),
405  ThreadCount(0),
406  StepSize(1.0/60.0),
407 
408  GhostCallback(NULL),
409  BulletSolverThreads(NULL),
410  BulletDispatcherThreads(NULL),
411  BulletBroadphase(NULL),
412  BulletCollisionConfiguration(NULL),
413  BulletDispatcher(NULL),
414  BulletSolver(NULL),
415  BulletDynamicsWorld(NULL),
416  BulletDrawer(NULL),
417 
418  SimulationWork(NULL),
419  WorldTriggerUpdateWork(NULL),
420  DebugDrawWork(NULL),
421  ThreadResources(NULL)
422  {
423  this->Construct(Info);
424  }
425 
427  SimulationPaused(false),
428  DebugRenderMode(0),
429  SubstepModifier(1),
430  ThreadCount(0),
431  StepSize(1.0/60.0),
432 
433  GhostCallback(NULL),
434  BulletSolverThreads(NULL),
435  BulletDispatcherThreads(NULL),
436  BulletBroadphase(NULL),
437  BulletCollisionConfiguration(NULL),
438  BulletDispatcher(NULL),
439  BulletSolver(NULL),
440  BulletDynamicsWorld(NULL),
441  BulletDrawer(NULL),
442 
443  SimulationWork(NULL),
444  WorldTriggerUpdateWork(NULL),
445  DebugDrawWork(NULL),
446  ThreadResources(NULL)
447  {
449  XML::Attribute CurrAttrib;
450 
451  XML::Node WorldSettings = XMLNode.GetChild("WorldSettings");
452  if(!WorldSettings.Empty())
453  {
454  CurrAttrib = WorldSettings.GetAttribute("LimitlessWorld");
455  if(!CurrAttrib.Empty())
456  {
458  }else{
459  CurrAttrib = WorldSettings.GetAttribute("WorldUpperBounds");
460  if(!CurrAttrib.Empty())
462  CurrAttrib = WorldSettings.GetAttribute("WorldLowerBounds");
463  if(!CurrAttrib.Empty())
465  CurrAttrib = WorldSettings.GetAttribute("MaxProxies");
466  if(!CurrAttrib.Empty())
467  Info.MaxProxies = CurrAttrib.AsWhole();
468  }
469  CurrAttrib = WorldSettings.GetAttribute("SoftRigidWorld");
470  if(!CurrAttrib.Empty())
471  {
473  }
474  CurrAttrib = WorldSettings.GetAttribute("MultiThreaded");
475  if(!CurrAttrib.Empty())
476  {
478  }
479  }
480 
481  this->Construct(Info);
482 
483  XML::Node StepModifier = XMLNode.GetChild("SubStepModifier");
484  if(!StepModifier.Empty())
485  {
486  CurrAttrib = WorldSettings.GetAttribute("Modifier");
487  if(!CurrAttrib.Empty()) {
489  }
490  }
491 
492  XML::Node DebugRender = XMLNode.GetChild("DebugRendering");
493  if(!DebugRender.Empty())
494  {
495  int RenderMode = 0;
496  CurrAttrib = WorldSettings.GetAttribute("RenderingMode");
497  if(!CurrAttrib.Empty())
498  RenderMode = CurrAttrib.AsInt();
499 
500  if(0 != RenderMode) {
501  this->SetDebugRenderingMode(RenderMode);
502  }
503  }
504  }
505 
507  {
508  btCollisionObjectArray ObjectArray( BulletDynamicsWorld->getCollisionObjectArray() );
509  for( Integer X = 0 ; X < BulletDynamicsWorld->getNumCollisionObjects() ; ++X )
510  {
511  CollidableProxy* Prox = static_cast<CollidableProxy*>( ObjectArray[X]->getUserPointer() );
512  Prox->RemoveFromWorld();
513  }
514 
515  this->DestroyAllConstraints();
516  this->DestroyAllProxies();
517  this->DestroyAllWorldTriggers();
518 
519  this->Deinitialize();
520 
521  //Destroy the physical world that we loved and cherished
522  this->Destroy();
523  }
524 
526  {
528 
529  // Create the broadphase
531  this->BulletBroadphase = new btDbvtBroadphase();
532  }else{
533  if( Info.MaxProxies < 65536 )
534  {
535  this->BulletBroadphase = new btAxisSweep3(Info.GeographyLowerBounds.GetBulletVector3(),
537  Info.MaxProxies);
538  }else{
539  this->BulletBroadphase = new bt32BitAxisSweep3(Info.GeographyLowerBounds.GetBulletVector3(),
541  Info.MaxProxies);
542  }
543  }
544 
545  // Create the collision configuration
546  //if( Info.PhysicsFlags & ManagerConstructionInfo::PCF_SoftRigidWorld ) {
547  this->BulletCollisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
548  /*}else{
549  this->BulletCollisionConfiguration = new btDefaultCollisionConfiguration();
550  }//*/
551 
552  // Create the dispatcher (narrowphase)
554  #ifdef WINDOWS
555  Win32ThreadSupport::Win32ThreadConstructionInfo BulletThreadInfo( "DispatcherThreads",
556  processCollisionTask,
557  createCollisionLocalStoreMemory,
558  ThreadCount );
559  this->BulletDispatcherThreads = new Win32ThreadSupport(BulletThreadInfo);
560  #else //WINDOWS
561  PosixThreadSupport::ThreadConstructionInfo BulletThreadInfo( "DispatcherThreads",
562  processCollisionTask,
563  createCollisionLocalStoreMemory,
564  ThreadCount );
565  this->BulletDispatcherThreads = new PosixThreadSupport(BulletThreadInfo);
566  #endif //WINDOWS
567  this->BulletDispatcher = new ParallelCollisionDispatcher(this->BulletDispatcherThreads,ThreadCount,this->BulletCollisionConfiguration);
568  }else{
569  this->BulletDispatcher = new CollisionDispatcher(this->BulletCollisionConfiguration);
570  }
571 
572  // Create the constraint solver
574  #ifdef WINDOWS
575  Win32ThreadSupport::Win32ThreadConstructionInfo BulletThreadInfo( "SolverThreads",
576  SolverThreadFunc,
577  SolverlsMemoryFunc,
578  ThreadCount );
579  this->BulletSolverThreads = new Win32ThreadSupport(BulletThreadInfo);
580  this->BulletSolverThreads->startSPU();
581  #else //WINDOWS
582  PosixThreadSupport::ThreadConstructionInfo BulletThreadInfo( "SolverThreads",
583  SolverThreadFunc,
584  SolverlsMemoryFunc,
585  ThreadCount );
586  this->BulletSolverThreads = new PosixThreadSupport(BulletThreadInfo);
587  #endif //WINDOWS
588  //this->BulletSolver = new btParallelConstraintSolver(this->BulletSolverThreads);
589  this->BulletSolver = new btSequentialImpulseConstraintSolver();
590  }else{
591  this->BulletSolver = new btSequentialImpulseConstraintSolver();
592  }
593 
594  // Create the world
595  //if( Info.PhysicsFlags & ManagerConstructionInfo::PCF_SoftRigidWorld ) {
596  this->BulletDynamicsWorld = new btSoftRigidDynamicsWorld( this->BulletDispatcher,
597  this->BulletBroadphase,
598  this->BulletSolver,
599  this->BulletCollisionConfiguration);
600  /*}else{
601  this->BulletDynamicsWorld = new btDiscreteDynamicsWorld( this->BulletDispatcher,
602  this->BulletBroadphase,
603  this->BulletSolver,
604  this->BulletCollisionConfiguration);
605  }//*/
606 
607  // Set up the work units
609  this->SimulationWork = new SimulationMonopolyWorkUnit(this);
610  }else{
611  this->SimulationWork = new SimulationWorkUnit(this);
612  }
614  this->DebugDrawWork = new DebugDrawWorkUnit(this);
615 
616  // Configure the extra data
617  btGImpactCollisionAlgorithm::registerAlgorithm(this->BulletDispatcher);
618 
619  this->GhostCallback = new btGhostPairCallback();
620  this->BulletBroadphase->getOverlappingPairCache()->setInternalGhostPairCallback(this->GhostCallback);
621 
622  this->BulletDynamicsWorld->setInternalTickCallback((btInternalTickCallback)PhysicsManager::InternalTickCallback,0,false);
623 
624  this->BulletDynamicsWorld->getWorldInfo().m_dispatcher = this->BulletDispatcher;
625  this->BulletDynamicsWorld->getWorldInfo().m_broadphase = this->BulletBroadphase;
626  this->BulletDynamicsWorld->getWorldInfo().m_sparsesdf.Initialize();
627 
628  this->BulletDynamicsWorld->getDispatchInfo().m_enableSPU = true;
629  this->BulletDynamicsWorld->getDispatchInfo().m_useContinuous = true;
630  //this->BulletDynamicsWorld->getSolverInfo().m_splitImpulse = true;
631  //this->BulletDynamicsWorld->getSolverInfo().m_numIterations = 20;
632  //this->BulletDynamicsWorld->getSolverInfo().m_globalCfm = 0.15;
633  //this->BulletDynamicsWorld->getSolverInfo().m_erp = 0.4;
634 
635  this->SetWorldGravity(Info.Gravity);
636  this->SetWorldSoftGravity(Info.Gravity);
637  this->WorldConstructionInfo = Info;
638  }
639 
641  {
642  delete this->BulletDynamicsWorld;
643  this->BulletDynamicsWorld = NULL;
644  delete this->BulletDispatcher;
645  this->BulletDispatcher = NULL;
646  delete this->BulletCollisionConfiguration;
647  this->BulletCollisionConfiguration = NULL;
648  delete this->BulletSolver;
649  this->BulletSolver = NULL;
650  delete this->BulletBroadphase;
651  this->BulletBroadphase = NULL;
652  delete this->GhostCallback;
653  this->GhostCallback = NULL;
654  if(BulletDrawer) {
655  delete this->BulletDrawer;
656  this->BulletDrawer = NULL;
657  }
658  if(BulletSolverThreads) {
659  delete this->BulletSolverThreads;
660  this->BulletSolverThreads = NULL;
661  }
662  if(BulletDispatcherThreads) {
663  delete this->BulletDispatcherThreads;
664  this->BulletDispatcherThreads = NULL;
665  }
666 
667  if(this->ThreadCount)
668  {
669  this->TheEntresol->GetScheduler().RemoveWorkUnitMonopoly( static_cast<Threading::MonopolyWorkUnit*>( this->SimulationWork ) );
670  }else{
672  }
673  delete this->SimulationWork;
674  this->SimulationWork = NULL;
675 
677  delete this->WorldTriggerUpdateWork;
678  this->WorldTriggerUpdateWork = NULL;
679 
681  delete this->DebugDrawWork;
682  this->DebugDrawWork = NULL;
683  }
684 
686  {
687  if( !Triggers.empty() )
688  {
689  for( std::vector<WorldTrigger*>::iterator Trig = Triggers.begin() ; Trig != Triggers.end() ; Trig++ )
690  {
691  if((*Trig)->ConditionsAreMet())
692  (*Trig)->ApplyTrigger();
693  }
694  }
695  }
696 
698  {
699  //Update the collisions that already exist as necessary
700  for( PhysicsManager::CollisionIterator ColIt = Collisions.begin() ; ColIt != Collisions.end() ; ColIt++ )
701  (*ColIt).second->Update();
702  //Process the collisions that are in the creation queue
703  AlgoList* AlgoQueue = ( this->WorldConstructionInfo.PhysicsFlags & ManagerConstructionInfo::PCF_Multithreaded ?
704  static_cast<ParallelCollisionDispatcher*>( this->BulletDispatcher )->GetAlgoCreationQueue() :
705  static_cast<CollisionDispatcher*>( this->BulletDispatcher )->GetAlgoCreationQueue() );
706  if(AlgoQueue->empty())
707  return;
708  #ifdef MEZZDEBUG
709  /*StringStream logstream;
710  logstream << "Processing " << AlgoQueue->size() << " algorithms for collisions.";
711  Entresol::GetSingletonPtr()->Log(logstream.str());
712  Entresol::GetSingletonPtr()->DoMainLoopLogging();//*/
713  #endif
714  btCollisionAlgorithm* NewAlgo = AlgoQueue->front();
715  while( NewAlgo != NULL )
716  {
717  CollidableProxy* ProxA = NULL;
718  CollidableProxy* ProxB = NULL;
719  /// @todo This is an absurd round-about way to get the data we need,
720  /// and bullet will probably have to be extended to change this so it's actually good.
721  btBroadphasePairArray& PairArray = BulletBroadphase->getOverlappingPairCache()->getOverlappingPairArray();
722  for( Integer X = 0 ; X < PairArray.size() ; ++X )
723  {
724  if( NewAlgo == PairArray[X].m_algorithm )
725  {
726  btCollisionObject* COA = (btCollisionObject*)PairArray[X].m_pProxy0->m_clientObject;
727  ProxA = static_cast<CollidableProxy*>( COA->getUserPointer() );
728  btCollisionObject* COB = (btCollisionObject*)PairArray[X].m_pProxy1->m_clientObject;
729  ProxB = static_cast<CollidableProxy*>( COB->getUserPointer() );
730  break;
731  }
732  }
733 
734  if( ( ProxA != NULL && ProxA->GetCollisionResponse() ) && ( ProxB != NULL && ProxB->GetCollisionResponse() ) )
735  {
736  // Create the collision
737  CollidablePair NewPair(ProxA,ProxB);
738  PhysicsManager::CollisionIterator ColIt = Collisions.find(NewPair);
739  if(ColIt == Collisions.end())
740  {
741  Physics::Collision* NewCol = new Physics::Collision(ProxA,ProxB,NewAlgo);
742  //NewCol->GetActorA()->_NotifyCollisionState(NewCol,Physics::Collision::Col_Begin);
743  //NewCol->GetActorB()->_NotifyCollisionState(NewCol,Physics::Collision::Col_Begin);
744  Collisions.insert( CollisionSortPair(NewPair,NewCol) );
745  }
746  }
747  AlgoQueue->pop_front();
748  if(AlgoQueue->size() > 0) NewAlgo = AlgoQueue->front();
749  else NewAlgo = NULL;
750  }//*/
751  }
752 
753  void PhysicsManager::InternalTickCallback(btDynamicsWorld* world, btScalar timeStep)
754  {
756  }
757 
758  ///////////////////////////////////////////////////////////////////////////////
759  // Simulation Management
760 
762  {
763  this->SimulationPaused = Pause;
764  }
765 
767  {
768  return this->SimulationPaused;
769  }
770 
771  ///////////////////////////////////////////////////////////////////////////////
772  // Gravity Management
773 
775  {
776  this->BulletDynamicsWorld->setGravity(pgrav.GetBulletVector3());
777  }
778 
780  {
781  Vector3 grav(this->BulletDynamicsWorld->getGravity());
782  return grav;
783  }
784 
786  {
787  this->BulletDynamicsWorld->getWorldInfo().m_gravity = sgrav.GetBulletVector3();
788  }
789 
791  {
792  Vector3 sgrav(this->BulletDynamicsWorld->getWorldInfo().m_gravity);
793  return sgrav;
794  }
795 
796  ///////////////////////////////////////////////////////////////////////////////
797  // Creating Proxies
798 
800  {
801  GhostProxy* NewProxy = new GhostProxy(this);
802  this->Proxies.push_back(NewProxy);
803  return NewProxy;
804  }
805 
807  {
808  GhostProxy* NewProxy = new GhostProxy(SelfRoot,this);
809  this->Proxies.push_back(NewProxy);
810  return NewProxy;
811  }
812 
814  {
815  RigidProxy* NewProxy = new RigidProxy(Mass,this);
816  this->Proxies.push_back(NewProxy);
817  return NewProxy;
818  }
819 
821  {
822  RigidProxy* NewProxy = new RigidProxy(SelfRoot,this);
823  this->Proxies.push_back(NewProxy);
824  return NewProxy;
825  }
826 
828  {
829  SoftProxy* NewProxy = new SoftProxy(Mass,this);
830  this->Proxies.push_back(NewProxy);
831  return NewProxy;
832  }
833 
835  {
836  SoftProxy* NewProxy = new SoftProxy(SelfRoot,this);
837  this->Proxies.push_back(NewProxy);
838  return NewProxy;
839  }
840 
841  ///////////////////////////////////////////////////////////////////////////////
842  // Proxy Management
843 
845  { return this->Proxies.at(Index); }
846 
848  { return this->Proxies.size(); }
849 
851  {
852  for( ProxyIterator ProxIt = this->Proxies.begin() ; ProxIt != this->Proxies.end() ; ++ProxIt )
853  {
854  if( ToBeDestroyed == (*ProxIt) ) {
855  WorldObject* Parent = (*ProxIt)->GetParentObject();
856  if( Parent )
857  Parent->_NotifyProxyDestroyed( (*ProxIt) );
858 
859  delete (*ProxIt);
860  this->Proxies.erase(ProxIt);
861  return;
862  }
863  }
864  }
865 
867  {
868  for( ProxyIterator ProxIt = this->Proxies.begin() ; ProxIt != this->Proxies.end() ; ++ProxIt )
869  {
870  WorldObject* Parent = (*ProxIt)->GetParentObject();
871  if( Parent )
872  Parent->_NotifyProxyDestroyed( (*ProxIt) );
873 
874  delete (*ProxIt);
875  }
876  this->Proxies.clear();
877  }
878 
879  ///////////////////////////////////////////////////////////////////////////////
880  // Constraint Management
881 
882  void PhysicsManager::AddConstraint(Physics::Constraint* Con, bool DisableCollisions)
883  {
884  this->BulletDynamicsWorld->addConstraint(Con->GetConstraintBase(), DisableCollisions);
885  this->Constraints.push_back(Con);
886  }
887 
889  {
890  return this->Constraints[Index];
891  }
892 
894  {
895  return this->Constraints.size();
896  }
897 
899  {
900  this->BulletDynamicsWorld->removeConstraint(Con->GetConstraintBase());
901  for( ConstraintIterator ConIt = this->Constraints.begin() ; ConIt < this->Constraints.end() ; ConIt++ )
902  {
903  if( (*ConIt) == Con )
904  {
905  this->Constraints.erase(ConIt);
906  return;
907  }
908  }
909  }
910 
912  {
913  for( ConstraintIterator Con = this->Constraints.begin() ; Con != this->Constraints.end() ; Con++ )
914  {
915  this->BulletDynamicsWorld->removeConstraint((*Con)->GetConstraintBase());
916  delete (*Con);
917  }
918  this->Constraints.clear();
919  }
920 
921  ///////////////////////////////////////////////////////////////////////////////
922  // Trigger Management
923 
925  {
926  this->Triggers.push_back(Trig);
927  }
928 
930  {
931  for( ConstWorldTriggerIterator Trig = this->Triggers.begin() ; Trig != this->Triggers.end() ; Trig++ )
932  {
933  if( Name == (*Trig)->GetName() )
934  {
935  return *Trig;
936  }
937  }
938  return NULL;
939  }
940 
942  {
943  return this->Triggers.at(Index);
944  }
945 
947  {
948  return this->Triggers.size();
949  }
950 
952  {
953  for( WorldTriggerIterator T = this->Triggers.begin() ; T != this->Triggers.end() ; T++ )
954  {
955  if( Trig == (*T) )
956  {
957  this->Triggers.erase(T);
958  return;
959  }
960  }
961  }
962 
964  {
965  for( WorldTriggerIterator Trig = this->Triggers.begin() ; Trig != this->Triggers.end() ; Trig++ )
966  delete (*Trig);
967  this->Triggers.clear();
968  }
969 
970  ///////////////////////////////////////////////////////////////////////////////
971  // Collision Management
972 
974  {
975  ConstCollisionIterator ColIt = this->Collisions.find(*Pair);
976  if(ColIt != this->Collisions.end()) return (*ColIt).second;
977  else return NULL;
978  }
979 
981  {
982  return this->Collisions.size();
983  }
984 
986  {
987  //((CollisionDispatcher*)BulletDispatcher)->releaseManifoldManual(Col->Manifold);
988  btBroadphasePair* btPair = this->BulletBroadphase->getOverlappingPairCache()->findPair(
989  Col->ProxyA->_GetBasePhysicsObject()->getBroadphaseHandle(),
990  Col->ProxyB->_GetBasePhysicsObject()->getBroadphaseHandle());
991  this->BulletBroadphase->getOverlappingPairCache()->removeOverlappingPair(
992  Col->ProxyA->_GetBasePhysicsObject()->getBroadphaseHandle(),
993  Col->ProxyB->_GetBasePhysicsObject()->getBroadphaseHandle(),
994  this->BulletDispatcher);// */
995  this->BulletBroadphase->getOverlappingPairCache()->cleanOverlappingPair(*btPair,this->BulletDispatcher);
996  delete btPair;
997  }
998 
1000  {
1001  if( !Proxy->IsInWorld() )
1002  return;
1003 
1004  this->BulletBroadphase->getOverlappingPairCache()->cleanProxyFromPairs( Proxy->_GetBasePhysicsObject()->getBroadphaseHandle(), this->BulletDispatcher );
1005 
1006  CollisionIterator ColIt = this->Collisions.begin();
1007  while( ColIt != this->Collisions.end() )
1008  {
1009  Physics::Collision* ToBeDestroyed = (*ColIt).second;
1010  if( Proxy == (*ColIt).second->ProxyA || Proxy == (*ColIt).second->ProxyB ) {
1011  CollisionIterator Delete = ColIt;
1012  ++ColIt;
1013  this->Collisions.erase(Delete);
1014  delete ToBeDestroyed;
1015  }else{
1016  ++ColIt;
1017  }
1018  }
1019  }
1020 
1022  {
1023  for( CollisionIterator ColIt = this->Collisions.begin() ; ColIt != this->Collisions.end() ; ++ColIt )
1024  {
1025  delete (*ColIt).second;
1026  }
1027  this->Collisions.clear();
1028  }
1029 
1031  {
1032  return this->Collisions.begin();
1033  }
1034 
1036  {
1037  return this->Collisions.end();
1038  }
1039 
1041  {
1042  return this->Collisions.begin();
1043  }
1044 
1046  {
1047  return this->Collisions.end();
1048  }
1049 
1050  ///////////////////////////////////////////////////////////////////////////////
1051  // Debug Management
1052 
1053  void PhysicsManager::SetDebugRenderingMode(const Integer DebugRenderingMode)
1054  {
1055  if( this->BulletDrawer ) {
1056  this->DebugRenderMode = DebugRenderingMode;
1057  this->BulletDrawer->setDebugMode( DebugRenderingMode );
1058  }
1059  }
1060 
1062  {
1063  return this->DebugRenderMode;
1064  }
1065 
1066  ///////////////////////////////////////////////////////////////////////////////
1067  // Utility
1068 
1070  {
1071  this->Destroy();
1072  if(Info) this->Construct(*Info);
1073  else this->Construct(WorldConstructionInfo);
1074 
1075  if( this->Initialized && this->BulletDrawer == NULL ) {
1076  this->BulletDrawer = new debug::InternalDebugDrawer();
1077  this->BulletDrawer->setDebugMode( this->DebugRenderMode );
1078  this->BulletDynamicsWorld->setDebugDrawer( this->BulletDrawer );
1079  }
1080  }
1081 
1083  {
1084  // Clean the broadphase of AABB data
1085  btOverlappingPairCache* Pairs = this->BulletBroadphase->getOverlappingPairCache();
1086  int NumPairs = Pairs->getNumOverlappingPairs();
1087  btBroadphasePairArray PairArray = Pairs->getOverlappingPairArray();
1088  for( Integer X = 0 ; X < NumPairs ; X++ )
1089  {
1090  btBroadphasePair& CurrPair = PairArray.at(X);
1091  Pairs->cleanOverlappingPair(CurrPair,this->BulletDispatcher);
1092  Pairs->removeOverlappingPair(CurrPair.m_pProxy0,CurrPair.m_pProxy1,this->BulletDispatcher);
1093  }
1094 
1095  // Clean the dispatcher(narrowphase) of shape data
1096  int numManifolds = this->BulletDispatcher->getNumManifolds();
1097  for ( int i = 0 ; i < numManifolds ; i++ )
1098  {
1099  this->BulletDispatcher->releaseManifold(this->BulletDispatcher->getManifoldByIndexInternal(i));
1100  }
1101 
1102  this->BulletBroadphase->resetPool(this->BulletDispatcher);
1103  this->BulletSolver->reset();
1104  this->BulletDynamicsWorld->stepSimulation(1.f/60.f,1,1.f/60.f);
1105  }
1106 
1108  {
1109  SubstepModifier = Modifier;
1110  }
1111 
1113  {
1114  // Implement later
1115  }
1116 
1118  {
1119  // Configure our area effects so they have an updated list and apply their effects immediately.
1120  this->BulletDynamicsWorld->updateAabbs();
1121  this->BulletBroadphase->calculateOverlappingPairs(this->BulletDispatcher);
1122  this->BulletDispatcher->dispatchAllCollisionPairs(this->BulletDynamicsWorld->getPairCache(),this->BulletDynamicsWorld->getDispatchInfo(),this->BulletDispatcher);
1123 
1124  // Set our ideal simulation step size
1125  //Real InvSubStepMod = 1.0 / this->SubstepModifier;
1126  //Real TargetTimeSeconds = static_cast<Real>( this->TheEntresol->GetTargetFrameTimeMicroseconds() ) * 0.000001;
1127  //this->StepSize = std::max( TargetTimeSeconds * InvSubStepMod, static_cast<Real>( 1.0 / 120.0 ) );
1128  //this->StepSize = TargetTimeSeconds * InvSubStepMod;
1129  this->StepSize = (static_cast<Real>( this->TheEntresol->GetTargetFrameTimeMicroseconds() ) * 0.000001) / this->SubstepModifier;
1130  }
1131 
1133  {
1134  if( !this->Initialized )
1135  {
1136  //WorldManager::Initialize();
1137 
1138  // Create the debugdrawer
1139  this->BulletDrawer = new debug::InternalDebugDrawer();
1140  this->BulletDrawer->setDebugMode( this->DebugRenderMode );
1141  this->BulletDynamicsWorld->setDebugDrawer( this->BulletDrawer );
1142 
1143  // Simulation work configuration
1144  if( this->WorldConstructionInfo.PhysicsFlags & ManagerConstructionInfo::PCF_Multithreaded ) {
1145  this->TheEntresol->GetScheduler().AddWorkUnitMonopoly( static_cast<Threading::MonopolyWorkUnit*>( this->SimulationWork ), "SimulationWorkMonopoly" );
1146  }else{
1147  this->TheEntresol->GetScheduler().AddWorkUnitMain( this->SimulationWork, "SimulationWorkMain" );
1148  }
1150  if( GraphicsMan )
1151  this->SimulationWork->AddDependency( GraphicsMan->GetRenderWork() );
1152 
1156  // Debug Draw work configuration
1157  // Must add as affinity since it manipulates raw buffers and makes rendersystem calls under the hood.
1158  this->TheEntresol->GetScheduler().AddWorkUnitAffinity( this->DebugDrawWork, "DebugDrawWork" );
1159  this->DebugDrawWork->AddDependency( this->SimulationWork );
1160  if( ActorMan )
1161  this->DebugDrawWork->AddDependency( ActorMan->GetActorUpdateWork() );
1162  if( AEMan )
1164  if( DebrisMan )
1165  this->DebugDrawWork->AddDependency( DebrisMan->GetDebrisUpdateWork() );
1166 
1167  // World Trigger Update work configuration
1168  this->TheEntresol->GetScheduler().AddWorkUnitMain( this->WorldTriggerUpdateWork, "WorldTriggerUpdateWork" );
1170  if( DebrisMan )
1172 
1173  this->Initialized = true;
1174  }
1175  }
1176 
1178  {
1179  if( this->Initialized )
1180  {
1181  // Destroy the debugdrawer
1182  delete this->BulletDrawer;
1183  this->BulletDrawer = NULL;
1184  this->BulletDynamicsWorld->setDebugDrawer( this->BulletDrawer );
1185 
1186  // Simulation work configuration
1187  if( this->WorldConstructionInfo.PhysicsFlags & ManagerConstructionInfo::PCF_Multithreaded ) {
1188  this->TheEntresol->GetScheduler().RemoveWorkUnitMonopoly( static_cast<Threading::MonopolyWorkUnit*>( this->SimulationWork ) );
1189  }else{
1191  }
1193 
1194  // Debug Draw work configuration
1195  // Must add as affinity since it manipulates raw buffers and makes rendersystem calls under the hood.
1198 
1199  // World Trigger Update work configuration
1202 
1203  this->Initialized = false;
1204  }
1205  }
1206 
1208  {
1209  return this->SimulationWork;
1210  }
1211 
1213  {
1214  return this->WorldTriggerUpdateWork;
1215  }
1216 
1218  {
1219  return this->DebugDrawWork;
1220  }
1221 
1222  ///////////////////////////////////////////////////////////////////////////////
1223  // Type Identifier Methods
1224 
1226  { return ManagerBase::MT_PhysicsManager; }
1227 
1229  { return "DefaultPhysicsManager"; }
1230 
1231  ///////////////////////////////////////////////////////////////////////////////
1232  // Internal Methods
1233 
1234  btSoftRigidDynamicsWorld* PhysicsManager::_GetPhysicsWorldPointer()
1235  { return this->BulletDynamicsWorld; }
1236 
1237  const btSoftRigidDynamicsWorld* PhysicsManager::_GetPhysicsWorldPointer() const
1238  { return this->BulletDynamicsWorld; }
1239 
1240  ///////////////////////////////////////////////////////////////////////////////
1241  // DefaultPhysicsManagerFactory Methods
1242 
1244  {
1245  }
1246 
1248  {
1249  }
1250 
1252  {
1253  return "DefaultPhysicsManager";
1254  }
1255 
1257  {
1258  if(Params.empty()) return new PhysicsManager();
1259  else
1260  {
1261  ManagerConstructionInfo PhysInfo;
1262  for( NameValuePairList::iterator ParIt = Params.begin() ; ParIt != Params.end() ; ++ParIt )
1263  {
1264  String Lower = (*ParIt).first;
1265  StringTools::ToLowerCase(Lower);
1266  if( "geographyupperbounds" == Lower )
1267  {
1268  PhysInfo.GeographyUpperBounds = StringTools::ConvertToVector3( (*ParIt).second );
1269  }
1270  else if( "geographylowerbounds" == Lower )
1271  {
1272  PhysInfo.GeographyLowerBounds = StringTools::ConvertToVector3( (*ParIt).second );
1273  }
1274  else if( "maxproxies" == Lower )
1275  {
1276  PhysInfo.MaxProxies = StringTools::ConvertToUInt32( (*ParIt).second );
1277  }
1278  else if( "gravity" == Lower )
1279  {
1280  PhysInfo.Gravity = StringTools::ConvertToVector3( (*ParIt).second );
1281  }
1282  else if( "softrigidworld" == Lower )
1283  {
1284  if(StringTools::ConvertToBool( (*ParIt).second ))
1286  }
1287  else if( "limitlessworld" == Lower )
1288  {
1289  if(StringTools::ConvertToBool( (*ParIt).second ))
1291  }
1292  else if( "multithreaded" == Lower )
1293  {
1294  if(StringTools::ConvertToBool( (*ParIt).second ))
1296  }
1297  }
1298  return new PhysicsManager(PhysInfo);
1299  }
1300  }
1301 
1303  {
1304  return new PhysicsManager(XMLNode);
1305  }
1306 
1308  {
1309  delete ToBeDestroyed;
1310  }
1311  }//Physics
1312 }//Mezzanine
1313 
1314 #endif