physics_callback.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /*
  2. * Copyright (c) 2012-2014 Daniele Bartolini and individual contributors.
  3. * License: https://github.com/taylor001/crown/blob/master/LICENSE
  4. */
  5. #pragma once
  6. #include "event_stream.h"
  7. #include "physics_types.h"
  8. #include "PxActor.h"
  9. #include "PxRigidActor.h"
  10. #include "PxController.h"
  11. #include "PxSimulationEventCallback.h"
  12. #include "PxQueryReport.h"
  13. #include "PxQueryFiltering.h"
  14. using physx::PxActor;
  15. using physx::PxConstraintInfo;
  16. using physx::PxContactPair;
  17. using physx::PxContactPairHeader;
  18. using physx::PxContactPairHeader;
  19. using physx::PxContactPairHeaderFlag;
  20. using physx::PxContactPairPoint;
  21. using physx::PxControllerObstacleHit;
  22. using physx::PxControllerShapeHit;
  23. using physx::PxControllersHit;
  24. using physx::PxSimulationEventCallback;
  25. using physx::PxTriggerPair;
  26. using physx::PxTriggerPairFlag;
  27. using physx::PxU32;
  28. using physx::PxUserControllerHitReport;
  29. using physx::PxVec3;
  30. using physx::PxRaycastCallback;
  31. using physx::PxAgain;
  32. using physx::PxRaycastHit;
  33. using physx::PxPairFlag;
  34. using physx::PxContactPairFlag;
  35. namespace crown
  36. {
  37. class PhysicsWorld;
  38. class PhysicsSimulationCallback : public PxSimulationEventCallback
  39. {
  40. public:
  41. PhysicsSimulationCallback(EventStream& stream)
  42. : m_events(stream)
  43. {
  44. }
  45. void onConstraintBreak(PxConstraintInfo* /*constraints*/, PxU32 /*count*/)
  46. {
  47. // printf("COSTRAINTBREAK\n");
  48. }
  49. void onContact(const PxContactPairHeader& pair_header, const PxContactPair* pairs, PxU32 num_pairs)
  50. {
  51. // Do not report contact if either actor0 or actor1 or both have been deleted
  52. if (pair_header.flags & PxContactPairHeaderFlag::eDELETED_ACTOR_0 ||
  53. pair_header.flags & PxContactPairHeaderFlag::eDELETED_ACTOR_1) return;
  54. for (PxU32 pp = 0; pp < num_pairs; pp++)
  55. {
  56. const PxContactPair& cp = pairs[pp];
  57. // We are only interested in touch found or lost
  58. if ((cp.events & PxPairFlag::eNOTIFY_TOUCH_FOUND) == (PxPairFlag::Enum)0 &&
  59. (cp.events & PxPairFlag::eNOTIFY_TOUCH_LOST) == (PxPairFlag::Enum)0) continue;
  60. // Skip if either shape0 or shape1 or both have been deleted
  61. if (cp.flags & PxContactPairFlag::eDELETED_SHAPE_0 ||
  62. cp.flags & PxContactPairFlag::eDELETED_SHAPE_1) continue;
  63. PxContactPairPoint points[8];
  64. const PxU32 num_points = cp.extractContacts(points, 8);
  65. PxVec3 where(0, 0, 0);
  66. PxVec3 normal(0, 0, 0);
  67. for (PxU32 i = 0; i < num_points; i++)
  68. {
  69. where = points[i].position;
  70. normal = points[i].normal;
  71. }
  72. post_collision_event((Actor*) pair_header.actors[0]->userData,
  73. (Actor*) pair_header.actors[1]->userData,
  74. Vector3(where.x, where.y, where.z),
  75. Vector3(normal.x, normal.y, normal.z),
  76. (cp.events & PxPairFlag::eNOTIFY_TOUCH_FOUND) ?
  77. physics_world::CollisionEvent::BEGIN_TOUCH :
  78. physics_world::CollisionEvent::END_TOUCH);
  79. }
  80. }
  81. void onTrigger(PxTriggerPair* pairs, PxU32 count)
  82. {
  83. for (PxU32 pp = 0; pp < count; pp++)
  84. {
  85. const PxTriggerPair& tp = pairs[pp];
  86. // Do not report event if either trigger ot other shape or both have been deleted
  87. if (tp.flags & PxTriggerPairFlag::eDELETED_SHAPE_TRIGGER ||
  88. tp.flags & PxTriggerPairFlag::eDELETED_SHAPE_OTHER) continue;
  89. post_trigger_event((Actor*)tp.triggerActor->userData,
  90. (Actor*)tp.otherActor->userData,
  91. (tp.status & PxPairFlag::eNOTIFY_TOUCH_FOUND ?
  92. physics_world::TriggerEvent::BEGIN_TOUCH : physics_world::TriggerEvent::END_TOUCH));
  93. }
  94. }
  95. void onWake(PxActor** /*actors*/, PxU32 /*count*/)
  96. {
  97. }
  98. void onSleep(PxActor** /*actors*/, PxU32 /*count*/)
  99. {
  100. }
  101. private:
  102. void post_collision_event(Actor* actor0, Actor* actor1, const Vector3& where, const Vector3& normal, physics_world::CollisionEvent::Type type)
  103. {
  104. physics_world::CollisionEvent ev;
  105. ev.type = type;
  106. ev.actors[0] = actor0;
  107. ev.actors[1] = actor1;
  108. ev.where = where;
  109. ev.normal = normal;
  110. event_stream::write(m_events, physics_world::EventType::COLLISION, ev);
  111. }
  112. void post_trigger_event(Actor* trigger, Actor* other, physics_world::TriggerEvent::Type type)
  113. {
  114. physics_world::TriggerEvent ev;
  115. ev.type = type;
  116. ev.trigger = trigger;
  117. ev.other = other;
  118. event_stream::write(m_events, physics_world::EventType::TRIGGER, ev);
  119. }
  120. private:
  121. EventStream& m_events;
  122. };
  123. class PhysicsControllerCallback : public PxUserControllerHitReport
  124. {
  125. void onShapeHit(const PxControllerShapeHit& /*hit*/)
  126. {
  127. }
  128. void onControllerHit(const PxControllersHit& /*hit*/)
  129. {
  130. }
  131. void onObstacleHit(const PxControllerObstacleHit& /*hit*/)
  132. {
  133. }
  134. };
  135. } // namespace crown