6#include "physxnode/qphysxtriggerbody_p.h"
8#include <QtCore/QPointer>
9#include <QtCore/QVarLengthArray>
14
15
16
17
18
19
20
21
22
25
26
27
28
29
30
31
32
33
36
37
38
39
40
43
44
45
46
47
48
49
50
52QTriggerBody::QTriggerBody() =
default;
54void QTriggerBody::registerCollision(QAbstractPhysicsNode *collision, ShapePair shapes)
61 const auto it = m_collisions.find(collision);
62 if (it != m_collisions.end()) {
67 it->pairs.insert(shapes);
68 it->unreported.remove(shapes);
77 const bool sends = collision->sendTriggerReports();
78 const bool receives = collision->receiveTriggerReports();
80 Overlaps &overlaps = m_collisions[collision];
81 overlaps.pairs.insert(shapes);
82 overlaps.sends = sends;
83 overlaps.receives = receives;
89 connect(collision, &QObject::destroyed,
this, &QTriggerBody::dropDestroyedBody,
90 Qt::UniqueConnection);
91 reportEntered(collision, sends, receives);
94void QTriggerBody::deregisterCollision(QAbstractPhysicsNode *collision, ShapePair shapes)
96 const auto it = m_collisions.find(collision);
97 if (it == m_collisions.end())
100 it->pairs.remove(shapes);
101 it->unreported.remove(shapes);
102 if (!it->pairs.isEmpty())
105 const bool sends = it->sends;
106 const bool receives = it->receives;
109 m_collisions.erase(it);
110 disconnect(collision, &QObject::destroyed,
this, &QTriggerBody::dropDestroyedBody);
111 reportExited(collision, sends, receives);
123void QTriggerBody::reportEntered(QAbstractPhysicsNode *body,
bool sends,
bool receives)
125 const QPointer<QTriggerBody> self(
this);
126 const QPointer<QAbstractPhysicsNode> weakBody(body);
129 emit bodyEntered(body);
132 if (!self.isNull() && m_collisions.contains(body))
133 emit collisionCountChanged();
135 if (receives && !self.isNull() && !weakBody.isNull())
136 emit body->enteredTriggerBody(
this);
139void QTriggerBody::reportExited(QAbstractPhysicsNode *body,
bool sends,
bool receives)
141 const QPointer<QTriggerBody> self(
this);
142 const QPointer<QAbstractPhysicsNode> weakBody(body);
145 emit bodyExited(body);
147 emit collisionCountChanged();
149 if (receives && !self.isNull() && !weakBody.isNull())
150 emit body->exitedTriggerBody(
this);
153void QTriggerBody::invalidateOverlaps(QAbstractPhysicsNode *node)
167 for (Overlaps &overlaps : m_collisions)
168 overlaps.unreported = overlaps.pairs;
172 const auto it = m_collisions.find(node);
173 if (it != m_collisions.end())
174 it->unreported = it->pairs;
177void QTriggerBody::dropUnreportedOverlaps()
181 QPointer<QAbstractPhysicsNode> body;
183 bool receives =
false;
185 QVarLengthArray<PendingExit, 4> pending;
187 for (
auto it = m_collisions.begin(); it != m_collisions.end();) {
188 if (it->unreported.isEmpty()) {
193 it->pairs.subtract(it->unreported);
194 it->unreported.clear();
196 if (it->pairs.isEmpty()) {
197 QAbstractPhysicsNode *body = it.key();
198 disconnect(body, &QObject::destroyed,
this, &QTriggerBody::dropDestroyedBody);
201 pending.append({ body, it->sends, it->receives });
202 it = m_collisions.erase(it);
218 const QPointer<QTriggerBody> self(
this);
220 for (
const PendingExit &exit : pending) {
224 if (!exit.body.isNull())
225 reportExited(exit.body.data(), exit.sends, exit.receives);
227 emit collisionCountChanged();
231void QTriggerBody::dropDestroyedBody(QObject *body)
237 for (
auto it = m_collisions.cbegin(); it != m_collisions.cend(); ++it) {
238 if (
static_cast<QObject *>(it.key()) == body) {
239 const bool wasCounted = it->sends;
242 m_collisions.erase(it);
244 emit collisionCountChanged();
250int QTriggerBody::collisionCount()
const
252 return m_reportedCount;
255QAbstractPhysXNode *QTriggerBody::createPhysXBackend()
257 return new QPhysXTriggerBody(
this);
#define QT_BEGIN_NAMESPACE