Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qphysicsworld_p.h
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5#ifndef PHYSICSWORLD_H
6#define PHYSICSWORLD_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists purely as an
13// implementation detail. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17//
18
19#include <QtQuick3DPhysics/qtquick3dphysicsglobal.h>
20
21#include <QtCore/QLoggingCategory>
22#include <QtCore/QObject>
23#include <QtCore/QTimerEvent>
24#include <QtCore/QElapsedTimer>
25#include <QtGui/QVector3D>
26#include <QtQml/qqml.h>
27#include <QBasicTimer>
28
29#include <QtQuick3D/private/qquick3dviewport_p.h>
30
31namespace physx {
32class PxMaterial;
33class PxPhysics;
34class PxShape;
35class PxRigidDynamic;
36class PxRigidActor;
37class PxRigidStatic;
38class PxCooking;
39class PxControllerManager;
40class PxConvexMesh;
41class PxTriangleMesh;
42class PxHeightField;
43class PxJoint;
44}
45
47
49
50class QAbstractPhysicsNode;
51class QAbstractCollisionShape;
52class QAbstractRigidBody;
54class QQuick3DModel;
55class QQuick3DGeometry;
56class QQuick3DPrincipledMaterial;
57class QPhysXWorld;
58class FrameAnimator;
59class QPhysicsJoint;
60
61class Q_QUICK3DPHYSICS_EXPORT QPhysicsWorld : public QObject, public QQmlParserStatus
62{
64 Q_INTERFACES(QQmlParserStatus)
65 Q_PROPERTY(QVector3D gravity READ gravity WRITE setGravity NOTIFY gravityChanged)
66 Q_PROPERTY(bool running READ running WRITE setRunning NOTIFY runningChanged)
67 Q_PROPERTY(bool forceDebugDraw READ forceDebugDraw WRITE setForceDebugDraw NOTIFY
68 forceDebugDrawChanged)
69 Q_PROPERTY(bool enableCCD READ enableCCD WRITE setEnableCCD NOTIFY enableCCDChanged)
70 Q_PROPERTY(float typicalLength READ typicalLength WRITE setTypicalLength NOTIFY
71 typicalLengthChanged)
73 float typicalSpeed READ typicalSpeed WRITE setTypicalSpeed NOTIFY typicalSpeedChanged)
74 Q_PROPERTY(float defaultDensity READ defaultDensity WRITE setDefaultDensity NOTIFY
75 defaultDensityChanged)
76 Q_PROPERTY(QQuick3DNode *viewport READ viewport WRITE setViewport NOTIFY viewportChanged
77 REVISION(6, 5))
78 Q_PROPERTY(float minimumTimestep READ minimumTimestep WRITE setMinimumTimestep NOTIFY
79 minimumTimestepChanged REVISION(6, 5))
80 Q_PROPERTY(float maximumTimestep READ maximumTimestep WRITE setMaximumTimestep NOTIFY
81 maximumTimestepChanged REVISION(6, 5))
82 Q_PROPERTY(QQuick3DNode *scene READ scene WRITE setScene NOTIFY sceneChanged REVISION(6, 5))
83 Q_PROPERTY(int numThreads READ numThreads WRITE setNumThreads NOTIFY numThreadsChanged
84 REVISION(6, 7))
85 Q_PROPERTY(bool reportKinematicKinematicCollisions READ reportKinematicKinematicCollisions WRITE
86 setReportKinematicKinematicCollisions NOTIFY
87 reportKinematicKinematicCollisionsChanged FINAL REVISION(6, 7))
88 Q_PROPERTY(bool reportStaticKinematicCollisions READ reportStaticKinematicCollisions WRITE
89 setReportStaticKinematicCollisions NOTIFY
90 reportStaticKinematicCollisionsChanged FINAL REVISION(6, 7))
92 Q_PROPERTY(QueryStructure staticQueryStructure READ staticQueryStructure WRITE
93 setStaticQueryStructure NOTIFY staticQueryStructureChanged FINAL REVISION(6, 13))
94
95 Q_PROPERTY(QueryStructure dynamicQueryStructure READ dynamicQueryStructure WRITE
96 setDynamicQueryStructure NOTIFY dynamicQueryStructureChanged FINAL REVISION(6, 13))
97
98 QML_NAMED_ELEMENT(PhysicsWorld)
99
100public:
101 enum class QueryStructure {
102 NoStructure, // eNONE
103 StaticTree, // eSTATIC_AABB_TREE
104 DynamicTree // eDYNAMIC_AABB_TREE
105 };
106 Q_ENUM(QueryStructure)
107
108 explicit QPhysicsWorld(QObject *parent = nullptr);
109 ~QPhysicsWorld();
111 void classBegin() override;
112 void componentComplete() override;
113
114 QVector3D gravity() const;
115
116 bool running() const;
117 bool forceDebugDraw() const;
118 bool enableCCD() const;
119 float typicalLength() const;
120 float typicalSpeed() const;
121 float defaultDensity() const;
122 Q_REVISION(6, 5) float minimumTimestep() const;
123 Q_REVISION(6, 5) float maximumTimestep() const;
124
125 bool isNodeRemoved(QAbstractPhysicsNode *object);
126
127 static QPhysicsWorld *getWorld(QQuick3DNode *node);
128 static QPhysicsWorld *getWorld(QPhysicsJoint *joint);
129
130 static void registerNode(QAbstractPhysicsNode *physicsNode);
131 static void deregisterNode(QAbstractPhysicsNode *physicsNode);
133 static void registerJoint(QPhysicsJoint *joint);
134 static void deregisterJoint(QPhysicsJoint *joint);
135
136 void registerContact(QAbstractPhysicsNode *sender, QAbstractPhysicsNode *receiver,
137 const QVector<QVector3D> &positions, const QVector<QVector3D> &impulses,
138 const QVector<QVector3D> &normals);
139
140 Q_REVISION(6, 5) QQuick3DNode *viewport() const;
141 void setHasIndividualDebugDraw();
142 physx::PxControllerManager *controllerManager();
143 Q_REVISION(6, 5) QQuick3DNode *scene() const;
144 Q_REVISION(6, 7) int numThreads() const;
145 Q_REVISION(6, 7) bool reportKinematicKinematicCollisions() const;
147 void setReportKinematicKinematicCollisions(bool newReportKinematicKinematicCollisions);
148 Q_REVISION(6, 7) bool reportStaticKinematicCollisions() const;
149 Q_REVISION(6, 7)
150 void setReportStaticKinematicCollisions(bool newReportStaticKinematicCollisions);
151
152 void cleanupRemovedJoints();
153
154 Q_REVISION(6, 13) QueryStructure staticQueryStructure() const;
155 Q_REVISION(6, 13) void setStaticQueryStructure(QueryStructure newStaticQueryStructure);
157 Q_REVISION(6, 13) QueryStructure dynamicQueryStructure() const;
158 Q_REVISION(6, 13) void setDynamicQueryStructure(QueryStructure newDynamicQueryStructure);
160public slots:
161 void setGravity(QVector3D gravity);
162 void setRunning(bool running);
163 void setForceDebugDraw(bool forceDebugDraw);
164 void setEnableCCD(bool enableCCD);
165 void setTypicalLength(float typicalLength);
166 void setTypicalSpeed(float typicalSpeed);
167 void setDefaultDensity(float defaultDensity);
168 Q_REVISION(6, 5) void setViewport(QQuick3DNode *viewport);
169 Q_REVISION(6, 5) void setMinimumTimestep(float minTimestep);
170 Q_REVISION(6, 5) void setMaximumTimestep(float maxTimestep);
171 Q_REVISION(6, 5) void setScene(QQuick3DNode *newScene);
172 Q_REVISION(6, 7) void setNumThreads(int newNumThreads);
175 void gravityChanged(QVector3D gravity);
176 void runningChanged(bool running);
177 void enableCCDChanged(bool enableCCD);
178 void forceDebugDrawChanged(bool forceDebugDraw);
179 void typicalLengthChanged(float typicalLength);
180 void typicalSpeedChanged(float typicalSpeed);
181 void defaultDensityChanged(float defaultDensity);
182 Q_REVISION(6, 5) void viewportChanged(QQuick3DNode *viewport);
183 Q_REVISION(6, 5) void minimumTimestepChanged(float minimumTimestep);
184 Q_REVISION(6, 5) void maximumTimestepChanged(float maxTimestep);
185 Q_REVISION(6, 5) void frameDone(float timestep);
186 Q_REVISION(6, 5) void sceneChanged();
187 Q_REVISION(6, 7) void numThreadsChanged();
188 Q_REVISION(6, 7) void reportKinematicKinematicCollisionsChanged();
189 Q_REVISION(6, 7) void reportStaticKinematicCollisionsChanged();
190
191
192 Q_REVISION(6, 13) void staticQueryStructureChanged();
193 Q_REVISION(6, 13) void dynamicQueryStructureChanged();
194
195private:
196 void simulateFrame();
197 void frameFinished(float deltaTime);
198 void frameFinishedDesignStudio();
199 void initPhysics();
200 void cleanupRemovedNodes();
201 void updateDebugDraw();
202 void updateDebugDrawDesignStudio();
203 void setupDebugMaterials(QQuick3DNode *sceneNode);
204 void disableDebugDraw();
205 void matchOrphanNodes();
206 void matchOrphanJoints();
207 void findPhysicsNodes();
208 void emitContactCallbacks();
209
210 struct BodyContact
211 {
212 QAbstractPhysicsNode *sender = nullptr;
213 QAbstractPhysicsNode *receiver = nullptr;
214 QVector<QVector3D> positions;
215 QVector<QVector3D> impulses;
216 QVector<QVector3D> normals;
217 };
218
219 struct DebugModelHolder
220 {
221 QQuick3DModel *model = nullptr;
222 QQuick3DGeometry *geometry = nullptr;
223 QVector3D data;
224 void *ptr = nullptr;
225
226 void releaseMeshPointer();
227
228 const QVector3D &halfExtents() const;
229 void setHalfExtents(const QVector3D &halfExtents);
230
231 float radius() const;
232 void setRadius(float radius);
233
234 float heightScale() const;
235 void setHeightScale(float heightScale);
236
237 float halfHeight() const;
238 void setHalfHeight(float halfHeight);
239
240 float rowScale() const;
241 void setRowScale(float rowScale);
242
243 float columnScale() const;
244 void setColumnScale(float columnScale);
245
246 physx::PxConvexMesh *getConvexMesh();
247 void setConvexMesh(physx::PxConvexMesh *mesh);
248
249 physx::PxTriangleMesh *getTriangleMesh();
250 void setTriangleMesh(physx::PxTriangleMesh *mesh);
251
252 physx::PxHeightField *getHeightField();
253 void setHeightField(physx::PxHeightField *hf);
254 };
255
256 QList<QAbstractPhysXNode *> m_physXBodies;
257 QList<QPhysicsJoint *> m_joints;
258 QList<QAbstractPhysicsNode *> m_newPhysicsNodes;
259 QHash<QPair<QAbstractCollisionShape *, QAbstractPhysicsNode *>, DebugModelHolder>
260 m_DesignStudioDebugModels;
261 QHash<QPair<QAbstractCollisionShape *, QAbstractPhysXNode *>, DebugModelHolder>
262 m_collisionShapeDebugModels;
263 QSet<QAbstractPhysicsNode *> m_removedPhysicsNodes;
264 QSet<physx::PxJoint *> m_removedJoints;
265 QMutex m_removedPhysicsNodesMutex;
266 QList<BodyContact> m_registeredContacts;
267
268 QVector3D m_gravity = QVector3D(0.f, -981.f, 0.f);
269 float m_typicalLength = 100.f; // 100 cm
270 float m_typicalSpeed = 1000.f; // 1000 cm/s
271 float m_defaultDensity = 0.001f; // 1 g/cm^3
272 float m_minTimestep = 1.0f; // 1000 fps
273 float m_maxTimestep = 33.333f; // 30 fps
274
275 bool m_running = true;
276 bool m_forceDebugDraw = false;
277 // For performance, used to keep track if we have indiviually enabled debug drawing for any
278 // collision shape
279 bool m_hasIndividualDebugDraw = false;
280 bool m_physicsInitialized = false;
281 bool m_enableCCD = false;
282
283 QPhysXWorld *m_physx = nullptr;
284 QQuick3DNode *m_viewport = nullptr;
285 QVector<QQuick3DPrincipledMaterial *> m_debugMaterials;
286
287 friend class QQuick3DPhysicsMesh; // TODO: better internal API
288 friend class QTriangleMeshShape; //####
289 friend class QHeightFieldShape;
290 friend class QQuick3DPhysicsHeightField;
291 friend class SimulationEventCallback;
292 friend class ControllerCallback;
293 static physx::PxPhysics *getPhysics();
294 static physx::PxCooking *getCooking();
295 FrameAnimator *m_frameAnimator = nullptr;
296 QQuick3DNode *m_scene = nullptr;
297 bool m_inDesignStudio = false;
298 int m_numThreads = -1;
299 bool m_reportKinematicKinematicCollisions = false;
300 bool m_reportStaticKinematicCollisions = false;
301 QElapsedTimer m_timer;
302 float m_currTimeStep = 0.f;
303 QList<float> m_frameTimings;
304 bool m_frameFetched = false;
305 QueryStructure m_staticQueryStructure = QueryStructure::DynamicTree;
306 QueryStructure m_dynamicQueryStructure = QueryStructure::DynamicTree;
307};
308
310
311#endif // PHYSICSWORLD_H
Q_ALWAYS_INLINE bool fuzzyEquals(const physx::PxTransform &a, const physx::PxTransform &b)
const QQuaternion kMinus90YawRotation
QT_BEGIN_NAMESPACE Q_DECLARE_LOGGING_CATEGORY(lcQuick3dPhysics)
#define QML_NAMED_ELEMENT(NAME)
#define QT_BEGIN_NAMESPACE
#define QT_END_NAMESPACE
#define Q_ENUM(x)
#define Q_PROPERTY(...)
#define Q_OBJECT
#define Q_REVISION(...)
#define Q_INTERFACES(x)
#define slots
#define signals
#define emit