8#include "physxnode/qphysxdynamicbody_p.h"
10#include <foundation/PxSimpleTypes.h>
15
16
17
18
19
20
21
22
23
24
25
26
27
30
31
32
33
34
35
36
37
38
39
40
41
44
45
46
47
48
49
50
51
52
53
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
131
132
133
134
135
136
137
138
139
140
141
144
145
146
147
148
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
197
198
199
200
201
202
203
204
205
208
209
210
211
212
213
214
215
216
217
220
221
222
223
224
225
226
227
228
229
232
233
234
235
236
237
238
239
240
241
242
245
246
247
248
249
250
251
252
253
254
255
258
259
260
261
262
263
264
265
266
267
268
271
272
273
274
275
276
277
278
279
280
281
284
285
286
287
288
289
290
293
294
295
296
299
300
301
302
305
306
307
308
311
312
313
314
317
318
319
320
323
324
325
326
329
330
331
332
335
336
337
338
341
342
343
344
346QDynamicRigidBody::QDynamicRigidBody() =
default;
348QDynamicRigidBody::~QDynamicRigidBody()
350 qDeleteAll(m_commandQueue);
351 m_commandQueue.clear();
354const QQuaternion &QDynamicRigidBody::centerOfMassRotation()
const
356 return m_centerOfMassRotation;
359void QDynamicRigidBody::setCenterOfMassRotation(
const QQuaternion &newCenterOfMassRotation)
361 if (qFuzzyCompare(m_centerOfMassRotation, newCenterOfMassRotation))
363 m_centerOfMassRotation = newCenterOfMassRotation;
366 if (m_massMode == MassMode::MassAndInertiaTensor)
367 m_commandQueue.enqueue(
new QPhysicsCommandSetMassAndInertiaTensor(m_mass, m_inertiaTensor));
369 emit centerOfMassRotationChanged();
372const QVector3D &QDynamicRigidBody::centerOfMassPosition()
const
374 return m_centerOfMassPosition;
377void QDynamicRigidBody::setCenterOfMassPosition(
const QVector3D &newCenterOfMassPosition)
379 if (qFuzzyCompare(m_centerOfMassPosition, newCenterOfMassPosition))
382 switch (m_massMode) {
383 case MassMode::MassAndInertiaTensor: {
384 m_commandQueue.enqueue(
new QPhysicsCommandSetMassAndInertiaTensor(m_mass, m_inertiaTensor));
387 case MassMode::MassAndInertiaMatrix: {
388 m_commandQueue.enqueue(
new QPhysicsCommandSetMassAndInertiaMatrix(m_mass, m_inertiaMatrix));
391 case MassMode::DefaultDensity:
392 case MassMode::CustomDensity:
397 m_centerOfMassPosition = newCenterOfMassPosition;
398 emit centerOfMassPositionChanged();
401QDynamicRigidBody::MassMode QDynamicRigidBody::massMode()
const
406void QDynamicRigidBody::setMassMode(
const MassMode newMassMode)
408 if (m_massMode == newMassMode)
411 switch (newMassMode) {
412 case MassMode::DefaultDensity: {
413 auto world = QPhysicsWorld::getWorld(
this);
415 m_commandQueue.enqueue(
new QPhysicsCommandSetDensity(world->defaultDensity()));
417 qWarning() <<
"No physics world found, cannot set default density.";
421 case MassMode::CustomDensity: {
422 m_commandQueue.enqueue(
new QPhysicsCommandSetDensity(m_density));
425 case MassMode::Mass: {
426 m_commandQueue.enqueue(
new QPhysicsCommandSetMass(m_mass));
429 case MassMode::MassAndInertiaTensor: {
430 m_commandQueue.enqueue(
new QPhysicsCommandSetMassAndInertiaTensor(m_mass, m_inertiaTensor));
433 case MassMode::MassAndInertiaMatrix: {
434 m_commandQueue.enqueue(
new QPhysicsCommandSetMassAndInertiaMatrix(m_mass, m_inertiaMatrix));
439 m_massMode = newMassMode;
440 emit massModeChanged();
443const QVector3D &QDynamicRigidBody::inertiaTensor()
const
445 return m_inertiaTensor;
448void QDynamicRigidBody::setInertiaTensor(
const QVector3D &newInertiaTensor)
450 if (qFuzzyCompare(m_inertiaTensor, newInertiaTensor))
452 m_inertiaTensor = newInertiaTensor;
454 if (m_massMode == MassMode::MassAndInertiaTensor)
455 m_commandQueue.enqueue(
new QPhysicsCommandSetMassAndInertiaTensor(m_mass, m_inertiaTensor));
457 emit inertiaTensorChanged();
460const QList<
float> &QDynamicRigidBody::readInertiaMatrix()
const
462 return m_inertiaMatrixList;
465static bool fuzzyEquals(
const QList<
float> &a,
const QList<
float> &b)
467 if (a.length() != b.length())
470 const int length = a.length();
471 for (
int i = 0; i < length; i++)
472 if (!qFuzzyCompare(a[i], b[i]))
478void QDynamicRigidBody::setInertiaMatrix(
const QList<
float> &newInertiaMatrix)
480 if (fuzzyEquals(m_inertiaMatrixList, newInertiaMatrix))
483 m_inertiaMatrixList = newInertiaMatrix;
484 const int elemsToCopy = qMin(m_inertiaMatrixList.length(), 9);
485 memcpy(m_inertiaMatrix.data(), m_inertiaMatrixList.data(), elemsToCopy *
sizeof(
float));
486 memset(m_inertiaMatrix.data() + elemsToCopy, 0, (9 - elemsToCopy) *
sizeof(
float));
488 if (m_massMode == MassMode::MassAndInertiaMatrix)
489 m_commandQueue.enqueue(
new QPhysicsCommandSetMassAndInertiaMatrix(m_mass, m_inertiaMatrix));
491 emit inertiaMatrixChanged();
494const QMatrix3x3 &QDynamicRigidBody::inertiaMatrix()
const
496 return m_inertiaMatrix;
499float QDynamicRigidBody::mass()
const
504bool QDynamicRigidBody::isKinematic()
const
506 return m_isKinematic;
509QDynamicRigidBody::CCDType QDynamicRigidBody::ccd()
const
514bool QDynamicRigidBody::gravityEnabled()
const
516 return m_gravityEnabled;
519void QDynamicRigidBody::setMass(
float mass)
521 if (mass < 0.f || qFuzzyCompare(m_mass, mass))
524 switch (m_massMode) {
525 case QDynamicRigidBody::MassMode::Mass:
526 m_commandQueue.enqueue(
new QPhysicsCommandSetMass(mass));
528 case QDynamicRigidBody::MassMode::MassAndInertiaTensor:
529 m_commandQueue.enqueue(
new QPhysicsCommandSetMassAndInertiaTensor(mass, m_inertiaTensor));
531 case QDynamicRigidBody::MassMode::MassAndInertiaMatrix:
532 m_commandQueue.enqueue(
new QPhysicsCommandSetMassAndInertiaMatrix(mass, m_inertiaMatrix));
534 case QDynamicRigidBody::MassMode::DefaultDensity:
535 case QDynamicRigidBody::MassMode::CustomDensity:
540 emit massChanged(m_mass);
543float QDynamicRigidBody::density()
const
548void QDynamicRigidBody::setDensity(
float density)
550 density = qBound(0.0000001f, density, PX_MAX_F32);
552 if (qFuzzyCompare(m_density, density))
555 if (m_massMode == MassMode::CustomDensity)
556 m_commandQueue.enqueue(
new QPhysicsCommandSetDensity(density));
559 emit densityChanged(m_density);
562void QDynamicRigidBody::setIsKinematic(
bool isKinematic)
564 if (m_isKinematic == isKinematic)
567 if (hasStaticShapes() && !isKinematic) {
569 <<
"Cannot make body containing trimesh/heightfield/plane non-kinematic, ignoring.";
573 m_isKinematic = isKinematic;
574 auto world = QPhysicsWorld::getWorld(
this);
575 m_commandQueue.enqueue(
576 new QPhysicsCommandSetIsKinematic(m_isKinematic, world && world->enableCCD()));
577 emit isKinematicChanged(m_isKinematic);
580void QDynamicRigidBody::setCCD(CCDType newCCD)
586 auto world = QPhysicsWorld::getWorld(
this);
587 m_commandQueue.enqueue(
new QPhysicsCommandSetCCD(m_CCD, world && world->enableCCD()));
591void QDynamicRigidBody::setGravityEnabled(
bool gravityEnabled)
593 if (m_gravityEnabled == gravityEnabled)
596 m_gravityEnabled = gravityEnabled;
597 m_commandQueue.enqueue(
new QPhysicsCommandSetGravityEnabled(m_gravityEnabled));
598 emit gravityEnabledChanged();
601void QDynamicRigidBody::setAngularVelocity(
const QVector3D &angularVelocity)
603 m_commandQueue.enqueue(
new QPhysicsCommandSetAngularVelocity(angularVelocity));
606QDynamicRigidBody::AxisLock QDynamicRigidBody::linearAxisLock()
const
608 return m_linearAxisLock;
611void QDynamicRigidBody::setLinearAxisLock(AxisLock newAxisLockLinear)
613 if (m_linearAxisLock == newAxisLockLinear)
615 m_linearAxisLock = newAxisLockLinear;
616 emit linearAxisLockChanged();
619QDynamicRigidBody::AxisLock QDynamicRigidBody::angularAxisLock()
const
621 return m_angularAxisLock;
624void QDynamicRigidBody::setAngularAxisLock(AxisLock newAxisLockAngular)
626 if (m_angularAxisLock == newAxisLockAngular)
628 m_angularAxisLock = newAxisLockAngular;
629 emit angularAxisLockChanged();
632QQueue<QPhysicsCommand *> &QDynamicRigidBody::commandQueue()
634 return m_commandQueue;
637void QDynamicRigidBody::updateDefaultDensity(
float defaultDensity)
639 if (m_massMode == MassMode::DefaultDensity)
640 m_commandQueue.enqueue(
new QPhysicsCommandSetDensity(defaultDensity));
643void QDynamicRigidBody::applyCentralForce(
const QVector3D &force)
645 m_commandQueue.enqueue(
new QPhysicsCommandApplyCentralForce(force));
648void QDynamicRigidBody::applyForce(
const QVector3D &force,
const QVector3D &position)
650 m_commandQueue.enqueue(
new QPhysicsCommandApplyForce(force, position));
653void QDynamicRigidBody::applyTorque(
const QVector3D &torque)
655 m_commandQueue.enqueue(
new QPhysicsCommandApplyTorque(torque));
658void QDynamicRigidBody::applyCentralImpulse(
const QVector3D &impulse)
660 m_commandQueue.enqueue(
new QPhysicsCommandApplyCentralImpulse(impulse));
663void QDynamicRigidBody::applyImpulse(
const QVector3D &impulse,
const QVector3D &position)
665 m_commandQueue.enqueue(
new QPhysicsCommandApplyImpulse(impulse, position));
668void QDynamicRigidBody::applyTorqueImpulse(
const QVector3D &impulse)
670 m_commandQueue.enqueue(
new QPhysicsCommandApplyTorqueImpulse(impulse));
673void QDynamicRigidBody::setLinearVelocity(
const QVector3D &linearVelocity)
675 m_commandQueue.enqueue(
new QPhysicsCommandSetLinearVelocity(linearVelocity));
678void QDynamicRigidBody::reset(
const QVector3D &position,
const QVector3D &eulerRotation)
680 m_commandQueue.enqueue(
new QPhysicsCommandReset(position, eulerRotation));
683void QDynamicRigidBody::setKinematicRotation(
const QQuaternion &rotation)
685 if (m_kinematicRotation == rotation)
688 m_kinematicRotation = rotation;
689 emit kinematicRotationChanged(m_kinematicRotation.toQuaternion());
690 emit kinematicEulerRotationChanged(m_kinematicRotation.toEulerAngles());
693QQuaternion QDynamicRigidBody::kinematicRotation()
const
695 return m_kinematicRotation.toQuaternion();
698void QDynamicRigidBody::setKinematicEulerRotation(
const QVector3D &rotation)
700 if (m_kinematicRotation == rotation)
703 m_kinematicRotation = rotation;
704 emit kinematicEulerRotationChanged(m_kinematicRotation.toEulerAngles());
705 emit kinematicRotationChanged(m_kinematicRotation.toQuaternion());
708QVector3D QDynamicRigidBody::kinematicEulerRotation()
const
710 return m_kinematicRotation.toEulerAngles();
713void QDynamicRigidBody::setKinematicPivot(
const QVector3D &pivot)
715 m_kinematicPivot = pivot;
716 emit kinematicPivotChanged(m_kinematicPivot);
719QVector3D QDynamicRigidBody::kinematicPivot()
const
721 return m_kinematicPivot;
724bool QDynamicRigidBody::isSleeping()
const
729void QDynamicRigidBody::setIsSleeping(
bool newIsSleeping)
731 if (m_isSleeping == newIsSleeping)
734 m_isSleeping = newIsSleeping;
735 emit isSleepingChanged(newIsSleeping);
738QAbstractPhysXNode *QDynamicRigidBody::createPhysXBackend()
740 return new QPhysXDynamicBody(
this);
743void QDynamicRigidBody::setKinematicPosition(
const QVector3D &position)
745 m_kinematicPosition = position;
746 emit kinematicPositionChanged(m_kinematicPosition);
749QVector3D QDynamicRigidBody::kinematicPosition()
const
751 return m_kinematicPosition;
static bool fuzzyEquals(const QList< float > &a, const QList< float > &b)
#define QT_BEGIN_NAMESPACE