• 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 CORE_UTIL_MESH_BUILDER_H
17 #define CORE_UTIL_MESH_BUILDER_H
18 
19 #include <3d/util/intf_mesh_builder.h>
20 #include <base/util/formats.h>
21 #include <core/namespace.h>
22 #include <render/resource_handle.h>
23 
24 #include "gltf/gltf2_util.h"
25 
26 RENDER_BEGIN_NAMESPACE()
27 class IRenderContext;
28 RENDER_END_NAMESPACE()
29 
CORE3D_BEGIN_NAMESPACE()30 CORE3D_BEGIN_NAMESPACE()
31 class MeshBuilder final : public IMeshBuilder {
32 public:
33     MeshBuilder(RENDER_NS::IRenderContext& renderContext);
34 
35     ~MeshBuilder() override = default;
36 
37     void Initialize(const RENDER_NS::VertexInputDeclarationView& vertexInputDeclaration, size_t submeshCount) override;
38     void Initialize(const Configuration& config) override;
39 
40     void AddSubmesh(const MeshBuilder::Submesh& submesh) override;
41 
42     const Submesh& GetSubmesh(size_t index) const override;
43 
44     void Allocate() override;
45 
46     void SetVertexData(size_t submeshIndex, const DataBuffer& positions, const DataBuffer& normals,
47         const DataBuffer& texcoords0, const DataBuffer& texcoords1, const DataBuffer& tangents,
48         const DataBuffer& colors) override;
49 
50     void SetIndexData(size_t submeshIndex, const DataBuffer& indices) override;
51 
52     void SetJointData(size_t submeshIndex, const DataBuffer& jointData, const DataBuffer& weightData,
53         const DataBuffer& vertexPositions) override;
54 
55     void SetMorphTargetData(size_t submeshIndex, const DataBuffer& basePositions, const DataBuffer& baseNormals,
56         const DataBuffer& baseTangents, const DataBuffer& targetPositions, const DataBuffer& targetNormals,
57         const DataBuffer& targetTangents) override;
58 
59     void SetAABB(size_t submeshIndex, const BASE_NS::Math::Vec3& min, const BASE_NS::Math::Vec3& max) override;
60     void CalculateAABB(size_t submeshIndex, const DataBuffer& positions) override;
61 
62     BASE_NS::array_view<const uint8_t> GetVertexData() const override;
63     BASE_NS::array_view<const uint8_t> GetIndexData() const override;
64     BASE_NS::array_view<const uint8_t> GetJointData() const override;
65     BASE_NS::array_view<const uint8_t> GetMorphTargetData() const override;
66 
67     BASE_NS::array_view<const float> GetJointBoundsData() const override;
68 
69     BASE_NS::array_view<const MeshComponent::Submesh> GetSubmeshes() const override;
70 
71     uint32_t GetVertexCount() const override;
72     uint32_t GetIndexCount() const override;
73 
74     void CreateGpuResources() override;
75     void CreateGpuResources(const GpuBufferCreateInfo& createInfo) override;
76 
77     CORE_NS::Entity CreateMesh(CORE_NS::IEcs& ecs) const override;
78     CORE_NS::Entity CreateMesh(CORE_NS::IEcs& ecs, CORE_NS::Entity meshEntity) const override;
79 
80     // IInterface
81     const IInterface* GetInterface(const BASE_NS::Uid& uid) const override;
82     IInterface* GetInterface(const BASE_NS::Uid& uid) override;
83 
84     void Ref() override;
85     void Unref() override;
86 
87     void EnablePrimitiveRestart(size_t index);
88 
89     struct BufferHandles {
90         RENDER_NS::RenderHandleReference vertexBuffer;
91     };
92 
93     struct BufferEntities {
94         CORE_NS::EntityReference vertexBuffer;
95         CORE_NS::EntityReference jointBuffer;
96         CORE_NS::EntityReference indexBuffer;
97         CORE_NS::EntityReference morphBuffer;
98     };
99 
100     // Morph target descriptor
101     struct MorphTargetDesc {
102         // Offset to morph target data from submesh's morphTargetOffset.
103         uint32_t offset { 0 };
104         // Byte size of morph target data.
105         uint32_t byteSize { 0 };
106     };
107 
108     // Extend submesh info with offset-data.
109     struct SubmeshExt {
110         MeshBuilder::Submesh info;
111 
112         // Automatically calculated by builder.
113         BASE_NS::vector<uint32_t> vertexBindingByteSize;
114         BASE_NS::vector<uint32_t> vertexBindingOffset;
115         BASE_NS::vector<MorphTargetDesc> morphTargets;
116         uint32_t jointBufferOffset = 0;
117         uint32_t indexBufferOffset = 0;
118         uint32_t morphTargetBufferOffset = 0;
119         uint32_t morphTargetBufferSize = 0;
120         bool hasNormals = false;
121         bool hasUv0 = false;
122         bool hasTangents = false;
123         int32_t positionOffset = -1;
124         uint32_t positionSize = 0;
125         int32_t normalOffset = -1;
126         uint32_t normalSize = 0;
127         int32_t uvOffset = -1;
128         uint32_t uvSize = 0;
129         int32_t tangentsOffset = -1;
130         uint32_t tangentSize = 0;
131         int32_t indexOffset = -1;
132         uint32_t indexSize = 0;
133     };
134 
135 private:
136     BufferEntities CreateBuffers(CORE_NS::IEcs& ecs) const;
137     void GenerateMissingAttributes() const;
138 
139     struct BufferSizesInBytes {
140         size_t indexBuffer;
141         size_t jointBuffer;
142         size_t morphVertexData;
143     };
144 
145     BufferSizesInBytes CalculateSizes();
146 
147     static void GatherDeltasP(SubmeshExt& submesh, uint8_t* dst, uint32_t baseOffset, uint32_t indexOffset,
148         uint32_t targetSize, const DataBuffer& targetPositions);
149     static void GatherDeltasPN(SubmeshExt& submesh, uint8_t* dst, uint32_t baseOffset, uint32_t indexOffset,
150         uint32_t targetSize, const DataBuffer& targetPositions, const DataBuffer& targetNormals);
151     static void GatherDeltasPT(SubmeshExt& submesh, uint8_t* dst, uint32_t baseOffset, uint32_t indexOffset,
152         uint32_t targetSize, const DataBuffer& targetPositions, const MeshBuilder::DataBuffer& targetTangents);
153     static void GatherDeltasPNT(SubmeshExt& submesh, uint8_t* dst, uint32_t baseOffset, uint32_t indexOffset,
154         uint32_t targetSize, const DataBuffer& targetPositions, const DataBuffer& targetNormals,
155         const DataBuffer& targetTangents);
156 
157     void CalculateJointBounds(
158         const DataBuffer& jointData, const DataBuffer& weightData, const DataBuffer& vertexPositions);
159 
160     bool WriteData(const DataBuffer& data, const SubmeshExt& submesh, uint32_t attributeLocation, uint32_t& byteOffset,
161         uint32_t& byteSize, uint8_t* dst) const;
162 
163     RENDER_NS::IRenderContext& renderContext_;
164     RENDER_NS::VertexInputDeclarationView vertexInputDeclaration_;
165 
166     mutable BASE_NS::vector<SubmeshExt> submeshInfos_;
167     mutable BASE_NS::vector<MeshComponent::Submesh> submeshes_;
168 
169     uint32_t vertexCount_ = 0;
170     uint32_t indexCount_ = 0;
171 
172     size_t vertexDataSize_ = 0;
173     size_t indexDataSize_ = 0;
174     size_t jointDataSize_ = 0;
175     size_t targetDataSize_ = 0;
176     BufferHandles bufferHandles_;
177     RENDER_NS::RenderHandleReference stagingBuffer_;
178     mutable uint8_t* stagingPtr_ = nullptr;
179     uint8_t* vertexPtr_ = nullptr;
180 
181     struct Bounds {
182         BASE_NS::Math::Vec3 min;
183         BASE_NS::Math::Vec3 max;
184     };
185     // Bounds for each joint is 6 floats (3 min & 3 max).
186     static_assert(sizeof(Bounds) == (sizeof(float) * 6));
187     BASE_NS::vector<Bounds> jointBoundsData_;
188 
189     mutable BASE_NS::vector<uint8_t> vertexData_;
190     BASE_NS::vector<uint8_t> indexData_;
191     uint32_t flags_ = 0;
192     bool rtEnabled_ { false };
193     uint32_t refCount_ = 0;
194 };
195 CORE3D_END_NAMESPACE()
196 
197 #endif // CORE_UTIL_MESH_BUILDER_H
198