BsPhysX.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823
  1. #include "BsPhysX.h"
  2. #include "PxPhysicsAPI.h"
  3. #include "BsPhysXMaterial.h"
  4. #include "BsPhysXMesh.h"
  5. #include "BsPhysXRigidbody.h"
  6. #include "BsPhysXBoxCollider.h"
  7. #include "BsPhysXSphereCollider.h"
  8. #include "BsPhysXPlaneCollider.h"
  9. #include "BsPhysXCapsuleCollider.h"
  10. #include "BsPhysXMeshCollider.h"
  11. #include "BsPhysXFixedJoint.h"
  12. #include "BsPhysXDistanceJoint.h"
  13. #include "BsPhysXHingeJoint.h"
  14. #include "BsPhysXSphericalJoint.h"
  15. #include "BsPhysXSliderJoint.h"
  16. #include "BsPhysXD6Joint.h"
  17. #include "BsPhysXCharacterController.h"
  18. #include "BsTaskScheduler.h"
  19. #include "BsTime.h"
  20. #include "Bsvector3.h"
  21. #include "BsAABox.h"
  22. using namespace physx;
  23. namespace BansheeEngine
  24. {
  25. class PhysXAllocator : public PxAllocatorCallback
  26. {
  27. public:
  28. void* allocate(size_t size, const char*, const char*, int) override
  29. {
  30. void* ptr = bs_alloc_aligned16((UINT32)size);
  31. PX_ASSERT((reinterpret_cast<size_t>(ptr) & 15) == 0);
  32. return ptr;
  33. }
  34. void deallocate(void* ptr) override
  35. {
  36. bs_free_aligned16(ptr);
  37. }
  38. };
  39. class PhysXErrorCallback : public PxErrorCallback
  40. {
  41. public:
  42. void reportError(PxErrorCode::Enum code, const char* message, const char* file, int line) override
  43. {
  44. {
  45. const char* errorCode = nullptr;
  46. UINT32 severity = 0;
  47. switch (code)
  48. {
  49. case PxErrorCode::eNO_ERROR:
  50. errorCode = "No error";
  51. break;
  52. case PxErrorCode::eINVALID_PARAMETER:
  53. errorCode = "Invalid parameter";
  54. severity = 2;
  55. break;
  56. case PxErrorCode::eINVALID_OPERATION:
  57. errorCode = "Invalid operation";
  58. severity = 2;
  59. break;
  60. case PxErrorCode::eOUT_OF_MEMORY:
  61. errorCode = "Out of memory";
  62. severity = 2;
  63. break;
  64. case PxErrorCode::eDEBUG_INFO:
  65. errorCode = "Info";
  66. break;
  67. case PxErrorCode::eDEBUG_WARNING:
  68. errorCode = "Warning";
  69. severity = 1;
  70. break;
  71. case PxErrorCode::ePERF_WARNING:
  72. errorCode = "Performance warning";
  73. severity = 1;
  74. break;
  75. case PxErrorCode::eABORT:
  76. errorCode = "Abort";
  77. severity = 2;
  78. break;
  79. case PxErrorCode::eINTERNAL_ERROR:
  80. errorCode = "Internal error";
  81. severity = 2;
  82. break;
  83. case PxErrorCode::eMASK_ALL:
  84. default:
  85. errorCode = "Unknown error";
  86. severity = 2;
  87. break;
  88. }
  89. StringStream ss;
  90. switch(severity)
  91. {
  92. case 0:
  93. ss << "PhysX info (" << errorCode << "): " << message << " at " << file << ":" << line;
  94. LOGDBG(ss.str());
  95. break;
  96. case 1:
  97. ss << "PhysX warning (" << errorCode << "): " << message << " at " << file << ":" << line;
  98. LOGWRN(ss.str());
  99. break;
  100. case 2:
  101. ss << "PhysX error (" << errorCode << "): " << message << " at " << file << ":" << line;
  102. LOGERR(ss.str());
  103. BS_ASSERT(false); // Halt execution on debug builds when error occurrs
  104. break;
  105. }
  106. }
  107. }
  108. };
  109. class PhysXEventCallback : public PxSimulationEventCallback
  110. {
  111. void onWake(PxActor** actors, PxU32 count) override { /* Do nothing */ }
  112. void onSleep(PxActor** actors, PxU32 count) override { /* Do nothing */ }
  113. void onTrigger(PxTriggerPair* pairs, PxU32 count) override
  114. {
  115. for (PxU32 i = 0; i < count; i++)
  116. {
  117. const PxTriggerPair& pair = pairs[i];
  118. PhysX::ContactEventType type;
  119. bool ignoreContact = false;
  120. switch ((UINT32)pair.status)
  121. {
  122. case PxPairFlag::eNOTIFY_TOUCH_FOUND:
  123. type = PhysX::ContactEventType::ContactBegin;
  124. break;
  125. case PxPairFlag::eNOTIFY_TOUCH_PERSISTS:
  126. type = PhysX::ContactEventType::ContactStay;
  127. break;
  128. case PxPairFlag::eNOTIFY_TOUCH_LOST:
  129. type = PhysX::ContactEventType::ContactEnd;
  130. break;
  131. default:
  132. ignoreContact = true;
  133. break;
  134. }
  135. if (ignoreContact)
  136. continue;
  137. PhysX::TriggerEvent event;
  138. event.trigger = (Collider*)pair.triggerShape->userData;
  139. event.other = (Collider*)pair.otherShape->userData;
  140. event.type = type;
  141. gPhysX()._reportTriggerEvent(event);
  142. }
  143. }
  144. void onContact(const PxContactPairHeader& pairHeader, const PxContactPair* pairs, PxU32 count) override
  145. {
  146. for (PxU32 i = 0; i < count; i++)
  147. {
  148. const PxContactPair& pair = pairs[i];
  149. PhysX::ContactEventType type;
  150. bool ignoreContact = false;
  151. switch((UINT32)pair.events)
  152. {
  153. case PxPairFlag::eNOTIFY_TOUCH_FOUND:
  154. type = PhysX::ContactEventType::ContactBegin;
  155. break;
  156. case PxPairFlag::eNOTIFY_TOUCH_PERSISTS:
  157. type = PhysX::ContactEventType::ContactStay;
  158. break;
  159. case PxPairFlag::eNOTIFY_TOUCH_LOST:
  160. type = PhysX::ContactEventType::ContactEnd;
  161. break;
  162. default:
  163. ignoreContact = true;
  164. break;
  165. }
  166. if (ignoreContact)
  167. continue;
  168. PhysX::ContactEvent event;
  169. event.colliderA = (Collider*)pair.shapes[0]->userData;
  170. event.colliderB = (Collider*)pair.shapes[1]->userData;
  171. event.type = type;
  172. PxU32 contactCount = pair.contactCount;
  173. const PxU8* stream = pair.contactStream;
  174. PxU16 streamSize = pair.contactStreamSize;
  175. if (contactCount > 0 && streamSize > 0)
  176. {
  177. PxU32 contactIdx = 0;
  178. PxContactStreamIterator iter((PxU8*)stream, streamSize);
  179. stream += ((streamSize + 15) & ~15);
  180. const PxReal* impulses = reinterpret_cast<const PxReal*>(stream);
  181. PxU32 hasImpulses = (pair.flags & PxContactPairFlag::eINTERNAL_HAS_IMPULSES);
  182. while (iter.hasNextPatch())
  183. {
  184. iter.nextPatch();
  185. while (iter.hasNextContact())
  186. {
  187. iter.nextContact();
  188. ContactPoint point;
  189. point.position = fromPxVector(iter.getContactPoint());
  190. point.separation = iter.getSeparation();
  191. point.normal = fromPxVector(iter.getContactNormal());
  192. if (hasImpulses)
  193. point.impulse = impulses[contactIdx];
  194. else
  195. point.impulse = 0.0f;
  196. event.points.push_back(point);
  197. contactIdx++;
  198. }
  199. }
  200. }
  201. gPhysX()._reportContactEvent(event);
  202. }
  203. }
  204. void onConstraintBreak(PxConstraintInfo* constraints, PxU32 count) override
  205. {
  206. for (UINT32 i = 0; i < count; i++)
  207. {
  208. PxConstraintInfo& constraintInfo = constraints[i];
  209. if (constraintInfo.type != PxConstraintExtIDs::eJOINT)
  210. continue;
  211. PxJoint* pxJoint = (PxJoint*)constraintInfo.externalReference;
  212. Joint* joint = (Joint*)pxJoint->userData;
  213. }
  214. }
  215. };
  216. class PhysXCPUDispatcher : public PxCpuDispatcher
  217. {
  218. public:
  219. void submitTask(PxBaseTask& physxTask) override
  220. {
  221. // Note: Banshee's task scheduler is pretty low granularity. Consider a better task manager in case PhysX ends
  222. // up submitting many tasks.
  223. // - PhysX's task manager doesn't seem much lighter either. But perhaps I can at least create a task pool to
  224. // avoid allocating them constantly.
  225. auto runTask = [&]() { physxTask.run(); physxTask.release(); };
  226. TaskPtr task = Task::create("PhysX", runTask);
  227. TaskScheduler::instance().addTask(task);
  228. }
  229. PxU32 getWorkerCount() const override
  230. {
  231. return (PxU32)TaskScheduler::instance().getNumWorkers();
  232. }
  233. };
  234. class PhysXBroadPhaseCallback : public PxBroadPhaseCallback
  235. {
  236. void onObjectOutOfBounds(PxShape& shape, PxActor& actor) override
  237. {
  238. Collider* collider = (Collider*)shape.userData;
  239. if (collider != nullptr)
  240. LOGWRN("Physics object out of bounds. Consider increasing broadphase region!");
  241. }
  242. void onObjectOutOfBounds(PxAggregate& aggregate) override { /* Do nothing */ }
  243. };
  244. PxFilterFlags PhysXFilterShader(PxFilterObjectAttributes attr0, PxFilterData data0, PxFilterObjectAttributes attr1,
  245. PxFilterData data1, PxPairFlags& pairFlags, const void* constantBlock, PxU32 constantBlockSize)
  246. {
  247. if (PxFilterObjectIsTrigger(attr0) || PxFilterObjectIsTrigger(attr1))
  248. {
  249. pairFlags = PxPairFlag::eTRIGGER_DEFAULT;
  250. return PxFilterFlags();
  251. }
  252. UINT64 groupA = *(UINT64*)&data0.word0;
  253. UINT64 groupB = *(UINT64*)&data1.word0;
  254. bool canCollide = gPhysics().isCollisionEnabled(groupA, groupB);
  255. if (!canCollide)
  256. return PxFilterFlag::eSUPPRESS;
  257. pairFlags = PxPairFlag::eCONTACT_DEFAULT;
  258. return PxFilterFlags();
  259. }
  260. static PhysXAllocator gPhysXAllocator;
  261. static PhysXErrorCallback gPhysXErrorHandler;
  262. static PhysXCPUDispatcher gPhysXCPUDispatcher;
  263. static PhysXEventCallback gPhysXEventCallback;
  264. static PhysXBroadPhaseCallback gPhysXBroadphaseCallback;
  265. PhysX::PhysX(const PHYSICS_INIT_DESC& input)
  266. :Physics(input)
  267. {
  268. mScale.length = input.typicalLength;
  269. mScale.speed = input.typicalSpeed;
  270. mFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gPhysXAllocator, gPhysXErrorHandler);
  271. mPhysics = PxCreateBasePhysics(PX_PHYSICS_VERSION, *mFoundation, mScale);
  272. PxRegisterArticulations(*mPhysics);
  273. if (input.initCooking)
  274. {
  275. // Note: PhysX supports cooking for specific platforms to make the generated results better. Consider
  276. // allowing the meshes to be re-cooked when target platform is changed. Right now we just use the default value.
  277. PxCookingParams cookingParams(mScale);
  278. mCooking = PxCreateCooking(PX_PHYSICS_VERSION, *mFoundation, cookingParams);
  279. }
  280. PxSceneDesc sceneDesc(mScale); // TODO - Test out various other parameters provided by scene desc
  281. sceneDesc.gravity = toPxVector(input.gravity);
  282. sceneDesc.cpuDispatcher = &gPhysXCPUDispatcher;
  283. sceneDesc.filterShader = PhysXFilterShader;
  284. sceneDesc.simulationEventCallback = &gPhysXEventCallback;
  285. sceneDesc.broadPhaseCallback = &gPhysXBroadphaseCallback;
  286. // Optionally: eENABLE_CCD, eENABLE_KINEMATIC_STATIC_PAIRS, eENABLE_KINEMATIC_PAIRS, eENABLE_PCM
  287. sceneDesc.flags = PxSceneFlag::eENABLE_ACTIVETRANSFORMS;
  288. // Optionally: eMBP
  289. sceneDesc.broadPhaseType = PxBroadPhaseType::eSAP;
  290. mScene = mPhysics->createScene(sceneDesc);
  291. // Character controller
  292. mCharManager = PxCreateControllerManager(*mScene);
  293. mSimulationStep = input.timeStep;
  294. mDefaultMaterial = mPhysics->createMaterial(0.0f, 0.0f, 0.0f);
  295. }
  296. PhysX::~PhysX()
  297. {
  298. mCharManager->release();
  299. mScene->release();
  300. if (mCooking != nullptr)
  301. mCooking->release();
  302. mPhysics->release();
  303. mFoundation->release();
  304. }
  305. void PhysX::update()
  306. {
  307. mUpdateInProgress = true;
  308. float nextFrameTime = mLastSimulationTime + mSimulationStep;
  309. float curFrameTime = gTime().getTime();
  310. if(curFrameTime < nextFrameTime)
  311. {
  312. // TODO - Interpolate rigidbodies but perform no actual simulation
  313. return;
  314. }
  315. float simulationAmount = curFrameTime - mLastSimulationTime;
  316. while (simulationAmount >= mSimulationStep) // In case we're running really slow multiple updates might be needed
  317. {
  318. // Note: Consider delaying fetchResults one frame. This could improve performance because Physics update would be
  319. // able to run parallel to the simulation thread, but at a cost to input latency.
  320. // TODO - Provide a scratch buffer for the simulation (use the frame allocator, but I must extend it so it allocates
  321. // on a 16 byte boundary).
  322. mScene->simulate(mSimulationStep);
  323. mScene->fetchResults(true);
  324. // Update rigidbodies with new transforms
  325. PxU32 numActiveTransforms;
  326. const PxActiveTransform* activeTransforms = mScene->getActiveTransforms(numActiveTransforms);
  327. for (PxU32 i = 0; i < numActiveTransforms; i++)
  328. {
  329. Rigidbody* rigidbody = static_cast<Rigidbody*>(activeTransforms[i].userData);
  330. const PxTransform& transform = activeTransforms[i].actor2World;
  331. // Note: Make this faster, avoid dereferencing Rigidbody and attempt to access pos/rot destination directly,
  332. // use non-temporal writes
  333. rigidbody->_setTransform(fromPxVector(transform.p), fromPxQuaternion(transform.q));
  334. }
  335. simulationAmount -= mSimulationStep;
  336. }
  337. // TODO - Consider extrapolating for the remaining "simulationAmount" value
  338. mLastSimulationTime = curFrameTime;
  339. mUpdateInProgress = false;
  340. triggerEvents();
  341. }
  342. void PhysX::_reportContactEvent(const ContactEvent& event)
  343. {
  344. mContactEvents.push_back(event);
  345. }
  346. void PhysX::_reportTriggerEvent(const TriggerEvent& event)
  347. {
  348. mTriggerEvents.push_back(event);
  349. }
  350. void PhysX::_reportJointBreakEvent(const JointBreakEvent& event)
  351. {
  352. mJointBreakEvents.push_back(event);
  353. }
  354. void PhysX::triggerEvents()
  355. {
  356. CollisionData data;
  357. for(auto& entry : mTriggerEvents)
  358. {
  359. data.collider = entry.other;
  360. switch (entry.type)
  361. {
  362. case ContactEventType::ContactBegin:
  363. entry.trigger->onCollisionBegin(data);
  364. break;
  365. case ContactEventType::ContactStay:
  366. entry.trigger->onCollisionStay(data);
  367. break;
  368. case ContactEventType::ContactEnd:
  369. entry.trigger->onCollisionEnd(data);
  370. break;
  371. }
  372. }
  373. auto notifyContact = [&](Collider* obj, Collider* other, ContactEventType type,
  374. const Vector<ContactPoint>& points, bool flipNormals = false)
  375. {
  376. data.collider = other;
  377. data.contactPoints = points;
  378. if(flipNormals)
  379. {
  380. for (auto& point : data.contactPoints)
  381. point.normal = -point.normal;
  382. }
  383. SPtr<Rigidbody> rigidbody = obj->getRigidbody();
  384. if(rigidbody != nullptr)
  385. {
  386. switch (type)
  387. {
  388. case ContactEventType::ContactBegin:
  389. rigidbody->onCollisionBegin(data);
  390. break;
  391. case ContactEventType::ContactStay:
  392. rigidbody->onCollisionStay(data);
  393. break;
  394. case ContactEventType::ContactEnd:
  395. rigidbody->onCollisionEnd(data);
  396. break;
  397. }
  398. }
  399. else
  400. {
  401. switch (type)
  402. {
  403. case ContactEventType::ContactBegin:
  404. obj->onCollisionBegin(data);
  405. break;
  406. case ContactEventType::ContactStay:
  407. obj->onCollisionStay(data);
  408. break;
  409. case ContactEventType::ContactEnd:
  410. obj->onCollisionEnd(data);
  411. break;
  412. }
  413. }
  414. };
  415. for (auto& entry : mContactEvents)
  416. {
  417. notifyContact(entry.colliderA, entry.colliderB, entry.type, entry.points, true);
  418. notifyContact(entry.colliderB, entry.colliderA, entry.type, entry.points, false);
  419. }
  420. for(auto& entry : mJointBreakEvents)
  421. {
  422. entry.joint->onJointBreak();
  423. }
  424. mTriggerEvents.clear();
  425. mContactEvents.clear();
  426. mJointBreakEvents.clear();
  427. }
  428. SPtr<PhysicsMaterial> PhysX::createMaterial(float staticFriction, float dynamicFriction, float restitution)
  429. {
  430. return bs_shared_ptr_new<PhysXMaterial>(mPhysics, staticFriction, dynamicFriction, restitution);
  431. }
  432. SPtr<PhysicsMesh> PhysX::createMesh(const MeshDataPtr& meshData, PhysicsMeshType type)
  433. {
  434. return bs_shared_ptr_new<PhysXMesh>(meshData, type);
  435. }
  436. SPtr<Rigidbody> PhysX::createRigidbody(const HSceneObject& linkedSO)
  437. {
  438. return bs_shared_ptr_new<PhysXRigidbody>(mPhysics, mScene, linkedSO);
  439. }
  440. SPtr<BoxCollider> PhysX::createBoxCollider(const Vector3& extents, const Vector3& position,
  441. const Quaternion& rotation)
  442. {
  443. return bs_shared_ptr_new<PhysXBoxCollider>(mPhysics, position, rotation, extents);
  444. }
  445. SPtr<SphereCollider> PhysX::createSphereCollider(float radius, const Vector3& position, const Quaternion& rotation)
  446. {
  447. return bs_shared_ptr_new<PhysXSphereCollider>(mPhysics, position, rotation, radius);
  448. }
  449. SPtr<PlaneCollider> PhysX::createPlaneCollider(const Vector3& position, const Quaternion& rotation)
  450. {
  451. return bs_shared_ptr_new<PhysXPlaneCollider>(mPhysics, position, rotation);
  452. }
  453. SPtr<CapsuleCollider> PhysX::createCapsuleCollider(float radius, float halfHeight, const Vector3& position,
  454. const Quaternion& rotation)
  455. {
  456. return bs_shared_ptr_new<PhysXCapsuleCollider>(mPhysics, position, rotation, radius, halfHeight);
  457. }
  458. SPtr<MeshCollider> PhysX::createMeshCollider(const Vector3& position, const Quaternion& rotation)
  459. {
  460. return bs_shared_ptr_new<PhysXMeshCollider>(mPhysics, position, rotation);
  461. }
  462. SPtr<FixedJoint> PhysX::createFixedJoint()
  463. {
  464. return bs_shared_ptr_new<PhysXFixedJoint>(mPhysics);
  465. }
  466. SPtr<DistanceJoint> PhysX::createDistanceJoint()
  467. {
  468. return bs_shared_ptr_new<PhysXDistanceJoint>(mPhysics);
  469. }
  470. SPtr<HingeJoint> PhysX::createHingeJoint()
  471. {
  472. return bs_shared_ptr_new<PhysXHingeJoint>(mPhysics);
  473. }
  474. SPtr<SphericalJoint> PhysX::createSphericalJoint()
  475. {
  476. return bs_shared_ptr_new<PhysXSphericalJoint>(mPhysics);
  477. }
  478. SPtr<SliderJoint> PhysX::createSliderJoint()
  479. {
  480. return bs_shared_ptr_new<PhysXSliderJoint>(mPhysics);
  481. }
  482. SPtr<D6Joint> PhysX::createD6Joint()
  483. {
  484. return bs_shared_ptr_new<PhysXD6Joint>(mPhysics);
  485. }
  486. SPtr<CharacterController> PhysX::createCharacterController(const CHAR_CONTROLLER_DESC& desc)
  487. {
  488. return bs_shared_ptr_new<PhysXCharacterController>(mCharManager, desc);
  489. }
  490. bool PhysX::rayCast(const Ray& ray, PhysicsQueryHit& hit, UINT64 layer, float max)
  491. {
  492. // TODO
  493. return false;
  494. }
  495. bool PhysX::rayCast(const Vector3& origin, const Vector3& direction, PhysicsQueryHit& hit, UINT64 layer, float max)
  496. {
  497. // TODO
  498. return false;
  499. }
  500. bool PhysX::boxCast(const AABox& box, const Quaternion& rotation, const Vector3& direction, PhysicsQueryHit& hit,
  501. UINT64 layer, float max)
  502. {
  503. // TODO
  504. return false;
  505. }
  506. bool PhysX::sphereCast(const Sphere& sphere, const Vector3& direction, PhysicsQueryHit& hit,
  507. UINT64 layer, float max)
  508. {
  509. // TODO
  510. return false;
  511. }
  512. bool PhysX::capsuleCast(const Capsule& capsule, const Quaternion& rotation, const Vector3& direction,
  513. PhysicsQueryHit& hit, UINT64 layer, float max)
  514. {
  515. // TODO
  516. return false;
  517. }
  518. bool PhysX::convexCast(const HPhysicsMesh& mesh, const Vector3& position, const Quaternion& rotation,
  519. const Vector3& direction, PhysicsQueryHit& hit, UINT64 layer, float max)
  520. {
  521. // TODO
  522. return false;
  523. }
  524. Vector<PhysicsQueryHit> PhysX::rayCastAll(const Ray& ray, UINT64 layer, float max)
  525. {
  526. // TODO
  527. return Vector<PhysicsQueryHit>();
  528. }
  529. Vector<PhysicsQueryHit> PhysX::rayCastAll(const Vector3& origin, const Vector3& direction,
  530. UINT64 layer, float max)
  531. {
  532. // TODO
  533. return Vector<PhysicsQueryHit>();
  534. }
  535. Vector<PhysicsQueryHit> PhysX::boxCastAll(const AABox& box, const Quaternion& rotation,
  536. const Vector3& direction, UINT64 layer, float max)
  537. {
  538. // TODO
  539. return Vector<PhysicsQueryHit>();
  540. }
  541. Vector<PhysicsQueryHit> PhysX::sphereCastAll(const Sphere& sphere, const Vector3& direction,
  542. UINT64 layer, float max)
  543. {
  544. // TODO
  545. return Vector<PhysicsQueryHit>();
  546. }
  547. Vector<PhysicsQueryHit> PhysX::capsuleCastAll(const Capsule& capsule, const Quaternion& rotation,
  548. const Vector3& direction, UINT64 layer, float max)
  549. {
  550. // TODO
  551. return Vector<PhysicsQueryHit>();
  552. }
  553. Vector<PhysicsQueryHit> PhysX::convexCastAll(const HPhysicsMesh& mesh, const Vector3& position,
  554. const Quaternion& rotation, const Vector3& direction, UINT64 layer, float max)
  555. {
  556. // TODO
  557. return Vector<PhysicsQueryHit>();
  558. }
  559. bool PhysX::rayCastAny(const Ray& ray, UINT64 layer, float max)
  560. {
  561. // TODO
  562. return false;
  563. }
  564. bool PhysX::rayCastAny(const Vector3& origin, const Vector3& direction,
  565. UINT64 layer, float max)
  566. {
  567. // TODO
  568. return false;
  569. }
  570. bool PhysX::boxCastAny(const AABox& box, const Quaternion& rotation, const Vector3& direction,
  571. UINT64 layer, float max)
  572. {
  573. // TODO
  574. return false;
  575. }
  576. bool PhysX::sphereCastAny(const Sphere& sphere, const Vector3& direction,
  577. UINT64 layer, float max)
  578. {
  579. // TODO
  580. return false;
  581. }
  582. bool PhysX::capsuleCastAny(const Capsule& capsule, const Quaternion& rotation, const Vector3& direction,
  583. UINT64 layer, float max)
  584. {
  585. // TODO
  586. return false;
  587. }
  588. bool PhysX::convexCastAny(const HPhysicsMesh& mesh, const Vector3& position, const Quaternion& rotation,
  589. const Vector3& direction, UINT64 layer, float max)
  590. {
  591. // TODO
  592. return false;
  593. }
  594. Vector<HCollider> PhysX::boxOverlap(const AABox& box, const Quaternion& rotation,
  595. UINT64 layer)
  596. {
  597. // TODO
  598. return Vector<HCollider>();
  599. }
  600. Vector<HCollider> PhysX::sphereOverlap(const Sphere& sphere, UINT64 layer)
  601. {
  602. // TODO
  603. return Vector<HCollider>();
  604. }
  605. Vector<HCollider> PhysX::capsuleOverlap(const Capsule& capsule, const Quaternion& rotation,
  606. UINT64 layer)
  607. {
  608. // TODO
  609. return Vector<HCollider>();
  610. }
  611. Vector<HCollider> PhysX::convexOverlap(const HPhysicsMesh& mesh, const Vector3& position,
  612. const Quaternion& rotation, UINT64 layer)
  613. {
  614. // TODO
  615. return Vector<HCollider>();
  616. }
  617. bool PhysX::boxOverlapAny(const AABox& box, const Quaternion& rotation, UINT64 layer)
  618. {
  619. // TODO
  620. return false;
  621. }
  622. bool PhysX::sphereOverlapAny(const Sphere& sphere, UINT64 layer)
  623. {
  624. // TODO
  625. return false;
  626. }
  627. bool PhysX::capsuleOverlapAny(const Capsule& capsule, const Quaternion& rotation,
  628. UINT64 layer)
  629. {
  630. // TODO
  631. return false;
  632. }
  633. bool PhysX::convexOverlapAny(const HPhysicsMesh& mesh, const Vector3& position, const Quaternion& rotation,
  634. UINT64 layer)
  635. {
  636. // TODO
  637. return false;
  638. }
  639. void PhysX::setFlag(PhysicsFlags flag, bool enabled)
  640. {
  641. Physics::setFlag(flag, enabled);
  642. mCharManager->setOverlapRecoveryModule(mFlags.isSet(PhysicsFlag::CCT_OverlapRecovery));
  643. mCharManager->setPreciseSweeps(mFlags.isSet(PhysicsFlag::CCT_PreciseSweeps));
  644. mCharManager->setTessellation(mFlags.isSet(PhysicsFlag::CCT_Tesselation), mTesselationLength);
  645. }
  646. Vector3 PhysX::getGravity() const
  647. {
  648. return fromPxVector(mScene->getGravity());
  649. }
  650. void PhysX::setGravity(const Vector3& gravity)
  651. {
  652. mScene->setGravity(toPxVector(gravity));
  653. }
  654. void PhysX::setMaxTesselationEdgeLength(float length)
  655. {
  656. mTesselationLength = length;
  657. mCharManager->setTessellation(mFlags.isSet(PhysicsFlag::CCT_Tesselation), mTesselationLength);
  658. }
  659. UINT32 PhysX::addBroadPhaseRegion(const AABox& region)
  660. {
  661. UINT32 id = mNextRegionIdx++;
  662. PxBroadPhaseRegion pxRegion;
  663. pxRegion.bounds = PxBounds3(toPxVector(region.getMin()), toPxVector(region.getMax()));
  664. pxRegion.userData = (void*)(UINT64)id;
  665. UINT32 handle = mScene->addBroadPhaseRegion(pxRegion, true);
  666. mBroadPhaseRegionHandles[id] = handle;
  667. return handle;
  668. }
  669. void PhysX::removeBroadPhaseRegion(UINT32 regionId)
  670. {
  671. auto iterFind = mBroadPhaseRegionHandles.find(regionId);
  672. if (iterFind == mBroadPhaseRegionHandles.end())
  673. return;
  674. mScene->removeBroadPhaseRegion(iterFind->second);
  675. mBroadPhaseRegionHandles.erase(iterFind);
  676. }
  677. void PhysX::clearBroadPhaseRegions()
  678. {
  679. for(auto& entry : mBroadPhaseRegionHandles)
  680. mScene->removeBroadPhaseRegion(entry.second);
  681. mBroadPhaseRegionHandles.clear();
  682. }
  683. PhysX& gPhysX()
  684. {
  685. return static_cast<PhysX&>(PhysX::instance());
  686. }
  687. }