physics_world.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. /*
  2. * Copyright (c) 2012-2015 Daniele Bartolini and individual contributors.
  3. * License: https://github.com/taylor001/crown/blob/master/LICENSE
  4. */
  5. #include "physics_world.h"
  6. #include "vector3.h"
  7. #include "actor.h"
  8. #include "device.h"
  9. #include "quaternion.h"
  10. #include "scene_graph.h"
  11. #include "controller.h"
  12. #include "joint.h"
  13. #include "physics_callback.h"
  14. #include "proxy_allocator.h"
  15. #include "memory.h"
  16. #include "string_utils.h"
  17. #include "actor.h"
  18. #include "resource_manager.h"
  19. #include "raycast.h"
  20. #include "unit.h"
  21. #include "config.h"
  22. #include "world.h"
  23. #include "debug_line.h"
  24. #include "color4.h"
  25. #include "int_setting.h"
  26. #include "physics.h"
  27. #include "matrix4x4.h"
  28. #include "log.h"
  29. #include "PxPhysicsAPI.h"
  30. using physx::PxSceneDesc;
  31. using physx::PxVec3;
  32. using physx::PxTransform;
  33. using physx::PxQuat;
  34. using physx::PxHalfPi;
  35. using physx::PxPlaneGeometry;
  36. using physx::PxMaterial;
  37. using physx::PxShape;
  38. using physx::PxRigidStatic;
  39. using physx::PxActiveTransform;
  40. using physx::PxU32;
  41. using physx::PxSceneFlag;
  42. using physx::PxFilterFlags;
  43. using physx::PxFilterData;
  44. using physx::PxPairFlags;
  45. using physx::PxFilterObjectAttributes;
  46. using physx::PxFilterObjectIsTrigger;
  47. using physx::PxPairFlag;
  48. using physx::PxFilterFlag;
  49. using physx::PxSceneLimits;
  50. using physx::PxVisualizationParameter;
  51. using physx::PxSphereGeometry;
  52. using physx::PxCapsuleGeometry;
  53. using physx::PxBoxGeometry;
  54. using physx::PxRenderBuffer;
  55. using physx::PxDebugLine;
  56. namespace crown
  57. {
  58. namespace physics_globals
  59. {
  60. using physx::PxFoundation;
  61. using physx::PxPhysics;
  62. using physx::PxCooking;
  63. using physx::PxCookingParams;
  64. using physx::PxTolerancesScale;
  65. using physx::PxAllocatorCallback;
  66. using physx::PxErrorCallback;
  67. using physx::PxErrorCode;
  68. class PhysXAllocator : public PxAllocatorCallback
  69. {
  70. public:
  71. PhysXAllocator()
  72. : m_backing("physics", default_allocator())
  73. {
  74. }
  75. void* allocate(size_t size, const char*, const char*, int)
  76. {
  77. return m_backing.allocate(size, 16);
  78. }
  79. void deallocate(void* p)
  80. {
  81. m_backing.deallocate(p);
  82. }
  83. private:
  84. ProxyAllocator m_backing;
  85. };
  86. class PhysXError : public PxErrorCallback
  87. {
  88. public:
  89. void reportError(PxErrorCode::Enum code, const char* message, const char* /*file*/, int /*line*/)
  90. {
  91. switch (code)
  92. {
  93. case PxErrorCode::eDEBUG_INFO:
  94. {
  95. CE_LOGI("PhysX: %s", message);
  96. break;
  97. }
  98. case PxErrorCode::eDEBUG_WARNING:
  99. case PxErrorCode::ePERF_WARNING:
  100. {
  101. CE_LOGW("PhysX: %s", message);
  102. break;
  103. }
  104. case PxErrorCode::eINVALID_PARAMETER:
  105. case PxErrorCode::eINVALID_OPERATION:
  106. case PxErrorCode::eOUT_OF_MEMORY:
  107. case PxErrorCode::eINTERNAL_ERROR:
  108. case PxErrorCode::eABORT:
  109. {
  110. CE_ASSERT(false, "PhysX: %s", message);
  111. break;
  112. }
  113. default:
  114. {
  115. CE_FATAL("Oops, unknown physx error");
  116. break;
  117. }
  118. }
  119. }
  120. };
  121. PxFilterFlags FilterShader(PxFilterObjectAttributes attributes0, PxFilterData filterData0,
  122. PxFilterObjectAttributes attributes1, PxFilterData filterData1,
  123. PxPairFlags& pairFlags, const void* constantBlock, PxU32 constantBlockSize)
  124. {
  125. // let triggers through
  126. if(PxFilterObjectIsTrigger(attributes0) || PxFilterObjectIsTrigger(attributes1))
  127. {
  128. pairFlags = PxPairFlag::eNOTIFY_TOUCH_FOUND | PxPairFlag::eNOTIFY_TOUCH_LOST;
  129. return PxFilterFlag::eDEFAULT;
  130. }
  131. // trigger the contact callback for pairs (A,B) where
  132. // the filtermask of A contains the ID of B and vice versa.
  133. if((filterData0.word0 & filterData1.word1) && (filterData1.word0 & filterData0.word1))
  134. {
  135. pairFlags |= PxPairFlag::eCONTACT_DEFAULT
  136. | PxPairFlag::eNOTIFY_TOUCH_FOUND
  137. | PxPairFlag::eNOTIFY_TOUCH_LOST
  138. | PxPairFlag::eNOTIFY_CONTACT_POINTS;
  139. return PxFilterFlag::eDEFAULT;
  140. }
  141. return PxFilterFlag::eSUPPRESS;
  142. }
  143. // Global PhysX objects
  144. static PhysXAllocator* s_px_allocator;
  145. static PhysXError* s_px_error;
  146. static PxFoundation* s_foundation;
  147. static PxPhysics* s_physics;
  148. static PxCooking* s_cooking;
  149. void init()
  150. {
  151. s_px_allocator = CE_NEW(default_allocator(), PhysXAllocator)();
  152. s_px_error = CE_NEW(default_allocator(), PhysXError)();
  153. s_foundation = PxCreateFoundation(PX_PHYSICS_VERSION, *s_px_allocator, *s_px_error);
  154. CE_ASSERT(s_foundation, "Unable to create PhysX Foundation");
  155. s_physics = PxCreatePhysics(PX_PHYSICS_VERSION, *s_foundation, physx::PxTolerancesScale());
  156. CE_ASSERT(s_physics, "Unable to create PhysX Physics");
  157. bool extension = PxInitExtensions(*s_physics);
  158. CE_ASSERT(extension, "Unable to initialize PhysX Extensions");
  159. CE_UNUSED(extension);
  160. s_cooking = PxCreateCooking(PX_PHYSICS_VERSION, *s_foundation, PxCookingParams(PxTolerancesScale()));
  161. CE_ASSERT(s_cooking, "Unable to create PhysX Cooking");
  162. }
  163. void shutdown()
  164. {
  165. PxCloseExtensions();
  166. s_cooking->release();
  167. s_physics->release();
  168. s_foundation->release();
  169. CE_DELETE(default_allocator(), s_px_error);
  170. CE_DELETE(default_allocator(), s_px_allocator);
  171. }
  172. } // namespace physics_globals
  173. PhysicsWorld::PhysicsWorld(World& world)
  174. : m_world(world)
  175. , m_scene(NULL)
  176. , m_buffer(m_hits, 64)
  177. , m_actors_pool(default_allocator(), CE_MAX_ACTORS, sizeof(Actor), CE_ALIGNOF(Actor))
  178. , m_controllers_pool(default_allocator(), CE_MAX_CONTROLLERS, sizeof(Controller), CE_ALIGNOF(Controller))
  179. , m_joints_pool(default_allocator(), CE_MAX_JOINTS, sizeof(Joint), CE_ALIGNOF(Joint))
  180. , m_raycasts_pool(default_allocator(), CE_MAX_RAYCASTS, sizeof(Raycast), CE_ALIGNOF(Raycast))
  181. , m_events(default_allocator())
  182. , m_callback(m_events)
  183. {
  184. // Create the scene
  185. PxSceneLimits scene_limits;
  186. scene_limits.maxNbActors = CE_MAX_ACTORS;
  187. CE_ASSERT(scene_limits.isValid(), "Scene limits is not valid");
  188. PxSceneDesc scene_desc(physics_globals::s_physics->getTolerancesScale());
  189. scene_desc.gravity = PxVec3(0.0f, -9.81f, 0.0f);
  190. scene_desc.limits = scene_limits;
  191. scene_desc.filterShader = physics_globals::FilterShader;
  192. scene_desc.simulationEventCallback = &m_callback;
  193. scene_desc.flags = PxSceneFlag::eENABLE_ACTIVETRANSFORMS
  194. | PxSceneFlag::eENABLE_KINEMATIC_STATIC_PAIRS
  195. | PxSceneFlag::eENABLE_KINEMATIC_PAIRS;
  196. if(!scene_desc.cpuDispatcher)
  197. {
  198. m_cpu_dispatcher = physx::PxDefaultCpuDispatcherCreate(1);
  199. CE_ASSERT(m_cpu_dispatcher != NULL, "Failed to create PhysX cpu dispatcher");
  200. scene_desc.cpuDispatcher = m_cpu_dispatcher;
  201. }
  202. CE_ASSERT(scene_desc.isValid(), "Scene is not valid");
  203. m_scene = physics_globals::s_physics->createScene(scene_desc);
  204. // Create controller manager
  205. m_controller_manager = PxCreateControllerManager(*m_scene);
  206. CE_ASSERT(m_controller_manager != NULL, "Failed to create PhysX controller manager");
  207. m_resource = (PhysicsConfigResource*) device()->resource_manager()->get(PHYSICS_CONFIG_TYPE, StringId64("global"));
  208. #if CROWN_DEBUG
  209. m_scene->setVisualizationParameter(PxVisualizationParameter::eSCALE, 1);
  210. m_scene->setVisualizationParameter(PxVisualizationParameter::eACTOR_AXES, 1);
  211. m_scene->setVisualizationParameter(PxVisualizationParameter::eCOLLISION_SHAPES, 1);
  212. #endif
  213. }
  214. PhysicsWorld::~PhysicsWorld()
  215. {
  216. m_cpu_dispatcher->release();
  217. m_controller_manager->release();
  218. m_scene->release();
  219. }
  220. ActorId PhysicsWorld::create_actor(const ActorResource* ar, SceneGraph& sg, UnitId unit_id)
  221. {
  222. Actor* actor = CE_NEW(m_actors_pool, Actor)(*this, ar, sg, unit_id);
  223. return id_array::create(m_actors, actor);
  224. }
  225. void PhysicsWorld::destroy_actor(ActorId id)
  226. {
  227. CE_DELETE(m_actors_pool, id_array::get(m_actors, id));
  228. id_array::destroy(m_actors, id);
  229. }
  230. ControllerId PhysicsWorld::create_controller(const ControllerResource* cr, SceneGraph& sg, UnitId id)
  231. {
  232. Controller* controller = CE_NEW(m_controllers_pool, Controller)(cr, sg, id, physics_globals::s_physics, m_controller_manager);
  233. return id_array::create(m_controllers, controller);
  234. }
  235. void PhysicsWorld::destroy_controller(ControllerId id)
  236. {
  237. CE_DELETE(m_controllers_pool, id_array::get(m_controllers, id));
  238. id_array::destroy(m_controllers, id);
  239. }
  240. JointId PhysicsWorld::create_joint(const JointResource* jr, const Actor& actor_0, const Actor& actor_1)
  241. {
  242. Joint* joint = CE_NEW(m_joints_pool, Joint)(physics_globals::s_physics, jr, actor_0, actor_1);
  243. return id_array::create(m_joints, joint);
  244. }
  245. void PhysicsWorld::destroy_joint(JointId id)
  246. {
  247. CE_DELETE(m_joints_pool, id_array::get(m_joints, id));
  248. id_array::destroy(m_joints, id);
  249. }
  250. RaycastId PhysicsWorld::create_raycast(CollisionMode::Enum mode, CollisionType::Enum filter)
  251. {
  252. Raycast* raycast = CE_NEW(m_raycasts_pool, Raycast)(m_scene, mode, filter);
  253. return id_array::create(m_raycasts, raycast);
  254. }
  255. void PhysicsWorld::destroy_raycast(RaycastId id)
  256. {
  257. CE_DELETE(m_raycasts_pool, id_array::get(m_raycasts, id));
  258. id_array::destroy(m_raycasts, id);
  259. }
  260. Actor* PhysicsWorld::get_actor(ActorId id)
  261. {
  262. return id_array::get(m_actors, id);
  263. }
  264. Controller* PhysicsWorld::get_controller(ControllerId id)
  265. {
  266. return id_array::get(m_controllers, id);
  267. }
  268. Raycast* PhysicsWorld::get_raycast(RaycastId id)
  269. {
  270. return id_array::get(m_raycasts, id);
  271. }
  272. Vector3 PhysicsWorld::gravity() const
  273. {
  274. PxVec3 g = m_scene->getGravity();
  275. return Vector3(g.x, g.y, g.z);
  276. }
  277. void PhysicsWorld::set_gravity(const Vector3& g)
  278. {
  279. m_scene->setGravity(PxVec3(g.x, g.y, g.z));
  280. }
  281. void PhysicsWorld::overlap_test(CollisionType::Enum filter, ShapeType::Enum type,
  282. const Vector3& pos, const Quaternion& rot, const Vector3& size, Array<Actor*>& actors)
  283. {
  284. PxTransform transform(PxVec3(pos.x, pos.y, pos.z), PxQuat(rot.x, rot.y, rot.z, rot.w));
  285. switch(type)
  286. {
  287. case ShapeType::SPHERE:
  288. {
  289. PxSphereGeometry geometry(size.x);
  290. m_scene->overlap(geometry, transform, m_buffer);
  291. break;
  292. }
  293. case ShapeType::CAPSULE:
  294. {
  295. PxCapsuleGeometry geometry(size.x, size.y);
  296. m_scene->overlap(geometry, transform, m_buffer);
  297. break;
  298. }
  299. case ShapeType::BOX:
  300. {
  301. PxBoxGeometry geometry(size.x, size.y, size.z);
  302. m_scene->overlap(geometry, transform, m_buffer);
  303. break;
  304. }
  305. default: CE_FATAL("Only spheres, capsules and boxs are supported in overlap test"); break;
  306. }
  307. for (uint32_t i = 0; i < m_buffer.getNbAnyHits(); i++)
  308. {
  309. PxOverlapHit oh = m_buffer.getAnyHit(i);
  310. array::push_back(actors, (Actor*)(oh.actor->userData));
  311. }
  312. }
  313. void PhysicsWorld::update(float dt)
  314. {
  315. // Run with fixed timestep
  316. m_scene->simulate(1.0 / 60.0);
  317. while (!m_scene->fetchResults());
  318. // Update transforms
  319. PxU32 num_active_transforms;
  320. const PxActiveTransform* active_transforms = m_scene->getActiveTransforms(num_active_transforms);
  321. // Update each actor with its new transform
  322. for (PxU32 i = 0; i < num_active_transforms; i++)
  323. {
  324. // Actors with userData == NULL are controllers
  325. if (active_transforms[i].userData == NULL) continue;
  326. const PxTransform tr = active_transforms[i].actor2World;
  327. const Vector3 pos(tr.p.x, tr.p.y, tr.p.z);
  328. const Quaternion rot(tr.q.x, tr.q.y, tr.q.z, tr.q.w);
  329. static_cast<Actor*>(active_transforms[i].userData)->update(Matrix4x4(rot, pos));
  330. }
  331. // Update controllers
  332. for (uint32_t i = 0; i < id_array::size(m_controllers); i++)
  333. {
  334. m_controllers[i]->update();
  335. }
  336. }
  337. void PhysicsWorld::draw_debug(DebugLine& lines)
  338. {
  339. CE_UNUSED(lines);
  340. #if CROWN_DEBUG
  341. const PxRenderBuffer& rb = m_scene->getRenderBuffer();
  342. for(PxU32 i = 0; i < rb.getNbLines(); i++)
  343. {
  344. const PxDebugLine& pxline = rb.getLines()[i];
  345. lines.add_line(Vector3(pxline.pos0.x, pxline.pos0.y, pxline.pos0.z),
  346. Vector3(pxline.pos1.x, pxline.pos1.y, pxline.pos1.z),
  347. Color4(pxline.color0));
  348. }
  349. lines.commit();
  350. lines.clear();
  351. #endif // CROWN_DEBUG
  352. }
  353. PxPhysics* PhysicsWorld::physx_physics() { return physics_globals::s_physics; }
  354. PxCooking* PhysicsWorld::physx_cooking() { return physics_globals::s_cooking; }
  355. PxScene* PhysicsWorld::physx_scene() { return m_scene; }
  356. } // namespace crown