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
qdynamicrigidbody.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
6#include "qphysicsworld_p.h"
8
10
306
308{
309 qDeleteAll(m_commandQueue);
310 m_commandQueue.clear();
311}
312
314{
315 return m_centerOfMassRotation;
316}
317
318void QDynamicRigidBody::setCenterOfMassRotation(const QQuaternion &newCenterOfMassRotation)
319{
320 if (qFuzzyCompare(m_centerOfMassRotation, newCenterOfMassRotation))
321 return;
322 m_centerOfMassRotation = newCenterOfMassRotation;
323
324 // Only inertia tensor is using rotation
325 if (m_massMode == MassMode::MassAndInertiaTensor)
326 m_commandQueue.enqueue(new QPhysicsCommandSetMassAndInertiaTensor(m_mass, m_inertiaTensor));
327
329}
330
332{
333 return m_centerOfMassPosition;
334}
335
336void QDynamicRigidBody::setCenterOfMassPosition(const QVector3D &newCenterOfMassPosition)
337{
338 if (qFuzzyCompare(m_centerOfMassPosition, newCenterOfMassPosition))
339 return;
340
341 switch (m_massMode) {
343 m_commandQueue.enqueue(new QPhysicsCommandSetMassAndInertiaTensor(m_mass, m_inertiaTensor));
344 break;
345 }
347 m_commandQueue.enqueue(new QPhysicsCommandSetMassAndInertiaMatrix(m_mass, m_inertiaMatrix));
348 break;
349 }
352 case MassMode::Mass:
353 break;
354 }
355
356 m_centerOfMassPosition = newCenterOfMassPosition;
358}
359
361{
362 return m_massMode;
363}
364
366{
367 if (m_massMode == newMassMode)
368 return;
369
370 switch (newMassMode) {
372 auto world = QPhysicsWorld::getWorld(this);
373 if (world) {
374 m_commandQueue.enqueue(new QPhysicsCommandSetDensity(world->defaultDensity()));
375 } else {
376 qWarning() << "No physics world found, cannot set default density.";
377 }
378 break;
379 }
381 m_commandQueue.enqueue(new QPhysicsCommandSetDensity(m_density));
382 break;
383 }
384 case MassMode::Mass: {
385 m_commandQueue.enqueue(new QPhysicsCommandSetMass(m_mass));
386 break;
387 }
389 m_commandQueue.enqueue(new QPhysicsCommandSetMassAndInertiaTensor(m_mass, m_inertiaTensor));
390 break;
391 }
393 m_commandQueue.enqueue(new QPhysicsCommandSetMassAndInertiaMatrix(m_mass, m_inertiaMatrix));
394 break;
395 }
396 }
397
398 m_massMode = newMassMode;
400}
401
403{
404 return m_inertiaTensor;
405}
406
408{
409 if (qFuzzyCompare(m_inertiaTensor, newInertiaTensor))
410 return;
411 m_inertiaTensor = newInertiaTensor;
412
413 if (m_massMode == MassMode::MassAndInertiaTensor)
414 m_commandQueue.enqueue(new QPhysicsCommandSetMassAndInertiaTensor(m_mass, m_inertiaTensor));
415
417}
418
419const QList<float> &QDynamicRigidBody::readInertiaMatrix() const
420{
421 return m_inertiaMatrixList;
422}
423
424static bool fuzzyEquals(const QList<float> &a, const QList<float> &b)
425{
426 if (a.length() != b.length())
427 return false;
428
429 const int length = a.length();
430 for (int i = 0; i < length; i++)
431 if (!qFuzzyCompare(a[i], b[i]))
432 return false;
433
434 return true;
435}
436
437void QDynamicRigidBody::setInertiaMatrix(const QList<float> &newInertiaMatrix)
438{
439 if (fuzzyEquals(m_inertiaMatrixList, newInertiaMatrix))
440 return;
441
442 m_inertiaMatrixList = newInertiaMatrix;
443 const int elemsToCopy = qMin(m_inertiaMatrixList.length(), 9);
444 memcpy(m_inertiaMatrix.data(), m_inertiaMatrixList.data(), elemsToCopy * sizeof(float));
445 memset(m_inertiaMatrix.data() + elemsToCopy, 0, (9 - elemsToCopy) * sizeof(float));
446
447 if (m_massMode == MassMode::MassAndInertiaMatrix)
448 m_commandQueue.enqueue(new QPhysicsCommandSetMassAndInertiaMatrix(m_mass, m_inertiaMatrix));
449
451}
452
454{
455 return m_inertiaMatrix;
456}
457
459{
460 return m_mass;
461}
462
464{
465 return m_isKinematic;
466}
467
469{
470 return m_gravityEnabled;
471}
472
474{
475 if (mass < 0.f || qFuzzyCompare(m_mass, mass))
476 return;
477
478 switch (m_massMode) {
480 m_commandQueue.enqueue(new QPhysicsCommandSetMass(mass));
481 break;
483 m_commandQueue.enqueue(new QPhysicsCommandSetMassAndInertiaTensor(mass, m_inertiaTensor));
484 break;
486 m_commandQueue.enqueue(new QPhysicsCommandSetMassAndInertiaMatrix(mass, m_inertiaMatrix));
487 break;
490 break;
491 }
492
493 m_mass = mass;
494 emit massChanged(m_mass);
495}
496
498{
499 return m_density;
500}
501
503{
504 if (qFuzzyCompare(m_density, density))
505 return;
506
507 if (m_massMode == MassMode::CustomDensity)
508 m_commandQueue.enqueue(new QPhysicsCommandSetDensity(density));
509
510 m_density = density;
511 emit densityChanged(m_density);
512}
513
515{
516 if (m_isKinematic == isKinematic)
517 return;
518
519 if (hasStaticShapes() && !isKinematic) {
520 qWarning()
521 << "Cannot make body containing trimesh/heightfield/plane non-kinematic, ignoring.";
522 return;
523 }
524
525 m_isKinematic = isKinematic;
526 m_commandQueue.enqueue(new QPhysicsCommandSetIsKinematic(m_isKinematic));
527 emit isKinematicChanged(m_isKinematic);
528}
529
531{
532 if (m_gravityEnabled == gravityEnabled)
533 return;
534
535 m_gravityEnabled = gravityEnabled;
536 m_commandQueue.enqueue(new QPhysicsCommandSetGravityEnabled(m_gravityEnabled));
538}
539
541{
542 m_commandQueue.enqueue(new QPhysicsCommandSetAngularVelocity(angularVelocity));
543}
544
546{
547 return m_linearAxisLock;
548}
549
550void QDynamicRigidBody::setLinearAxisLock(AxisLock newAxisLockLinear)
551{
552 if (m_linearAxisLock == newAxisLockLinear)
553 return;
554 m_linearAxisLock = newAxisLockLinear;
555 emit linearAxisLockChanged();
556}
557
559{
560 return m_angularAxisLock;
561}
562
563void QDynamicRigidBody::setAngularAxisLock(AxisLock newAxisLockAngular)
564{
565 if (m_angularAxisLock == newAxisLockAngular)
566 return;
567 m_angularAxisLock = newAxisLockAngular;
568 emit angularAxisLockChanged();
569}
570
571QQueue<QPhysicsCommand *> &QDynamicRigidBody::commandQueue()
572{
573 return m_commandQueue;
574}
575
577{
578 if (m_massMode == MassMode::DefaultDensity)
579 m_commandQueue.enqueue(new QPhysicsCommandSetDensity(defaultDensity));
580}
581
583{
584 m_commandQueue.enqueue(new QPhysicsCommandApplyCentralForce(force));
585}
586
588{
589 m_commandQueue.enqueue(new QPhysicsCommandApplyForce(force, position));
590}
591
593{
594 m_commandQueue.enqueue(new QPhysicsCommandApplyTorque(torque));
595}
596
598{
599 m_commandQueue.enqueue(new QPhysicsCommandApplyCentralImpulse(impulse));
600}
601
603{
604 m_commandQueue.enqueue(new QPhysicsCommandApplyImpulse(impulse, position));
605}
606
608{
609 m_commandQueue.enqueue(new QPhysicsCommandApplyTorqueImpulse(impulse));
610}
611
613{
614 m_commandQueue.enqueue(new QPhysicsCommandSetLinearVelocity(linearVelocity));
615}
616
617void QDynamicRigidBody::reset(const QVector3D &position, const QVector3D &eulerRotation)
618{
620}
621
622void QDynamicRigidBody::setKinematicRotation(const QQuaternion &rotation)
623{
624 if (m_kinematicRotation == rotation)
625 return;
626
627 m_kinematicRotation = rotation;
628 emit kinematicRotationChanged(m_kinematicRotation);
629 emit kinematicEulerRotationChanged(m_kinematicRotation.getEulerRotation());
630}
631
633{
634 return m_kinematicRotation.getQuaternionRotation();
635}
636
637void QDynamicRigidBody::setKinematicEulerRotation(const QVector3D &rotation)
638{
639 if (m_kinematicRotation == rotation)
640 return;
641
642 m_kinematicRotation = rotation;
643 emit kinematicEulerRotationChanged(m_kinematicRotation);
644 emit kinematicRotationChanged(m_kinematicRotation.getQuaternionRotation());
645}
646
648{
649 return m_kinematicRotation.getEulerRotation();
650}
651
652void QDynamicRigidBody::setKinematicPivot(const QVector3D &pivot)
653{
654 m_kinematicPivot = pivot;
655 emit kinematicPivotChanged(m_kinematicPivot);
656}
657
659{
660 return m_kinematicPivot;
661}
662
667
668void QDynamicRigidBody::setKinematicPosition(const QVector3D &position)
669{
670 m_kinematicPosition = position;
671 emit kinematicPositionChanged(m_kinematicPosition);
672}
673
675{
676 return m_kinematicPosition;
677}
678
Q_INVOKABLE void applyCentralForce(const QVector3D &force)
QQueue< QPhysicsCommand * > & commandQueue()
const QList< float > & readInertiaMatrix() const
QList< float > inertiaMatrix
QQuaternion centerOfMassRotation
void inertiaMatrixChanged()
Q_INVOKABLE void setAngularVelocity(const QVector3D &angularVelocity)
void setInertiaMatrix(const QList< float > &newInertiaMatrix)
QQuaternion kinematicRotation
void setMass(float mass)
Q_INVOKABLE void applyCentralImpulse(const QVector3D &impulse)
void setMassMode(const MassMode newMassMode)
Q_INVOKABLE void setLinearVelocity(const QVector3D &linearVelocity)
void setDensity(float density)
void setIsKinematic(bool isKinematic)
void updateDefaultDensity(float defaultDensity)
QAbstractPhysXNode * createPhysXBackend() final
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)
void setGravityEnabled(bool gravityEnabled)
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)
void centerOfMassRotationChanged()
void setCenterOfMassPosition(const QVector3D &newCenterOfMassPosition)
T * data()
Returns a pointer to the raw data of this matrix.
qsizetype length() const noexcept
Definition qlist.h:399
pointer data()
Definition qlist.h:431
void clear()
Definition qlist.h:434
static QPhysicsWorld * getWorld(QQuick3DNode *node)
The QQuaternion class represents a quaternion consisting of a vector and scalar.
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
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.
static bool fuzzyEquals(const QList< float > &a, const QList< float > &b)
bool qFuzzyCompare(qfloat16 p1, qfloat16 p2) noexcept
Definition qfloat16.h:333
#define qWarning
Definition qlogging.h:166
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 qreal position(const QQuickItem *item, QQuickAnchors::Anchor anchorLine)
#define emit
QLatin1StringView world("world")