32 void onTrigger(physx::PxTriggerPair *pairs, physx::PxU32 count)
override
34 QMutexLocker locker(&world->m_removedPhysicsNodesMutex);
36 for (physx::PxU32 i = 0; i < count; i++) {
39 & (physx::PxTriggerPairFlag::eREMOVED_SHAPE_TRIGGER
40 | physx::PxTriggerPairFlag::eREMOVED_SHAPE_OTHER))
43 QTriggerBody *triggerNode =
44 static_cast<QTriggerBody *>(pairs[i].triggerActor->userData);
46 QAbstractPhysicsNode *otherNode =
47 static_cast<QAbstractPhysicsNode *>(pairs[i].otherActor->userData);
49 if (!triggerNode || !otherNode) {
50 qWarning() <<
"QtQuick3DPhysics internal error: null pointer in trigger collision.";
54 if (world->isNodeRemoved(triggerNode) || world->isNodeRemoved(otherNode))
57 const auto status = pairs[i].status;
59 if (status == physx::PxPairFlag::eNOTIFY_TOUCH_FOUND) {
60 if (otherNode->sendTriggerReports()) {
61 triggerNode->registerCollision(otherNode);
63 if (otherNode->receiveTriggerReports()) {
64 emit otherNode->enteredTriggerBody(triggerNode);
66 }
else if (status == physx::PxPairFlag::eNOTIFY_TOUCH_LOST) {
67 if (otherNode->sendTriggerReports()) {
68 triggerNode->deregisterCollision(otherNode);
70 if (otherNode->receiveTriggerReports()) {
71 emit otherNode->exitedTriggerBody(triggerNode);
81 void onContact(
const physx::PxContactPairHeader &pairHeader,
const physx::PxContactPair *pairs,
82 physx::PxU32 nbPairs)
override
84 QMutexLocker locker(&world->m_removedPhysicsNodesMutex);
85 constexpr physx::PxU32 bufferSize = 64;
86 physx::PxContactPairPoint contacts[bufferSize];
88 for (physx::PxU32 i = 0; i < nbPairs; i++) {
89 const physx::PxContactPair &contactPair = pairs[i];
91 if (contactPair.events & physx::PxPairFlag::eNOTIFY_TOUCH_FOUND) {
92 QAbstractPhysicsNode *trigger =
93 static_cast<QAbstractPhysicsNode *>(pairHeader.actors[0]->userData);
94 QAbstractPhysicsNode *other =
95 static_cast<QAbstractPhysicsNode *>(pairHeader.actors[1]->userData);
97 if (!trigger || !other || world->isNodeRemoved(trigger)
98 || world->isNodeRemoved(other) || !trigger->m_backendObject
99 || !other->m_backendObject)
102 const bool triggerReceive =
103 trigger->receiveContactReports() && other->sendContactReports();
104 const bool otherReceive =
105 other->receiveContactReports() && trigger->sendContactReports();
107 if (!triggerReceive && !otherReceive)
110 physx::PxU32 nbContacts = pairs[i].extractContacts(contacts, bufferSize);
112 QList<QVector3D> positions;
113 QList<QVector3D> impulses;
114 QList<QVector3D> normals;
116 positions.reserve(nbContacts);
117 impulses.reserve(nbContacts);
118 normals.reserve(nbContacts);
120 for (physx::PxU32 j = 0; j < nbContacts; j++) {
121 physx::PxVec3 position = contacts[j].position;
122 physx::PxVec3 impulse = contacts[j].impulse;
123 physx::PxVec3 normal = contacts[j].normal;
125 positions.push_back(QPhysicsUtils::toQtType(position));
126 impulses.push_back(QPhysicsUtils::toQtType(impulse));
127 normals.push_back(QPhysicsUtils::toQtType(normal));
130 QList<QVector3D> normalsInverted;
131 normalsInverted.reserve(normals.size());
132 for (
const QVector3D &v : std::as_const(normals)) {
133 normalsInverted.push_back(QVector3D(-v.x(), -v.y(), -v.z()));
137 world->registerContact(other, trigger, positions, impulses, normals);
139 world->registerContact(trigger, other, positions, impulses, normalsInverted);