Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qrigidbody.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 "qrigidbody_p.h"
6#include "qphysicsworld_p.h"
7
9
283
285{
286 qDeleteAll(m_commandQueue);
287 m_commandQueue.clear();
288}
289
291{
292 return m_centerOfMassRotation;
293}
294
295void QDynamicRigidBody::setCenterOfMassRotation(const QQuaternion &newCenterOfMassRotation)
296{
297 if (qFuzzyCompare(m_centerOfMassRotation, newCenterOfMassRotation))
298 return;
299 m_centerOfMassRotation = newCenterOfMassRotation;
300
301 // Only inertia tensor is using rotation
302 if (m_massMode == MassMode::MassAndInertiaTensor)
303 m_commandQueue.enqueue(new QPhysicsCommandSetMassAndInertiaTensor(m_mass, m_inertiaTensor));
304
306}
307
309{
310 return m_centerOfMassPosition;
311}
312
313void QDynamicRigidBody::setCenterOfMassPosition(const QVector3D &newCenterOfMassPosition)
314{
315 if (qFuzzyCompare(m_centerOfMassPosition, newCenterOfMassPosition))
316 return;
317
318 switch (m_massMode) {
320 m_commandQueue.enqueue(new QPhysicsCommandSetMassAndInertiaTensor(m_mass, m_inertiaTensor));
321 break;
322 }
324 m_commandQueue.enqueue(new QPhysicsCommandSetMassAndInertiaMatrix(m_mass, m_inertiaMatrix));
325 break;
326 }
329 case MassMode::Mass:
330 break;
331 }
332
333 m_centerOfMassPosition = newCenterOfMassPosition;
335}
336
338{
339 return m_massMode;
340}
341
343{
344 if (m_massMode == newMassMode)
345 return;
346
347 switch (newMassMode) {
349 auto world = QPhysicsWorld::getWorld(this);
350 if (world) {
351 m_commandQueue.enqueue(new QPhysicsCommandSetDensity(world->defaultDensity()));
352 } else {
353 qWarning() << "No physics world found, cannot set default density.";
354 }
355 break;
356 }
358 m_commandQueue.enqueue(new QPhysicsCommandSetDensity(m_density));
359 break;
360 }
361 case MassMode::Mass: {
362 m_commandQueue.enqueue(new QPhysicsCommandSetMass(m_mass));
363 break;
364 }
366 m_commandQueue.enqueue(new QPhysicsCommandSetMassAndInertiaTensor(m_mass, m_inertiaTensor));
367 break;
368 }
370 m_commandQueue.enqueue(new QPhysicsCommandSetMassAndInertiaMatrix(m_mass, m_inertiaMatrix));
371 break;
372 }
373 }
374
375 m_massMode = newMassMode;
377}
378
380{
381 return m_inertiaTensor;
382}
383
385{
386 if (qFuzzyCompare(m_inertiaTensor, newInertiaTensor))
387 return;
388 m_inertiaTensor = newInertiaTensor;
389
390 if (m_massMode == MassMode::MassAndInertiaTensor)
391 m_commandQueue.enqueue(new QPhysicsCommandSetMassAndInertiaTensor(m_mass, m_inertiaTensor));
392
394}
395
397{
398 return m_inertiaMatrixList;
399}
400
401static bool fuzzyEquals(const QList<float> &a, const QList<float> &b)
402{
403 if (a.length() != b.length())
404 return false;
405
406 const int length = a.length();
407 for (int i = 0; i < length; i++)
408 if (!qFuzzyCompare(a[i], b[i]))
409 return false;
410
411 return true;
412}
413
415{
416 if (fuzzyEquals(m_inertiaMatrixList, newInertiaMatrix))
417 return;
418
419 m_inertiaMatrixList = newInertiaMatrix;
420 const int elemsToCopy = qMin(m_inertiaMatrixList.length(), 9);
421 memcpy(m_inertiaMatrix.data(), m_inertiaMatrixList.data(), elemsToCopy * sizeof(float));
422 memset(m_inertiaMatrix.data() + elemsToCopy, 0, (9 - elemsToCopy) * sizeof(float));
423
424 if (m_massMode == MassMode::MassAndInertiaMatrix)
425 m_commandQueue.enqueue(new QPhysicsCommandSetMassAndInertiaMatrix(m_mass, m_inertiaMatrix));
426
428}
429
431{
432 return m_inertiaMatrix;
433}
434
436{
437 return m_mass;
438}
439
441{
442 return m_isKinematic;
443}
444
446{
447 return m_gravityEnabled;
448}
449
451{
452 if (mass < 0.f || qFuzzyCompare(m_mass, mass))
453 return;
454
455 switch (m_massMode) {
457 m_commandQueue.enqueue(new QPhysicsCommandSetMass(mass));
458 break;
460 m_commandQueue.enqueue(new QPhysicsCommandSetMassAndInertiaTensor(mass, m_inertiaTensor));
461 break;
463 m_commandQueue.enqueue(new QPhysicsCommandSetMassAndInertiaMatrix(mass, m_inertiaMatrix));
464 break;
467 break;
468 }
469
470 m_mass = mass;
471 emit massChanged(m_mass);
472}
473
475{
476 return m_density;
477}
478
480{
481 if (qFuzzyCompare(m_density, density))
482 return;
483
484 if (m_massMode == MassMode::CustomDensity)
485 m_commandQueue.enqueue(new QPhysicsCommandSetDensity(density));
486
487 m_density = density;
488 emit densityChanged(m_density);
489}
490
492{
493 if (m_isKinematic == isKinematic)
494 return;
495
496 if (hasStaticShapes() && !isKinematic) {
497 qWarning()
498 << "Cannot make body containing trimesh/heightfield/plane non-kinematic, ignoring.";
499 return;
500 }
501
502 m_isKinematic = isKinematic;
503 m_commandQueue.enqueue(new QPhysicsCommandSetIsKinematic(m_isKinematic));
504 emit isKinematicChanged(m_isKinematic);
505}
506
508{
509 if (m_gravityEnabled == gravityEnabled)
510 return;
511
512 m_gravityEnabled = gravityEnabled;
513 m_commandQueue.enqueue(new QPhysicsCommandSetGravityEnabled(m_gravityEnabled));
515}
516
518{
519 m_commandQueue.enqueue(new QPhysicsCommandSetAngularVelocity(angularVelocity));
520}
521
523{
524 return m_linearAxisLock;
525}
526
527void QDynamicRigidBody::setLinearAxisLock(AxisLock newAxisLockLinear)
528{
529 if (m_linearAxisLock == newAxisLockLinear)
530 return;
531 m_linearAxisLock = newAxisLockLinear;
532 emit linearAxisLockChanged();
533}
534
536{
537 return m_angularAxisLock;
538}
539
540void QDynamicRigidBody::setAngularAxisLock(AxisLock newAxisLockAngular)
541{
542 if (m_angularAxisLock == newAxisLockAngular)
543 return;
544 m_angularAxisLock = newAxisLockAngular;
545 emit angularAxisLockChanged();
546}
547
549{
550 return m_commandQueue;
551}
552
554{
555 if (m_massMode == MassMode::DefaultDensity)
556 m_commandQueue.enqueue(new QPhysicsCommandSetDensity(defaultDensity));
557}
558
560{
561 m_commandQueue.enqueue(new QPhysicsCommandApplyCentralForce(force));
562}
563
565{
566 m_commandQueue.enqueue(new QPhysicsCommandApplyForce(force, position));
567}
568
570{
571 m_commandQueue.enqueue(new QPhysicsCommandApplyTorque(torque));
572}
573
575{
576 m_commandQueue.enqueue(new QPhysicsCommandApplyCentralImpulse(impulse));
577}
578
580{
581 m_commandQueue.enqueue(new QPhysicsCommandApplyImpulse(impulse, position));
582}
583
585{
586 m_commandQueue.enqueue(new QPhysicsCommandApplyTorqueImpulse(impulse));
587}
588
590{
591 m_commandQueue.enqueue(new QPhysicsCommandSetLinearVelocity(linearVelocity));
592}
593
594void QDynamicRigidBody::reset(const QVector3D &position, const QVector3D &eulerRotation)
595{
597}
598
599void QDynamicRigidBody::setKinematicRotation(const QQuaternion &rotation)
600{
601 if (m_kinematicRotation == rotation)
602 return;
603
604 m_kinematicRotation = rotation;
605 emit kinematicRotationChanged(m_kinematicRotation);
606 emit kinematicEulerRotationChanged(m_kinematicRotation.getEulerRotation());
607}
608
610{
611 return m_kinematicRotation.getQuaternionRotation();
612}
613
614void QDynamicRigidBody::setKinematicEulerRotation(const QVector3D &rotation)
615{
616 if (m_kinematicRotation == rotation)
617 return;
618
619 m_kinematicRotation = rotation;
620 emit kinematicEulerRotationChanged(m_kinematicRotation);
621 emit kinematicRotationChanged(m_kinematicRotation.getQuaternionRotation());
622}
623
625{
626 return m_kinematicRotation.getEulerRotation();
627}
628
629void QDynamicRigidBody::setKinematicPivot(const QVector3D &pivot)
630{
631 m_kinematicPivot = pivot;
632 emit kinematicPivotChanged(m_kinematicPivot);
633}
634
636{
637 return m_kinematicPivot;
638}
639
640void QDynamicRigidBody::setKinematicPosition(const QVector3D &position)
641{
642 m_kinematicPosition = position;
643 emit kinematicPositionChanged(m_kinematicPosition);
644}
645
647{
648 return m_kinematicPosition;
649}
650
666
Q_INVOKABLE void applyCentralForce(const QVector3D &force)
QVector3D kinematicPosition
QQueue< QPhysicsCommand * > & commandQueue()
const QList< float > & readInertiaMatrix() const
QList< float > inertiaMatrix
QQuaternion centerOfMassRotation
void inertiaMatrixChanged()
Q_INVOKABLE void setAngularVelocity(const QVector3D &angularVelocity)
QVector3D kinematicPivot
void setInertiaMatrix(const QList< float > &newInertiaMatrix)
QQuaternion kinematicRotation
QVector3D centerOfMassPosition
void setMass(float mass)
Q_INVOKABLE void applyCentralImpulse(const QVector3D &impulse)
QVector3D inertiaTensor
void setMassMode(const MassMode newMassMode)
Q_INVOKABLE void setLinearVelocity(const QVector3D &linearVelocity)
void setDensity(float density)
void setIsKinematic(bool isKinematic)
void updateDefaultDensity(float defaultDensity)
void gravityEnabledChanged()
void centerOfMassPositionChanged()
Q_INVOKABLE void applyImpulse(const QVector3D &impulse, const QVector3D &position)
Q_INVOKABLE void applyForce(const QVector3D &force, const QVector3D &position)
Q_INVOKABLE void applyTorqueImpulse(const QVector3D &impulse)
void isKinematicChanged(bool isKinematic)
QVector3D kinematicEulerRotation
void setGravityEnabled(bool gravityEnabled)
AxisLock angularAxisLock
void massChanged(float mass)
void densityChanged(float density)
Q_INVOKABLE void reset(const QVector3D &position, const QVector3D &eulerRotation)
void setInertiaTensor(const QVector3D &newInertiaTensor)
void inertiaTensorChanged()
QDynamicRigidBody()
\qmltype DynamicRigidBody \inqmlmodule QtQuick3D.Physics \inherits PhysicsBody
Q_INVOKABLE void applyTorque(const QVector3D &torque)
void setCenterOfMassRotation(const QQuaternion &newCenterOfMassRotation)
AxisLock linearAxisLock
void centerOfMassRotationChanged()
void setCenterOfMassPosition(const QVector3D &newCenterOfMassPosition)
T * data()
Returns a pointer to the raw data of this matrix.
Definition qlist.h:74
qsizetype length() const noexcept
Definition qlist.h:388
pointer data()
Definition qlist.h:414
void clear()
Definition qlist.h:417
static QPhysicsWorld * getWorld(QQuick3DNode *node)
The QQuaternion class represents a quaternion consisting of a vector and scalar.
Definition qquaternion.h:21
\inmodule QtCore
Definition qqueue.h:14
void enqueue(const T &t)
Adds value t to the tail of the queue.
Definition qqueue.h:18
QVector3D pivot
QQuaternion rotation
QVector3D eulerRotation
QVector3D position
QStaticRigidBody()
\qmltype StaticRigidBody \inqmlmodule QtQuick3D.Physics \inherits PhysicsBody
The QVector3D class represents a vector or vertex in 3D space.
Definition qvectornd.h:171
QVector3D getEulerRotation() const
QQuaternion getQuaternionRotation() const
qDeleteAll(list.begin(), list.end())
Combined button and popup list for selecting options.
bool qFuzzyCompare(qfloat16 p1, qfloat16 p2) noexcept
Definition qfloat16.h:287
#define qWarning
Definition qlogging.h:162
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
GLboolean GLboolean GLboolean b
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLenum GLsizei length
static bool fuzzyEquals(const physx::PxTransform &a, const physx::PxTransform &b)
static qreal position(const QQuickItem *item, QQuickAnchors::Anchor anchorLine)
static bool fuzzyEquals(const QList< float > &a, const QList< float > &b)
#define emit
QLatin1StringView world("world")