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))
91
92 QML_NAMED_ELEMENT(PhysicsWorld)
93
94public:
95 explicit QPhysicsWorld(QObject *parent = nullptr);
96 ~QPhysicsWorld();
97
98 void classBegin() override;
99 void componentComplete() override;
101 QVector3D gravity() const;
102
103 bool running() const;
104 bool forceDebugDraw() const;
105 bool enableCCD() const;
106 float typicalLength() const;
107 float typicalSpeed() const;
108 float defaultDensity() const;
109 Q_REVISION(6, 5) float minimumTimestep() const;
110 Q_REVISION(6, 5) float maximumTimestep() const;
111
112 bool isNodeRemoved(QAbstractPhysicsNode *object);
113
114 static QPhysicsWorld *getWorld(QQuick3DNode *node);
115 static QPhysicsWorld *getWorld(QPhysicsJoint *joint);
116
117 static void registerNode(QAbstractPhysicsNode *physicsNode);
118 static void deregisterNode(QAbstractPhysicsNode *physicsNode);
119
120 static void registerJoint(QPhysicsJoint *joint);
121 static void deregisterJoint(QPhysicsJoint *joint);
123 void registerContact(QAbstractPhysicsNode *sender, QAbstractPhysicsNode *receiver,
124 const QVector<QVector3D> &positions, const QVector<QVector3D> &impulses,
125 const QVector<QVector3D> &normals);
126
127 Q_REVISION(6, 5) QQuick3DNode *viewport() const;
128 void setHasIndividualDebugDraw();
129 physx::PxControllerManager *controllerManager();
130 Q_REVISION(6, 5) QQuick3DNode *scene() const;
131 Q_REVISION(6, 7) int numThreads() const;
132 Q_REVISION(6, 7) bool reportKinematicKinematicCollisions() const;
133 Q_REVISION(6, 7)
134 void setReportKinematicKinematicCollisions(bool newReportKinematicKinematicCollisions);
135 Q_REVISION(6, 7) bool reportStaticKinematicCollisions() const;
136 Q_REVISION(6, 7)
137 void setReportStaticKinematicCollisions(bool newReportStaticKinematicCollisions);
138
139 void cleanupRemovedJoints();
141public slots:
142 void setGravity(QVector3D gravity);
143 void setRunning(bool running);
144 void setForceDebugDraw(bool forceDebugDraw);
145 void setEnableCCD(bool enableCCD);
146 void setTypicalLength(float typicalLength);
147 void setTypicalSpeed(float typicalSpeed);
148 void setDefaultDensity(float defaultDensity);
149 Q_REVISION(6, 5) void setViewport(QQuick3DNode *viewport);
150 Q_REVISION(6, 5) void setMinimumTimestep(float minTimestep);
151 Q_REVISION(6, 5) void setMaximumTimestep(float maxTimestep);
152 Q_REVISION(6, 5) void setScene(QQuick3DNode *newScene);
153 Q_REVISION(6, 7) void setNumThreads(int newNumThreads);
156 void gravityChanged(QVector3D gravity);
157 void runningChanged(bool running);
158 void enableCCDChanged(bool enableCCD);
159 void forceDebugDrawChanged(bool forceDebugDraw);
160 void typicalLengthChanged(float typicalLength);
161 void typicalSpeedChanged(float typicalSpeed);
162 void defaultDensityChanged(float defaultDensity);
163 Q_REVISION(6, 5) void viewportChanged(QQuick3DNode *viewport);
164 Q_REVISION(6, 5) void minimumTimestepChanged(float minimumTimestep);
165 Q_REVISION(6, 5) void maximumTimestepChanged(float maxTimestep);
166 Q_REVISION(6, 5) void frameDone(float timestep);
167 Q_REVISION(6, 5) void sceneChanged();
168 Q_REVISION(6, 7) void numThreadsChanged();
169 Q_REVISION(6, 7) void reportKinematicKinematicCollisionsChanged();
170 Q_REVISION(6, 7) void reportStaticKinematicCollisionsChanged();
171
172private:
173 void simulateFrame();
174 void frameFinished(float deltaTime);
175 void frameFinishedDesignStudio();
176 void initPhysics();
177 void cleanupRemovedNodes();
178 void updateDebugDraw();
179 void updateDebugDrawDesignStudio();
180 void setupDebugMaterials(QQuick3DNode *sceneNode);
181 void disableDebugDraw();
182 void matchOrphanNodes();
183 void matchOrphanJoints();
184 void findPhysicsNodes();
185 void emitContactCallbacks();
186
187 struct BodyContact
188 {
189 QAbstractPhysicsNode *sender = nullptr;
190 QAbstractPhysicsNode *receiver = nullptr;
191 QVector<QVector3D> positions;
192 QVector<QVector3D> impulses;
193 QVector<QVector3D> normals;
194 };
195
196 struct DebugModelHolder
197 {
198 QQuick3DModel *model = nullptr;
199 QQuick3DGeometry *geometry = nullptr;
200 QVector3D data;
201 void *ptr = nullptr;
202
203 void releaseMeshPointer();
204
205 const QVector3D &halfExtents() const;
206 void setHalfExtents(const QVector3D &halfExtents);
207
208 float radius() const;
209 void setRadius(float radius);
210
211 float heightScale() const;
212 void setHeightScale(float heightScale);
213
214 float halfHeight() const;
215 void setHalfHeight(float halfHeight);
216
217 float rowScale() const;
218 void setRowScale(float rowScale);
219
220 float columnScale() const;
221 void setColumnScale(float columnScale);
222
223 physx::PxConvexMesh *getConvexMesh();
224 void setConvexMesh(physx::PxConvexMesh *mesh);
225
226 physx::PxTriangleMesh *getTriangleMesh();
227 void setTriangleMesh(physx::PxTriangleMesh *mesh);
228
229 physx::PxHeightField *getHeightField();
230 void setHeightField(physx::PxHeightField *hf);
231 };
232
233 QList<QAbstractPhysXNode *> m_physXBodies;
234 QList<QPhysicsJoint *> m_joints;
235 QList<QAbstractPhysicsNode *> m_newPhysicsNodes;
236 QHash<QPair<QAbstractCollisionShape *, QAbstractPhysicsNode *>, DebugModelHolder>
237 m_DesignStudioDebugModels;
238 QHash<QPair<QAbstractCollisionShape *, QAbstractPhysXNode *>, DebugModelHolder>
239 m_collisionShapeDebugModels;
240 QSet<QAbstractPhysicsNode *> m_removedPhysicsNodes;
241 QSet<physx::PxJoint *> m_removedJoints;
242 QMutex m_removedPhysicsNodesMutex;
243 QList<BodyContact> m_registeredContacts;
244
245 QVector3D m_gravity = QVector3D(0.f, -981.f, 0.f);
246 float m_typicalLength = 100.f; // 100 cm
247 float m_typicalSpeed = 1000.f; // 1000 cm/s
248 float m_defaultDensity = 0.001f; // 1 g/cm^3
249 float m_minTimestep = 1.0f; // 1000 fps
250 float m_maxTimestep = 33.333f; // 30 fps
251
252 bool m_running = true;
253 bool m_forceDebugDraw = false;
254 // For performance, used to keep track if we have indiviually enabled debug drawing for any
255 // collision shape
256 bool m_hasIndividualDebugDraw = false;
257 bool m_physicsInitialized = false;
258 bool m_enableCCD = false;
260 QPhysXWorld *m_physx = nullptr;
261 QQuick3DNode *m_viewport = nullptr;
262 QVector<QQuick3DPrincipledMaterial *> m_debugMaterials;
263
264 friend class QQuick3DPhysicsMesh; // TODO: better internal API
265 friend class QTriangleMeshShape; //####
266 friend class QHeightFieldShape;
267 friend class QQuick3DPhysicsHeightField;
268 friend class SimulationEventCallback;
269 friend class ControllerCallback;
270 static physx::PxPhysics *getPhysics();
271 static physx::PxCooking *getCooking();
272 FrameAnimator *m_frameAnimator = nullptr;
273 QQuick3DNode *m_scene = nullptr;
274 bool m_inDesignStudio = false;
275 int m_numThreads = -1;
276 bool m_reportKinematicKinematicCollisions = false;
277 bool m_reportStaticKinematicCollisions = false;
278 QElapsedTimer m_timer;
279 float m_currTimeStep = 0.f;
280 QList<float> m_frameTimings;
281 bool m_frameFetched = false;
282};
283
285
286#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_PROPERTY(...)
#define Q_OBJECT
#define Q_REVISION(...)
#define Q_INTERFACES(x)
#define slots
#define signals
#define emit