/* * Copyright (C) 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "gltf2.h" #include <3d/gltf/gltf.h> #include <3d/intf_graphics_context.h> #include #include #include #include #include #include #include #include #include "data.h" #include "gltf2_exporter.h" #include "gltf2_importer.h" #include "gltf2_loader.h" CORE3D_BEGIN_NAMESPACE() using namespace BASE_NS; using namespace CORE_NS; Gltf2::Gltf2(IGraphicsContext& graphicsContext) : engine_(&(graphicsContext.GetRenderContext().GetEngine())), renderContext_(&graphicsContext.GetRenderContext()), fileManager_(engine_->GetFileManager()) {} Gltf2::Gltf2(IFileManager& fileManager) : fileManager_(fileManager) {} // Internal helper. GLTFLoadResult LoadGLTF(IFileManager& fileManager, const string_view uri) { auto loadResult = GLTF2::LoadGLTF(fileManager, uri); GLTFLoadResult result; result.error = std::move(loadResult.error); result.success = loadResult.success; result.data = IGLTFData::Ptr { loadResult.data.release() }; return result; } // Api loading function. GLTFLoadResult Gltf2::LoadGLTF(const string_view uri) { return CORE3D_NS::LoadGLTF(fileManager_, uri); } GLTFLoadResult Gltf2::LoadGLTF(array_view data) { auto loadResult = GLTF2::LoadGLTF(fileManager_, data); GLTFLoadResult result; result.error = std::move(loadResult.error); result.success = loadResult.success; result.data = IGLTFData::Ptr { loadResult.data.release() }; return result; } // Api import functions Entity Gltf2::ImportGltfScene(size_t sceneIndex, const IGLTFData& gltfData, const GLTFResourceData& gltfResourceData, IEcs& ecs, Entity rootEntity, GltfSceneImportFlags flags) { CORE_ASSERT(renderContext_); if (renderContext_) { const GLTF2::Data& data = static_cast(gltfData); return ImportScene(renderContext_->GetDevice(), sceneIndex, data, gltfResourceData, ecs, rootEntity, flags); } return {}; } IGLTF2Importer::Ptr Gltf2::CreateGLTF2Importer(IEcs& ecs) { CORE_ASSERT(engine_ && renderContext_); if (engine_ && renderContext_) { if (auto pool = ecs.GetThreadPool(); pool) { return CreateGLTF2Importer(ecs, *pool); } return IGLTF2Importer::Ptr { new GLTF2::GLTF2Importer(*engine_, *renderContext_, ecs) }; } return nullptr; } IGLTF2Importer::Ptr Gltf2::CreateGLTF2Importer(IEcs& ecs, IThreadPool& pool) { CORE_ASSERT(engine_ && renderContext_); if (engine_ && renderContext_) { return IGLTF2Importer::Ptr { new GLTF2::GLTF2Importer(*engine_, *renderContext_, ecs, pool) }; } return nullptr; } // Api exporting function. bool Gltf2::SaveGLTF(IEcs& ecs, const string_view uri) { CORE_ASSERT(engine_); if (engine_) { if (auto result = GLTF2::ExportGLTF(*engine_, ecs); result.success) { if (auto file = fileManager_.CreateFile(uri); file) { auto const ext = uri.rfind('.'); auto const extension = string_view(uri.data() + ext + 1); if (extension == "gltf") { for (auto const& buffer : result.data->buffers) { string dataFileUri = uri.substr(0, ext) + ".bin"; if (auto dataFile = fileManager_.CreateFile(dataFileUri); dataFile) { dataFile->Write(buffer->data.data(), buffer->data.size()); if (auto const path = dataFileUri.rfind('/'); path != string::npos) { dataFileUri.erase(0, path + 1); } buffer->uri = dataFileUri; } } GLTF2::SaveGLTF(*result.data, *file, engine_->GetVersion()); } else { GLTF2::SaveGLB(*result.data, *file, engine_->GetVersion()); } } else { result.error += "Failed to create file: " + uri; result.success = false; } return result.success; } else { return result.success; } } return false; } CORE3D_END_NAMESPACE()