7#include "physxnode/qphysxdynamicbody_p.h"
12
13
14
15
16
17
18
19
20
21
22
23
24
27
28
29
30
31
32
33
34
35
36
37
38
41
42
43
44
45
46
47
48
49
50
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
99
100
101
102
103
104
105
106
107
108
109
112
113
114
115
116
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
165
166
167
168
169
170
171
172
173
176
177
178
179
180
181
182
183
184
185
188
189
190
191
192
193
194
195
196
197
200
201
202
203
204
205
206
207
208
209
210
213
214
215
216
217
218
219
220
221
222
223
226
227
228
229
230
231
232
233
234
235
236
239
240
241
242
243
244
245
246
247
248
249
252
253
254
255
256
257
258
261
262
263
264
267
268
269
270
273
274
275
276
279
280
281
282
285
286
287
288
291
292
293
294
297
298
299
300
303
304
305
306
309
310
311
312
314QDynamicRigidBody::QDynamicRigidBody() =
default;
316QDynamicRigidBody::~QDynamicRigidBody()
318 qDeleteAll(m_commandQueue);
319 m_commandQueue.clear();
322const QQuaternion &QDynamicRigidBody::centerOfMassRotation()
const
324 return m_centerOfMassRotation;
327void QDynamicRigidBody::setCenterOfMassRotation(
const QQuaternion &newCenterOfMassRotation)
329 if (qFuzzyCompare(m_centerOfMassRotation, newCenterOfMassRotation))
331 m_centerOfMassRotation = newCenterOfMassRotation;
334 if (m_massMode == MassMode::MassAndInertiaTensor)
335 m_commandQueue.enqueue(
new QPhysicsCommandSetMassAndInertiaTensor(m_mass, m_inertiaTensor));
337 emit centerOfMassRotationChanged();
340const QVector3D &QDynamicRigidBody::centerOfMassPosition()
const
342 return m_centerOfMassPosition;
345void QDynamicRigidBody::setCenterOfMassPosition(
const QVector3D &newCenterOfMassPosition)
347 if (qFuzzyCompare(m_centerOfMassPosition, newCenterOfMassPosition))
350 switch (m_massMode) {
351 case MassMode::MassAndInertiaTensor: {
352 m_commandQueue.enqueue(
new QPhysicsCommandSetMassAndInertiaTensor(m_mass, m_inertiaTensor));
355 case MassMode::MassAndInertiaMatrix: {
356 m_commandQueue.enqueue(
new QPhysicsCommandSetMassAndInertiaMatrix(m_mass, m_inertiaMatrix));
359 case MassMode::DefaultDensity:
360 case MassMode::CustomDensity:
365 m_centerOfMassPosition = newCenterOfMassPosition;
366 emit centerOfMassPositionChanged();
369QDynamicRigidBody::MassMode QDynamicRigidBody::massMode()
const
374void QDynamicRigidBody::setMassMode(
const MassMode newMassMode)
376 if (m_massMode == newMassMode)
379 switch (newMassMode) {
380 case MassMode::DefaultDensity: {
381 auto world = QPhysicsWorld::getWorld(
this);
383 m_commandQueue.enqueue(
new QPhysicsCommandSetDensity(world->defaultDensity()));
385 qWarning() <<
"No physics world found, cannot set default density.";
389 case MassMode::CustomDensity: {
390 m_commandQueue.enqueue(
new QPhysicsCommandSetDensity(m_density));
393 case MassMode::Mass: {
394 m_commandQueue.enqueue(
new QPhysicsCommandSetMass(m_mass));
397 case MassMode::MassAndInertiaTensor: {
398 m_commandQueue.enqueue(
new QPhysicsCommandSetMassAndInertiaTensor(m_mass, m_inertiaTensor));
401 case MassMode::MassAndInertiaMatrix: {
402 m_commandQueue.enqueue(
new QPhysicsCommandSetMassAndInertiaMatrix(m_mass, m_inertiaMatrix));
407 m_massMode = newMassMode;
408 emit massModeChanged();
411const QVector3D &QDynamicRigidBody::inertiaTensor()
const
413 return m_inertiaTensor;
416void QDynamicRigidBody::setInertiaTensor(
const QVector3D &newInertiaTensor)
418 if (qFuzzyCompare(m_inertiaTensor, newInertiaTensor))
420 m_inertiaTensor = newInertiaTensor;
422 if (m_massMode == MassMode::MassAndInertiaTensor)
423 m_commandQueue.enqueue(
new QPhysicsCommandSetMassAndInertiaTensor(m_mass, m_inertiaTensor));
425 emit inertiaTensorChanged();
428const QList<
float> &QDynamicRigidBody::readInertiaMatrix()
const
430 return m_inertiaMatrixList;
433static bool fuzzyEquals(
const QList<
float> &a,
const QList<
float> &b)
435 if (a.length() != b.length())
438 const int length = a.length();
439 for (
int i = 0; i < length; i++)
440 if (!qFuzzyCompare(a[i], b[i]))
446void QDynamicRigidBody::setInertiaMatrix(
const QList<
float> &newInertiaMatrix)
448 if (fuzzyEquals(m_inertiaMatrixList, newInertiaMatrix))
451 m_inertiaMatrixList = newInertiaMatrix;
452 const int elemsToCopy = qMin(m_inertiaMatrixList.length(), 9);
453 memcpy(m_inertiaMatrix.data(), m_inertiaMatrixList.data(), elemsToCopy *
sizeof(
float));
454 memset(m_inertiaMatrix.data() + elemsToCopy, 0, (9 - elemsToCopy) *
sizeof(
float));
456 if (m_massMode == MassMode::MassAndInertiaMatrix)
457 m_commandQueue.enqueue(
new QPhysicsCommandSetMassAndInertiaMatrix(m_mass, m_inertiaMatrix));
459 emit inertiaMatrixChanged();
462const QMatrix3x3 &QDynamicRigidBody::inertiaMatrix()
const
464 return m_inertiaMatrix;
467float QDynamicRigidBody::mass()
const
472bool QDynamicRigidBody::isKinematic()
const
474 return m_isKinematic;
477bool QDynamicRigidBody::gravityEnabled()
const
479 return m_gravityEnabled;
482void QDynamicRigidBody::setMass(
float mass)
484 if (mass < 0.f || qFuzzyCompare(m_mass, mass))
487 switch (m_massMode) {
488 case QDynamicRigidBody::MassMode::Mass:
489 m_commandQueue.enqueue(
new QPhysicsCommandSetMass(mass));
491 case QDynamicRigidBody::MassMode::MassAndInertiaTensor:
492 m_commandQueue.enqueue(
new QPhysicsCommandSetMassAndInertiaTensor(mass, m_inertiaTensor));
494 case QDynamicRigidBody::MassMode::MassAndInertiaMatrix:
495 m_commandQueue.enqueue(
new QPhysicsCommandSetMassAndInertiaMatrix(mass, m_inertiaMatrix));
497 case QDynamicRigidBody::MassMode::DefaultDensity:
498 case QDynamicRigidBody::MassMode::CustomDensity:
503 emit massChanged(m_mass);
506float QDynamicRigidBody::density()
const
511void QDynamicRigidBody::setDensity(
float density)
513 if (qFuzzyCompare(m_density, density))
516 if (m_massMode == MassMode::CustomDensity)
517 m_commandQueue.enqueue(
new QPhysicsCommandSetDensity(density));
520 emit densityChanged(m_density);
523void QDynamicRigidBody::setIsKinematic(
bool isKinematic)
525 if (m_isKinematic == isKinematic)
528 if (hasStaticShapes() && !isKinematic) {
530 <<
"Cannot make body containing trimesh/heightfield/plane non-kinematic, ignoring.";
534 m_isKinematic = isKinematic;
535 m_commandQueue.enqueue(
new QPhysicsCommandSetIsKinematic(m_isKinematic));
536 emit isKinematicChanged(m_isKinematic);
539void QDynamicRigidBody::setGravityEnabled(
bool gravityEnabled)
541 if (m_gravityEnabled == gravityEnabled)
544 m_gravityEnabled = gravityEnabled;
545 m_commandQueue.enqueue(
new QPhysicsCommandSetGravityEnabled(m_gravityEnabled));
546 emit gravityEnabledChanged();
549void QDynamicRigidBody::setAngularVelocity(
const QVector3D &angularVelocity)
551 m_commandQueue.enqueue(
new QPhysicsCommandSetAngularVelocity(angularVelocity));
554QDynamicRigidBody::AxisLock QDynamicRigidBody::linearAxisLock()
const
556 return m_linearAxisLock;
559void QDynamicRigidBody::setLinearAxisLock(AxisLock newAxisLockLinear)
561 if (m_linearAxisLock == newAxisLockLinear)
563 m_linearAxisLock = newAxisLockLinear;
564 emit linearAxisLockChanged();
567QDynamicRigidBody::AxisLock QDynamicRigidBody::angularAxisLock()
const
569 return m_angularAxisLock;
572void QDynamicRigidBody::setAngularAxisLock(AxisLock newAxisLockAngular)
574 if (m_angularAxisLock == newAxisLockAngular)
576 m_angularAxisLock = newAxisLockAngular;
577 emit angularAxisLockChanged();
580QQueue<QPhysicsCommand *> &QDynamicRigidBody::commandQueue()
582 return m_commandQueue;
585void QDynamicRigidBody::updateDefaultDensity(
float defaultDensity)
587 if (m_massMode == MassMode::DefaultDensity)
588 m_commandQueue.enqueue(
new QPhysicsCommandSetDensity(defaultDensity));
591void QDynamicRigidBody::applyCentralForce(
const QVector3D &force)
593 m_commandQueue.enqueue(
new QPhysicsCommandApplyCentralForce(force));
596void QDynamicRigidBody::applyForce(
const QVector3D &force,
const QVector3D &position)
598 m_commandQueue.enqueue(
new QPhysicsCommandApplyForce(force, position));
601void QDynamicRigidBody::applyTorque(
const QVector3D &torque)
603 m_commandQueue.enqueue(
new QPhysicsCommandApplyTorque(torque));
606void QDynamicRigidBody::applyCentralImpulse(
const QVector3D &impulse)
608 m_commandQueue.enqueue(
new QPhysicsCommandApplyCentralImpulse(impulse));
611void QDynamicRigidBody::applyImpulse(
const QVector3D &impulse,
const QVector3D &position)
613 m_commandQueue.enqueue(
new QPhysicsCommandApplyImpulse(impulse, position));
616void QDynamicRigidBody::applyTorqueImpulse(
const QVector3D &impulse)
618 m_commandQueue.enqueue(
new QPhysicsCommandApplyTorqueImpulse(impulse));
621void QDynamicRigidBody::setLinearVelocity(
const QVector3D &linearVelocity)
623 m_commandQueue.enqueue(
new QPhysicsCommandSetLinearVelocity(linearVelocity));
626void QDynamicRigidBody::reset(
const QVector3D &position,
const QVector3D &eulerRotation)
628 m_commandQueue.enqueue(
new QPhysicsCommandReset(position, eulerRotation));
631void QDynamicRigidBody::setKinematicRotation(
const QQuaternion &rotation)
633 if (m_kinematicRotation == rotation)
636 m_kinematicRotation = rotation;
637 emit kinematicRotationChanged(m_kinematicRotation);
638 emit kinematicEulerRotationChanged(m_kinematicRotation.getEulerRotation());
641QQuaternion QDynamicRigidBody::kinematicRotation()
const
643 return m_kinematicRotation.getQuaternionRotation();
646void QDynamicRigidBody::setKinematicEulerRotation(
const QVector3D &rotation)
648 if (m_kinematicRotation == rotation)
651 m_kinematicRotation = rotation;
652 emit kinematicEulerRotationChanged(m_kinematicRotation);
653 emit kinematicRotationChanged(m_kinematicRotation.getQuaternionRotation());
656QVector3D QDynamicRigidBody::kinematicEulerRotation()
const
658 return m_kinematicRotation.getEulerRotation();
661void QDynamicRigidBody::setKinematicPivot(
const QVector3D &pivot)
663 m_kinematicPivot = pivot;
664 emit kinematicPivotChanged(m_kinematicPivot);
667QVector3D QDynamicRigidBody::kinematicPivot()
const
669 return m_kinematicPivot;
672bool QDynamicRigidBody::isSleeping()
const
677void QDynamicRigidBody::setIsSleeping(
bool newIsSleeping)
679 if (m_isSleeping == newIsSleeping)
682 m_isSleeping = newIsSleeping;
683 emit isSleepingChanged(newIsSleeping);
686QAbstractPhysXNode *QDynamicRigidBody::createPhysXBackend()
688 return new QPhysXDynamicBody(
this);
691void QDynamicRigidBody::setKinematicPosition(
const QVector3D &position)
693 m_kinematicPosition = position;
694 emit kinematicPositionChanged(m_kinematicPosition);
697QVector3D QDynamicRigidBody::kinematicPosition()
const
699 return m_kinematicPosition;
static bool fuzzyEquals(const QList< float > &a, const QList< float > &b)
#define QT_BEGIN_NAMESPACE