1 /*
2  * Copyright (c) 2024 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__DATA_H
17 #define CORE__GLTF__DATA_H
18 
19 #include <3d/gltf/gltf.h>
20 #include <3d/loaders/intf_scene_loader.h>
21 #include <base/containers/unique_ptr.h>
22 #include <base/containers/vector.h>
23 #include <core/io/intf_file.h>
24 
25 #include "gltf/gltf2_data_structures.h"
26 
27 CORE_BEGIN_NAMESPACE()
28 class IFileManager;
29 CORE_END_NAMESPACE()
30 
CORE3D_BEGIN_NAMESPACE()31 CORE3D_BEGIN_NAMESPACE()
32 namespace GLTF2 {
33 struct Assets {
34     Assets() = default;
35     Assets(const Assets& aOther) = delete;
36     virtual ~Assets() = default;
37 
38     BASE_NS::string filepath;
39     BASE_NS::string defaultResources;
40     int32_t defaultResourcesOffset = -1;
41 
42     size_t size { 0 };
43 
44     BASE_NS::unique_ptr<GLTF2::Material> defaultMaterial;
45     BASE_NS::unique_ptr<GLTF2::Sampler> defaultSampler;
46     GLTF2::Scene* defaultScene { nullptr };
47 
48     BASE_NS::vector<BASE_NS::unique_ptr<GLTF2::Buffer>> buffers;
49     BASE_NS::vector<BASE_NS::unique_ptr<GLTF2::BufferView>> bufferViews;
50     BASE_NS::vector<BASE_NS::unique_ptr<GLTF2::Accessor>> accessors;
51     BASE_NS::vector<BASE_NS::unique_ptr<GLTF2::Mesh>> meshes;
52     BASE_NS::vector<BASE_NS::unique_ptr<GLTF2::Camera>> cameras;
53     BASE_NS::vector<BASE_NS::unique_ptr<GLTF2::Image>> images;
54     BASE_NS::vector<BASE_NS::unique_ptr<GLTF2::Sampler>> samplers;
55     BASE_NS::vector<BASE_NS::unique_ptr<GLTF2::Texture>> textures;
56     BASE_NS::vector<BASE_NS::unique_ptr<GLTF2::Material>> materials;
57     BASE_NS::vector<BASE_NS::unique_ptr<GLTF2::Node>> nodes;
58     BASE_NS::vector<BASE_NS::unique_ptr<GLTF2::Scene>> scenes;
59     BASE_NS::vector<BASE_NS::unique_ptr<GLTF2::Animation>> animations;
60     BASE_NS::vector<BASE_NS::unique_ptr<GLTF2::Skin>> skins;
61 
62 #if defined(GLTF2_EXTENSION_KHR_LIGHTS) || defined(GLTF2_EXTENSION_KHR_LIGHTS_PBR)
63 
64 #ifdef GLTF2_EXTENSION_KHR_LIGHTS_PBR
65     uint32_t pbrLightOffset; // whats this? (seems to be a parse time helper, index to first pbr light)
66 #endif
67 
68     BASE_NS::vector<BASE_NS::unique_ptr<GLTF2::KHRLight>> lights;
69 #endif
70 
71 #if defined(GLTF2_EXTENSION_HW_XR_EXT)
72     struct Thumbnail {
73         BASE_NS::string uri;
74         BASE_NS::string extension;
75         BASE_NS::vector<uint8_t> data;
76     };
77     BASE_NS::vector<Thumbnail> thumbnails;
78 #endif
79 
80 #if defined(GLTF2_EXTENSION_EXT_LIGHTS_IMAGE_BASED)
81     BASE_NS::vector<BASE_NS::unique_ptr<GLTF2::ImageBasedLight>> imageBasedLights;
82 #endif
83 
84 #if defined(GLTF2_EXTENSION_KHR_MESH_QUANTIZATION)
85     // true then KHR_mesh_quantization extension required. this expands the valid attribute componentTypes.
86     bool quantization { false };
87 #endif
88 };
89 
90 // Implementation of outside-world GLTF data interface.
91 class Data : public Assets, public IGLTFData {
92 public:
93     explicit Data(CORE_NS::IFileManager& fileManager);
94     bool LoadBuffers() override;
95     void ReleaseBuffers() override;
96 
97     BASE_NS::vector<BASE_NS::string> GetExternalFileUris() override;
98 
99     size_t GetDefaultSceneIndex() const override;
100     size_t GetSceneCount() const override;
101 
102     size_t GetThumbnailImageCount() const override;
103     IGLTFData::ThumbnailImage GetThumbnailImage(size_t thumbnailIndex) override;
104 
105     CORE_NS::IFile::Ptr memoryFile_;
106 
107 protected:
108     CORE_NS::IFileManager& fileManager_;
109     void Destroy() override;
110 };
111 
112 class SceneData : public ISceneData {
113 public:
114     static constexpr auto UID = BASE_NS::Uid { "e745a051-2372-4935-8ed1-30dfc0d5f305" };
115 
116     using Ptr = BASE_NS::refcnt_ptr<SceneData>;
117 
118     SceneData(BASE_NS::unique_ptr<GLTF2::Data> data);
119 
120     const GLTF2::Data* GetData() const;
121 
122     size_t GetDefaultSceneIndex() const override;
123     size_t GetSceneCount() const override;
124 
125     const IInterface* GetInterface(const BASE_NS::Uid& uid) const override;
126     IInterface* GetInterface(const BASE_NS::Uid& uid) override;
127     void Ref() override;
128     void Unref() override;
129 
130 protected:
131     friend Ptr;
132 
133     uint32_t refcnt_ { 0 };
134     BASE_NS::unique_ptr<GLTF2::Data> data_;
135 };
136 } // namespace GLTF2
137 CORE3D_END_NAMESPACE()
138 
139 #endif // CORE__GLTF__DATA_H
140