19 const QDynamicRigidBody &rigidBody,
physx::PxRigidBody &body)
21 for (
auto command : commandQueue) {
22 command->execute(rigidBody, body);
30 QHash<QQuick3DNode *, QMatrix4x4> &transformCache)
33 if (transformCache.contains(node))
34 return transformCache[node];
36 QMatrix4x4 localTransform;
39 if (
auto drb = qobject_cast<
const QDynamicRigidBody *>(node); drb !=
nullptr) {
40 if (!drb->isKinematic()) {
41 qWarning() <<
"Non-kinematic body as a parent of a kinematic body is unsupported";
43 localTransform = QSSGRenderNode::calculateTransformMatrix(
44 drb->kinematicPosition(), drb->scale(), drb->kinematicPivot(),
45 drb->kinematicRotation());
47 localTransform = QSSGRenderNode::calculateTransformMatrix(node->position(), node->scale(),
48 node->pivot(), node->rotation());
51 QQuick3DNode *parent = node->parentNode();
53 return localTransform;
56 QMatrix4x4 parentTransform = calculateKinematicNodeTransform(parent, transformCache);
57 QMatrix4x4 sceneTransform = parentTransform * localTransform;
59 transformCache[node] = sceneTransform;
60 return sceneTransform;
65 const auto lockAngular = body->angularAxisLock();
66 const auto lockLinear = body->linearAxisLock();
67 const int flags = (lockAngular & QDynamicRigidBody::AxisLock::LockX
68 ? physx::PxRigidDynamicLockFlag::eLOCK_ANGULAR_X
70 | (lockAngular & QDynamicRigidBody::AxisLock::LockY
71 ? physx::PxRigidDynamicLockFlag::eLOCK_ANGULAR_Y
73 | (lockAngular & QDynamicRigidBody::AxisLock::LockZ
74 ? physx::PxRigidDynamicLockFlag::eLOCK_ANGULAR_Z
76 | (lockLinear & QDynamicRigidBody::AxisLock::LockX
77 ? physx::PxRigidDynamicLockFlag::eLOCK_LINEAR_X
79 | (lockLinear & QDynamicRigidBody::AxisLock::LockY
80 ? physx::PxRigidDynamicLockFlag::eLOCK_LINEAR_Y
82 | (lockLinear & QDynamicRigidBody::AxisLock::LockZ
83 ? physx::PxRigidDynamicLockFlag::eLOCK_LINEAR_Z
85 return static_cast<physx::PxRigidDynamicLockFlags>(flags);
90 auto rotationMatrix = transform;
91 QSSGUtils::mat44::normalize(rotationMatrix);
93 QQuaternion::fromRotationMatrix(QSSGUtils::mat44::getUpper3x3(rotationMatrix)).normalized();
94 const QVector3D worldPosition = QSSGUtils::mat44::getPosition(transform);
95 return physx::PxTransform(QPhysicsUtils::toPhysXType(worldPosition),
96 QPhysicsUtils::toPhysXType(rotation));
110 auto *dynamicRigidBody =
static_cast<QDynamicRigidBody *>(frontendNode);
112 dynamicRigidBody->updateFromPhysicsTransform(
actor->getGlobalPose());
114 auto *dynamicActor =
static_cast<physx::PxRigidDynamic *>(actor);
115 processCommandQueue(dynamicRigidBody->commandQueue(), *dynamicRigidBody, *dynamicActor);
116 if (dynamicRigidBody->isKinematic()) {
120 QMatrix4x4 transform = calculateKinematicNodeTransform(dynamicRigidBody, transformCache);
121 dynamicActor->setKinematicTarget(getPhysXWorldTransform(transform));
123 dynamicActor->setRigidDynamicLockFlags(getLockFlags(dynamicRigidBody));
126 const bool disabledPrevious = actor->getActorFlags() & physx::PxActorFlag::eDISABLE_SIMULATION;
127 const bool disabled = !dynamicRigidBody->simulationEnabled();
128 if (disabled != disabledPrevious) {
129 actor->setActorFlag(physx::PxActorFlag::eDISABLE_SIMULATION, disabled);
130 if (!disabled && !dynamicRigidBody->isKinematic())
131 dynamicActor->wakeUp();
134 dynamicRigidBody->setIsSleeping(dynamicActor->isSleeping());
136 QPhysXActorBody::sync(deltaTime, transformCache);
146 QDynamicRigidBody *drb =
static_cast<QDynamicRigidBody *>(frontendNode);
149 if (!drb->hasStaticShapes()) {
152 switch (drb->massMode()) {
153 case QDynamicRigidBody::MassMode::DefaultDensity: {
157 case QDynamicRigidBody::MassMode::CustomDensity: {
161 case QDynamicRigidBody::MassMode::Mass: {
162 const float mass = qMax(drb->mass(), 0.f);
166 case QDynamicRigidBody::MassMode::MassAndInertiaTensor: {
167 const float mass = qMax(drb->mass(), 0.f);
171 case QDynamicRigidBody::MassMode::MassAndInertiaMatrix: {
172 const float mass = qMax(drb->mass(), 0.f);
178 drb->commandQueue().enqueue(command);
179 }
else if (!drb->isKinematic()) {
181 qWarning() <<
"Cannot make body containing trimesh/heightfield/plane non-kinematic, "
182 "forcing kinematic.";
183 drb->setIsKinematic(
true);
186 const bool isKinematic = drb->isKinematic();
187 auto *dynamicBody =
static_cast<physx::PxRigidDynamic *>(actor);
188 dynamicBody->setRigidBodyFlag(physx::PxRigidBodyFlag::eKINEMATIC, isKinematic);
190 if (world->enableCCD()) {
193 dynamicBody->setRigidBodyFlag(physx::PxRigidBodyFlag::eENABLE_CCD, !isKinematic);
194 dynamicBody->setRigidBodyFlag(physx::PxRigidBodyFlag::eENABLE_SPECULATIVE_CCD, isKinematic);
void buildShapes(QPhysXWorld *physX)
physx::PxRigidActor * actor
void updateDefaultDensity(float density) override
QPhysXDynamicBody(QDynamicRigidBody *frontEnd)
DebugDrawBodyType getDebugDrawBodyType() override
void sync(float deltaTime, QHash< QQuick3DNode *, QMatrix4x4 > &transformCache) override
void rebuildDirtyShapes(QPhysicsWorld *world, QPhysXWorld *physX) override
static QMatrix4x4 calculateKinematicNodeTransform(QQuick3DNode *node, QHash< QQuick3DNode *, QMatrix4x4 > &transformCache)
static physx::PxTransform getPhysXWorldTransform(const QMatrix4x4 transform)
static physx::PxRigidDynamicLockFlags getLockFlags(QDynamicRigidBody *body)
static QT_BEGIN_NAMESPACE void processCommandQueue(QQueue< QPhysicsCommand * > &commandQueue, const QDynamicRigidBody &rigidBody, physx::PxRigidBody &body)