6#include "PxRigidDynamic.h"
7#include "characterkinematic/PxController.h"
8#include "characterkinematic/PxControllerManager.h"
9#include "characterkinematic/PxCapsuleController.h"
16#define PHYSX_RELEASE(x) \
29 void onShapeHit(
const physx::PxControllerShapeHit &hit)
override
47 void onObstacleHit(
const physx::PxControllerObstacleHit & )
override { }
61 delete reportCallback;
62 reportCallback =
nullptr;
72 auto shapes = characterController->getCollisionShapesList();
73 if (
shapes.length() != 1) {
74 qWarning() <<
"CharacterController: invalid collision shapes list.";
77 auto *capsule = qobject_cast<QCapsuleShape *>(
shapes.first());
79 qWarning() <<
"CharacterController: collision shape is not a capsule.";
82 auto *mgr =
world->controllerManager();
84 qWarning() <<
"QtQuick3DPhysics internal error: missing controller manager.";
93 physx::PxCapsuleControllerDesc desc;
95 desc.reportCallback = reportCallback;
96 desc.radius = 0.5f *
radiusScale * capsule->diameter();
97 desc.height = heightScale * capsule->height();
98 desc.stepOffset = 0.25f * desc.height;
101 const QVector3D pos = characterController->scenePosition();
102 desc.position = {
pos.x(),
pos.y(),
pos.z() };
105 controller =
static_cast<physx::PxCapsuleController *
>(mgr->createController(desc));
108 qWarning() <<
"QtQuick3DPhysics internal error: could not create controller.";
112 controller->setUserData(
static_cast<void *
>(
frontendNode));
114 auto *actor = controller->getActor();
116 actor->userData = characterController;
118 qWarning() <<
"QtQuick3DPhysics internal error: CharacterController created without actor.";
122 QHash<QQuick3DNode *, QMatrix4x4> & )
124 if (controller ==
nullptr)
130 const auto &
shapes = characterController->getCollisionShapesList();
131 auto capsule =
shapes.length() == 1 ? qobject_cast<QCapsuleShape *>(
shapes.front()) :
nullptr;
133 if (
shapes.length() != 1) {
134 qWarning() <<
"CharacterController: invalid collision shapes list.";
135 }
else if (!capsule) {
136 qWarning() <<
"CharacterController: collision shape is not a capsule.";
138 const QVector3D sceneScale = characterController->sceneScale();
139 const qreal heightScale = sceneScale.
y();
143 const float heightNew = heightScale * capsule->height();
145 controller->resize(heightNew);
147 const float radiusNew = 0.5f *
radiusScale * capsule->diameter();
149 controller->setRadius(radiusNew);
151 const float stepOffsetNew = 0.25f * heightNew;
152 if (!
qFuzzyCompare(controller->getStepOffset(), stepOffsetNew))
153 controller->setStepOffset(stepOffsetNew);
167 bool teleport = characterController->getTeleport(teleportPos);
169 controller->setPosition({ teleportPos.x(), teleportPos.y(), teleportPos.z() });
170 }
else if (deltaTime > 0) {
171 const auto displacement =
174 controller->move(displacement, displacement.magnitude() / 100, deltaTime, {});
175 characterController->setCollisions(QCharacterController::Collisions(
uint(collisions)));
void onShapeHit(const physx::PxControllerShapeHit &hit) override
void onControllerHit(const physx::PxControllersHit &) override
ControllerCallback(QPhysicsWorld *worldIn)
void onObstacleHit(const physx::PxControllerObstacleHit &) override
QAbstractPhysicsNode * frontendNode
QVector< physx::PxShape * > shapes
virtual void cleanup(QPhysXWorld *)
physx::PxMaterial * material
void createMaterialFromQtMaterial(QPhysXWorld *physX, QPhysicsMaterial *qtMaterial)
void shapeHit(QAbstractPhysicsNode *body, const QVector3D &position, const QVector3D &impulse, const QVector3D &normal)
bool enableShapeHitCallback
QPhysXCharacterController(QCharacterController *frontEnd)
bool debugGeometryCapability() override
DebugDrawBodyType getDebugDrawBodyType() override
void init(QPhysicsWorld *world, QPhysXWorld *physX) override
void cleanup(QPhysXWorld *physX) override
void createMaterial(QPhysXWorld *physX) override
void sync(float deltaTime, QHash< QQuick3DNode *, QMatrix4x4 > &transformCache) override
Q_INVOKABLE QVector3D mapPositionFromScene(const QVector3D &scenePosition) const
\qmlmethod vector3d QtQuick3D::Node::mapPositionFromScene(vector3d scenePosition)
void setPosition(const QVector3D &position)
The QVector3D class represents a vector or vertex in 3D space.
constexpr float y() const noexcept
Returns the y coordinate of this point.
constexpr float x() const noexcept
Returns the x coordinate of this point.
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.
bool qFuzzyCompare(qfloat16 p1, qfloat16 p2) noexcept
GLenum GLenum GLenum GLenum GLenum scale
static qreal position(const QQuickItem *item, QQuickAnchors::Anchor anchorLine)
QLatin1StringView world("world")