1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #ifndef API_3D_UTIL_IMESH_BUILDER_H
17 #define API_3D_UTIL_IMESH_BUILDER_H
18
19 #include <cstddef>
20
21 #include <3d/ecs/components/mesh_component.h>
22 #include <base/containers/refcnt_ptr.h>
23 #include <base/util/formats.h>
24 #include <core/ecs/entity.h>
25 #include <core/namespace.h>
26 #include <core/plugin/intf_interface.h>
27 #include <render/device/pipeline_state_desc.h>
28 #include <render/resource_handle.h>
29
30 CORE_BEGIN_NAMESPACE()
31 class IEcs;
32 CORE_END_NAMESPACE()
33
CORE3D_BEGIN_NAMESPACE()34 CORE3D_BEGIN_NAMESPACE()
35 /** @ingroup group_util_imeshbuilder */
36 /** Mesh builder interface for building meshes */
37 class IMeshBuilder : public CORE_NS::IInterface {
38 public:
39 static constexpr auto UID = BASE_NS::Uid { "8d2892a4-77e5-4304-a5aa-38f866b7c788" };
40
41 using Ptr = BASE_NS::refcnt_ptr<IMeshBuilder>;
42
43 /** Submesh attributes */
44 struct Submesh {
45 /** Vertex count */
46 uint32_t vertexCount { 0 };
47 /** Index count */
48 uint32_t indexCount { 0 };
49 /** Instance count */
50 uint32_t instanceCount { 1 };
51 /** Morph target count */
52 uint32_t morphTargetCount { 0 };
53 /** Index type */
54 RENDER_NS::IndexType indexType { RENDER_NS::IndexType::CORE_INDEX_TYPE_UINT32 };
55
56 /** Material */
57 CORE_NS::Entity material {};
58 /** Tangents */
59 bool tangents { false };
60 /** Colors */
61 bool colors { false };
62 /** Joints */
63 bool joints { false };
64 };
65
66 /** GPU buffer create info */
67 struct GpuBufferCreateInfo {
68 /** Vertex buffer additional usage flags */
69 RENDER_NS::BufferUsageFlags vertexBufferFlags { 0U };
70 /** Index buffer additional usage flags */
71 RENDER_NS::BufferUsageFlags indexBufferFlags { 0U };
72 /** Morph buffer additional usage flags */
73 RENDER_NS::BufferUsageFlags morphBufferFlags { 0U };
74 };
75
76 /** Setup vertex declaration and submesh count for the builder. Also resets the builder for re-use.
77 */
78 virtual void Initialize(
79 const RENDER_NS::VertexInputDeclarationView& vertexInputDeclaration, size_t submeshCount) = 0;
80
81 /** Add a submesh and related import info to this mesh.
82 * @param submesh Submesh import information that is used to determine memory requirements etc.
83 */
84 virtual void AddSubmesh(const Submesh& submesh) = 0;
85
86 /** Returns Import info for given submesh.
87 * @param index Index of the submesh.
88 * @return Import information for the given submesh.
89 */
90 virtual const Submesh& GetSubmesh(size_t index) const = 0;
91
92 /** Allocates memory for this mesh, should be called after all submeshes have been added to this mesh and before
93 * data is being fed to submeshes. */
94 virtual void Allocate() = 0;
95
96 /** Struct for passing data to the mesh builder.*/
97 struct DataBuffer {
98 /** Format of each element in buffer. e.g. three float values per element would be R32G32B32_SFLOAT. */
99 BASE_NS::Format format;
100 /** Offset between elements. This should match the size of one element for tightly packed values. */
101 uint32_t stride;
102 /** Byte arrays which will be interpreted based on format and stride. */
103 BASE_NS::array_view<const uint8_t> buffer;
104 };
105
106 /** Set geometry data for a given submesh.
107 * @param submeshIndex Index of the submesh.
108 * @param positions Position data (3 * vertexCount values), this parameter is required.
109 * @param normals Normal data (3 * vertexCount values), this parameter is required.
110 * @param texcoords0 Texture coordinate 0 data (2 * vertexCount values), this parameter is required.
111 * @param texcoords1 Texture coordinate 1 data (2 * vertexCount values), this parameter is optional.
112 * @param tangents Tangent data (4 * vertexCount values), this parameter is optional.
113 * @param colors Vertex color data (4 * vertexCount values), this parameter is optional.
114 */
115 virtual void SetVertexData(size_t submeshIndex, const DataBuffer& positions, const DataBuffer& normals,
116 const DataBuffer& texcoords0, const DataBuffer& texcoords1, const DataBuffer& tangents,
117 const DataBuffer& colors) = 0;
118
119 /** Set Axis-aligned bounding box for a submesh.
120 * @param submeshIndex Index of the submesh.
121 * @param min Minimum corner.
122 * @param max Minimum corner.
123 */
124 virtual void SetAABB(size_t submeshIndex, const BASE_NS::Math::Vec3& min, const BASE_NS::Math::Vec3& max) = 0;
125
126 /** Calculate Axis-aligned bounding box for a submesh.
127 * @param submeshIndex Index of the submesh.
128 * @param positions Array of vertex positions in submesh.
129 */
130 virtual void CalculateAABB(size_t submeshIndex, const DataBuffer& positions) = 0;
131
132 /** Set triangle indices for a submesh.
133 * @param submeshIndex Index of the submesh.
134 * @param indices Index data.
135 */
136 virtual void SetIndexData(size_t submeshIndex, const DataBuffer& indices) = 0;
137
138 /** Set Joint data for a submesh.
139 * @param submeshIndex Index of the submesh.
140 * @param jointData Joint indices per vertex, (4 indices per bone).
141 * @param weightData Joint weights per vertex , (4 weights per bone).
142 * @param vertexPositions Position data that is used for skin bounds calculations (3 * vertexCount
143 * values), this data should match the data set with SetVertexData().
144 */
145 virtual void SetJointData(size_t submeshIndex, const DataBuffer& jointData, const DataBuffer& weightData,
146 const DataBuffer& vertexPositions) = 0;
147
148 /** Set Morph targets for a submesh.
149 * @param submeshIndex Index of the submesh.
150 * @param basePositions Initial vertex positions (base pose).
151 * @param baseNormals Initial vertex normals (base pose).
152 * @param baseTangents Initial vertex tangents (base pose).
153 * @param targetPositions Morph target vertex positions (delta offsets from base vertex, total size of array is
154 * target_count * vertex_count).
155 * @param targetNormals Morph target vertex normals (delta offsets from base vertex, total size of array is
156 * target_count * vertex_count).
157 * @param targetTangents Morph target vertex tangents (delta offsets from base vertex, total size of array is
158 * target_count * vertex_count).
159 */
160 virtual void SetMorphTargetData(size_t submeshIndex, const DataBuffer& basePositions, const DataBuffer& baseNormals,
161 const DataBuffer& baseTangents, const DataBuffer& targetPositions, const DataBuffer& targetNormals,
162 const DataBuffer& targetTangents) = 0;
163
164 /** Returns all vertex data of this mesh. */
165 virtual BASE_NS::array_view<const uint8_t> GetVertexData() const = 0;
166
167 /** Returns all index data of this mesh. */
168 virtual BASE_NS::array_view<const uint8_t> GetIndexData() const = 0;
169
170 /** Returns all joint data of this mesh. */
171 virtual BASE_NS::array_view<const uint8_t> GetJointData() const = 0;
172
173 /** Returns all morph target data of this mesh. */
174 virtual BASE_NS::array_view<const uint8_t> GetMorphTargetData() const = 0;
175
176 /**
177 * Returns an array of joint bounds data. Each joint that is referenced by the vertex joint data will
178 * be represented by 6 values defining the min and max bounds defining the bounds for that joint.
179 */
180 virtual BASE_NS::array_view<const float> GetJointBoundsData() const = 0;
181
182 /** Returns all submeshes of this mesh. */
183 virtual BASE_NS::array_view<const MeshComponent::Submesh> GetSubmeshes() const = 0;
184
185 /** Returns total vertex count in this mesh, note that this function should be called after Allocate() has been
186 * called. */
187 virtual uint32_t GetVertexCount() const = 0;
188
189 /** Returns total index count in this mesh, note that 16bit indices are packed (two per one 32-bit slot) and there
190 * might be padding involved. */
191 virtual uint32_t GetIndexCount() const = 0;
192
193 /** Creates GPU buffers and copies the data passed in by the Set*Data calls.
194 */
195 virtual void CreateGpuResources() = 0;
196
197 /** Creates GPU buffers and copies the data passed in by the Set*Data calls.
198 * @param Additional create info with additional flags for buffers.
199 */
200 virtual void CreateGpuResources(const GpuBufferCreateInfo& createInfo) = 0;
201
202 /** Helper for creating an entity with a mesh component. The mesh component is filled using the previously given
203 * data (submeshes, vertex data, index data, etc.). NOTE: the mesh component owns the attached GPU resources.
204 */
205 virtual CORE_NS::Entity CreateMesh(CORE_NS::IEcs& ecs) const = 0;
206
207 protected:
208 IMeshBuilder() = default;
209 virtual ~IMeshBuilder() = default;
210 };
211
GetName(const IMeshBuilder *)212 inline constexpr BASE_NS::string_view GetName(const IMeshBuilder*)
213 {
214 return "IMeshBuilder";
215 }
216 CORE3D_END_NAMESPACE()
217
218 #endif // API_3D_UTIL_IMESH_BUILDER_H
219