20 const QDynamicRigidBody &rigidBody,
physx::PxRigidBody &body)
22 for (
auto command : commandQueue) {
23 command->execute(rigidBody, body);
31 QHash<QQuick3DNode *, QMatrix4x4> &transformCache)
34 if (transformCache.contains(node))
35 return transformCache[node];
37 QMatrix4x4 localTransform;
40 if (
auto drb = qobject_cast<
const QDynamicRigidBody *>(node); drb !=
nullptr) {
41 if (!drb->isKinematic()) {
42 qWarning() <<
"Non-kinematic body as a parent of a kinematic body is unsupported";
44 localTransform = QSSGRenderNode::calculateTransformMatrix(
45 drb->kinematicPosition(), drb->scale(), drb->kinematicPivot(),
46 drb->kinematicRotation());
48 localTransform = QSSGRenderNode::calculateTransformMatrix(node->position(), node->scale(),
49 node->pivot(), node->rotation());
52 QQuick3DNode *parent = node->parentNode();
54 return localTransform;
57 QMatrix4x4 parentTransform = calculateKinematicNodeTransform(parent, transformCache);
58 QMatrix4x4 sceneTransform = parentTransform * localTransform;
60 transformCache[node] = sceneTransform;
61 return sceneTransform;
66 const auto lockAngular = body->angularAxisLock();
67 const auto lockLinear = body->linearAxisLock();
68 const int flags = (lockAngular & QDynamicRigidBody::AxisLock::LockX
69 ? physx::PxRigidDynamicLockFlag::eLOCK_ANGULAR_X
71 | (lockAngular & QDynamicRigidBody::AxisLock::LockY
72 ? physx::PxRigidDynamicLockFlag::eLOCK_ANGULAR_Y
74 | (lockAngular & QDynamicRigidBody::AxisLock::LockZ
75 ? physx::PxRigidDynamicLockFlag::eLOCK_ANGULAR_Z
77 | (lockLinear & QDynamicRigidBody::AxisLock::LockX
78 ? physx::PxRigidDynamicLockFlag::eLOCK_LINEAR_X
80 | (lockLinear & QDynamicRigidBody::AxisLock::LockY
81 ? physx::PxRigidDynamicLockFlag::eLOCK_LINEAR_Y
83 | (lockLinear & QDynamicRigidBody::AxisLock::LockZ
84 ? physx::PxRigidDynamicLockFlag::eLOCK_LINEAR_Z
86 return static_cast<physx::PxRigidDynamicLockFlags>(flags);
91 auto rotationMatrix = transform;
92 QSSGUtils::mat44::normalize(rotationMatrix);
94 QQuaternion::fromRotationMatrix(QSSGUtils::mat44::getUpper3x3(rotationMatrix)).normalized();
95 const QVector3D worldPosition = QSSGUtils::mat44::getPosition(transform);
96 return physx::PxTransform(QPhysicsUtils::toPhysXType(worldPosition),
97 QPhysicsUtils::toPhysXType(rotation));
111 auto *dynamicRigidBody =
static_cast<QDynamicRigidBody *>(frontendNode);
113 dynamicRigidBody->updateFromPhysicsTransform(actor->getGlobalPose());
115 auto *dynamicActor =
static_cast<physx::PxRigidDynamic *>(actor);
116 processCommandQueue(dynamicRigidBody->commandQueue(), *dynamicRigidBody, *dynamicActor);
117 if (dynamicRigidBody->isKinematic()) {
121 QMatrix4x4 transform = calculateKinematicNodeTransform(dynamicRigidBody, transformCache);
122 dynamicActor->setKinematicTarget(getPhysXWorldTransform(transform));
124 dynamicActor->setRigidDynamicLockFlags(getLockFlags(dynamicRigidBody));
127 const bool disabledPrevious = actor->getActorFlags() & physx::PxActorFlag::eDISABLE_SIMULATION;
128 const bool disabled = !dynamicRigidBody->simulationEnabled();
129 if (disabled != disabledPrevious) {
130 actor->setActorFlag(physx::PxActorFlag::eDISABLE_SIMULATION, disabled);
131 if (!disabled && !dynamicRigidBody->isKinematic())
132 dynamicActor->wakeUp();
135 dynamicRigidBody->setIsSleeping(dynamicActor->isSleeping());
137 QPhysXActorBody::sync(deltaTime, transformCache);
147 QDynamicRigidBody *drb =
static_cast<QDynamicRigidBody *>(frontendNode);
150 if (!drb->hasStaticShapes()) {
153 switch (drb->massMode()) {
154 case QDynamicRigidBody::MassMode::DefaultDensity: {
158 case QDynamicRigidBody::MassMode::CustomDensity: {
162 case QDynamicRigidBody::MassMode::Mass: {
163 const float mass = qMax(drb->mass(), 0.f);
167 case QDynamicRigidBody::MassMode::MassAndInertiaTensor: {
168 const float mass = qMax(drb->mass(), 0.f);
172 case QDynamicRigidBody::MassMode::MassAndInertiaMatrix: {
173 const float mass = qMax(drb->mass(), 0.f);
179 drb->commandQueue().enqueue(command);
180 }
else if (!drb->isKinematic()) {
182 qWarning() <<
"Cannot make body containing trimesh/heightfield/plane non-kinematic, "
183 "forcing kinematic.";
184 drb->setIsKinematic(
true);
187 const bool isKinematic = drb->isKinematic();
188 auto *dynamicBody =
static_cast<physx::PxRigidDynamic *>(actor);
189 dynamicBody->setRigidBodyFlag(physx::PxRigidBodyFlag::eKINEMATIC, isKinematic);
191 if (world->enableCCD()) {
194 dynamicBody->setRigidBodyFlag(physx::PxRigidBodyFlag::eENABLE_CCD, !isKinematic);
195 dynamicBody->setRigidBodyFlag(physx::PxRigidBodyFlag::eENABLE_SPECULATIVE_CCD, isKinematic);
void buildShapes(QPhysXWorld *physX)
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)