• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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     enum ConfigurationFlagBits : uint32_t {
44         /** Don't use staging buffer. Requires less memory and avoids copying data from staging to final buffers, but
45            this implies host visible buffers which can have . */
46         NO_STAGING_BUFFER = 0x1,
47     };
48 
49     /** Initialization parameters. */
50     struct Configuration {
51         /** Defines the expected vertex input layout i.e. how the mesh data should be stored in buffers. */
52         RENDER_NS::VertexInputDeclarationView vertexInputDeclaration;
53         /** Number of submeshes in the next mesh. */
54         size_t submeshCount;
55         uint32_t flags;
56     };
57 
58     /** Submesh attributes */
59     struct Submesh {
60         /** Vertex count */
61         uint32_t vertexCount { 0 };
62         /** Index count */
63         uint32_t indexCount { 0 };
64         /** Instance count */
65         uint32_t instanceCount { 1 };
66         /** Morph target count */
67         uint32_t morphTargetCount { 0 };
68         /** Index type */
69         RENDER_NS::IndexType indexType { RENDER_NS::IndexType::CORE_INDEX_TYPE_UINT32 };
70 
71         /** Material */
72         CORE_NS::Entity material {};
73         /** Tangents */
74         bool tangents { false };
75         /** Colors */
76         bool colors { false };
77         /** Joints */
78         bool joints { false };
79 
80         /** Optional input assembly. Will be filled to Submesh */
81         RENDER_NS::GraphicsState::InputAssembly inputAssembly { false,
82             RENDER_NS::PrimitiveTopology::CORE_PRIMITIVE_TOPOLOGY_MAX_ENUM };
83     };
84 
85     /** GPU buffer create info */
86     struct GpuBufferCreateInfo {
87         /** Additional usage flags */
88         RENDER_NS::BufferUsageFlags usage { 0U };
89         /** Engine creation flags */
90         RENDER_NS::EngineBufferCreationFlags engineCreation { 0U };
91         /** Memory property flags */
92         RENDER_NS::MemoryPropertyFlags memoryFlags { 0U };
93     };
94 
95     /** Prepare the builder for adding submeshes. Also resets the builder for re-use.
96      */
97     virtual void Initialize(
98         const RENDER_NS::VertexInputDeclarationView& vertexInputDeclaration, size_t submeshCount) = 0;
99 
100     /** Prepare the builder for adding submeshes. Also resets the builder for re-use.
101      * @param config Configuration parameters.
102      */
103     virtual void Initialize(const Configuration& config) = 0;
104 
105     /** Add a submesh and related import info to this mesh.
106      * @param submesh Submesh import information that is used to determine memory requirements etc.
107      */
108     virtual void AddSubmesh(const Submesh& submesh) = 0;
109 
110     /** Returns Import info for given submesh.
111      * @param index Index of the submesh.
112      * @return Import information for the given submesh.
113      */
114     virtual const Submesh& GetSubmesh(size_t index) const = 0;
115 
116     /** Allocates memory for this mesh, should be called after all submeshes have been added to this mesh and before
117      * data is being fed to submeshes. */
118     virtual void Allocate() = 0;
119 
120     /** Struct for passing data to the mesh builder.*/
121     struct DataBuffer {
122         /** Format of each element in buffer. e.g. three float values per element would be R32G32B32_SFLOAT. */
123         BASE_NS::Format format;
124         /** Offset between elements. This should match the size of one element for tightly packed values. */
125         uint32_t stride;
126         /** Byte arrays which will be interpreted based on format and stride. */
127         BASE_NS::array_view<const uint8_t> buffer;
128     };
129 
130     /** Set geometry data for a given submesh.
131      * @param submeshIndex Index of the submesh.
132      * @param positions Position data (3 * vertexCount values), this parameter is required.
133      * @param normals Normal data (3 * vertexCount values), this parameter is required.
134      * @param texcoords0 Texture coordinate 0 data (2 * vertexCount values), this parameter is required.
135      * @param texcoords1 Texture coordinate 1 data (2 * vertexCount values), this parameter is optional.
136      * @param tangents Tangent data (4 * vertexCount values), this parameter is optional.
137      * @param colors Vertex color data  (4 * vertexCount values), this parameter is optional.
138      */
139     virtual void SetVertexData(size_t submeshIndex, const DataBuffer& positions, const DataBuffer& normals,
140         const DataBuffer& texcoords0, const DataBuffer& texcoords1, const DataBuffer& tangents,
141         const DataBuffer& colors) = 0;
142 
143     /** Set Axis-aligned bounding box for a submesh.
144      * @param submeshIndex Index of the submesh.
145      * @param min Minimum corner.
146      * @param max Minimum corner.
147      */
148     virtual void SetAABB(size_t submeshIndex, const BASE_NS::Math::Vec3& min, const BASE_NS::Math::Vec3& max) = 0;
149 
150     /** Calculate Axis-aligned bounding box for a submesh.
151      * @param submeshIndex Index of the submesh.
152      * @param positions Array of vertex positions in submesh.
153      */
154     virtual void CalculateAABB(size_t submeshIndex, const DataBuffer& positions) = 0;
155 
156     /** Set triangle indices for a submesh.
157      * @param submeshIndex Index of the submesh.
158      * @param indices Index data.
159      */
160     virtual void SetIndexData(size_t submeshIndex, const DataBuffer& indices) = 0;
161 
162     /** Set Joint data for a submesh.
163      * @param submeshIndex Index of the submesh.
164      * @param jointData Joint indices per vertex, (4 indices per bone).
165      * @param weightData Joint weights per vertex , (4 weights per bone).
166      * @param vertexPositions Position data that is used for skin bounds calculations (3 * vertexCount
167      * values), this data should match the data set with SetVertexData().
168      */
169     virtual void SetJointData(size_t submeshIndex, const DataBuffer& jointData, const DataBuffer& weightData,
170         const DataBuffer& vertexPositions) = 0;
171 
172     /** Set Morph targets for a submesh.
173      * @param submeshIndex Index of the submesh.
174      * @param basePositions Initial vertex positions (base pose).
175      * @param baseNormals Initial vertex normals (base pose).
176      * @param baseTangents Initial vertex tangents (base pose).
177      * @param targetPositions Morph target vertex positions (delta offsets from base vertex, total size of array is
178      * target_count * vertex_count).
179      * @param targetNormals Morph target vertex normals (delta offsets from base vertex, total size of array is
180      * target_count * vertex_count).
181      * @param targetTangents Morph target vertex tangents (delta offsets from base vertex, total size of array is
182      * target_count * vertex_count).
183      */
184     virtual void SetMorphTargetData(size_t submeshIndex, const DataBuffer& basePositions, const DataBuffer& baseNormals,
185         const DataBuffer& baseTangents, const DataBuffer& targetPositions, const DataBuffer& targetNormals,
186         const DataBuffer& targetTangents) = 0;
187 
188     /** Returns all vertex data of this mesh. */
189     virtual BASE_NS::array_view<const uint8_t> GetVertexData() const = 0;
190 
191     /** Returns all index data of this mesh. */
192     virtual BASE_NS::array_view<const uint8_t> GetIndexData() const = 0;
193 
194     /** Returns all joint data of this mesh. */
195     virtual BASE_NS::array_view<const uint8_t> GetJointData() const = 0;
196 
197     /** Returns all morph target data of this mesh. */
198     virtual BASE_NS::array_view<const uint8_t> GetMorphTargetData() const = 0;
199 
200     /**
201      * Returns an array of joint bounds data. Each joint that is referenced by the vertex joint data will
202      * be represented by 6 values defining the min and max bounds defining the bounds for that joint.
203      */
204     virtual BASE_NS::array_view<const float> GetJointBoundsData() const = 0;
205 
206     /** Returns all submeshes of this mesh. */
207     virtual BASE_NS::array_view<const MeshComponent::Submesh> GetSubmeshes() const = 0;
208 
209     /** Returns total vertex count in this mesh, note that this function should be called after Allocate() has been
210      * called. */
211     virtual uint32_t GetVertexCount() const = 0;
212 
213     /** Returns total index count in this mesh, note that 16bit indices are packed (two per one 32-bit slot) and there
214      * might be padding involved. */
215     virtual uint32_t GetIndexCount() const = 0;
216 
217     /** Creates GPU buffers and copies the data passed in by the Set*Data calls.
218      */
219     virtual void CreateGpuResources() = 0;
220 
221     /** Creates GPU buffers and copies the data passed in by the Set*Data calls.
222      * @param Additional create info with additional flags for buffers.
223      */
224     virtual void CreateGpuResources(const GpuBufferCreateInfo& createInfo) = 0;
225 
226     /** Create a mesh entity with a mesh component from the previously given data (submeshes, vertices, indices etc).
227      * @param ecs The ECS instance.
228      * @return The created entity, or an invalid entity if there is no mesh data or if an error occurred.
229      * @note The mesh component owns the attached GPU resources.
230      */
231     virtual CORE_NS::Entity CreateMesh(CORE_NS::IEcs& ecs) const = 0;
232 
233     /** Create a mesh entity with a mesh component from the previously given data (submeshes, vertices, indices etc).
234      * @param ecs The ECS instance.
235      * @param meshEntity If valid, append to the mesh component of this entity (or create a new component).
236      * @return The created entity, or an invalid entity if there is no mesh data or if an error occurred.
237      * @note The mesh component owns the attached GPU resources.
238      */
239     virtual CORE_NS::Entity CreateMesh(CORE_NS::IEcs& ecs, CORE_NS::Entity meshEntity) const = 0;
240 
241 protected:
242     IMeshBuilder() = default;
243     virtual ~IMeshBuilder() = default;
244 };
245 
GetName(const IMeshBuilder *)246 inline constexpr BASE_NS::string_view GetName(const IMeshBuilder*)
247 {
248     return "IMeshBuilder";
249 }
250 CORE3D_END_NAMESPACE()
251 
252 #endif // API_3D_UTIL_IMESH_BUILDER_H
253