8#include "physxnode/qphysxdynamicbody_p.h"
13
14
15
16
17
18
19
20
21
22
23
24
25
28
29
30
31
32
33
34
35
36
37
38
39
42
43
44
45
46
47
48
49
50
51
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
100
101
102
103
104
105
106
107
108
109
110
113
114
115
116
117
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
145
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
166
167
168
169
170
171
172
173
174
177
178
179
180
181
182
183
184
185
186
189
190
191
192
193
194
195
196
197
198
201
202
203
204
205
206
207
208
209
210
211
214
215
216
217
218
219
220
221
222
223
224
227
228
229
230
231
232
233
234
235
236
237
240
241
242
243
244
245
246
247
248
249
250
253
254
255
256
257
258
259
262
263
264
265
268
269
270
271
274
275
276
277
280
281
282
283
286
287
288
289
292
293
294
295
298
299
300
301
304
305
306
307
310
311
312
313
315QDynamicRigidBody::QDynamicRigidBody() =
default;
317QDynamicRigidBody::~QDynamicRigidBody()
319 qDeleteAll(m_commandQueue);
320 m_commandQueue.clear();
323const QQuaternion &QDynamicRigidBody::centerOfMassRotation()
const
325 return m_centerOfMassRotation;
328void QDynamicRigidBody::setCenterOfMassRotation(
const QQuaternion &newCenterOfMassRotation)
330 if (qFuzzyCompare(m_centerOfMassRotation, newCenterOfMassRotation))
332 m_centerOfMassRotation = newCenterOfMassRotation;
335 if (m_massMode == MassMode::MassAndInertiaTensor)
336 m_commandQueue.enqueue(
new QPhysicsCommandSetMassAndInertiaTensor(m_mass, m_inertiaTensor));
338 emit centerOfMassRotationChanged();
341const QVector3D &QDynamicRigidBody::centerOfMassPosition()
const
343 return m_centerOfMassPosition;
346void QDynamicRigidBody::setCenterOfMassPosition(
const QVector3D &newCenterOfMassPosition)
348 if (qFuzzyCompare(m_centerOfMassPosition, newCenterOfMassPosition))
351 switch (m_massMode) {
352 case MassMode::MassAndInertiaTensor: {
353 m_commandQueue.enqueue(
new QPhysicsCommandSetMassAndInertiaTensor(m_mass, m_inertiaTensor));
356 case MassMode::MassAndInertiaMatrix: {
357 m_commandQueue.enqueue(
new QPhysicsCommandSetMassAndInertiaMatrix(m_mass, m_inertiaMatrix));
360 case MassMode::DefaultDensity:
361 case MassMode::CustomDensity:
366 m_centerOfMassPosition = newCenterOfMassPosition;
367 emit centerOfMassPositionChanged();
370QDynamicRigidBody::MassMode QDynamicRigidBody::massMode()
const
375void QDynamicRigidBody::setMassMode(
const MassMode newMassMode)
377 if (m_massMode == newMassMode)
380 switch (newMassMode) {
381 case MassMode::DefaultDensity: {
382 auto world = QPhysicsWorld::getWorld(
this);
384 m_commandQueue.enqueue(
new QPhysicsCommandSetDensity(world->defaultDensity()));
386 qWarning() <<
"No physics world found, cannot set default density.";
390 case MassMode::CustomDensity: {
391 m_commandQueue.enqueue(
new QPhysicsCommandSetDensity(m_density));
394 case MassMode::Mass: {
395 m_commandQueue.enqueue(
new QPhysicsCommandSetMass(m_mass));
398 case MassMode::MassAndInertiaTensor: {
399 m_commandQueue.enqueue(
new QPhysicsCommandSetMassAndInertiaTensor(m_mass, m_inertiaTensor));
402 case MassMode::MassAndInertiaMatrix: {
403 m_commandQueue.enqueue(
new QPhysicsCommandSetMassAndInertiaMatrix(m_mass, m_inertiaMatrix));
408 m_massMode = newMassMode;
409 emit massModeChanged();
412const QVector3D &QDynamicRigidBody::inertiaTensor()
const
414 return m_inertiaTensor;
417void QDynamicRigidBody::setInertiaTensor(
const QVector3D &newInertiaTensor)
419 if (qFuzzyCompare(m_inertiaTensor, newInertiaTensor))
421 m_inertiaTensor = newInertiaTensor;
423 if (m_massMode == MassMode::MassAndInertiaTensor)
424 m_commandQueue.enqueue(
new QPhysicsCommandSetMassAndInertiaTensor(m_mass, m_inertiaTensor));
426 emit inertiaTensorChanged();
429const QList<
float> &QDynamicRigidBody::readInertiaMatrix()
const
431 return m_inertiaMatrixList;
434static bool fuzzyEquals(
const QList<
float> &a,
const QList<
float> &b)
436 if (a.length() != b.length())
439 const int length = a.length();
440 for (
int i = 0; i < length; i++)
441 if (!qFuzzyCompare(a[i], b[i]))
447void QDynamicRigidBody::setInertiaMatrix(
const QList<
float> &newInertiaMatrix)
449 if (fuzzyEquals(m_inertiaMatrixList, newInertiaMatrix))
452 m_inertiaMatrixList = newInertiaMatrix;
453 const int elemsToCopy = qMin(m_inertiaMatrixList.length(), 9);
454 memcpy(m_inertiaMatrix.data(), m_inertiaMatrixList.data(), elemsToCopy *
sizeof(
float));
455 memset(m_inertiaMatrix.data() + elemsToCopy, 0, (9 - elemsToCopy) *
sizeof(
float));
457 if (m_massMode == MassMode::MassAndInertiaMatrix)
458 m_commandQueue.enqueue(
new QPhysicsCommandSetMassAndInertiaMatrix(m_mass, m_inertiaMatrix));
460 emit inertiaMatrixChanged();
463const QMatrix3x3 &QDynamicRigidBody::inertiaMatrix()
const
465 return m_inertiaMatrix;
468float QDynamicRigidBody::mass()
const
473bool QDynamicRigidBody::isKinematic()
const
475 return m_isKinematic;
478bool QDynamicRigidBody::gravityEnabled()
const
480 return m_gravityEnabled;
483void QDynamicRigidBody::setMass(
float mass)
485 if (mass < 0.f || qFuzzyCompare(m_mass, mass))
488 switch (m_massMode) {
489 case QDynamicRigidBody::MassMode::Mass:
490 m_commandQueue.enqueue(
new QPhysicsCommandSetMass(mass));
492 case QDynamicRigidBody::MassMode::MassAndInertiaTensor:
493 m_commandQueue.enqueue(
new QPhysicsCommandSetMassAndInertiaTensor(mass, m_inertiaTensor));
495 case QDynamicRigidBody::MassMode::MassAndInertiaMatrix:
496 m_commandQueue.enqueue(
new QPhysicsCommandSetMassAndInertiaMatrix(mass, m_inertiaMatrix));
498 case QDynamicRigidBody::MassMode::DefaultDensity:
499 case QDynamicRigidBody::MassMode::CustomDensity:
504 emit massChanged(m_mass);
507float QDynamicRigidBody::density()
const
512void QDynamicRigidBody::setDensity(
float density)
514 if (qFuzzyCompare(m_density, density))
517 if (m_massMode == MassMode::CustomDensity)
518 m_commandQueue.enqueue(
new QPhysicsCommandSetDensity(density));
521 emit densityChanged(m_density);
524void QDynamicRigidBody::setIsKinematic(
bool isKinematic)
526 if (m_isKinematic == isKinematic)
529 if (hasStaticShapes() && !isKinematic) {
531 <<
"Cannot make body containing trimesh/heightfield/plane non-kinematic, ignoring.";
535 m_isKinematic = isKinematic;
536 m_commandQueue.enqueue(
new QPhysicsCommandSetIsKinematic(m_isKinematic));
537 emit isKinematicChanged(m_isKinematic);
540void QDynamicRigidBody::setGravityEnabled(
bool gravityEnabled)
542 if (m_gravityEnabled == gravityEnabled)
545 m_gravityEnabled = gravityEnabled;
546 m_commandQueue.enqueue(
new QPhysicsCommandSetGravityEnabled(m_gravityEnabled));
547 emit gravityEnabledChanged();
550void QDynamicRigidBody::setAngularVelocity(
const QVector3D &angularVelocity)
552 m_commandQueue.enqueue(
new QPhysicsCommandSetAngularVelocity(angularVelocity));
555QDynamicRigidBody::AxisLock QDynamicRigidBody::linearAxisLock()
const
557 return m_linearAxisLock;
560void QDynamicRigidBody::setLinearAxisLock(AxisLock newAxisLockLinear)
562 if (m_linearAxisLock == newAxisLockLinear)
564 m_linearAxisLock = newAxisLockLinear;
565 emit linearAxisLockChanged();
568QDynamicRigidBody::AxisLock QDynamicRigidBody::angularAxisLock()
const
570 return m_angularAxisLock;
573void QDynamicRigidBody::setAngularAxisLock(AxisLock newAxisLockAngular)
575 if (m_angularAxisLock == newAxisLockAngular)
577 m_angularAxisLock = newAxisLockAngular;
578 emit angularAxisLockChanged();
581QQueue<QPhysicsCommand *> &QDynamicRigidBody::commandQueue()
583 return m_commandQueue;
586void QDynamicRigidBody::updateDefaultDensity(
float defaultDensity)
588 if (m_massMode == MassMode::DefaultDensity)
589 m_commandQueue.enqueue(
new QPhysicsCommandSetDensity(defaultDensity));
592void QDynamicRigidBody::applyCentralForce(
const QVector3D &force)
594 m_commandQueue.enqueue(
new QPhysicsCommandApplyCentralForce(force));
597void QDynamicRigidBody::applyForce(
const QVector3D &force,
const QVector3D &position)
599 m_commandQueue.enqueue(
new QPhysicsCommandApplyForce(force, position));
602void QDynamicRigidBody::applyTorque(
const QVector3D &torque)
604 m_commandQueue.enqueue(
new QPhysicsCommandApplyTorque(torque));
607void QDynamicRigidBody::applyCentralImpulse(
const QVector3D &impulse)
609 m_commandQueue.enqueue(
new QPhysicsCommandApplyCentralImpulse(impulse));
612void QDynamicRigidBody::applyImpulse(
const QVector3D &impulse,
const QVector3D &position)
614 m_commandQueue.enqueue(
new QPhysicsCommandApplyImpulse(impulse, position));
617void QDynamicRigidBody::applyTorqueImpulse(
const QVector3D &impulse)
619 m_commandQueue.enqueue(
new QPhysicsCommandApplyTorqueImpulse(impulse));
622void QDynamicRigidBody::setLinearVelocity(
const QVector3D &linearVelocity)
624 m_commandQueue.enqueue(
new QPhysicsCommandSetLinearVelocity(linearVelocity));
627void QDynamicRigidBody::reset(
const QVector3D &position,
const QVector3D &eulerRotation)
629 m_commandQueue.enqueue(
new QPhysicsCommandReset(position, eulerRotation));
632void QDynamicRigidBody::setKinematicRotation(
const QQuaternion &rotation)
634 if (m_kinematicRotation == rotation)
637 m_kinematicRotation = rotation;
638 emit kinematicRotationChanged(m_kinematicRotation);
639 emit kinematicEulerRotationChanged(m_kinematicRotation.getEulerRotation());
642QQuaternion QDynamicRigidBody::kinematicRotation()
const
644 return m_kinematicRotation.getQuaternionRotation();
647void QDynamicRigidBody::setKinematicEulerRotation(
const QVector3D &rotation)
649 if (m_kinematicRotation == rotation)
652 m_kinematicRotation = rotation;
653 emit kinematicEulerRotationChanged(m_kinematicRotation);
654 emit kinematicRotationChanged(m_kinematicRotation.getQuaternionRotation());
657QVector3D QDynamicRigidBody::kinematicEulerRotation()
const
659 return m_kinematicRotation.getEulerRotation();
662void QDynamicRigidBody::setKinematicPivot(
const QVector3D &pivot)
664 m_kinematicPivot = pivot;
665 emit kinematicPivotChanged(m_kinematicPivot);
668QVector3D QDynamicRigidBody::kinematicPivot()
const
670 return m_kinematicPivot;
673bool QDynamicRigidBody::isSleeping()
const
678void QDynamicRigidBody::setIsSleeping(
bool newIsSleeping)
680 if (m_isSleeping == newIsSleeping)
683 m_isSleeping = newIsSleeping;
684 emit isSleepingChanged(newIsSleeping);
687QAbstractPhysXNode *QDynamicRigidBody::createPhysXBackend()
689 return new QPhysXDynamicBody(
this);
692void QDynamicRigidBody::setKinematicPosition(
const QVector3D &position)
694 m_kinematicPosition = position;
695 emit kinematicPositionChanged(m_kinematicPosition);
698QVector3D QDynamicRigidBody::kinematicPosition()
const
700 return m_kinematicPosition;
static bool fuzzyEquals(const QList< float > &a, const QList< float > &b)
#define QT_BEGIN_NAMESPACE