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