• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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 
CORE3D_BEGIN_NAMESPACE()26 CORE3D_BEGIN_NAMESPACE()
27 class MeshBuilder final : public IMeshBuilder {
28 public:
29     MeshBuilder() = default;
30 
31     ~MeshBuilder() override = default;
32 
33     void Initialize(const RENDER_NS::VertexInputDeclarationView& vertexInputDeclaration, size_t submeshCount) override;
34 
35     void AddSubmesh(const MeshBuilder::Submesh& submesh) override;
36 
37     const Submesh& GetSubmesh(size_t index) const override;
38 
39     void Allocate() override;
40 
41     void SetVertexData(size_t submeshIndex, const BASE_NS::array_view<const BASE_NS::Math::Vec3>& positions,
42         const BASE_NS::array_view<const BASE_NS::Math::Vec3>& normals,
43         const BASE_NS::array_view<const BASE_NS::Math::Vec2>& texcoords0,
44         const BASE_NS::array_view<const BASE_NS::Math::Vec2>& texcoords1,
45         const BASE_NS::array_view<const BASE_NS::Math::Vec4>& tangents,
46         const BASE_NS::array_view<const BASE_NS::Math::Vec4>& colors) override;
47 
48     void SetVertexData(size_t submeshIndex, const BASE_NS::array_view<const float>& positions,
49         const BASE_NS::array_view<const float>& normals, const BASE_NS::array_view<const float>& texcoords0,
50         const BASE_NS::array_view<const float>& texcoords1, const BASE_NS::array_view<const float>& tangents,
51         const BASE_NS::array_view<const float>& colors) override;
52 
53     void SetIndexData(size_t submeshIndex, const BASE_NS::array_view<const uint8_t>& indices) override;
54     void SetJointData(size_t submeshIndex, const BASE_NS::array_view<const uint8_t>& jointData,
55         const BASE_NS::array_view<const BASE_NS::Math::Vec4>& weightData,
56         const BASE_NS::array_view<const BASE_NS::Math::Vec3>& vertexPositions) override;
57 
58     void SetMorphTargetData(size_t submeshIndex, const BASE_NS::array_view<const BASE_NS::Math::Vec3>& basePositions,
59         const BASE_NS::array_view<const BASE_NS::Math::Vec3>& baseNormals,
60         const BASE_NS::array_view<const BASE_NS::Math::Vec4>& baseTangents,
61         const BASE_NS::array_view<const BASE_NS::Math::Vec3>& targetPositions,
62         const BASE_NS::array_view<const BASE_NS::Math::Vec3>& targetNormals,
63         const BASE_NS::array_view<const BASE_NS::Math::Vec3>& targetTangents) override;
64 
65     void SetAABB(size_t submeshIndex, const BASE_NS::Math::Vec3& min, const BASE_NS::Math::Vec3& max) override;
66     void CalculateAABB(size_t submeshIndex, const BASE_NS::array_view<const BASE_NS::Math::Vec3>& positions) override;
67 
68     BASE_NS::array_view<const uint8_t> GetVertexData() const override;
69     BASE_NS::array_view<const uint8_t> GetIndexData() const override;
70     BASE_NS::array_view<const uint8_t> GetJointData() const override;
71     BASE_NS::array_view<const uint8_t> GetMorphTargetData() const override;
72 
73     BASE_NS::array_view<const float> GetJointBoundsData() const override;
74 
75     const BASE_NS::array_view<const MeshComponent::Submesh> GetSubmeshes() const override;
76 
77     uint32_t GetVertexCount() const override;
78     uint32_t GetIndexCount() const override;
79 
80     CORE_NS::Entity CreateMesh(CORE_NS::IEcs& ecs) const override;
81 
82     // IInterface
83     const IInterface* GetInterface(const BASE_NS::Uid& uid) const override;
84     IInterface* GetInterface(const BASE_NS::Uid& uid) override;
85 
86     void Ref() override;
87     void Unref() override;
88 
89     struct BufferEntities {
90         CORE_NS::EntityReference vertexBuffer;
91         CORE_NS::EntityReference jointBuffer;
92         CORE_NS::EntityReference indexBuffer;
93         CORE_NS::EntityReference morphBuffer;
94     };
95 
96 private:
97     BufferEntities CreateBuffers(CORE_NS::IEcs& ecs) const;
98 
99     // Morph target descriptor
100     struct MorphTargetDesc {
101         // Offset to morph target data from submesh's morphTargetOffset.
102         uint32_t offset { 0 };
103         // Byte size of morph target data.
104         uint32_t byteSize { 0 };
105     };
106 
107     // Extend submesh info with offset-data.
108     struct SubmeshExt {
109         MeshBuilder::Submesh info;
110 
111         // Automatically calculated by builder.
112         uint32_t vertexIndex = 0;
113         BASE_NS::vector<uint32_t> vertexBindingByteSize;
114         BASE_NS::vector<uint32_t> vertexBindingOffset;
115         uint32_t jointBufferOffset = 0;
116         uint32_t indexBufferOffset = 0;
117         uint32_t morphTargetBufferOffset = 0;
118         uint32_t morphTargetBufferSize = 0;
119 
120         BASE_NS::vector<MorphTargetDesc> morphTargets;
121     };
122     struct BufferSizesInBytes {
123         size_t indexBuffer;
124         size_t jointBuffer;
125         size_t morphVertexData;
126     };
127     BufferSizesInBytes CalculateSizes();
128     void GatherDeltas(SubmeshExt& submesh, uint32_t baseOffset, uint32_t indexOffset, uint32_t targetSize,
129         const BASE_NS::array_view<const BASE_NS::Math::Vec3> targetPositions,
130         const BASE_NS::array_view<const BASE_NS::Math::Vec3> targetNormals,
131         const BASE_NS::array_view<const BASE_NS::Math::Vec3> targetTangents);
132 
133     void CalculateJointBounds(const BASE_NS::array_view<const BASE_NS::Math::Vec4>& weightData,
134         const BASE_NS::array_view<const uint8_t>& jointData,
135         const BASE_NS::array_view<const BASE_NS::Math::Vec3>& vertexPositions);
136 
137     bool WriteData(const BASE_NS::array_view<const float>& data, uint32_t componentCount, const SubmeshExt& submesh,
138         uint32_t attributeLocation, uint32_t& byteOffset, uint32_t& byteSize);
139 
140     void WriteFloatAttributeData(const void* destination, const void* source, size_t bufferOffset, size_t stride,
141         size_t componentCount, size_t componentByteSize, size_t elementCount, BASE_NS::Format targetFormat);
142 
143     void WriteByteAttributeData(const void* destination, const void* source, size_t bufferOffset, size_t stride,
144         size_t componentCount, size_t componentByteSize, size_t elementCount, BASE_NS::Format targetFormat);
145 
146     RENDER_NS::VertexInputDeclarationView vertexInputDeclaration_;
147 
148     BASE_NS::vector<SubmeshExt> submeshInfos_;
149     BASE_NS::vector<MeshComponent::Submesh> submeshes_;
150 
151     uint32_t vertexCount_ = 0;
152     uint32_t indexCount_ = 0;
153 
154     BASE_NS::vector<uint8_t> vertexData_;
155     BASE_NS::vector<uint8_t> jointData_;
156     BASE_NS::vector<uint8_t> indexData_;
157     BASE_NS::vector<uint8_t> targetData_;
158 
159     struct Bounds {
160         BASE_NS::Math::Vec3 min;
161         BASE_NS::Math::Vec3 max;
162     };
163     // Bounds for each joint is 6 floats (3 min & 3 max).
164     static_assert(sizeof(Bounds) == (sizeof(float) * 6));
165     BASE_NS::vector<Bounds> jointBoundsData_;
166     uint32_t refCount_ = 0;
167 };
168 
169 CORE3D_END_NAMESPACE()
170 
171 #endif // CORE_UTIL_MESH_BUILDER_H
172