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
4#ifndef PHYSICSWORLD_H
5#define PHYSICSWORLD_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <QtQuick3DPhysics/qtquick3dphysicsglobal.h>
19
20#include <QtCore/QLoggingCategory>
21#include <QtCore/QObject>
22#include <QtCore/QTimerEvent>
23#include <QtCore/QElapsedTimer>
24#include <QtGui/QVector3D>
25#include <QtQml/qqml.h>
26#include <QBasicTimer>
27
28#include <QtQuick3D/private/qquick3dviewport_p.h>
29
30namespace physx {
31class PxMaterial;
32class PxPhysics;
33class PxShape;
34class PxRigidDynamic;
35class PxRigidActor;
36class PxRigidStatic;
37class PxCooking;
38class PxControllerManager;
39class PxConvexMesh;
40class PxTriangleMesh;
41class PxHeightField;
42}
43
45
47
48class QAbstractPhysicsNode;
49class QAbstractCollisionShape;
50class QAbstractRigidBody;
52class QQuick3DModel;
53class QQuick3DGeometry;
54class QQuick3DPrincipledMaterial;
55class QPhysXWorld;
56class FrameAnimator;
57
58class Q_QUICK3DPHYSICS_EXPORT QPhysicsWorld : public QObject, public QQmlParserStatus
59{
60 Q_OBJECT
61 Q_INTERFACES(QQmlParserStatus)
62 Q_PROPERTY(QVector3D gravity READ gravity WRITE setGravity NOTIFY gravityChanged)
63 Q_PROPERTY(bool running READ running WRITE setRunning NOTIFY runningChanged)
64 Q_PROPERTY(bool forceDebugDraw READ forceDebugDraw WRITE setForceDebugDraw NOTIFY
65 forceDebugDrawChanged)
66 Q_PROPERTY(bool enableCCD READ enableCCD WRITE setEnableCCD NOTIFY enableCCDChanged)
67 Q_PROPERTY(float typicalLength READ typicalLength WRITE setTypicalLength NOTIFY
68 typicalLengthChanged)
69 Q_PROPERTY(
70 float typicalSpeed READ typicalSpeed WRITE setTypicalSpeed NOTIFY typicalSpeedChanged)
71 Q_PROPERTY(float defaultDensity READ defaultDensity WRITE setDefaultDensity NOTIFY
72 defaultDensityChanged)
73 Q_PROPERTY(QQuick3DNode *viewport READ viewport WRITE setViewport NOTIFY viewportChanged
74 REVISION(6, 5))
75 Q_PROPERTY(float minimumTimestep READ minimumTimestep WRITE setMinimumTimestep NOTIFY
76 minimumTimestepChanged REVISION(6, 5))
77 Q_PROPERTY(float maximumTimestep READ maximumTimestep WRITE setMaximumTimestep NOTIFY
78 maximumTimestepChanged REVISION(6, 5))
79 Q_PROPERTY(QQuick3DNode *scene READ scene WRITE setScene NOTIFY sceneChanged REVISION(6, 5))
80 Q_PROPERTY(int numThreads READ numThreads WRITE setNumThreads NOTIFY numThreadsChanged
81 REVISION(6, 7))
82 Q_PROPERTY(bool reportKinematicKinematicCollisions READ reportKinematicKinematicCollisions WRITE
83 setReportKinematicKinematicCollisions NOTIFY
84 reportKinematicKinematicCollisionsChanged FINAL REVISION(6, 7))
85 Q_PROPERTY(bool reportStaticKinematicCollisions READ reportStaticKinematicCollisions WRITE
86 setReportStaticKinematicCollisions NOTIFY
87 reportStaticKinematicCollisionsChanged FINAL REVISION(6, 7))
88
89 QML_NAMED_ELEMENT(PhysicsWorld)
90
91public:
92 explicit QPhysicsWorld(QObject *parent = nullptr);
93 ~QPhysicsWorld();
94
95 void classBegin() override;
96 void componentComplete() override;
97
98 QVector3D gravity() const;
99
100 bool running() const;
101 bool forceDebugDraw() const;
102 bool enableCCD() const;
103 float typicalLength() const;
104 float typicalSpeed() const;
105 float defaultDensity() const;
106 Q_REVISION(6, 5) float minimumTimestep() const;
107 Q_REVISION(6, 5) float maximumTimestep() const;
108
109 bool isNodeRemoved(QAbstractPhysicsNode *object);
110
111 static QPhysicsWorld *getWorld(QQuick3DNode *node);
112
113 static void registerNode(QAbstractPhysicsNode *physicsNode);
114 static void deregisterNode(QAbstractPhysicsNode *physicsNode);
115
116 void registerContact(QAbstractPhysicsNode *sender, QAbstractPhysicsNode *receiver,
117 const QVector<QVector3D> &positions, const QVector<QVector3D> &impulses,
118 const QVector<QVector3D> &normals);
119
120 Q_REVISION(6, 5) QQuick3DNode *viewport() const;
121 void setHasIndividualDebugDraw();
122 physx::PxControllerManager *controllerManager();
123 Q_REVISION(6, 5) QQuick3DNode *scene() const;
124 Q_REVISION(6, 7) int numThreads() const;
125 Q_REVISION(6, 7) bool reportKinematicKinematicCollisions() const;
126 Q_REVISION(6, 7)
127 void setReportKinematicKinematicCollisions(bool newReportKinematicKinematicCollisions);
128 Q_REVISION(6, 7) bool reportStaticKinematicCollisions() const;
129 Q_REVISION(6, 7)
130 void setReportStaticKinematicCollisions(bool newReportStaticKinematicCollisions);
131
132public slots:
133 void setGravity(QVector3D gravity);
134 void setRunning(bool running);
135 void setForceDebugDraw(bool forceDebugDraw);
136 void setEnableCCD(bool enableCCD);
137 void setTypicalLength(float typicalLength);
138 void setTypicalSpeed(float typicalSpeed);
139 void setDefaultDensity(float defaultDensity);
140 Q_REVISION(6, 5) void setViewport(QQuick3DNode *viewport);
141 Q_REVISION(6, 5) void setMinimumTimestep(float minTimestep);
142 Q_REVISION(6, 5) void setMaximumTimestep(float maxTimestep);
143 Q_REVISION(6, 5) void setScene(QQuick3DNode *newScene);
144 Q_REVISION(6, 7) void setNumThreads(int newNumThreads);
145
146signals:
147 void gravityChanged(QVector3D gravity);
148 void runningChanged(bool running);
149 void enableCCDChanged(bool enableCCD);
150 void forceDebugDrawChanged(bool forceDebugDraw);
151 void typicalLengthChanged(float typicalLength);
152 void typicalSpeedChanged(float typicalSpeed);
153 void defaultDensityChanged(float defaultDensity);
154 Q_REVISION(6, 5) void viewportChanged(QQuick3DNode *viewport);
155 Q_REVISION(6, 5) void minimumTimestepChanged(float minimumTimestep);
156 Q_REVISION(6, 5) void maximumTimestepChanged(float maxTimestep);
157 Q_REVISION(6, 5) void frameDone(float timestep);
158 Q_REVISION(6, 5) void sceneChanged();
159 Q_REVISION(6, 7) void numThreadsChanged();
160 Q_REVISION(6, 7) void reportKinematicKinematicCollisionsChanged();
161 Q_REVISION(6, 7) void reportStaticKinematicCollisionsChanged();
162
163private:
164 void simulateFrame();
165 void frameFinished(float deltaTime);
166 void frameFinishedDesignStudio();
167 void initPhysics();
168 void cleanupRemovedNodes();
169 void updateDebugDraw();
170 void updateDebugDrawDesignStudio();
171 void setupDebugMaterials(QQuick3DNode *sceneNode);
172 void disableDebugDraw();
173 void matchOrphanNodes();
174 void findPhysicsNodes();
175 void emitContactCallbacks();
176
177 struct BodyContact
178 {
179 QAbstractPhysicsNode *sender = nullptr;
180 QAbstractPhysicsNode *receiver = nullptr;
181 QVector<QVector3D> positions;
182 QVector<QVector3D> impulses;
183 QVector<QVector3D> normals;
184 };
185
186 struct DebugModelHolder
187 {
188 QQuick3DModel *model = nullptr;
189 QQuick3DGeometry *geometry = nullptr;
190 QVector3D data;
191 void *ptr = nullptr;
192
193 void releaseMeshPointer();
194
195 const QVector3D &halfExtents() const;
196 void setHalfExtents(const QVector3D &halfExtents);
197
198 float radius() const;
199 void setRadius(float radius);
200
201 float heightScale() const;
202 void setHeightScale(float heightScale);
203
204 float halfHeight() const;
205 void setHalfHeight(float halfHeight);
206
207 float rowScale() const;
208 void setRowScale(float rowScale);
209
210 float columnScale() const;
211 void setColumnScale(float columnScale);
212
213 physx::PxConvexMesh *getConvexMesh();
214 void setConvexMesh(physx::PxConvexMesh *mesh);
215
216 physx::PxTriangleMesh *getTriangleMesh();
217 void setTriangleMesh(physx::PxTriangleMesh *mesh);
218
219 physx::PxHeightField *getHeightField();
220 void setHeightField(physx::PxHeightField *hf);
221 };
222
223 QList<QAbstractPhysXNode *> m_physXBodies;
224 QList<QAbstractPhysicsNode *> m_newPhysicsNodes;
225 QHash<QPair<QAbstractCollisionShape *, QAbstractPhysicsNode *>, DebugModelHolder>
226 m_DesignStudioDebugModels;
227 QHash<QPair<QAbstractCollisionShape *, QAbstractPhysXNode *>, DebugModelHolder>
228 m_collisionShapeDebugModels;
229 QSet<QAbstractPhysicsNode *> m_removedPhysicsNodes;
230 QMutex m_removedPhysicsNodesMutex;
231 QList<BodyContact> m_registeredContacts;
232
233 QVector3D m_gravity = QVector3D(0.f, -981.f, 0.f);
234 float m_typicalLength = 100.f; // 100 cm
235 float m_typicalSpeed = 1000.f; // 1000 cm/s
236 float m_defaultDensity = 0.001f; // 1 g/cm^3
237 float m_minTimestep = 1.0f; // 1000 fps
238 float m_maxTimestep = 33.333f; // 30 fps
239
240 bool m_running = true;
241 bool m_forceDebugDraw = false;
242 // For performance, used to keep track if we have indiviually enabled debug drawing for any
243 // collision shape
244 bool m_hasIndividualDebugDraw = false;
245 bool m_physicsInitialized = false;
246 bool m_enableCCD = false;
247
248 QPhysXWorld *m_physx = nullptr;
249 QQuick3DNode *m_viewport = nullptr;
250 QVector<QQuick3DPrincipledMaterial *> m_debugMaterials;
251
252 friend class QQuick3DPhysicsMesh; // TODO: better internal API
253 friend class QTriangleMeshShape; //####
254 friend class QHeightFieldShape;
255 friend class QQuick3DPhysicsHeightField;
256 friend class SimulationEventCallback;
257 friend class ControllerCallback;
258 static physx::PxPhysics *getPhysics();
259 static physx::PxCooking *getCooking();
260 FrameAnimator *m_frameAnimator = nullptr;
261 QQuick3DNode *m_scene = nullptr;
262 bool m_inDesignStudio = false;
263 int m_numThreads = -1;
264 bool m_reportKinematicKinematicCollisions = false;
265 bool m_reportStaticKinematicCollisions = false;
266 QElapsedTimer m_timer;
267 float m_currTimeStep = 0.f;
268 QList<float> m_frameTimings;
269 bool m_frameFetched = false;
270};
271
273
274#endif // PHYSICSWORLD_H
QAbstractPhysicsNode * frontendNode
virtual void cleanup(QPhysXWorld *)
physx::PxMaterial * material
QPhysXCharacterController(QCharacterController *frontEnd)
DebugDrawBodyType getDebugDrawBodyType() override
void init(QPhysicsWorld *world, QPhysXWorld *physX) override
void cleanup(QPhysXWorld *physX) override
void createMaterial(QPhysXWorld *physX) override
void sync(float deltaTime, QHash< QQuick3DNode *, QMatrix4x4 > &transformCache) override
#define PHYSX_RELEASE(x)
DebugDrawBodyType
QT_BEGIN_NAMESPACE Q_DECLARE_LOGGING_CATEGORY(lcQuick3dPhysics)
#define QT_BEGIN_NAMESPACE
#define QT_END_NAMESPACE