1 /****************************************************************************
2 **
3 ** Copyright (C) 2008-2012 NVIDIA Corporation.
4 ** Copyright (C) 2019 The Qt Company Ltd.
5 ** Contact: https://www.qt.io/licensing/
6 **
7 ** This file is part of Qt Quick 3D.
8 **
9 ** $QT_BEGIN_LICENSE:GPL$
10 ** Commercial License Usage
11 ** Licensees holding valid commercial Qt licenses may use this file in
12 ** accordance with the commercial license agreement provided with the
13 ** Software or, alternatively, in accordance with the terms contained in
14 ** a written agreement between you and The Qt Company. For licensing terms
15 ** and conditions see https://www.qt.io/terms-conditions. For further
16 ** information use the contact form at https://www.qt.io/contact-us.
17 **
18 ** GNU General Public License Usage
19 ** Alternatively, this file may be used under the terms of the GNU
20 ** General Public License version 3 or (at your option) any later version
21 ** approved by the KDE Free Qt Foundation. The licenses are as published by
22 ** the Free Software Foundation and appearing in the file LICENSE.GPL3
23 ** included in the packaging of this file. Please review the following
24 ** information to ensure the GNU General Public License requirements will
25 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
26 **
27 ** $QT_END_LICENSE$
28 **
29 ****************************************************************************/
30 
31 #ifndef QSSG_RENDER_MESH_H
32 #define QSSG_RENDER_MESH_H
33 
34 //
35 //  W A R N I N G
36 //  -------------
37 //
38 // This file is not part of the Qt API.  It exists purely as an
39 // implementation detail.  This header file may change from version to
40 // version without notice, or even be removed.
41 //
42 // We mean it.
43 //
44 
45 #include <QtQuick3DRender/private/qssgrendervertexbuffer_p.h>
46 #include <QtQuick3DRender/private/qssgrenderindexbuffer_p.h>
47 #include <QtQuick3DRender/private/qssgrenderinputassembler_p.h>
48 
49 #include <QtQuick3DUtils/private/qssgbounds3_p.h>
50 #include <QtQuick3DUtils/private/qssgmeshbvh_p.h>
51 
52 QT_BEGIN_NAMESPACE
53 
54 struct QSSGRenderSubsetBase
55 {
56     quint32 count;
57     quint32 offset;
58     QSSGBounds3 bounds; // Vertex buffer bounds
59     QSSGMeshBVHNode *bvhRoot = nullptr;
60     QSSGRenderSubsetBase() = default;
QSSGRenderSubsetBaseQSSGRenderSubsetBase61     QSSGRenderSubsetBase(const QSSGRenderSubsetBase &inOther)
62         : count(inOther.count)
63         , offset(inOther.offset)
64         , bounds(inOther.bounds)
65         , bvhRoot(inOther.bvhRoot)
66     {
67     }
68 
69     QSSGRenderSubsetBase &operator=(const QSSGRenderSubsetBase &inOther)
70     {
71         count = inOther.count;
72         offset = inOther.offset;
73         bounds = inOther.bounds;
74         bvhRoot = inOther.bvhRoot;
75         return *this;
76     }
77 };
78 
79 struct QSSGRenderJoint
80 {
81     qint32 jointID;
82     qint32 parentID;
83     float invBindPose[16];
84     float localToGlobalBoneSpace[16];
85 };
86 
87 struct QSSGRenderSubset : public QSSGRenderSubsetBase
88 {
89     QSSGRef<QSSGRenderInputAssembler> inputAssembler;
90     QSSGRef<QSSGRenderInputAssembler> inputAssemblerDepth;
91     QSSGRef<QSSGRenderInputAssembler> inputAssemblerPoints; ///< similar to depth but ignores index buffer.
92     QSSGRef<QSSGRenderVertexBuffer> vertexBuffer;
93     QSSGRef<QSSGRenderVertexBuffer> posVertexBuffer; ///< separate position buffer for fast depth path rendering
94     QSSGRef<QSSGRenderIndexBuffer> indexBuffer;
95     QSSGRenderDrawMode primitiveType; ///< primitive type used for drawing
96     float edgeTessFactor = 1.0f; ///< edge tessellation amount used for tessellation shaders
97     float innerTessFactor = 1.0f; ///< inner tessellation amount used for tessellation shaders
98     bool wireframeMode; ///< true if we should draw the object as wireframe ( currently ony if
99     /// tessellation is enabled )
100     QVector<QSSGRenderJoint> joints;
101     QString name;
102     QVector<QSSGRenderSubsetBase> subSubsets;
103 
104     QSSGRenderSubset() = default;
QSSGRenderSubsetQSSGRenderSubset105     QSSGRenderSubset(const QSSGRenderSubset &inOther)
106         : QSSGRenderSubsetBase(inOther)
107         , inputAssembler(inOther.inputAssembler)
108         , inputAssemblerDepth(inOther.inputAssemblerDepth)
109         , inputAssemblerPoints(inOther.inputAssemblerPoints)
110         , vertexBuffer(inOther.vertexBuffer)
111         , posVertexBuffer(inOther.posVertexBuffer)
112         , indexBuffer(inOther.indexBuffer)
113         , primitiveType(inOther.primitiveType)
114         , edgeTessFactor(inOther.edgeTessFactor)
115         , innerTessFactor(inOther.innerTessFactor)
116         , wireframeMode(inOther.wireframeMode)
117         , joints(inOther.joints)
118         , name(inOther.name)
119         , subSubsets(inOther.subSubsets)
120     {
121     }
122     // Note that subSubsets is *not* copied.
QSSGRenderSubsetQSSGRenderSubset123     QSSGRenderSubset(const QSSGRenderSubset &inOther, const QSSGRenderSubsetBase &inBase)
124         : QSSGRenderSubsetBase(inBase)
125         , inputAssembler(inOther.inputAssembler)
126         , inputAssemblerDepth(inOther.inputAssemblerDepth)
127         , inputAssemblerPoints(inOther.inputAssemblerPoints)
128         , vertexBuffer(inOther.vertexBuffer)
129         , posVertexBuffer(inOther.posVertexBuffer)
130         , indexBuffer(inOther.indexBuffer)
131         , primitiveType(inOther.primitiveType)
132         , edgeTessFactor(inOther.edgeTessFactor)
133         , innerTessFactor(inOther.innerTessFactor)
134         , wireframeMode(inOther.wireframeMode)
135         , name(inOther.name)
136     {
137     }
138 
139     QSSGRenderSubset &operator=(const QSSGRenderSubset &inOther)
140     {
141         if (this != &inOther) {
142             QSSGRenderSubsetBase::operator=(inOther);
143             inputAssembler = inOther.inputAssembler;
144             inputAssemblerDepth = inOther.inputAssemblerDepth;
145             vertexBuffer = inOther.vertexBuffer;
146             posVertexBuffer = inOther.posVertexBuffer;
147             indexBuffer = inOther.indexBuffer;
148             primitiveType = inOther.primitiveType;
149             edgeTessFactor = inOther.edgeTessFactor;
150             innerTessFactor = inOther.innerTessFactor;
151             wireframeMode = inOther.wireframeMode;
152             joints = inOther.joints;
153             name = inOther.name;
154             subSubsets = inOther.subSubsets;
155         }
156         return *this;
157     }
158 };
159 
160 struct QSSGRenderMeshPath
161 {
162     QString path;
163     uint key = 0;
164 
isNullQSSGRenderMeshPath165     inline bool isNull() const { return path.isNull(); }
166 
createQSSGRenderMeshPath167     static QSSGRenderMeshPath create(const QString &path)
168     {
169         QSSGRenderMeshPath p;
170         p.path = path;
171         p.key = qHash(path);
172         return p;
173     }
174 };
175 
176 inline bool operator==(const QSSGRenderMeshPath &p1, const QSSGRenderMeshPath &p2)
177 {
178     return (p1.path == p2.path);
179 }
180 
qHash(const QSSGRenderMeshPath & path,uint seed)181 inline uint qHash(const QSSGRenderMeshPath &path, uint seed) Q_DECL_NOTHROW
182 {
183     return (path.key) ? path.key : qHash(path.path, seed);
184 }
185 
186 struct QSSGRenderMesh
187 {
188     Q_DISABLE_COPY(QSSGRenderMesh)
189 
190     QVector<QSSGRenderSubset> subsets;
191     QVector<QSSGRenderJoint> joints;
192     QSSGRenderDrawMode drawMode;
193     QSSGRenderWinding winding; // counterclockwise
194     quint32 meshId; // Id from the file of this mesh.
195     QSSGMeshBVH *bvh = nullptr;
196     QVector<QByteArray> inputLayoutInputNames;
197 
QSSGRenderMeshQSSGRenderMesh198     QSSGRenderMesh(QSSGRenderDrawMode inDrawMode, QSSGRenderWinding inWinding, quint32 inMeshId)
199         : drawMode(inDrawMode), winding(inWinding), meshId(inMeshId)
200     {
201     }
202 
~QSSGRenderMeshQSSGRenderMesh203     ~QSSGRenderMesh()
204     {
205         delete bvh;
206     }
207 };
208 QT_END_NAMESPACE
209 
210 #endif
211