6#include "characterkinematic/PxControllerManager.h"
7#include "cooking/PxCooking.h"
8#include "extensions/PxDefaultCpuDispatcher.h"
9#include "pvd/PxPvdTransport.h"
10#include "PxFoundation.h"
12#include "PxPhysicsVersion.h"
13#include "PxRigidActor.h"
15#include "PxSimulationEventCallback.h"
35 for (physx::PxU32
i = 0;
i <
count;
i++) {
38 & (physx::PxTriggerPairFlag::eREMOVED_SHAPE_TRIGGER
39 | physx::PxTriggerPairFlag::eREMOVED_SHAPE_OTHER))
48 if (!triggerNode || !otherNode) {
49 qWarning() <<
"QtQuick3DPhysics internal error: null pointer in trigger collision.";
56 if (pairs->status == physx::PxPairFlag::eNOTIFY_TOUCH_FOUND) {
57 if (otherNode->sendTriggerReports()) {
58 triggerNode->registerCollision(otherNode);
60 if (otherNode->receiveTriggerReports()) {
61 emit otherNode->enteredTriggerBody(triggerNode);
63 }
else if (pairs->status == physx::PxPairFlag::eNOTIFY_TOUCH_LOST) {
64 if (otherNode->sendTriggerReports()) {
65 triggerNode->deregisterCollision(otherNode);
67 if (otherNode->receiveTriggerReports()) {
68 emit otherNode->exitedTriggerBody(triggerNode);
75 physx::PxU32 )
override {};
76 void onWake(physx::PxActor ** , physx::PxU32 )
override {};
77 void onSleep(physx::PxActor ** , physx::PxU32 )
override {};
78 void onContact(
const physx::PxContactPairHeader &pairHeader,
const physx::PxContactPair *pairs,
79 physx::PxU32 nbPairs)
override
82 constexpr physx::PxU32 bufferSize = 64;
83 physx::PxContactPairPoint contacts[bufferSize];
85 for (physx::PxU32
i = 0;
i < nbPairs;
i++) {
86 const physx::PxContactPair &contactPair = pairs[
i];
88 if (contactPair.events & physx::PxPairFlag::eNOTIFY_TOUCH_FOUND) {
96 || !
other->m_backendObject)
99 const bool triggerReceive =
101 const bool otherReceive =
104 if (!triggerReceive && !otherReceive)
107 physx::PxU32 nbContacts = pairs[
i].extractContacts(contacts, bufferSize);
110 QList<QVector3D> impulses;
111 QList<QVector3D> normals;
114 impulses.reserve(nbContacts);
115 normals.reserve(nbContacts);
117 for (physx::PxU32
j = 0;
j < nbContacts;
j++) {
118 physx::PxVec3
position = contacts[
j].position;
119 physx::PxVec3 impulse = contacts[
j].impulse;
120 physx::PxVec3 normal = contacts[
j].normal;
127 QList<QVector3D> normalsInverted;
128 normalsInverted.reserve(normals.size());
130 normalsInverted.push_back(
QVector3D(-
v.x(), -
v.y(), -
v.z()));
141 const physx::PxTransform * ,
142 const physx::PxU32 )
override {};
154static physx::PxFilterFlags
156 physx::PxFilterData filterData0,
157 physx::PxFilterObjectAttributes ,
158 physx::PxFilterData filterData1, physx::PxPairFlags &pairFlags,
159 const void * , physx::PxU32 )
162 const quint32 id0 = filterData0.word0;
163 const quint32 id1 = filterData1.word0;
164 const quint32 mask0 = filterData0.word1;
165 const quint32 mask1 = filterData1.word1;
168 if (id0 < 32 && id1 < 32 && (
isBitSet(mask0, id1) ||
isBitSet(mask1, id0))) {
170 return physx::PxFilterFlag::eSUPPRESS;
174 const auto defaultCollisonFlags =
175 physx::PxPairFlag::eSOLVE_CONTACT | physx::PxPairFlag::eDETECT_DISCRETE_CONTACT;
178 const auto notifyTouchFlags =
179 physx::PxPairFlag::eNOTIFY_TOUCH_FOUND | physx::PxPairFlag::eNOTIFY_TOUCH_LOST;
182 const auto notifyContactFlags = physx::PxPairFlag::eNOTIFY_CONTACT_POINTS;
184 pairFlags = defaultCollisonFlags | notifyTouchFlags | notifyContactFlags;
185 return physx::PxFilterFlag::eDEFAULT;
188static physx::PxFilterFlags
190 physx::PxFilterData ,
191 physx::PxFilterObjectAttributes ,
192 physx::PxFilterData , physx::PxPairFlags &pairFlags,
193 const void * , physx::PxU32 )
196 const auto defaultCollisonFlags = physx::PxPairFlag::eSOLVE_CONTACT
197 | physx::PxPairFlag::eDETECT_DISCRETE_CONTACT | physx::PxPairFlag::eDETECT_CCD_CONTACT;
200 const auto notifyTouchFlags =
201 physx::PxPairFlag::eNOTIFY_TOUCH_FOUND | physx::PxPairFlag::eNOTIFY_TOUCH_LOST;
204 const auto notifyContactFlags = physx::PxPairFlag::eNOTIFY_CONTACT_POINTS;
206 pairFlags = defaultCollisonFlags | notifyTouchFlags | notifyContactFlags;
207 return physx::PxFilterFlag::eDEFAULT;
210#define PHYSX_RELEASE(x) \
211 if (x != nullptr) { \
219 s_physx.foundationRefCount++;
221 if (s_physx.foundationCreated)
224 s_physx.foundation = PxCreateFoundation(
225 PX_PHYSICS_VERSION, s_physx.defaultAllocatorCallback, s_physx.defaultErrorCallback);
226 if (!s_physx.foundation)
227 qFatal(
"PxCreateFoundation failed!");
229 s_physx.foundationCreated =
true;
232 s_physx.pvd = PxCreatePvd(*m_physx->foundation);
233 s_physx.transport = physx::PxDefaultPvdSocketTransportCreate(
"qt", 5425, 10);
234 s_physx.pvd->connect(*m_physx->transport, physx::PxPvdInstrumentationFlag::eALL);
238 s_physx.cooking = PxCreateCooking(PX_PHYSICS_VERSION, *s_physx.foundation,
239 physx::PxCookingParams(physx::PxTolerancesScale()));
246 s_physx.foundationRefCount--;
247 if (s_physx.foundationRefCount == 0) {
259 s_physx.foundationCreated =
false;
260 s_physx.physicsCreated =
false;
270 bool enableCCD,
QPhysicsWorld *physicsWorld,
unsigned int numThreads)
273 qWarning() <<
"Scene already created";
277 physx::PxTolerancesScale
scale;
278 scale.length = typicalLength;
279 scale.speed = typicalSpeed;
283 if (!s_physx.physicsCreated) {
284 constexpr bool recordMemoryAllocations =
true;
285 s_physx.physics = PxCreatePhysics(PX_PHYSICS_VERSION, *s_physx.foundation,
scale,
286 recordMemoryAllocations, s_physx.pvd);
287 if (!s_physx.physics)
288 qFatal(
"PxCreatePhysics failed!");
290 s_physx.dispatcher = physx::PxDefaultCpuDispatcherCreate(numThreads);
291 s_physx.physicsCreated =
true;
296 physx::PxSceneDesc sceneDesc(
scale);
298 sceneDesc.cpuDispatcher = s_physx.dispatcher;
302 sceneDesc.flags |= physx::PxSceneFlag::eENABLE_CCD;
306 sceneDesc.solverType = physx::PxSolverType::eTGS;
307 sceneDesc.simulationEventCallback =
callback;
309 if (physicsWorld->reportKinematicKinematicCollisions())
310 sceneDesc.kineKineFilteringMode = physx::PxPairFilteringMode::eKEEP;
311 if (physicsWorld->reportStaticKinematicCollisions())
312 sceneDesc.staticKineFilteringMode = physx::PxPairFilteringMode::eKEEP;
314 scene = s_physx.physics->createScene(sceneDesc);
bool receiveContactReports
SimulationEventCallback * callback
void createScene(float typicalLength, float typicalSpeed, const QVector3D &gravity, bool enableCCD, QPhysicsWorld *physicsWorld, unsigned int numThreads)
physx::PxControllerManager * controllerManager
bool isNodeRemoved(QAbstractPhysicsNode *object)
void registerContact(QAbstractPhysicsNode *sender, QAbstractPhysicsNode *receiver, const QVector< QVector3D > &positions, const QVector< QVector3D > &impulses, const QVector< QVector3D > &normals)
The QVector3D class represents a vector or vertex in 3D space.
SimulationEventCallback(QPhysicsWorld *worldIn)
void onConstraintBreak(physx::PxConstraintInfo *, physx::PxU32) override
virtual ~SimulationEventCallback()=default
void onContact(const physx::PxContactPairHeader &pairHeader, const physx::PxContactPair *pairs, physx::PxU32 nbPairs) override
void onAdvance(const physx::PxRigidBody *const *, const physx::PxTransform *, const physx::PxU32) override
void onWake(physx::PxActor **, physx::PxU32) override
void onTrigger(physx::PxTriggerPair *pairs, physx::PxU32 count) override
void onSleep(physx::PxActor **, physx::PxU32) override
Q_ALWAYS_INLINE physx::PxVec3 toPhysXType(const QVector3D &qvec)
Q_ALWAYS_INLINE QVector3D toQtType(const physx::PxVec3 &vec)
Combined button and popup list for selecting options.
static const QCssKnownValue positions[NumKnownPositionModes - 1]
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
GLsizei const GLfloat * v
[13]
GLenum GLenum GLsizei count
GLenum GLenum GLenum GLenum GLenum scale
static physx::PxFilterFlags contactReportFilterShaderCCD(physx::PxFilterObjectAttributes, physx::PxFilterData, physx::PxFilterObjectAttributes, physx::PxFilterData, physx::PxPairFlags &pairFlags, const void *, physx::PxU32)
static constexpr bool isBitSet(quint32 value, quint32 position)
static physx::PxFilterFlags contactReportFilterShader(physx::PxFilterObjectAttributes, physx::PxFilterData filterData0, physx::PxFilterObjectAttributes, physx::PxFilterData filterData1, physx::PxPairFlags &pairFlags, const void *, physx::PxU32)
static qreal position(const QQuickItem *item, QQuickAnchors::Anchor anchorLine)
static StaticPhysXObjects & getReference()