Quark Physics  1.0
2D Rigid and Soft Body Physics Engine
qworld.h
1 
2 /************************************************************************************
3  * MIT License
4  *
5  * Copyright (c) 2023 Eray Zesen
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy
8  * of this software and associated documentation files (the "Software"), to deal
9  * in the Software without restriction, including without limitation the rights
10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11  * copies of the Software, and to permit persons to whom the Software is
12  * furnished to do so, subject to the following conditions:
13  * The above copyright notice and this permission notice shall be included in all
14  * copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  *
24  * https://github.com/erayzesen/QuarkPhysics
25  *
26 **************************************************************************************/
27 
28 #ifndef QWORLD_H
29 #define QWORLD_H
30 #include <iostream>
31 #include <map>
32 #include <vector>
33 #include "qbody.h"
34 #include "qjoint.h"
35 #include "qvector.h"
36 #include "qmanifold.h"
37 #include "qgizmos.h"
38 #include "qbroadphase.h"
39 #include "qcollision.h"
40 #include "qrigidbody.h"
41 #include "qsoftbody.h"
42 #include "qraycast.h"
43 #include "qjoint.h"
44 #include "qmath_utils.h"
45 
46 
47 using namespace std;
51 class QWorld{
52 
53 protected:
54 
55 
56  //Collections
57 
58 
59  vector <QJoint*> joints=vector<QJoint*>();
60 
61  vector <QSpring*> springs=vector<QSpring*>();
62 
63  vector<QRaycast*> raycasts=vector<QRaycast*>();
64 
65  vector <QGizmo*> gizmos=vector<QGizmo*>();
66 
67  vector<vector<QBody*> > sleepingIslands=vector<vector<QBody*> >();
68 
69  unordered_set<pair<QBody*, QBody*>, QBody::BodyPairHash,QBody::BodyPairEqual> collisionExceptions;
70 
71  vector<QManifold> manifolds;
72 
73  //Broadphase
74  QBroadPhase *broadPhase=nullptr;
75 
76 
77 
78  //Physics World Properties
79 
80  bool enabled=true;
81  QVector gravity=QVector(0.0f,0.2f);
82  bool enableSleeping=true;
83  bool enableBroadphase=true;
84  int iteration=4;
85  float timeScale=1.0f;
86 
87 
88  //Sleeping
89  float sleepingPositionTolerance=0.1f;
90  float sleepingRotationTolerance=M_PI/180.0f;
91 
92  //Debug Features
93  int debugAABBTestCount=0; //aabb test method call count
94  int debugCollisionTestCount=0; // any collision method call count
95 
96  void ClearGizmos();
97  void ClearBodies();
98 
99 
100  //Collisions, Dynamic Colliders Islands and Sleeping Feature
101  void CreateIslands(int bodyIndex, vector<QBody*> &bodyList, vector<QBody*> &island, vector<bool> &visitedList);
102  void GenerateIslands(vector<QBody*> &bodyList, vector<vector<QBody*>> &islandList);
103  static bool SortBodiesHorizontal(const QBody *bodyA,const QBody *bodyB);
104  static bool SortBodiesVertical(const QBody *bodyA,const QBody *bodyB);
105  void GetCollisionPairs(vector<QBody *> &bodyList,vector<pair<QBody *, QBody *> > *resList);
106 
107  void CreateIslands(QBody &body, vector<QBody*> island);
108  vector<vector<QBody>> GenerateIslands(vector<QBody> bodyList );
109 
110  //Constraints
111  void UpdateConstraints();
112 
113 
114 
115 
116 public:
117 
118 
119 
120  vector<QBody*> bodies=vector<QBody*>();
121 
122  /* It's the maximum world size in pixels. It is used in some calculations that require maximum values. */
123  inline static float MAX_WORLD_SIZE=99999.0f;
124 
125  //General Get Methods
126  /* Returns the gravity force of the world.
127  */
128  QVector GetGravity(){
129  return gravity;
130  }
131 
132 
136  return enableSleeping;
137  }
141  return sleepingPositionTolerance;
142  }
146  return sleepingRotationTolerance;
147  }
151  return enableBroadphase;
152  }
153 
158  return broadPhase;
159  }
160 
161 
166  return iteration;
167  }
168 
170  float GetTimeScale(){
171  return timeScale;
172  }
173 
175  bool GetEnabled(){
176  return enabled;
177  }
178 
179  //General Set Methods
185  gravity=value;
186  return this;
187  }
192  enableSleeping=value;
193  return this;
194  }
199  sleepingPositionTolerance=value;
200  return this;
201  }
206  sleepingRotationTolerance=value;
207  return this;
208  }
212  enableBroadphase=value;
213  return this;
214  }
215 
220  QWorld *SetBroadphase(QBroadPhase *externalBroadphase){
221  broadPhase=externalBroadphase;
222  if (broadPhase!=nullptr){
223  broadPhase->Clear();
224  }
225  return this;
226  }
227 
228 
234  iteration=value;
235  return this;
236  }
237 
238 
242  QWorld *SetTimeScale(float value=1.0f){
243  timeScale=value;
244  return this;
245  }
246 
250  QWorld *SetEnabled(bool value){
251  enabled=value;
252  return this;
253  }
254 
255 
256 
257 
258 
259  //Methods
262  void Update();
263 
264 
265 
271  static vector<QCollision::Contact*> GetCollisions(QBody *bodyA, QBody *bodyB);
272 
273 
277  QWorld *AddBody(QBody *body);
281  QWorld *AddBodyGroup(const vector<QBody*> &bodyGroup);
285  QWorld *RemoveBody(QBody *body);
290  QWorld *RemoveBodyAt(int index);
294  return bodies.size();
295  }
299  QBody *GetBodyAt(int index){
300  return bodies[index];
301  }
305  int GetBodyIndex(QBody *body){
306  if(body==nullptr)
307  return -1;
308  for(int i=0;i<bodies.size();i++){
309  if(bodies[i]==body)
310  return i;
311  }
312  return -1;
313  }
320  vector<QBody*> GetBodiesHitByPoint(QVector point,int maxBodyCount=1,bool onlyRigidBodies=true,int layersBit=-1);
328  vector<QParticle*> GetParticlesCloseToPoint(QVector point,float distance,int maxParticleCount=1,bool exceptRigidBodies=true,int layersBit=-1);
332  bool CollideWithWorld(QBody *body);
333 
337  vector<QManifold> TestCollisionWithWorld(QBody *body);
338 
339  //Joint Operations
343  QWorld *AddJoint(QJoint *joint);
347  QWorld *RemoveJoint(QJoint *joint);
352  QWorld *RemoveJointAt(int index);
356  QWorld *RemoveMatchingJoints(QBody *body);
360  return joints.size();
361  }
365  QJoint *GetJointAt(int index){
366  return joints[index];
367  }
371  int GetJointIndex(QJoint *joint){
372  for(int i=0;i<joints.size();i++)
373  if(joints[i]==joint)
374  return i;
375  return -1;
376  }
377 
378  //Spring Operations
382  QWorld *AddSpring(QSpring *spring);
386  QWorld *RemoveSpring(QSpring *spring);
391  QWorld *RemoveSpringAt(int index);
395  QWorld *RemoveMatchingSprings(QBody *body);
399  QWorld *RemoveMatchingSprings(QParticle *particle);
403  return springs.size();
404  }
408  QSpring *GetSpringAt(int index){
409  return springs[index];
410  }
414  int GetSpringIndex(QSpring *spring){
415  for(int i=0;i<springs.size();i++)
416  if(springs[i]==spring)
417  return i;
418  return -1;
419  }
420 
421  //Raycast Operations
425  QWorld *AddRaycast(QRaycast * raycast);
429  QWorld *RemoveRaycast(QRaycast *raycast);
434  QWorld *RemoveRaycastAt(int index);
438  return raycasts.size();
439  }
443  QRaycast *GetRaycastAt(int index){
444  return raycasts[index];
445  }
449  int GetRaycastIndex(QRaycast *raycast){
450  for(int i=0;i<raycasts.size();i++)
451  if(raycasts[i]==raycast)
452  return i;
453  return -1;
454  }
455 
456  //Gizmos Operations
459  vector<QGizmo*> *GetGizmos(){
460  return &gizmos;
461  };
462 
463  //Collision Exceptions
468  QWorld *AddCollisionException(QBody *bodyA, QBody *bodyB);
473  QWorld *RemoveCollisionException(QBody *bodyA, QBody *bodyB);
477  QWorld *RemoveMatchingCollisionException(QBody *body);
482  bool CheckCollisionException(QBody *bodyA, QBody *bodyB);
483 
484  //
487  QWorld();
488  ~QWorld();
491  QWorld *ClearJoints();
494  QWorld *ClearSprings();
497  QWorld *ClearRaycasts();
500  QWorld *ClearWorld();
501 
502  friend class QCollision;
503  friend class QManifold;
504  friend class QSoftBody;
505  friend class QBroadPhase;
506 
507 
508 
509 };
510 
511 #endif // QWORLD_H
QBody objects are the base class for all types of bodies. Any class derived from QBody shares these m...
Definition: qbody.h:43
Definition: qbroadphase.h:44
The QCollision class performs all collision detection operations. The relevant methods return contact...
Definition: qcollision.h:44
QJoint objects serves to apply various distance constraints between rigid bodies. Additionally,...
Definition: qjoint.h:37
QManifold retrieves collision data from collision tests between two QBody objects using QCollision me...
Definition: qmanifold.h:36
QParticle objects form the network structures of QMesh objects defined for all body object types....
Definition: qparticle.h:37
QRaycast objects send a ray into the world and return collision results with body objects....
Definition: qraycast.h:38
QSoftBody is a body type that defines deformable, soft objects in the physics world....
Definition: qsoftbody.h:35
You can apply distance constraints between 2 particles using the QSpring. The physics engine uses QSp...
Definition: qspring.h:39
A QWorld object is required to create a physics simulation. The QWorld class manages the entire physi...
Definition: qworld.h:51
bool GetEnabled()
Definition: qworld.h:175
QWorld * SetSleepingRotationTolerance(float value)
Definition: qworld.h:205
bool GetBroadphaseEnabled()
Definition: qworld.h:150
QWorld * SetSleepingPositionTolerance(float value)
Definition: qworld.h:198
QWorld * SetTimeScale(float value=1.0f)
Definition: qworld.h:242
QSpring * GetSpringAt(int index)
Definition: qworld.h:408
float GetTimeScale()
Definition: qworld.h:170
int GetBodyCount()
Definition: qworld.h:293
int GetBodyIndex(QBody *body)
Definition: qworld.h:305
int GetIterationCount()
Definition: qworld.h:165
int GetRaycastCount()
Definition: qworld.h:437
float GetSleepingPositionTolerance()
Definition: qworld.h:140
int GetJointCount()
Definition: qworld.h:359
bool GetSleepingEnabled()
Definition: qworld.h:135
QJoint * GetJointAt(int index)
Definition: qworld.h:365
QBody * GetBodyAt(int index)
Definition: qworld.h:299
int GetJointIndex(QJoint *joint)
Definition: qworld.h:371
QRaycast * GetRaycastAt(int index)
Definition: qworld.h:443
QWorld * SetBroadphaseEnabled(bool value)
Definition: qworld.h:211
QWorld * SetSleepingEnabled(bool value)
Definition: qworld.h:191
int GetSpringIndex(QSpring *spring)
Definition: qworld.h:414
QWorld * SetBroadphase(QBroadPhase *externalBroadphase)
Definition: qworld.h:220
QWorld * SetIterationCount(int value)
Definition: qworld.h:233
QWorld * SetGravity(QVector value)
Definition: qworld.h:184
vector< QGizmo * > * GetGizmos()
Definition: qworld.h:459
float GetSleepingRotationTolerance()
Definition: qworld.h:145
int GetRaycastIndex(QRaycast *raycast)
Definition: qworld.h:449
QWorld * SetEnabled(bool value)
Definition: qworld.h:250
QBroadPhase * GetBroadphase()
Definition: qworld.h:157
int GetSpringCount()
Definition: qworld.h:402
Definition: qbody.h:76
Definition: qbody.h:68
Definition: qvector.h:44