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 <QtCore/QSpan>
26#include <QtGui/QVector3D>
27#include <QtQml/qqml.h>
28#include <QBasicTimer>
29#include <QtQuick3DPhysics/private/qquick3dphysicslocationhit_p.h>
30
31#include <QtQuick3D/private/qquick3dviewport_p.h>
32
33namespace physx {
34class PxMaterial;
35class PxPhysics;
36class PxShape;
37class PxRigidDynamic;
38class PxRigidActor;
39class PxRigidStatic;
40struct PxCookingParams;
41class PxControllerManager;
42class PxConvexMesh;
43class PxTriangleMesh;
44class PxHeightField;
45class PxJoint;
46}
47
49
51
52class QAbstractPhysicsNode;
53class QAbstractCollisionShape;
54class QAbstractRigidBody;
56class QQuick3DModel;
57class QQuick3DGeometry;
58class QQuick3DPrincipledMaterial;
59class QPhysXWorld;
60class FrameAnimator;
61class QPhysicsJoint;
62class QRaycaster;
63
64class Q_QUICK3DPHYSICS_EXPORT QPhysicsWorld : public QObject, public QQmlParserStatus
65{
67 Q_INTERFACES(QQmlParserStatus)
68 Q_PROPERTY(QVector3D gravity READ gravity WRITE setGravity NOTIFY gravityChanged)
69 Q_PROPERTY(bool running READ running WRITE setRunning NOTIFY runningChanged)
70 Q_PROPERTY(bool forceDebugDraw READ forceDebugDraw WRITE setForceDebugDraw NOTIFY
71 forceDebugDrawChanged)
72 Q_PROPERTY(bool enableCCD READ enableCCD WRITE setEnableCCD NOTIFY enableCCDChanged)
73 Q_PROPERTY(float typicalLength READ typicalLength WRITE setTypicalLength NOTIFY
74 typicalLengthChanged)
76 float typicalSpeed READ typicalSpeed WRITE setTypicalSpeed NOTIFY typicalSpeedChanged)
77 Q_PROPERTY(float defaultDensity READ defaultDensity WRITE setDefaultDensity NOTIFY
78 defaultDensityChanged)
79 Q_PROPERTY(QQuick3DNode *viewport READ viewport WRITE setViewport NOTIFY viewportChanged
80 REVISION(6, 5))
81 Q_PROPERTY(float minimumTimestep READ minimumTimestep WRITE setMinimumTimestep NOTIFY
82 minimumTimestepChanged REVISION(6, 5))
83 Q_PROPERTY(float maximumTimestep READ maximumTimestep WRITE setMaximumTimestep NOTIFY
84 maximumTimestepChanged REVISION(6, 5))
85 Q_PROPERTY(QQuick3DNode *scene READ scene WRITE setScene NOTIFY sceneChanged REVISION(6, 5))
86 Q_PROPERTY(int numThreads READ numThreads WRITE setNumThreads NOTIFY numThreadsChanged
87 REVISION(6, 7))
88 Q_PROPERTY(bool reportKinematicKinematicCollisions READ reportKinematicKinematicCollisions WRITE
89 setReportKinematicKinematicCollisions NOTIFY
90 reportKinematicKinematicCollisionsChanged FINAL REVISION(6, 7))
91 Q_PROPERTY(bool reportStaticKinematicCollisions READ reportStaticKinematicCollisions WRITE
92 setReportStaticKinematicCollisions NOTIFY
93 reportStaticKinematicCollisionsChanged FINAL REVISION(6, 7))
95 Q_PROPERTY(QueryStructure staticQueryStructure READ staticQueryStructure WRITE
96 setStaticQueryStructure NOTIFY staticQueryStructureChanged FINAL REVISION(6, 13))
97
98 Q_PROPERTY(QueryStructure dynamicQueryStructure READ dynamicQueryStructure WRITE
99 setDynamicQueryStructure NOTIFY dynamicQueryStructureChanged FINAL REVISION(6, 13))
100
101 QML_NAMED_ELEMENT(PhysicsWorld)
102
103public:
104 enum class QueryStructure {
105 NoStructure, // eNONE
106 StaticTree, // eSTATIC_AABB_TREE
107 DynamicTree // eDYNAMIC_AABB_TREE
108 };
109 Q_ENUM(QueryStructure)
110
111 explicit QPhysicsWorld(QObject *parent = nullptr);
112 ~QPhysicsWorld();
114 void classBegin() override;
115 void componentComplete() override;
116
117 QVector3D gravity() const;
118
119 bool running() const;
120 bool forceDebugDraw() const;
121 bool enableCCD() const;
122 float typicalLength() const;
123 float typicalSpeed() const;
124 float defaultDensity() const;
125 Q_REVISION(6, 5) float minimumTimestep() const;
126 Q_REVISION(6, 5) float maximumTimestep() const;
127
128 bool isNodeRemoved(QAbstractPhysicsNode *object);
129
130 static QPhysicsWorld *getWorld(QQuick3DNode *node);
131 static QPhysicsWorld *getWorld(QPhysicsJoint *joint);
132
133 static void registerNode(QAbstractPhysicsNode *physicsNode);
134 static void deregisterNode(QAbstractPhysicsNode *physicsNode);
136 static void registerJoint(QPhysicsJoint *joint);
137 static void deregisterJoint(QPhysicsJoint *joint);
138
139 void registerContact(QAbstractPhysicsNode *sender, QAbstractPhysicsNode *receiver,
140 const QVector<QVector3D> &positions, const QVector<QVector3D> &impulses,
141 const QVector<QVector3D> &normals);
142
143 Q_REVISION(6, 5) QQuick3DNode *viewport() const;
144 void setHasIndividualDebugDraw();
145 physx::PxControllerManager *controllerManager();
146 Q_REVISION(6, 5) QQuick3DNode *scene() const;
147 Q_REVISION(6, 7) int numThreads() const;
148 Q_REVISION(6, 7) bool reportKinematicKinematicCollisions() const;
150 void setReportKinematicKinematicCollisions(bool newReportKinematicKinematicCollisions);
151 Q_REVISION(6, 7) bool reportStaticKinematicCollisions() const;
153 void setReportStaticKinematicCollisions(bool newReportStaticKinematicCollisions);
155 void cleanupRemovedJoints();
156
157 Q_REVISION(6, 13) QueryStructure staticQueryStructure() const;
158 Q_REVISION(6, 13) void setStaticQueryStructure(QueryStructure newStaticQueryStructure);
159
160 Q_REVISION(6, 13) QueryStructure dynamicQueryStructure() const;
161 Q_REVISION(6, 13) void setDynamicQueryStructure(QueryStructure newDynamicQueryStructure);
162
163 Q_REVISION(6, 13) Q_INVOKABLE bool testRaycastQuery(const QVector3D &origin,
164 const QVector3D &direction,
165 float maxDistance,
166 bool includeStatic = true,
167 bool includeDynamic = true) const;
168
169 Q_REVISION(6, 13) Q_INVOKABLE QQuick3DPhysicsLocationHit singleRaycastQuery(const QVector3D &origin,
170 const QVector3D &direction,
171 float maxDistance,
172 bool includeStatic = true,
173 bool includeDynamic = true) const;
174
175 Q_REVISION(6, 13) Q_INVOKABLE QList<QQuick3DPhysicsLocationHit> multiRaycastQuery(const QVector3D &origin,
176 const QVector3D &direction,
177 float maxDistance,
178 bool includeStatic = true,
179 bool includeDynamic = true) const;
180
181 Q_REVISION(6, 13) Q_INVOKABLE bool testSweepQuery(QAbstractCollisionShape *shape,
182 const QVector3D &direction,
183 float maxDistance,
184 bool includeStatic = true,
185 bool includeDynamic = true) const;
186
187 Q_REVISION(6, 13) Q_INVOKABLE QQuick3DPhysicsLocationHit singleSweepQuery(QAbstractCollisionShape *shape,
188 const QVector3D &direction,
189 float maxDistance,
190 bool includeStatic = true,
191 bool includeDynamic = true) const;
192
193 Q_REVISION(6, 13) Q_INVOKABLE QList<QQuick3DPhysicsLocationHit> multiSweepQuery(QAbstractCollisionShape *shape,
194 const QVector3D &direction,
195 float maxDistance,
196 bool includeStatic = true,
197 bool includeDynamic = true) const;
198
199 Q_REVISION(6, 13) Q_INVOKABLE bool testOverlapQuery(QAbstractCollisionShape *shape,
200 bool includeStatic = true,
201 bool includeDynamic = true) const;
202
203 Q_REVISION(6, 13) Q_INVOKABLE QList<QQuick3DPhysicsQueryHit> multiOverlapQuery(QAbstractCollisionShape *shape,
204 bool includeStatic = true,
205 bool includeDynamic = true) const;
207public slots:
208 void setGravity(QVector3D gravity);
209 void setRunning(bool running);
210 void setForceDebugDraw(bool forceDebugDraw);
211 void setEnableCCD(bool enableCCD);
212 void setTypicalLength(float typicalLength);
213 void setTypicalSpeed(float typicalSpeed);
214 void setDefaultDensity(float defaultDensity);
215 Q_REVISION(6, 5) void setViewport(QQuick3DNode *viewport);
216 Q_REVISION(6, 5) void setMinimumTimestep(float minTimestep);
217 Q_REVISION(6, 5) void setMaximumTimestep(float maxTimestep);
218 Q_REVISION(6, 5) void setScene(QQuick3DNode *newScene);
219 Q_REVISION(6, 7) void setNumThreads(int newNumThreads);
222 void gravityChanged(QVector3D gravity);
223 void runningChanged(bool running);
224 void enableCCDChanged(bool enableCCD);
225 void forceDebugDrawChanged(bool forceDebugDraw);
226 void typicalLengthChanged(float typicalLength);
227 void typicalSpeedChanged(float typicalSpeed);
228 void defaultDensityChanged(float defaultDensity);
229 Q_REVISION(6, 5) void viewportChanged(QQuick3DNode *viewport);
230 Q_REVISION(6, 5) void minimumTimestepChanged(float minimumTimestep);
231 Q_REVISION(6, 5) void maximumTimestepChanged(float maxTimestep);
232 Q_REVISION(6, 5) void frameDone(float timestep);
233 Q_REVISION(6, 5) void sceneChanged();
234 Q_REVISION(6, 7) void numThreadsChanged();
235 Q_REVISION(6, 7) void reportKinematicKinematicCollisionsChanged();
236 Q_REVISION(6, 7) void reportStaticKinematicCollisionsChanged();
237
238 Q_REVISION(6, 13) void staticQueryStructureChanged();
239 Q_REVISION(6, 13) void dynamicQueryStructureChanged();
240
241private:
242 static void registerRaycaster(QRaycaster *raycaster);
243 static void deregisterRaycaster(QRaycaster *raycaster);
244
245 QQuick3DPhysicsLocationHit
246 closestRaycastHit(const QVector3D &origin, const QVector3D &direction, float maxDistance,
247 bool includeStatic, bool includeDynamic,
248 QSpan<const QAbstractPhysicsNode *const> excludedBodies) const;
249
250 void simulateFrame();
251 void frameFinished(float deltaTime);
252 void frameFinishedDesignStudio();
253 void initPhysics();
254 void invalidateTriggerOverlaps(QSpan<QAbstractPhysXNode *const> rebuiltBodies);
255 void dropUnreportedTriggerOverlaps();
256 void cleanupRemovedNodes();
257 void updateDebugDraw();
258 void updateDebugDrawDesignStudio();
259 void setupDebugMaterials(QQuick3DNode *sceneNode);
260 void disableDebugDraw();
261 void matchOrphanNodes();
262 void matchOrphanJoints();
263 void matchOrphanRaycasters();
264 void findPhysicsNodes();
265 void emitContactCallbacks();
266
267 struct BodyContact
268 {
269 QAbstractPhysicsNode *sender = nullptr;
270 QAbstractPhysicsNode *receiver = nullptr;
271 QVector<QVector3D> positions;
272 QVector<QVector3D> impulses;
273 QVector<QVector3D> normals;
274 };
275
276 struct DebugModelHolder
277 {
278 QQuick3DModel *model = nullptr;
279 QQuick3DGeometry *geometry = nullptr;
280 QVector3D data;
281 void *ptr = nullptr;
282
283 void releaseMeshPointer();
284
285 const QVector3D &halfExtents() const;
286 void setHalfExtents(const QVector3D &halfExtents);
287
288 float radius() const;
289 void setRadius(float radius);
290
291 float heightScale() const;
292 void setHeightScale(float heightScale);
293
294 float halfHeight() const;
295 void setHalfHeight(float halfHeight);
296
297 float rowScale() const;
298 void setRowScale(float rowScale);
299
300 float columnScale() const;
301 void setColumnScale(float columnScale);
302
303 physx::PxConvexMesh *getConvexMesh();
304 void setConvexMesh(physx::PxConvexMesh *mesh);
305
306 physx::PxTriangleMesh *getTriangleMesh();
307 void setTriangleMesh(physx::PxTriangleMesh *mesh);
308
309 physx::PxHeightField *getHeightField();
310 void setHeightField(physx::PxHeightField *hf);
311 };
312
313 QList<QAbstractPhysXNode *> m_physXBodies;
314 QList<QPhysicsJoint *> m_joints;
315 QList<QRaycaster *> m_raycasters;
316 QList<QAbstractPhysicsNode *> m_newPhysicsNodes;
317 QHash<QPair<QAbstractCollisionShape *, QAbstractPhysicsNode *>, DebugModelHolder>
318 m_DesignStudioDebugModels;
319 QHash<QPair<QAbstractCollisionShape *, QAbstractPhysXNode *>, DebugModelHolder>
320 m_collisionShapeDebugModels;
321 QSet<QAbstractPhysicsNode *> m_removedPhysicsNodes;
322 QSet<physx::PxJoint *> m_removedJoints;
323 // Whether any trigger is holding shape pairs that are waiting to be reported
324 // again after the shapes on one side of them were replaced.
325 bool m_triggerOverlapsInvalidated = false;
326 QList<BodyContact> m_registeredContacts;
327
328 QVector3D m_gravity = QVector3D(0.f, -981.f, 0.f);
329 float m_typicalLength = 100.f; // 100 cm
330 float m_typicalSpeed = 1000.f; // 1000 cm/s
331 float m_defaultDensity = 0.001f; // 1 g/cm^3
332 float m_minTimestep = 1.0f; // 1000 fps
333 float m_maxTimestep = 33.333f; // 30 fps
334
335 bool m_running = true;
336 bool m_forceDebugDraw = false;
337 // For performance, used to keep track if we have indiviually enabled debug drawing for any
338 // collision shape
339 bool m_hasIndividualDebugDraw = false;
340 bool m_physicsInitialized = false;
341 bool m_enableCCD = false;
342
343 QPhysXWorld *m_physx = nullptr;
344 QQuick3DNode *m_viewport = nullptr;
345 QVector<QQuick3DPrincipledMaterial *> m_debugMaterials;
346
347 friend class QQuick3DPhysicsMesh; // TODO: better internal API
348 friend class QTriangleMeshShape; //####
349 friend class QHeightFieldShape;
350 friend class QQuick3DPhysicsHeightField;
351 friend class SimulationEventCallback;
352 friend class ControllerCallback;
353 static physx::PxPhysics *getPhysics();
354 static const physx::PxCookingParams *getCookingParams();
355 FrameAnimator *m_frameAnimator = nullptr;
356 QQuick3DNode *m_scene = nullptr;
357 bool m_inDesignStudio = false;
358 int m_numThreads = -1;
359 bool m_reportKinematicKinematicCollisions = false;
360 bool m_reportStaticKinematicCollisions = false;
361 QElapsedTimer m_timer;
362 float m_currTimeStep = 0.f;
363 QList<float> m_frameTimings;
364 bool m_frameFetched = false;
365 QueryStructure m_staticQueryStructure = QueryStructure::DynamicTree;
366 QueryStructure m_dynamicQueryStructure = QueryStructure::DynamicTree;
367
368 friend class QRaycaster;
369};
370
372
373#endif // PHYSICSWORLD_H
Q_ALWAYS_INLINE bool fuzzyEquals(const physx::PxTransform &a, const physx::PxTransform &b)
const QQuaternion kMinus90YawRotation
Q_ALWAYS_INLINE bool isFinite(const QVector3D &v)
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_INVOKABLE
#define Q_INTERFACES(x)
#define slots
#define signals
#define emit