PhysicsWorld.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. // Copyright (C) 2009-2015, Panagiotis Christopoulos Charitos.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #include "anki/physics/PhysicsWorld.h"
  6. #include "anki/physics/PhysicsPlayerController.h"
  7. #include "anki/physics/PhysicsCollisionShape.h"
  8. namespace anki {
  9. //==============================================================================
  10. // Ugly but there is no other way
  11. static HeapAllocator<U8>* gAlloc = nullptr;
  12. static void* newtonAlloc(int size)
  13. {
  14. return gAlloc->allocate(size);
  15. }
  16. static void newtonFree(void* const ptr, int size)
  17. {
  18. gAlloc->deallocate(ptr, size);
  19. }
  20. //==============================================================================
  21. PhysicsWorld::PhysicsWorld()
  22. {}
  23. //==============================================================================
  24. PhysicsWorld::~PhysicsWorld()
  25. {
  26. if(m_sceneBody)
  27. {
  28. NewtonDestroyBody(m_sceneBody);
  29. m_sceneBody = nullptr;
  30. }
  31. if(m_sceneCollision)
  32. {
  33. NewtonDestroyCollision(m_sceneCollision);
  34. m_sceneCollision = nullptr;
  35. }
  36. if(m_world)
  37. {
  38. NewtonDestroy(m_world);
  39. m_world = nullptr;
  40. }
  41. gAlloc = nullptr;
  42. }
  43. //==============================================================================
  44. Error PhysicsWorld::create(AllocAlignedCallback allocCb, void* allocCbData)
  45. {
  46. Error err = ErrorCode::NONE;
  47. m_alloc = HeapAllocator<U8>(allocCb, allocCbData);
  48. // Set allocators
  49. gAlloc = &m_alloc;
  50. NewtonSetMemorySystem(newtonAlloc, newtonFree);
  51. // Initialize world
  52. m_world = NewtonCreate();
  53. if(!m_world)
  54. {
  55. ANKI_LOGE("NewtonCreate() failed");
  56. return ErrorCode::FUNCTION_FAILED;
  57. }
  58. // Set the simplified solver mode (faster but less accurate)
  59. NewtonSetSolverModel(m_world, 1);
  60. // Create scene collision
  61. m_sceneCollision = NewtonCreateSceneCollision(m_world, 0);
  62. Mat4 trf = Mat4::getIdentity();
  63. m_sceneBody = NewtonCreateDynamicBody(m_world, m_sceneCollision, &trf[0]);
  64. // Set the post update listener
  65. NewtonWorldAddPostListener(m_world, "world", this, postUpdateCallback,
  66. destroyCallback);
  67. return err;
  68. }
  69. //==============================================================================
  70. Error PhysicsWorld::updateAsync(F32 dt)
  71. {
  72. m_dt = dt;
  73. // Do cleanup of marked for deletion
  74. cleanupMarkedForDeletion();
  75. // Update
  76. NewtonUpdateAsync(m_world, dt);
  77. return ErrorCode::NONE;
  78. }
  79. //==============================================================================
  80. void PhysicsWorld::waitUpdate()
  81. {
  82. NewtonWaitForUpdateToFinish(m_world);
  83. }
  84. //==============================================================================
  85. void PhysicsWorld::cleanupMarkedForDeletion()
  86. {
  87. LockGuard<Mutex> lock(m_mtx);
  88. while(!m_forDeletion.isEmpty())
  89. {
  90. auto it = m_forDeletion.getBegin();
  91. PhysicsObject* obj = *it;
  92. // Remove from objects marked for deletion
  93. m_forDeletion.erase(m_alloc, it);
  94. // Remove from player controllers
  95. if(obj->getType() == PhysicsObject::Type::PLAYER_CONTROLLER)
  96. {
  97. auto it2 = m_playerControllers.getBegin();
  98. for(; it2 != m_playerControllers.getEnd(); ++it2)
  99. {
  100. PhysicsObject* obj2 = *it2;
  101. if(obj2 == obj)
  102. {
  103. break;
  104. }
  105. }
  106. ANKI_ASSERT(it2 != m_playerControllers.getEnd());
  107. m_playerControllers.erase(m_alloc, it2);
  108. }
  109. // Finaly, delete it
  110. m_alloc.deleteInstance(obj);
  111. }
  112. }
  113. //==============================================================================
  114. void PhysicsWorld::postUpdate(F32 dt)
  115. {
  116. for(PhysicsPlayerController* player : m_playerControllers)
  117. {
  118. NewtonDispachThreadJob(m_world,
  119. PhysicsPlayerController::postUpdateKernelCallback, player);
  120. }
  121. }
  122. //==============================================================================
  123. void PhysicsWorld::registerObject(PhysicsObject* ptr)
  124. {
  125. if(isa<PhysicsPlayerController>(ptr))
  126. {
  127. LockGuard<Mutex> lock(m_mtx);
  128. m_playerControllers.pushBack(
  129. m_alloc, dcast<PhysicsPlayerController*>(ptr));
  130. }
  131. }
  132. } // end namespace anki