• 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__GLTF__GLTF2_IMPORTER_H
17 #define CORE__GLTF__GLTF2_IMPORTER_H
18 
19 #include <atomic>
20 #include <mutex>
21 
22 #include <3d/gltf/gltf.h>
23 #include <3d/loaders/intf_scene_loader.h>
24 #include <3d/util/intf_mesh_builder.h>
25 #include <base/containers/string.h>
26 #include <base/containers/unique_ptr.h>
27 #include <base/containers/vector.h>
28 #include <base/util/color.h>
29 #include <core/ecs/entity_reference.h>
30 #include <core/ecs/intf_ecs.h>
31 #include <core/namespace.h>
32 #include <core/threading/intf_thread_pool.h>
33 
34 BASE_BEGIN_NAMESPACE()
35 template<class Key, class T>
36 class unordered_map;
37 BASE_END_NAMESPACE()
38 
39 CORE_BEGIN_NAMESPACE()
40 class IEngine;
41 class IImageLoaderManager;
42 class IPerformanceDataManager;
43 CORE_END_NAMESPACE()
44 
45 RENDER_BEGIN_NAMESPACE()
46 class IDevice;
47 class IGpuResourceManager;
48 class IRenderContext;
49 class IShaderManager;
50 RENDER_END_NAMESPACE()
51 
52 CORE3D_BEGIN_NAMESPACE()
53 class IGraphicsContext;
54 class IRenderHandleComponentManager;
55 class IMaterialComponentManager;
56 class IMeshComponentManager;
57 class INameComponentManager;
58 class IUriComponentManager;
59 class IAnimationInputComponentManager;
60 class IAnimationOutputComponentManager;
61 
62 namespace GLTF2 {
63 class Data;
64 struct Accessor;
65 struct AnimationTrack;
66 enum class ImportPhase {
67     BUFFERS = 0,
68     SAMPLERS,
69     IMAGES,
70     TEXTURES,
71     MATERIALS,
72     ANIMATION_SAMPLERS,
73     ANIMATIONS,
74     SKINS,
75     MESHES,
76     FINISHED
77 };
78 
79 // A class that executes GLTF load and import operation over multiple frames.
80 class GLTF2Importer final : public IGLTF2Importer {
81 public:
82     GLTF2Importer(CORE_NS::IEngine& engine, RENDER_NS::IRenderContext& renderContext, CORE_NS::IEcs& ecs);
83     GLTF2Importer(CORE_NS::IEngine& engine, RENDER_NS::IRenderContext& renderContext, CORE_NS::IEcs& ecs,
84         CORE_NS::IThreadPool& pool);
85     ~GLTF2Importer() override;
86 
87     void ImportGLTF(const IGLTFData& data, GltfResourceImportFlags flags) override;
88     void ImportGLTFAsync(const IGLTFData& data, GltfResourceImportFlags flags, Listener* listener) override;
89     bool Execute(uint32_t timeBudget) override;
90 
91     void Cancel() override;
92     bool IsCompleted() const override;
93 
94     const GLTFImportResult& GetResult() const override;
95 
96     const GltfMeshData& GetMeshData() const override;
97 
98     bool IsValid() const;
99 
100     struct DefaultMaterialShaderData {
101         struct SingleShaderData {
102             CORE_NS::EntityReference shader;
103             CORE_NS::EntityReference gfxState;
104             CORE_NS::EntityReference gfxStateDoubleSided;
105         };
106         SingleShaderData opaque;
107         SingleShaderData blend;
108         SingleShaderData depth;
109     };
110 
111 protected:
112     void Destroy() override;
113 
114 private:
115     friend class Gltf2;
116 
117     struct ImporterTask;
118     template<typename T>
119     struct GatheredDataTask;
120     template<typename Component>
121     struct ComponentTaskData;
122     struct AnimationTaskData;
123 
124     class ImportThreadTask;
125     class GatherThreadTask;
126 
127     void LaunchGatherTasks(size_t firstTask, ImportPhase phase);
128     void Prepare();
129     void PrepareBufferTasks();
130     void PrepareSamplerTasks();
131     void PrepareImageTasks();
132     void PrepareImageBasedLightTasks();
133     void PrepareMaterialTasks();
134     void PrepareAnimationTasks();
135     void PrepareSkinTasks();
136     void PrepareMeshTasks();
137     template<typename T>
138     GatheredDataTask<T>* PrepareAnimationInputTask(BASE_NS::unordered_map<GLTF2::Accessor*, GatheredDataTask<T>*>&,
139         const GLTF2::AnimationTrack&, IAnimationInputComponentManager*);
140     template<typename T>
141     GatheredDataTask<T>* PrepareAnimationOutputTask(BASE_NS::unordered_map<GLTF2::Accessor*, GatheredDataTask<T>*>&,
142         const GLTF2::AnimationTrack&, IAnimationOutputComponentManager*);
143     void QueueImage(size_t i, BASE_NS::string&& uri, BASE_NS::string&& name);
144 
145     void QueueTask(BASE_NS::unique_ptr<ImporterTask>&& task);
146     bool ProgressTask(ImporterTask& task);
147     void Gather(ImporterTask& task);
148     void Import(ImporterTask& task);
149     void CompleteTask(ImporterTask& task);
150 
151     void StartPhase(ImportPhase phase);
152     void HandleGatherTasks();
153     void HandleImportTasks();
154 
155     ImporterTask* FindTaskById(uint64_t id);
156 
157     ImportPhase phase_ { ImportPhase::BUFFERS };
158     GltfResourceImportFlags flags_ { CORE_GLTF_IMPORT_RESOURCE_FLAG_BITS_ALL };
159 
160     const CORE_NS::IThreadPool::ITask* bufferTask_ { nullptr };
161     BASE_NS::vector<BASE_NS::unique_ptr<ImporterTask>> tasks_;
162     CORE_NS::IThreadPool::IResult::Ptr gatherResults_[static_cast<uint32_t>(ImportPhase::FINISHED)];
163 
164     CORE_NS::IEngine& engine_;
165     RENDER_NS::IRenderContext& renderContext_;
166     RENDER_NS::IDevice& device_;
167     RENDER_NS::IGpuResourceManager& gpuResourceManager_;
168     CORE_NS::IEcs::Ptr ecs_;
169     IRenderHandleComponentManager* renderHandleManager_;
170     IMaterialComponentManager* materialManager_;
171     IMeshComponentManager* meshManager_;
172     INameComponentManager* nameManager_;
173     IUriComponentManager* uriManager_;
174 
175     // assigned to material in import
176     DefaultMaterialShaderData dmShaderData_;
177 
178     const Data* data_ { nullptr };
179 
180     CORE_NS::IThreadPool::Ptr threadPool_;
181     CORE_NS::IDispatcherTaskQueue::Ptr mainThreadQueue_;
182     Listener* listener_ { nullptr };
183 
184     GLTFImportResult result_;
185 
186     std::mutex gatherTasksLock_;
187     BASE_NS::vector<uint64_t> finishedGatherTasks_[static_cast<uint32_t>(ImportPhase::FINISHED)];
188 
189     size_t pendingGatherTasks_[static_cast<uint32_t>(ImportPhase::FINISHED)] {};
190     size_t pendingImportTasks_ { 0 };
191     size_t completedTasks_ { 0 };
192 
193     BASE_NS::vector<IMeshBuilder::Ptr> meshBuilders_;
194     GltfMeshData meshData_;
195 
196     BASE_NS::ColorSpaceFlags colorSpaceFlags_ { 0U };
197     std::atomic_bool cancelled_ { false };
198 };
199 
200 class Gltf2SceneImporter final : public ISceneImporter, IGLTF2Importer::Listener {
201 public:
202     Gltf2SceneImporter(CORE_NS::IEngine& engine, RENDER_NS::IRenderContext& renderContext, CORE_NS::IEcs& ecs);
203     Gltf2SceneImporter(CORE_NS::IEngine& engine, RENDER_NS::IRenderContext& renderContext, CORE_NS::IEcs& ecs,
204         CORE_NS::IThreadPool& pool);
205     ~Gltf2SceneImporter() = default;
206 
207     void ImportResources(const ISceneData::Ptr& data, ResourceImportFlags flags) override;
208     void ImportResources(
209         const ISceneData::Ptr& data, ResourceImportFlags flags, ISceneImporter::Listener* listener) override;
210     bool Execute(uint32_t timeBudget) override;
211     void Cancel() override;
212     bool IsCompleted() const override;
213     const Result& GetResult() const override;
214     const MeshData& GetMeshData() const override;
215     CORE_NS::Entity ImportScene(size_t sceneIndex) override;
216     CORE_NS::Entity ImportScene(size_t sceneIndex, SceneImportFlags flags) override;
217     CORE_NS::Entity ImportScene(size_t sceneIndex, CORE_NS::Entity parentEntity) override;
218     CORE_NS::Entity ImportScene(size_t sceneIndex, CORE_NS::Entity parentEntity, SceneImportFlags flags) override;
219     CORE_NS::Entity ImportScene(size_t sceneIndex, uint32_t sceneId, SceneImportFlags flags) override;
220 
221     // IInterface
222     const IInterface* GetInterface(const BASE_NS::Uid& uid) const override;
223     IInterface* GetInterface(const BASE_NS::Uid& uid) override;
224     void Ref() override;
225     void Unref() override;
226 
227     // IGLTF2Importer::Listener
228     void OnImportStarted() override;
229     void OnImportFinished() override;
230     void OnImportProgressed(size_t taskIndex, size_t taskCount) override;
231 
232 private:
233     void UpdateResults();
234 
235     CORE_NS::IEcs& ecs_;
236     IGraphicsContext* graphicsContext_ { nullptr };
237     GLTF2Importer::Ptr importer_;
238     ISceneData::Ptr data_;
239     uint32_t refcnt_ { 0 };
240     Result result_;
241     MeshData meshData_;
242     ISceneImporter::Listener* listener_ { nullptr };
243 };
244 } // namespace GLTF2
245 
246 CORE_NS::Entity ImportScene(RENDER_NS::IDevice& device, size_t sceneIndex, const GLTF2::Data& data,
247     const GLTFResourceData& gltfResourceData, CORE_NS::IEcs& ecs, CORE_NS::Entity rootEntity, uint32_t level,
248     GltfSceneImportFlags flags);
249 CORE3D_END_NAMESPACE()
250 
251 #endif // CORE__GLTF__GLTF2_IMPORTER_H
252