Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
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
4#include "qphysicsworld_p.h"
6#include "qphysicsutils_p.h"
8#include "PxPhysicsAPI.h"
9
11
12static bool isKinematicBody(physx::PxRigidBody &body)
13{
14 return static_cast<bool>(body.getRigidBodyFlags() & physx::PxRigidBodyFlag::eKINEMATIC);
15}
16
21
23 physx::PxRigidBody &body)
24{
25 Q_UNUSED(rigidBody)
26 if (isKinematicBody(body))
27 return;
28 body.addForce(QPhysicsUtils::toPhysXType(force));
29}
30
32 const QVector3D &inPosition)
33 : QPhysicsCommand(), force(inForce), position(inPosition)
34{
35}
36
38 physx::PxRigidBody &body)
39{
40 Q_UNUSED(rigidBody)
41 if (isKinematicBody(body))
42 return;
43 physx::PxRigidBodyExt::addForceAtPos(body, QPhysicsUtils::toPhysXType(force),
45}
46
51
53 physx::PxRigidBody &body)
54{
55 Q_UNUSED(rigidBody)
56 if (isKinematicBody(body))
57 return;
58 body.addTorque(QPhysicsUtils::toPhysXType(torque));
59}
60
65
67 physx::PxRigidBody &body)
68{
69 Q_UNUSED(rigidBody)
70 if (isKinematicBody(body))
71 return;
72 body.addForce(QPhysicsUtils::toPhysXType(impulse), physx::PxForceMode::eIMPULSE);
73}
74
76 const QVector3D &inPosition)
77 : QPhysicsCommand(), impulse(inImpulse), position(inPosition)
78{
79}
80
82 physx::PxRigidBody &body)
83{
84 Q_UNUSED(rigidBody)
85 if (isKinematicBody(body))
86 return;
87 physx::PxRigidBodyExt::addForceAtPos(body, QPhysicsUtils::toPhysXType(impulse),
89 physx::PxForceMode::eIMPULSE);
90}
91
96
98 physx::PxRigidBody &body)
99{
100 Q_UNUSED(rigidBody)
101 if (isKinematicBody(body))
102 return;
103
104 body.addTorque(QPhysicsUtils::toPhysXType(impulse), physx::PxForceMode::eIMPULSE);
105}
106
108 const QVector3D &inAngularVelocity)
109 : QPhysicsCommand(), angularVelocity(inAngularVelocity)
110{
111}
112
114 physx::PxRigidBody &body)
115{
116 Q_UNUSED(rigidBody)
117 body.setAngularVelocity(QPhysicsUtils::toPhysXType(angularVelocity));
118}
119
121 const QVector3D &inLinearVelocity)
122 : QPhysicsCommand(), linearVelocity(inLinearVelocity)
123{
124}
125
127 physx::PxRigidBody &body)
128{
129 Q_UNUSED(rigidBody)
130 body.setLinearVelocity(QPhysicsUtils::toPhysXType(linearVelocity));
131}
132
134
135void QPhysicsCommandSetMass::execute(const QDynamicRigidBody &rigidBody, physx::PxRigidBody &body)
136{
137 if (rigidBody.hasStaticShapes()) {
138 qWarning() << "Cannot set mass or density on a body containing trimesh/heightfield/plane, "
139 "ignoring.";
140 return;
141 }
142
143 physx::PxRigidBodyExt::setMassAndUpdateInertia(body, mass);
144}
145
147 physx::PxRigidBody &body)
148{
149 if (rigidBody.hasStaticShapes()) {
150 qWarning() << "Cannot set mass or density on a body containing trimesh/heightfield/plane, "
151 "ignoring.";
152 return;
153 }
154
155 body.setMass(mass);
156 body.setCMassLocalPose(
157 physx::PxTransform(QPhysicsUtils::toPhysXType(rigidBody.centerOfMassPosition()),
158 QPhysicsUtils::toPhysXType(rigidBody.centerOfMassRotation())));
159 body.setMassSpaceInertiaTensor(QPhysicsUtils::toPhysXType(inertia));
160}
161
163 float inMass, const QMatrix3x3 &inInertia)
164 : QPhysicsCommand(), mass(inMass), inertia(inInertia)
165{
166}
167
169 physx::PxRigidBody &body)
170{
171 if (rigidBody.hasStaticShapes()) {
172 qWarning() << "Cannot set mass or density on a body containing trimesh/heightfield/plane, "
173 "ignoring.";
174 return;
175 }
176
177 physx::PxQuat massFrame;
178 physx::PxVec3 diagTensor = physx::PxDiagonalize(QPhysicsUtils::toPhysXType(inertia), massFrame);
179 if ((diagTensor.x <= 0.0f) || (diagTensor.y <= 0.0f) || (diagTensor.z <= 0.0f))
180 return; // FIXME: print error?
181
182 body.setCMassLocalPose(physx::PxTransform(
183 QPhysicsUtils::toPhysXType(rigidBody.centerOfMassPosition()), massFrame));
184 body.setMass(mass);
185 body.setMassSpaceInertiaTensor(diagTensor);
186}
187
189 : QPhysicsCommand(), density(inDensity)
190{
191}
192
194 physx::PxRigidBody &body)
195{
196 if (rigidBody.hasStaticShapes()) {
197 qWarning() << "Cannot set mass or density on a body containing trimesh/heightfield/plane, "
198 "ignoring.";
199 return;
200 }
201
202 const float clampedDensity = qMax(0.0000001, density);
203 if (clampedDensity != density) {
204 qWarning() << "Clamping density " << density;
205 return;
206 }
207
208 physx::PxRigidBodyExt::updateMassAndInertia(body, clampedDensity);
209}
210
212 : QPhysicsCommand(), isKinematic(inIsKinematic)
213{
214}
215
217 physx::PxRigidBody &body)
218{
219 if (rigidBody.hasStaticShapes() && !isKinematic) {
220 qWarning() << "Cannot make a body containing trimesh/heightfield/plane non-kinematic, "
221 "ignoring.";
222 return;
223 }
224
225 body.setRigidBodyFlag(physx::PxRigidBodyFlag::eKINEMATIC, isKinematic);
226}
227
229 : QPhysicsCommand(), gravityEnabled(inGravityEnabled)
230{
231}
232
234 physx::PxRigidBody &body)
235{
236 Q_UNUSED(rigidBody)
237 body.setActorFlag(physx::PxActorFlag::eDISABLE_GRAVITY, !gravityEnabled);
238}
239
241 : QPhysicsCommand(), position(inPosition), eulerRotation(inEulerRotation)
242{
243}
244
245void QPhysicsCommandReset::execute(const QDynamicRigidBody &rigidBody, physx::PxRigidBody &body)
246{
247 Q_UNUSED(rigidBody)
248 body.setLinearVelocity(physx::PxVec3(0, 0, 0));
249 body.setAngularVelocity(physx::PxVec3(0, 0, 0));
250
251 auto *parentNode = rigidBody.parentNode();
252 QVector3D scenePosition = parentNode ? parentNode->mapPositionToScene(position) : position;
253 // TODO: rotation also needs to be mapped
254
255 body.setGlobalPose(physx::PxTransform(
256 QPhysicsUtils::toPhysXType(scenePosition),
257 QPhysicsUtils::toPhysXType(QQuaternion::fromEulerAngles(eulerRotation))));
258}
259
261 float inMass, const QVector3D &inInertia)
262 : QPhysicsCommand(), mass(inMass), inertia(inInertia)
263{
264}
265
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)
void execute(const QDynamicRigidBody &rigidBody, physx::PxRigidBody &body) override
void execute(const QDynamicRigidBody &rigidBody, physx::PxRigidBody &body) 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(const QVector3D &inTorque)
void execute(const QDynamicRigidBody &rigidBody, physx::PxRigidBody &body) override
QPhysicsCommandReset(QVector3D inPosition, QVector3D inEulerRotation)
QPhysicsCommandSetAngularVelocity(const QVector3D &inAngularVelocity)
void execute(const QDynamicRigidBody &rigidBody, physx::PxRigidBody &body) override
QPhysicsCommandSetDensity(float inDensity)
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(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)
void execute(const QDynamicRigidBody &rigidBody, physx::PxRigidBody &body) override
The QVector3D class represents a vector or vertex in 3D space.
Definition qvectornd.h:171
Q_ALWAYS_INLINE physx::PxVec3 toPhysXType(const QVector3D &qvec)
Combined button and popup list for selecting options.
#define qWarning
Definition qlogging.h:166
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
static QT_BEGIN_NAMESPACE bool isKinematicBody(physx::PxRigidBody &body)
static qreal position(const QQuickItem *item, QQuickAnchors::Anchor anchorLine)
#define Q_UNUSED(x)