12 #ifndef hifi_PhysicsEngine_h
13 #define hifi_PhysicsEngine_h
20 #include <btBulletDynamicsCommon.h>
21 #include <BulletCollision/CollisionDispatch/btGhostObject.h>
23 #include "BulletUtil.h"
24 #include "ContactInfo.h"
25 #include "ObjectMotionState.h"
26 #include "ThreadSafeDynamicsWorld.h"
27 #include "ObjectAction.h"
28 #include "ObjectConstraint.h"
30 const float HALF_SIMULATION_EXTENT = 512.0f;
32 class CharacterController;
33 class PhysicsDebugDraw;
38 ContactKey() =
delete;
39 ContactKey(
void* a,
void* b) : _a(a), _b(b) {}
40 bool operator<(
const ContactKey& other)
const {
return _a < other._a || (_a == other._a && _b < other._b); }
41 bool operator==(
const ContactKey& other)
const {
return _a == other._a && _b == other._b; }
46 struct ContactTestResult {
47 ContactTestResult() =
delete;
49 ContactTestResult(
const ContactTestResult& contactTestResult) :
50 foundID(contactTestResult.foundID),
51 testCollisionPoint(contactTestResult.testCollisionPoint),
52 foundCollisionPoint(contactTestResult.foundCollisionPoint),
53 collisionNormal(contactTestResult.collisionNormal) {
56 ContactTestResult(
const QUuid& foundID,
const glm::vec3& testCollisionPoint,
const glm::vec3& otherCollisionPoint,
const glm::vec3& collisionNormal) :
58 testCollisionPoint(testCollisionPoint),
59 foundCollisionPoint(otherCollisionPoint),
60 collisionNormal(collisionNormal) {
65 glm::vec3 testCollisionPoint;
67 glm::vec3 foundCollisionPoint;
69 glm::vec3 collisionNormal;
72 using ContactMap = std::map<ContactKey, ContactInfo>;
73 using CollisionEvents = std::vector<Collision>;
77 using ContactAddedCallback = bool (*)(btManifoldPoint& cp,
78 const btCollisionObjectWrapper* colObj0Wrap,
int partId0,
int index0,
79 const btCollisionObjectWrapper* colObj1Wrap,
int partId1,
int index1);
84 objectsToRemove.clear();
86 objectsToReinsert.clear();
87 activeStaticObjects.clear();
89 std::vector<ObjectMotionState*> objectsToRemove;
90 std::vector<ObjectMotionState*> objectsToAdd;
91 std::vector<ObjectMotionState*> objectsToReinsert;
92 std::vector<ObjectMotionState*> activeStaticObjects;
95 PhysicsEngine(
const glm::vec3& offset);
99 uint32_t getNumSubsteps()
const;
100 int32_t getNumCollisionObjects()
const;
102 void removeObjects(
const VectorOfMotionStates& objects);
103 void removeSetOfObjects(
const SetOfMotionStates& objects);
105 void addObjects(
const VectorOfMotionStates& objects);
106 void changeObjects(
const VectorOfMotionStates& objects);
107 void reinsertObject(ObjectMotionState*
object);
109 void processTransaction(Transaction& transaction);
111 void stepSimulation();
112 void harvestPerformanceStats();
113 void printPerformanceStatsToFile(
const QString& filename);
114 void updateContactMap();
115 void doOwnershipInfectionForConstraints();
117 bool hasOutgoingChanges()
const {
return _hasOutgoingChanges; }
120 const VectorOfMotionStates& getChangedMotionStates();
121 const VectorOfMotionStates& getDeactivatedMotionStates()
const {
return _dynamicsWorld->getDeactivatedMotionStates(); }
124 const CollisionEvents& getCollisionEvents();
127 void dumpStatsIfNecessary();
130 void saveNextPhysicsStats(QString filename);
133 void setOriginOffset(
const glm::vec3& offset) { _originOffset = offset; }
136 const glm::vec3& getOriginOffset()
const {
return _originOffset; }
138 void setCharacterController(CharacterController* character);
140 void dumpNextStats() { _dumpNextStats =
true; }
142 EntityDynamicPointer getDynamicByID(
const QUuid& dynamicID)
const;
143 bool addDynamic(EntityDynamicPointer dynamic);
144 void removeDynamic(
const QUuid dynamicID);
145 void forEachDynamic(std::function<
void(EntityDynamicPointer)> actor);
147 void setShowBulletWireframe(
bool value);
148 void setShowBulletAABBs(
bool value);
149 void setShowBulletContactPoints(
bool value);
150 void setShowBulletConstraints(
bool value);
151 void setShowBulletConstraintLimits(
bool value);
155 std::vector<ContactTestResult> contactTest(uint16_t mask,
const ShapeInfo& regionShapeInfo,
const Transform& regionTransform, uint16_t group = USER_COLLISION_GROUP_DYNAMIC,
float threshold = 0.0f)
const;
157 void setContactAddedCallback(ContactAddedCallback cb);
159 btDiscreteDynamicsWorld* getDynamicsWorld()
const {
return _dynamicsWorld; }
160 void removeContacts(ObjectMotionState* motionState);
163 QList<EntityDynamicPointer> removeDynamicsForBody(btRigidBody* body);
164 void addObjectToDynamicsWorld(ObjectMotionState* motionState);
167 void bumpAndPruneContacts(ObjectMotionState* motionState);
169 void doOwnershipInfection(
const btCollisionObject* objectA,
const btCollisionObject* objectB);
172 btDefaultCollisionConfiguration* _collisionConfig = NULL;
173 btCollisionDispatcher* _collisionDispatcher = NULL;
174 btBroadphaseInterface* _broadphaseFilter = NULL;
175 btSequentialImpulseConstraintSolver* _constraintSolver = NULL;
176 ThreadSafeDynamicsWorld* _dynamicsWorld = NULL;
177 btGhostPairCallback* _ghostPairCallback = NULL;
178 std::unique_ptr<PhysicsDebugDraw> _physicsDebugDraw;
180 ContactMap _contactMap;
181 CollisionEvents _collisionEvents;
182 QHash<QUuid, EntityDynamicPointer> _objectDynamics;
183 QHash<btRigidBody*, QSet<QUuid>> _objectDynamicsByBody;
184 std::set<btRigidBody*> _activeStaticBodies;
185 QString _statsFilename;
187 glm::vec3 _originOffset;
189 CharacterController* _myAvatarController;
191 uint32_t _numContactFrames { 0 };
193 bool _dumpNextStats {
false };
194 bool _saveNextStats {
false };
195 bool _hasOutgoingChanges {
false };
199 typedef std::shared_ptr<PhysicsEngine> PhysicsEnginePointer;