1 | // Copyright (C) 2021 The Qt Company Ltd. |
---|---|
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only |
3 | |
4 | #include "qtrianglemeshshape_p.h" |
5 | |
6 | #include <QtQuick3D/QQuick3DGeometry> |
7 | #include <extensions/PxExtensionsAPI.h> |
8 | |
9 | #include "qphysicsmeshutils_p_p.h" |
10 | |
11 | //######################################################################################## |
12 | // NOTE: |
13 | // Triangle mesh, heightfield or plane geometry shapes configured as eSIMULATION_SHAPE are |
14 | // not supported for non-kinematic PxRigidDynamic instances. |
15 | //######################################################################################## |
16 | |
17 | QT_BEGIN_NAMESPACE |
18 | |
19 | /*! |
20 | \qmltype TriangleMeshShape |
21 | \inqmlmodule QtQuick3D.Physics |
22 | \inherits CollisionShape |
23 | \since 6.4 |
24 | \brief A collision shape based on a 3D mesh. |
25 | |
26 | This type defines a shape based on the same 3D mesh file format used by |
27 | \l [QtQuick3D]{Model::source}{QtQuick3D.Model}. |
28 | |
29 | Objects that are controlled by the physics simulation cannot use TriangleMeshShape: It can only |
30 | be used with \l StaticRigidBody and \l {DynamicRigidBody::isKinematic}{kinematic bodies}. Use \l |
31 | ConvexMeshShape for non-kinematic dynamic bodies. |
32 | |
33 | \sa {Qt Quick 3D Physics Shapes and Bodies}{Shapes and Bodies overview documentation} |
34 | */ |
35 | |
36 | /*! |
37 | \qmlproperty url TriangleMeshShape::source |
38 | This property defines the location of the mesh file used to define the shape. |
39 | |
40 | Internally, TriangleMeshShape converts the mesh to an optimized data structure. This conversion |
41 | can be done in advance. See the \l{Qt Quick 3D Physics Cooking}{cooking overview documentation} |
42 | for details. |
43 | */ |
44 | |
45 | QTriangleMeshShape::QTriangleMeshShape() = default; |
46 | |
47 | QTriangleMeshShape::~QTriangleMeshShape() |
48 | { |
49 | delete m_meshGeometry; |
50 | if (m_mesh) |
51 | QQuick3DPhysicsMeshManager::releaseMesh(mesh: m_mesh); |
52 | } |
53 | |
54 | physx::PxGeometry *QTriangleMeshShape::getPhysXGeometry() |
55 | { |
56 | if (m_dirtyPhysx || m_scaleDirty) { |
57 | updatePhysXGeometry(); |
58 | } |
59 | return m_meshGeometry; |
60 | } |
61 | |
62 | void QTriangleMeshShape::updatePhysXGeometry() |
63 | { |
64 | delete m_meshGeometry; |
65 | m_meshGeometry = nullptr; |
66 | |
67 | if (!m_mesh) |
68 | return; |
69 | auto *triangleMesh = m_mesh->triangleMesh(); |
70 | if (!triangleMesh) |
71 | return; |
72 | |
73 | auto meshScale = sceneScale(); |
74 | physx::PxMeshScale scale(physx::PxVec3(meshScale.x(), meshScale.y(), meshScale.z()), |
75 | physx::PxQuat(physx::PxIdentity)); |
76 | |
77 | m_meshGeometry = new physx::PxTriangleMeshGeometry(triangleMesh, scale); |
78 | m_dirtyPhysx = false; |
79 | } |
80 | |
81 | const QUrl &QTriangleMeshShape::source() const |
82 | { |
83 | return m_meshSource; |
84 | } |
85 | |
86 | void QTriangleMeshShape::setSource(const QUrl &newSource) |
87 | { |
88 | if (m_meshSource == newSource) |
89 | return; |
90 | m_meshSource = newSource; |
91 | m_mesh = QQuick3DPhysicsMeshManager::getMesh(source: m_meshSource, contextObject: this); |
92 | |
93 | updatePhysXGeometry(); |
94 | |
95 | emit needsRebuild(this); |
96 | emit sourceChanged(); |
97 | } |
98 | |
99 | QT_END_NAMESPACE |
100 |