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
qphysicscommands.cpp
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
8#include "PxPhysicsAPI.h"
9
10#include <QtGui/qquaternion.h>
11
13
14static bool isKinematicBody(physx::PxRigidBody &body)
15{
16 return static_cast<bool>(body.getRigidBodyFlags() & physx::PxRigidBodyFlag::eKINEMATIC);
17}
18
19
21 = default;
22
27
29 = default;
30
31void QPhysicsCommandApplyCentralForce::execute(const QDynamicRigidBody &rigidBody,
32 physx::PxRigidBody &body)
33{
34 Q_UNUSED(rigidBody)
35 if (isKinematicBody(body))
36 return;
37 body.addForce(QPhysicsUtils::toPhysXType(force));
38}
39
41 const QVector3D &inPosition)
43{
44}
45
47 = default;
48
49void QPhysicsCommandApplyForce::execute(const QDynamicRigidBody &rigidBody,
50 physx::PxRigidBody &body)
51{
52 Q_UNUSED(rigidBody)
53 if (isKinematicBody(body))
54 return;
55 physx::PxRigidBodyExt::addForceAtPos(body, QPhysicsUtils::toPhysXType(force),
56 QPhysicsUtils::toPhysXType(position));
57}
58
63
65 = default;
66
67void QPhysicsCommandApplyTorque::execute(const QDynamicRigidBody &rigidBody,
68 physx::PxRigidBody &body)
69{
70 Q_UNUSED(rigidBody)
71 if (isKinematicBody(body))
72 return;
73 body.addTorque(QPhysicsUtils::toPhysXType(torque));
74}
75
80
82 = default;
83
84void QPhysicsCommandApplyCentralImpulse::execute(const QDynamicRigidBody &rigidBody,
85 physx::PxRigidBody &body)
86{
87 Q_UNUSED(rigidBody)
88 if (isKinematicBody(body))
89 return;
90 body.addForce(QPhysicsUtils::toPhysXType(impulse), physx::PxForceMode::eIMPULSE);
91}
92
94 const QVector3D &inPosition)
96{
97}
98
100 = default;
101
102void QPhysicsCommandApplyImpulse::execute(const QDynamicRigidBody &rigidBody,
103 physx::PxRigidBody &body)
104{
105 Q_UNUSED(rigidBody)
106 if (isKinematicBody(body))
107 return;
108 physx::PxRigidBodyExt::addForceAtPos(body, QPhysicsUtils::toPhysXType(impulse),
109 QPhysicsUtils::toPhysXType(position),
110 physx::PxForceMode::eIMPULSE);
111}
112
117
119 = default;
120
121void QPhysicsCommandApplyTorqueImpulse::execute(const QDynamicRigidBody &rigidBody,
122 physx::PxRigidBody &body)
123{
124 Q_UNUSED(rigidBody)
125 if (isKinematicBody(body))
126 return;
127
128 body.addTorque(QPhysicsUtils::toPhysXType(impulse), physx::PxForceMode::eIMPULSE);
129}
130
136
138 = default;
139
140void QPhysicsCommandSetAngularVelocity::execute(const QDynamicRigidBody &rigidBody,
141 physx::PxRigidBody &body)
142{
143 Q_UNUSED(rigidBody)
144 body.setAngularVelocity(QPhysicsUtils::toPhysXType(angularVelocity));
145}
146
152
154 = default;
155
156void QPhysicsCommandSetLinearVelocity::execute(const QDynamicRigidBody &rigidBody,
157 physx::PxRigidBody &body)
158{
159 Q_UNUSED(rigidBody)
160 body.setLinearVelocity(QPhysicsUtils::toPhysXType(linearVelocity));
161}
162
164
166 = default;
167
168void QPhysicsCommandSetMass::execute(const QDynamicRigidBody &rigidBody, physx::PxRigidBody &body)
169{
170 if (rigidBody.hasStaticShapes()) {
171 qWarning() << "Cannot set mass or density on a body containing trimesh/heightfield/plane, "
172 "ignoring.";
173 return;
174 }
175
176 physx::PxRigidBodyExt::setMassAndUpdateInertia(body, mass);
177}
178
179void QPhysicsCommandSetMassAndInertiaTensor::execute(const QDynamicRigidBody &rigidBody,
180 physx::PxRigidBody &body)
181{
182 if (rigidBody.hasStaticShapes()) {
183 qWarning() << "Cannot set mass or density on a body containing trimesh/heightfield/plane, "
184 "ignoring.";
185 return;
186 }
187
188 body.setMass(mass);
189 body.setCMassLocalPose(
190 physx::PxTransform(QPhysicsUtils::toPhysXType(rigidBody.centerOfMassPosition()),
191 QPhysicsUtils::toPhysXType(rigidBody.centerOfMassRotation())));
192 body.setMassSpaceInertiaTensor(QPhysicsUtils::toPhysXType(inertia));
193}
194
196 float inMass, const QMatrix3x3 &inInertia)
197 : QPhysicsCommand(), mass(inMass), inertia(inInertia)
198{
199}
200
202 = default;
203
204void QPhysicsCommandSetMassAndInertiaMatrix::execute(const QDynamicRigidBody &rigidBody,
205 physx::PxRigidBody &body)
206{
207 if (rigidBody.hasStaticShapes()) {
208 qWarning() << "Cannot set mass or density on a body containing trimesh/heightfield/plane, "
209 "ignoring.";
210 return;
211 }
212
213 physx::PxQuat massFrame;
214 physx::PxVec3 diagTensor = physx::PxDiagonalize(QPhysicsUtils::toPhysXType(inertia), massFrame);
215 if ((diagTensor.x <= 0.0f) || (diagTensor.y <= 0.0f) || (diagTensor.z <= 0.0f))
216 return; // FIXME: print error?
217
218 body.setCMassLocalPose(physx::PxTransform(
219 QPhysicsUtils::toPhysXType(rigidBody.centerOfMassPosition()), massFrame));
220 body.setMass(mass);
221 body.setMassSpaceInertiaTensor(diagTensor);
222}
223
225 : QPhysicsCommand(), density(inDensity)
226{
227}
228
230 = default;
231
232void QPhysicsCommandSetDensity::execute(const QDynamicRigidBody &rigidBody,
233 physx::PxRigidBody &body)
234{
235 if (rigidBody.hasStaticShapes()) {
236 qWarning() << "Cannot set mass or density on a body containing trimesh/heightfield/plane, "
237 "ignoring.";
238 return;
239 }
240
241 const float clampedDensity = qMax(0.0000001, density);
242 if (clampedDensity != density) {
243 qWarning() << "Clamping density " << density;
244 return;
245 }
246
247 physx::PxRigidBodyExt::updateMassAndInertia(body, clampedDensity);
248}
249
251 : QPhysicsCommand(), isKinematic(inIsKinematic)
252{
253}
254
256 = default;
257
258void QPhysicsCommandSetIsKinematic::execute(const QDynamicRigidBody &rigidBody,
259 physx::PxRigidBody &body)
260{
261 if (rigidBody.hasStaticShapes() && !isKinematic) {
262 qWarning() << "Cannot make a body containing trimesh/heightfield/plane non-kinematic, "
263 "ignoring.";
264 return;
265 }
266
267 body.setRigidBodyFlag(physx::PxRigidBodyFlag::eKINEMATIC, isKinematic);
268}
269
271 : QPhysicsCommand(), gravityEnabled(inGravityEnabled)
272{
273}
274
276 = default;
277
278void QPhysicsCommandSetGravityEnabled::execute(const QDynamicRigidBody &rigidBody,
279 physx::PxRigidBody &body)
280{
281 Q_UNUSED(rigidBody)
282 body.setActorFlag(physx::PxActorFlag::eDISABLE_GRAVITY, !gravityEnabled);
283}
284
285QPhysicsCommandReset::QPhysicsCommandReset(QVector3D inPosition, QVector3D inEulerRotation)
287{
288}
289
291 = default;
292
293void QPhysicsCommandReset::execute(const QDynamicRigidBody &rigidBody, physx::PxRigidBody &body)
294{
295 Q_UNUSED(rigidBody)
296 body.setLinearVelocity(physx::PxVec3(0, 0, 0));
297 body.setAngularVelocity(physx::PxVec3(0, 0, 0));
298
299 auto *parentNode = rigidBody.parentNode();
300 QVector3D scenePosition = parentNode ? parentNode->mapPositionToScene(position) : position;
301 // TODO: rotation also needs to be mapped
302
303 body.setGlobalPose(physx::PxTransform(
304 QPhysicsUtils::toPhysXType(scenePosition),
305 QPhysicsUtils::toPhysXType(QQuaternion::fromEulerAngles(eulerRotation))));
306}
307
309 float inMass, const QVector3D &inInertia)
310 : QPhysicsCommand(), mass(inMass), inertia(inInertia)
311{
312}
313
315 = default;
316
317QT_END_NAMESPACE
QPhysicsCommandApplyCentralForce(const QVector3D &inForce)
void execute(const QDynamicRigidBody &rigidBody, physx::PxRigidBody &body) override
QPhysicsCommandApplyCentralImpulse(const QVector3D &inImpulse)
void execute(const QDynamicRigidBody &rigidBody, physx::PxRigidBody &body) override
QPhysicsCommandApplyForce(const QVector3D &inForce, const QVector3D &inPosition)
~QPhysicsCommandApplyForce() override
void execute(const QDynamicRigidBody &rigidBody, physx::PxRigidBody &body) override
void execute(const QDynamicRigidBody &rigidBody, physx::PxRigidBody &body) override
~QPhysicsCommandApplyImpulse() override
QPhysicsCommandApplyImpulse(const QVector3D &inImpulse, const QVector3D &inPosition)
QPhysicsCommandApplyTorqueImpulse(const QVector3D &inImpulse)
void execute(const QDynamicRigidBody &rigidBody, physx::PxRigidBody &body) override
void execute(const QDynamicRigidBody &rigidBody, physx::PxRigidBody &body) override
~QPhysicsCommandApplyTorque() override
QPhysicsCommandApplyTorque(const QVector3D &inTorque)
void execute(const QDynamicRigidBody &rigidBody, physx::PxRigidBody &body) override
~QPhysicsCommandReset() override
QPhysicsCommandReset(QVector3D inPosition, QVector3D inEulerRotation)
QPhysicsCommandSetAngularVelocity(const QVector3D &inAngularVelocity)
void execute(const QDynamicRigidBody &rigidBody, physx::PxRigidBody &body) override
QPhysicsCommandSetDensity(float inDensity)
~QPhysicsCommandSetDensity() override
void execute(const QDynamicRigidBody &rigidBody, physx::PxRigidBody &body) override
QPhysicsCommandSetGravityEnabled(bool inGravityEnabled)
void execute(const QDynamicRigidBody &rigidBody, physx::PxRigidBody &body) override
void execute(const QDynamicRigidBody &rigidBody, physx::PxRigidBody &body) override
~QPhysicsCommandSetIsKinematic() override
QPhysicsCommandSetIsKinematic(bool inIsKinematic)
void execute(const QDynamicRigidBody &rigidBody, physx::PxRigidBody &body) override
QPhysicsCommandSetLinearVelocity(const QVector3D &inLinearVelocity)
QPhysicsCommandSetMassAndInertiaMatrix(float inMass, const QMatrix3x3 &inInertia)
void execute(const QDynamicRigidBody &rigidBody, physx::PxRigidBody &body) override
void execute(const QDynamicRigidBody &rigidBody, physx::PxRigidBody &body) override
QPhysicsCommandSetMassAndInertiaTensor(float inMass, const QVector3D &inInertia)
QPhysicsCommandSetMass(float inMass)
~QPhysicsCommandSetMass() override
void execute(const QDynamicRigidBody &rigidBody, physx::PxRigidBody &body) override
virtual ~QPhysicsCommand()
static QT_BEGIN_NAMESPACE bool isKinematicBody(physx::PxRigidBody &body)