33 #include "qparticle.h"
34 #include "qangleconstraint.h"
35 #include "json/json.hpp"
37 #include "qmath_utils.h"
39 using json =nlohmann::json;
51 enum CollisionBehaviors{
57 vector<QParticle*> particles=vector<QParticle*>();
60 QVector position=QVector::Zero();
61 QVector globalPosition=QVector::Zero();
63 float globalRotation=0.0f;
64 vector<QSpring*> springs=vector<QSpring*>();
65 vector<QAngleConstraint*> angleConstraints=vector<QAngleConstraint*>();
66 vector <QParticle*> polygon=vector<QParticle*>();
67 vector<vector<QParticle*>> subConvexPolygons=vector<vector<QParticle*>>();
68 float circumference=0.0f;
69 QBody *ownerBody=
nullptr;
70 CollisionBehaviors collisionBehavior=CollisionBehaviors::CIRCLES;
71 vector<vector<int>> UVMaps=vector<vector<int>>();
72 bool disablePolygonForCollisions=
false;
74 bool collisionBehaviorNeedsUpdate=
false;
77 void UpdateCollisionBehavior();
80 vector<float> lastPolygonCornerAngles;
81 float minAngleConstraintOfPolygon=M_PI*0.3;
84 void UpdateSubConvexPolygons(
bool majorUpdate=
true);
85 void ApplyAngleConstraintsToPolygon();
86 bool CheckIsPolygonConcave(vector<QParticle*> polygonParticles);
88 static bool CheckIsReflex(
int indexA,
int indexB,
int indexC, vector<QParticle*> polygonParticles);
89 static void TriangulatePolygon(vector<QParticle*> &polygonParticles,vector<vector<int>> &triangles);
90 static void DecompositePolygon(vector<QParticle*> &polygonParticles,vector<vector<QParticle*>> &polygons);
91 static void DecompositePolygon2(vector<QParticle*> &polygonParticles,vector<vector<QParticle*>> &polygons);
92 bool subConvexPolygonsNeedsUpdate=
false;
160 return globalPosition;
168 return globalRotation;
173 for(
size_t n=0;n<GetSubConvexPolygonCount();n++){
175 res+=GetPolygonArea(GetSubConvexPolygonAt(n),
true);
177 for(
auto particle:particles){
178 if(particle->GetRadius()>0.5f){
179 res+=particle->GetRadius()*particle->GetRadius();
187 for(
size_t n=0;n<GetSubConvexPolygonCount();n++){
188 res+=GetPolygonArea(GetSubConvexPolygonAt(n),
true);
196 for(
size_t n=0;n<GetSubConvexPolygonCount();n++){
197 res+=GetPolygonArea(GetSubConvexPolygonAt(n));
199 for(
auto particle:particles){
200 if(particle->GetRadius()>0.5f){
201 res+=particle->GetRadius()*particle->GetRadius();
209 for(
size_t n=0;n<GetSubConvexPolygonCount();n++){
210 res+=GetPolygonArea(GetSubConvexPolygonAt(n));
219 for(
size_t n=0;n<GetSubConvexPolygonCount();n++){
220 auto polygon=GetSubConvexPolygonAt(n);
221 for(
int i=0;i<polygon.size();i++){
223 QParticle *np=polygon[(i+1)%polygon.size()];
243 if(collisionBehaviorNeedsUpdate){
244 UpdateCollisionBehavior();
245 collisionBehaviorNeedsUpdate=
false;
247 return collisionBehavior;
256 return disablePolygonForCollisions;
274 globalPosition=value;
295 disablePolygonForCollisions=value;
296 collisionBehaviorNeedsUpdate=
true;
316 QMesh * RemoveParticleAt(
int index);
324 int GetParticleCount();
335 for(
int i=0;i<particles.size();i++){
336 if(particles[i]==particle){
352 QMesh * SetPolygon(vector<QParticle *> polygonParticles);
360 QMesh * AddParticleToPolygon(
QParticle * particle,
int position=-1);
376 QMesh * RemoveParticleFromPolygonAt(
int index);
382 QMesh * RemovePolygon();
386 int GetPolygonParticleCount();
393 QParticle *GetParticleFromPolygon(
int index);
401 return minAngleConstraintOfPolygon;
410 minAngleConstraintOfPolygon=radian;
419 if (subConvexPolygonsNeedsUpdate==
true){
420 UpdateSubConvexPolygons();
421 subConvexPolygonsNeedsUpdate=
false;
423 return subConvexPolygons.size();
429 if (subConvexPolygonsNeedsUpdate==
true){
430 UpdateSubConvexPolygons();
431 subConvexPolygonsNeedsUpdate=
false;
433 return subConvexPolygons[index];
453 QMesh *RemoveSpringAt(
int index);
462 return springs.size();
468 return springs[index];
475 for(
int i=0;i<springs.size();i++)
476 if(springs[i]==spring)
488 return UVMaps.size();
495 return UVMaps[index];
502 QMesh * AddUVMap(vector<int> map);
509 QMesh * RemoveUVMapAt(
int index);
515 QMesh * ClearUVMaps();
522 QMesh * RemoveMatchingUVMaps(
int particleIndex);
531 return angleConstraints.size();
538 return angleConstraints[index];
545 angleConstraints.push_back(angleConstraint);
555 angleConstraints.erase(angleConstraints.begin()+index );
563 for(
int i=0;i<angleConstraints.size();i++)
564 if(angleConstraints[i]==angleConstraint)
574 int index=GetAngleConstraintIndex(angleConstraint);
576 RemoveAngleConstraintAt(index);
588 while(i<angleConstraints.size()){
591 RemoveAngleConstraintAt(i);
611 static QMesh * CreateWithCircle(
float radius,
QVector centerPosition=QVector::Zero());
623 static QMesh * CreateWithPolygon(
float radius,
int sideCount,
QVector centerPosition=QVector::Zero(),
int polarGrid=-1,
bool enableSprings=
true,
bool enablePolygons=
true,
float particleRadius=0.5f);
635 static QMesh * CreateWithRect(
QVector size,
QVector centerPosition=QVector::Zero(),
QVector grid=QVector::Zero(),
bool enableSprings=
true,
bool enablePolygons=
true,
float particleRadius=0.5f);
643 static QMesh * CreateWithMeshData(
QMesh::MeshData &data,
bool enableSprings=
true,
bool enablePolygons=
true);
649 static vector<QMesh::MeshData> GetMeshDatasFromFile(
string filePath);
656 static vector<QMesh::MeshData> GetMeshDatasFromJsonData(std::string &jsonBasedData);
667 static float GetPolygonArea(vector<QParticle*> &polygonPoints,
bool withLocalPositions=
false);
677 static bool CheckCollisionBehaviors(
QMesh *meshA,
QMesh * meshB,CollisionBehaviors firstBehavior,CollisionBehaviors secondBehavior );
686 static MeshData GenerateRectangleMeshData(
QVector size,
QVector centerPosition=QVector::Zero(),
QVector grid=QVector::Zero(),
float particleRadius=0.5f);
696 static MeshData GeneratePolygonMeshData(
float radius,
int sideCount,
QVector centerPosition=QVector::Zero(),
int polarGrid=-1,
float particleRadius=0.5f);
702 static pair<QVector, float> GetAveragePositionAndRotation(vector<QParticle*> particleCollection);
711 static vector<QVector> GetMatchingParticlePositions(vector<QParticle*> particleCollection,
QVector targetPosition,
float targetRotation);
You can apply angle constraints between 3 particles using the QAngleConstraint. The physics engine us...
Definition: qangleconstraint.h:38
QParticle * GetParticleB()
Definition: qangleconstraint.h:84
QParticle * GetParticleC()
Definition: qangleconstraint.h:88
QParticle * GetParticleA()
Definition: qangleconstraint.h:80
QBody objects are the base class for all types of bodies. Any class derived from QBody shares these m...
Definition: qbody.h:43
The QCollision class performs all collision detection operations. The relevant methods return contact...
Definition: qcollision.h:44
QParticle objects form the network structures of QMesh objects defined for all body object types....
Definition: qparticle.h:40
bool manualDeletion
Definition: qparticle.h:270
QVector GetPosition()
Definition: qparticle.h:102
QRaycast objects send a ray into the world and return collision results with body objects....
Definition: qraycast.h:38
QRigidBody is a type of body that is simulated with the dynamics of Rigid body. A rigid body is a typ...
Definition: qrigidbody.h:40
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
vector< QVector > particlePositions
Definition: qmesh.h:99
vector< pair< int, int > > springList
Definition: qmesh.h:111
vector< bool > particleLazyValues
Definition: qmesh.h:107
vector< bool > particleInternalValues
Definition: qmesh.h:103
vector< int > polygon
Definition: qmesh.h:122
vector< vector< int > > UVMaps
Definition: qmesh.h:130
vector< float > particleRadValues
Definition: qmesh.h:101
vector< pair< int, int > > internalSpringList
Definition: qmesh.h:116
vector< bool > particleEnabledValues
Definition: qmesh.h:105
Every QBody object requires meshes. In other traditional physics engines, the term 'shape' is used in...
Definition: qmesh.h:49
vector< QParticle * > & GetSubConvexPolygonAt(int index)
Definition: qmesh.h:428
QVector GetGlobalPosition()
Definition: qmesh.h:159
QSpring * GetSpringAt(int index)
Definition: qmesh.h:467
int GetSpringIndex(QSpring *spring)
Definition: qmesh.h:474
QMesh * SetPolygonForCollisionsDisabled(bool value)
Definition: qmesh.h:294
bool GetPolygonForCollisionsDisabled()
Definition: qmesh.h:255
QVector GetPosition()
Definition: qmesh.h:155
QMesh * RemoveAngleConstraintAt(int index)
Definition: qmesh.h:554
float GetRotation()
Definition: qmesh.h:163
int GetAngleConstraintCount()
Definition: qmesh.h:530
QAngleConstraint * GetAngleConstraintAt(int index)
Definition: qmesh.h:537
QMesh * SetGlobalPosition(QVector value)
Definition: qmesh.h:273
QMesh * AddAngleConstraint(QAngleConstraint *angleConstraint)
Definition: qmesh.h:544
float GetGlobalRotation()
Definition: qmesh.h:167
int GetUVMapCount()
Definition: qmesh.h:487
float GetMinAngleConstraintOfPolygon()
Definition: qmesh.h:400
float GetArea()
Definition: qmesh.h:194
int GetParticleIndex(QParticle *particle)
Definition: qmesh.h:334
int GetAngleConstraintIndex(QAngleConstraint *angleConstraint)
Definition: qmesh.h:562
vector< int > GetUVMapAt(int index)
Definition: qmesh.h:494
QBody * GetOwnerBody()
Definition: qmesh.h:236
float GetInitialPolygonsArea()
Definition: qmesh.h:185
QMesh * SetRotation(float value)
Definition: qmesh.h:281
int GetSpringCount()
Definition: qmesh.h:461
int GetSubConvexPolygonCount()
Definition: qmesh.h:418
QMesh * RemoveAngleConstraint(QAngleConstraint *angleConstraint)
Definition: qmesh.h:573
float GetCircumference()
Definition: qmesh.h:217
QMesh * RemoveMatchingAngleConstraints(QParticle *particle)
Definition: qmesh.h:586
float GetInitialArea()
Definition: qmesh.h:171
QMesh * SetPosition(QVector value)
Definition: qmesh.h:265
float GetPolygonsArea()
Definition: qmesh.h:207
QMesh * SetMinAngleConstraintOfPolygon(float radian)
Definition: qmesh.h:409
CollisionBehaviors GetCollisionBehavior()
Definition: qmesh.h:242