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__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 <base/containers/string.h> 24 #include <base/containers/unique_ptr.h> 25 #include <base/containers/vector.h> 26 #include <core/ecs/entity_reference.h> 27 #include <core/ecs/intf_ecs.h> 28 #include <core/namespace.h> 29 #include <core/threading/intf_thread_pool.h> 30 31 CORE_BEGIN_NAMESPACE() 32 class IEngine; 33 class IImageLoaderManager; 34 class IPerformanceDataManager; 35 CORE_END_NAMESPACE() 36 37 RENDER_BEGIN_NAMESPACE() 38 class IDevice; 39 class IGpuResourceManager; 40 class IRenderContext; 41 class IShaderManager; 42 RENDER_END_NAMESPACE() 43 44 CORE3D_BEGIN_NAMESPACE() 45 class IRenderHandleComponentManager; 46 class IMaterialComponentManager; 47 class IMeshComponentManager; 48 class INameComponentManager; 49 class IUriComponentManager; 50 class IAnimationInputComponentManager; 51 class IAnimationOutputComponentManager; 52 53 namespace GLTF2 { 54 class Data; 55 struct Accessor; 56 struct AnimationTrack; 57 enum class ImportPhase { 58 BUFFERS = 0, 59 SAMPLERS, 60 IMAGES, 61 TEXTURES, 62 MATERIALS, 63 ANIMATION_SAMPLERS, 64 ANIMATIONS, 65 SKINS, 66 MESHES, 67 FINISHED 68 }; 69 70 // A class that executes GLTF load and import operation over multiple frames. 71 class GLTF2Importer final : public IGLTF2Importer { 72 public: 73 GLTF2Importer(CORE_NS::IEngine& engine, RENDER_NS::IRenderContext& renderContext, CORE_NS::IEcs& ecs); 74 GLTF2Importer(CORE_NS::IEngine& engine, RENDER_NS::IRenderContext& renderContext, CORE_NS::IEcs& ecs, 75 CORE_NS::IThreadPool& pool); 76 ~GLTF2Importer() override; 77 78 void ImportGLTF(const IGLTFData& data, GltfResourceImportFlags flags) override; 79 void ImportGLTFAsync(const IGLTFData& data, GltfResourceImportFlags flags, Listener* listener) override; 80 bool Execute(uint32_t timeBudget) override; 81 82 void Cancel() override; 83 bool IsCompleted() const override; 84 85 const GLTFImportResult& GetResult() const override; 86 87 struct DefaultMaterialShaderData { 88 struct SingleShaderData { 89 CORE_NS::EntityReference shader; 90 CORE_NS::EntityReference gfxState; 91 CORE_NS::EntityReference gfxStateDoubleSided; 92 }; 93 SingleShaderData opaque; 94 SingleShaderData blend; 95 SingleShaderData depth; 96 }; 97 98 protected: 99 void Destroy() override; 100 101 private: 102 struct ImporterTask; 103 template<typename T> 104 struct GatheredDataTask; 105 template<typename Component> 106 struct ComponentTaskData; 107 struct AnimationTaskData; 108 109 class ImportThreadTask; 110 class GatherThreadTask; 111 112 void Prepare(); 113 void PrepareBufferTasks(); 114 void PrepareSamplerTasks(); 115 void PrepareImageTasks(); 116 void PrepareImageBasedLightTasks(); 117 void PrepareMaterialTasks(); 118 void PrepareAnimationTasks(); 119 void PrepareSkinTasks(); 120 void PrepareMeshTasks(); 121 template<typename T> 122 GatheredDataTask<T>* PrepareAnimationInputTask(BASE_NS::unordered_map<GLTF2::Accessor*, GatheredDataTask<T>*>&, 123 const GLTF2::AnimationTrack&, IAnimationInputComponentManager*); 124 template<typename T> 125 GatheredDataTask<T>* PrepareAnimationOutputTask(BASE_NS::unordered_map<GLTF2::Accessor*, GatheredDataTask<T>*>&, 126 const GLTF2::AnimationTrack&, IAnimationOutputComponentManager*); 127 void QueueImage(size_t i, BASE_NS::string&& uri, BASE_NS::string&& name); 128 void ResolveReferencedImages(BASE_NS::vector<bool>& imageLoadingRequred); 129 130 void QueueTask(BASE_NS::unique_ptr<ImporterTask>&& task); 131 bool ProgressTask(ImporterTask& task); 132 void Gather(ImporterTask& task); 133 void Import(ImporterTask& task); 134 void CompleteTask(ImporterTask& task); 135 136 void StartPhase(ImportPhase phase); 137 void HandleGatherTasks(); 138 void HandleImportTasks(); 139 140 ImporterTask* FindTaskById(uint64_t id); 141 142 ImportPhase phase_ { ImportPhase::BUFFERS }; 143 BASE_NS::vector<BASE_NS::unique_ptr<ImporterTask>> tasks_; 144 145 CORE_NS::IEngine& engine_; 146 RENDER_NS::IRenderContext& renderContext_; 147 RENDER_NS::IDevice& device_; 148 RENDER_NS::IGpuResourceManager& gpuResourceManager_; 149 CORE_NS::IEcs::Ptr ecs_; 150 IRenderHandleComponentManager& gpuHandleManager_; 151 IMaterialComponentManager& materialManager_; 152 IMeshComponentManager& meshManager_; 153 INameComponentManager& nameManager_; 154 IUriComponentManager& uriManager_; 155 156 // assigned to material in import 157 DefaultMaterialShaderData dmShaderData_; 158 159 const Data* data_ { nullptr }; 160 161 CORE_NS::IThreadPool::Ptr threadPool_; 162 CORE_NS::IDispatcherTaskQueue::Ptr mainThreadQueue_; 163 Listener* listener_ { nullptr }; 164 165 GltfResourceImportFlags flags_ { CORE_GLTF_IMPORT_RESOURCE_FLAG_BITS_ALL }; 166 GLTFImportResult result_; 167 168 std::mutex gatherTasksLock_; 169 BASE_NS::vector<uint64_t> finishedGatherTasks_; 170 BASE_NS::vector<CORE_NS::IThreadPool::IResult::Ptr> gatherTaskResults_; 171 172 size_t pendingGatherTasks_ { 0 }; 173 size_t pendingImportTasks_ { 0 }; 174 size_t completedTasks_ { 0 }; 175 176 std::atomic_bool cancelled_ { false }; 177 }; 178 } // namespace GLTF2 179 180 CORE_NS::Entity ImportScene(RENDER_NS::IDevice& device, size_t sceneIndex, const GLTF2::Data& data, 181 const GLTFResourceData& gltfResourceData, CORE_NS::IEcs& ecs, CORE_NS::Entity rootEntity, 182 GltfSceneImportFlags flags); 183 CORE3D_END_NAMESPACE() 184 185 #endif // CORE__GLTF__GLTF2_IMPORTER_H 186