9#include <QtQuick3D/QQuick3DGeometry>
10#include <extensions/PxExtensionsAPI.h>
12#include "foundation/PxVec3.h"
13#include "cooking/PxConvexMeshDesc.h"
14#include "extensions/PxDefaultStreams.h"
16#include <QtQml/qqml.h>
17#include <QtQml/QQmlFile>
18#include <QtQml/qqmlcontext.h>
20#include <QtQuick3DUtils/private/qssgmesh_p.h>
29 if (m_convexMesh !=
nullptr)
32 physx::PxPhysics *thePhysics = QPhysicsWorld::getPhysics();
33 if (thePhysics ==
nullptr)
37 if (m_convexMesh !=
nullptr)
41 if (m_convexMesh !=
nullptr)
49 physx::PxDefaultMemoryOutputStream
buf;
50 physx::PxConvexMeshCookingResult::Enum
result;
55 qCDebug(lcQuick3dPhysics) <<
"prepare cooking" << vCount <<
"verts";
59 for (
int i = 0;
i < vCount; ++
i) {
60 auto *vp =
reinterpret_cast<const QVector3D *
>(vd + vStride *
i + m_posOffset);
61 verts << physx::PxVec3 { vp->x(), vp->y(), vp->z() };
64 const auto *convexVerts = verts.
constData();
66 physx::PxConvexMeshDesc convexDesc;
67 convexDesc.points.count = vCount;
68 convexDesc.points.stride =
sizeof(physx::PxVec3);
69 convexDesc.points.data = convexVerts;
70 convexDesc.flags = physx::PxConvexFlag::eCOMPUTE_CONVEX;
72 const auto cooking = QPhysicsWorld::getCooking();
73 if (cooking && cooking->cookConvexMesh(convexDesc,
buf, &
result)) {
77 m_convexMesh = thePhysics->createConvexMesh(
input);
78 qCDebug(lcQuick3dPhysics) <<
"Created convex mesh" << m_convexMesh <<
"for mesh" <<
this;
81 qCWarning(lcQuick3dPhysics) <<
"Could not create convex mesh from" << m_meshPath;
90 if (m_triangleMesh !=
nullptr)
91 return m_triangleMesh;
93 physx::PxPhysics *thePhysics = QPhysicsWorld::getPhysics();
94 if (thePhysics ==
nullptr)
98 if (m_triangleMesh !=
nullptr)
99 return m_triangleMesh;
102 if (m_triangleMesh !=
nullptr)
103 return m_triangleMesh;
109 physx::PxDefaultMemoryOutputStream
buf;
110 physx::PxTriangleMeshCookingResult::Enum
result;
121 qCDebug(lcQuick3dPhysics) <<
"prepare cooking" << vCount <<
"verts" << iCount <<
"idxs";
123 physx::PxTriangleMeshDesc triangleDesc;
124 triangleDesc.points.count = vCount;
125 triangleDesc.points.stride = vStride;
126 triangleDesc.points.data = vd + m_posOffset;
128 triangleDesc.flags = {};
130 triangleDesc.triangles.count = iCount / 3;
131 triangleDesc.triangles.stride = iStride * 3;
134 const auto cooking = QPhysicsWorld::getCooking();
135 if (cooking && cooking->cookTriangleMesh(triangleDesc,
buf, &
result)) {
139 m_triangleMesh = thePhysics->createTriangleMesh(
input);
140 qCDebug(lcQuick3dPhysics) <<
"Created triangle mesh" << m_triangleMesh <<
"for mesh"
144 qCWarning(lcQuick3dPhysics) <<
"Could not create triangle mesh from" << m_meshPath;
147 return m_triangleMesh;
150void QQuick3DPhysicsMesh::loadSsgMesh()
155 static const char *compTypes[] = {
"Null",
"UnsignedInt8",
"Int8",
"UnsignedInt16",
156 "Int16",
"UnsignedInt32",
"Int32",
"UnsignedInt64",
157 "Int64",
"Float16",
"Float32",
"Float64" };
165 qCDebug(lcQuick3dPhysics) <<
"Loaded SSG mesh from" << m_meshPath << m_ssgMesh.
isValid()
166 <<
"draw" << int(m_ssgMesh.
drawMode()) <<
"wind"
167 << int(m_ssgMesh.
winding()) <<
"subs" << m_ssgMesh.
subsets().count()
174 for (
auto &
v : m_ssgMesh.vertexBuffer().entries) {
175 qCDebug(lcQuick3dPhysics) <<
" attr" <<
v.name << compTypes[int(
v.componentType)] <<
"cc"
176 <<
v.componentCount <<
"offs" <<
v.offset;
177 Q_ASSERT(
v.componentType == QSSGMesh::Mesh::ComponentType::Float32);
178 if (
v.name ==
"attr_pos")
179 m_posOffset =
v.offset;
184 qCDebug(lcQuick3dPhysics) <<
"..." <<
sub.name <<
"count" <<
sub.count <<
"bounds"
185 <<
sub.bounds.min <<
sub.bounds.max <<
"offset" <<
sub.offset;
196 auto getPoint = [&vb, vStride,
this](
int idx) ->
QVector3D {
197 auto *vp = vb.constData() + vStride * idx + m_posOffset;
198 return *
reinterpret_cast<const QVector3D *
>(vp);
205 auto *ip =
reinterpret_cast<const uint32_t *
>(ib.data());
206 int n = ib.size() / iStride;
207 for (
int i = 0;
i <
qMin(50,
n);
i += 3) {
209 qDebug() <<
" " << ip [
i] << ip[
i+1] << ip[
i+2] <<
" --- "
210 << getPoint(ip[
i]) << getPoint(ip[
i+1]) << getPoint(ip[
i+2]);
215 qCWarning(lcQuick3dPhysics) <<
"Could not read mesh from" << m_meshPath;
224 auto *mesh = meshHash.
value(qmlSource);
227 meshHash[qmlSource] = mesh;
235 if (mesh->
deref() == 0) {
236 qCDebug(lcQuick3dPhysics()) <<
"deleting mesh" << mesh;
237 erase_if(meshHash, [mesh](std::pair<const QString &, QQuick3DPhysicsMesh *&>
h) {
238 return h.second == mesh;
275 delete m_meshGeometry;
283 updatePhysXGeometry();
285 return m_meshGeometry;
288void QConvexMeshShape::updatePhysXGeometry()
290 delete m_meshGeometry;
291 m_meshGeometry =
nullptr;
298 physx::PxMeshScale
scale(physx::PxVec3(meshScale.x(), meshScale.y(), meshScale.z()),
299 physx::PxQuat(physx::PxIdentity));
301 m_meshGeometry =
new physx::PxConvexMeshGeometry(convexMesh,
scale);
302 m_dirtyPhysx =
false;
310void QConvexMeshShape::setSource(
const QUrl &newSource)
312 if (m_meshSource == newSource)
314 m_meshSource = newSource;
316 updatePhysXGeometry();
321 emit sourceChanged();
void needsRebuild(QObject *)
qsizetype size() const noexcept
Returns the number of bytes in this byte array.
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
physx::PxGeometry * getPhysXGeometry() override
QConvexMeshShape()
\qmltype ConvexMeshShape \inherits CollisionShape \inqmlmodule QtQuick3D.Physics
\inmodule QtCore \reentrant
QString absoluteFilePath() const
Returns an absolute path including the file name.
bool exists() const
Returns true if the file exists; otherwise returns false.
bool open(OpenMode flags) override
Opens the file using OpenMode mode, returning true if successful; otherwise false.
T value(const Key &key) const noexcept
const_pointer constData() const noexcept
The QQmlContext class defines a context within a QML engine.
static QString urlToLocalFileOrQrc(const QString &)
If url is a local file returns a path suitable for passing to QFile.
static void releaseMesh(QQuick3DPhysicsMesh *mesh)
static QQuick3DPhysicsMesh * getMesh(const QUrl &source, const QObject *contextObject)
physx::PxTriangleMesh * triangleMesh()
physx::PxConvexMesh * convexMesh()
static Mesh loadMesh(QIODevice *device, quint32 id=0)
VertexBuffer vertexBuffer() const
IndexBuffer indexBuffer() const
QVector< Subset > subsets() const
DrawMode drawMode() const
The QVector3D class represents a vector or vertex in 3D space.
void writeCachedConvexMesh(const QString &filePath, physx::PxDefaultMemoryOutputStream &buf)
void writeCachedTriangleMesh(const QString &filePath, physx::PxDefaultMemoryOutputStream &buf)
physx::PxTriangleMesh * readCachedTriangleMesh(const QString &filePath, physx::PxPhysics &physics)
physx::PxConvexMesh * readCookedConvexMesh(const QString &filePath, physx::PxPhysics &physics)
physx::PxTriangleMesh * readCookedTriangleMesh(const QString &filePath, physx::PxPhysics &physics)
physx::PxConvexMesh * readCachedConvexMesh(const QString &filePath, physx::PxPhysics &physics)
Combined button and popup list for selecting options.
qsizetype erase_if(QByteArray &ba, Predicate pred)
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter * sub
#define qCWarning(category,...)
#define qCDebug(category,...)
constexpr const T & qMin(const T &a, const T &b)
GLsizei const GLfloat * v
[13]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLuint GLenum GLsizei const GLchar * buf
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLfloat GLfloat GLfloat GLfloat h
GLsizei GLsizei GLchar * source
GLenum GLenum GLenum GLenum GLenum scale
GLenum GLenum GLenum input
QQmlContext * qmlContext(const QObject *obj)
static QUrl resolvedUrl(const QUrl &url, const QQmlRefPointer< QQmlContextData > &context)
ComponentType componentType
QVector< VertexBufferEntry > entries