3fa27057efba6b687df806f87ff93a49eb777721
[platform/core/uifw/dali-toolkit.git] / dali-scene3d / internal / loader / gltf2-asset.h
1 #ifndef DALI_SCENE3D_LOADER_GLTF2_ASSET_H_
2 #define DALI_SCENE3D_LOADER_GLTF2_ASSET_H_
3 /*
4  * Copyright (c) 2022 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 // INTERNAL INCLUDES
21 #include "dali-scene3d/internal/loader/json-reader.h"
22 #include "dali-scene3d/public-api/loader/index.h"
23
24 // EXTERNAL INCLUDES
25 #include <cstdint>
26 #include <memory>
27 #include "dali/devel-api/common/map-wrapper.h"
28 #include "dali/public-api/common/vector-wrapper.h"
29 #include "dali/public-api/math/quaternion.h"
30 #include "dali/public-api/math/vector4.h"
31
32 namespace gltf2
33 {
34 using Index = Dali::Scene3D::Loader::Index;
35
36 template<typename T>
37 class Ref
38 {
39 public:
40   Ref() = default;
41   Ref(std::vector<T>& v, Index i)
42   : mVector(&v),
43     mIndex(i)
44   {
45   }
46
47   /**
48    * @return The index of the object into the vector.
49    * @note It is client code responsibility to ensure that the vector is unambiguous. It should be in
50    *  a glTF document, since there's one vector for each type.
51    */
52   Index GetIndex() const
53   {
54     return mIndex;
55   }
56
57   /**
58    * @brief There may be scenarios in which the object, whose vector we're populating, changes, e.g.
59    *  when we don't have a final one at the time of reading the references.
60    */
61   void UpdateVector(std::vector<T>& v)
62   {
63     mVector = &v;
64   }
65
66   operator bool() const
67   {
68     return mVector != nullptr;
69   }
70   T* operator->() const
71   {
72     return &(*mVector)[mIndex];
73   }
74   T& operator*() const
75   {
76     return (*mVector)[mIndex];
77   }
78
79   bool operator==(const Ref<T>& other) const
80   {
81     return mVector == other.mVector && mIndex == other.mIndex;
82   }
83
84   bool operator!=(const Ref<T>& other) const
85   {
86     return !operator==(other);
87   }
88
89 private:
90   std::vector<T>* mVector = nullptr;
91   Index           mIndex  = Dali::Scene3D::Loader::INVALID_INDEX;
92 };
93
94 struct Asset
95 {
96   std::string_view mGenerator;
97   std::string_view mVersion;
98 };
99
100 struct Component
101 {
102   enum Type
103   {
104     BYTE           = 5120,
105     UNSIGNED_BYTE  = 5121,
106     SHORT          = 5122,
107     UNSIGNED_SHORT = 5123,
108     UNSIGNED_INT   = 5125,
109     FLOAT          = 5126,
110     INVALID        = -1
111   };
112
113   static bool     IsUnsigned(Type t);
114   static uint32_t Size(Type t);
115
116   Component() = delete;
117 };
118
119 struct AccessorType
120 {
121   enum Type
122   {
123     SCALAR,
124     VEC2,
125     VEC3,
126     VEC4,
127     MAT2,
128     MAT3,
129     MAT4,
130     INVALID
131   };
132
133   static uint32_t ElementCount(Type t);
134
135   static Type FromString(const char* s, size_t len);
136
137   AccessorType() = delete;
138 };
139
140 struct AlphaMode
141 {
142   enum Type
143   {
144     OPAQUE,
145     MASK,
146     BLEND,
147     INVALID
148   };
149
150   static Type FromString(const char* s, size_t len);
151
152   AlphaMode() = delete;
153 };
154
155 struct Attribute
156 {
157   enum Type
158   {
159     POSITION,
160     NORMAL,
161     TANGENT,
162     TEXCOORD_0,
163     TEXCOORD_1,
164     COLOR_0,
165     JOINTS_0,
166     WEIGHTS_0,
167     INVALID
168   };
169
170   static Type FromString(const char* s, size_t len);
171
172   Attribute() = delete;
173 };
174
175 struct Buffer
176 {
177   uint32_t         mByteLength;
178   std::string_view mUri;
179   //TODO: extensions
180   //TODO: extras
181 };
182
183 struct BufferView
184 {
185   struct Target
186   {
187     enum Type
188     {
189       NONE,
190       ARRAY_BUFFER         = 34962,
191       ELEMENT_ARRAY_BUFFER = 34963
192     };
193
194     Target() = delete;
195   };
196
197   Ref<Buffer> mBuffer;
198   uint32_t    mByteOffset = 0;
199   uint32_t    mByteLength;
200   uint32_t    mByteStride = 0; // if 0 after reading, it needs to be calculated
201   uint32_t    mTarget;
202   //TODO: extensions
203   //TODO: extras
204 };
205
206 struct BufferViewClient
207 {
208   Ref<BufferView> mBufferView;
209   uint32_t        mByteOffset = 0;
210 };
211
212 struct ComponentTypedBufferViewClient : BufferViewClient
213 {
214   Component::Type mComponentType = Component::INVALID;
215
216   uint32_t GetBytesPerComponent() const;
217 };
218
219 struct Named
220 {
221   std::string_view mName;
222
223 protected:
224   Named() = default;
225 };
226
227 struct Accessor : ComponentTypedBufferViewClient, Named
228 {
229   struct Sparse
230   {
231     uint32_t                       mCount;
232     ComponentTypedBufferViewClient mIndices;
233     BufferViewClient               mValues;
234     //TODO: extensions
235     //TODO: extras
236   };
237
238   uint32_t                mCount;
239   bool                    mNormalized = false;
240   AccessorType::Type      mType       = AccessorType::INVALID;
241   std::vector<float>      mMin;
242   std::vector<float>      mMax;
243   std::unique_ptr<Sparse> mSparse;
244   //TODO: extensions
245   //TODO: extras
246
247   uint32_t GetElementSizeBytes() const
248   {
249     return GetBytesPerComponent() * AccessorType::ElementCount(mType);
250   }
251
252   uint32_t GetBytesLength() const
253   {
254     return GetElementSizeBytes() * mCount;
255   }
256
257   void SetSparse(const Sparse& s)
258   {
259     mSparse.reset(new Sparse(s));
260   }
261 };
262
263 struct Image : Named
264 {
265   std::string_view mUri;
266   std::string_view mMimeType;
267   Ref<BufferView>  mBufferView;
268   //TODO: extensions
269   //TODO: extras
270 };
271
272 struct Filter
273 {
274   enum Type
275   {
276     NEAREST                = 9728,
277     LINEAR                 = 9729,
278     NEAREST_MIPMAP_NEAREST = 9984,
279     NEAREST_MIPMAP_LINEAR  = 9985,
280     LINEAR_MIPMAP_NEAREST  = 9986,
281     LINEAR_MIPMAP_LINEAR   = 9987,
282   };
283
284   Filter() = delete;
285 };
286
287 struct Wrap
288 {
289   enum Type
290   {
291     REPEAT          = 10497,
292     CLAMP_TO_EDGE   = 33071,
293     MIRRORED_REPEAT = 33648,
294   };
295
296   Wrap() = delete;
297 };
298
299 struct Sampler
300 {
301   Filter::Type mMinFilter = Filter::LINEAR;
302   Filter::Type mMagFilter = Filter::LINEAR;
303   Wrap::Type   mWrapS     = Wrap::CLAMP_TO_EDGE;
304   Wrap::Type   mWrapT     = Wrap::CLAMP_TO_EDGE;
305   //TODO: extensions
306   //TODO: extras
307 };
308
309 struct Texture
310 {
311   Ref<Image>   mSource;
312   Ref<Sampler> mSampler;
313 };
314
315 struct TextureInfo
316 {
317   Ref<gltf2::Texture> mTexture;
318   uint32_t            mTexCoord = 0;
319   float               mScale    = 1.f;
320   float               mStrength = 1.f;
321
322   operator bool() const
323   {
324     return !!mTexture;
325   }
326 };
327
328 /**
329  * Material Ior is supported with KHR_materials_ior extension.
330  * https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_materials_ior
331  */
332 struct MaterialIor
333 {
334   float mIor = MAXFLOAT;
335 };
336
337 /**
338  * Material Specular is supported with KHR_materials_ior extension.
339  * https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_materials_specular
340  */
341 struct MaterialSpecular
342 {
343   float         mSpecularFactor = 1.0f;
344   TextureInfo   mSpecularTexture;
345   Dali::Vector3 mSpecularColorFactor = Dali::Vector3::ONE;
346   TextureInfo   mSpecularColorTexture;
347 };
348
349 struct MaterialExtensions
350 {
351   MaterialSpecular mMaterialSpecular;
352   MaterialIor      mMaterialIor;
353 };
354
355 struct Material : Named
356 {
357   struct Pbr // MetallicRoughness
358   {
359     Dali::Vector4 mBaseColorFactor = Dali::Vector4::ONE;
360     TextureInfo   mBaseColorTexture;
361     float         mMetallicFactor  = 1.f;
362     float         mRoughnessFactor = 1.f;
363     TextureInfo   mMetallicRoughnessTexture;
364     //TODO: extensions
365     //TODO: extras
366   };
367
368   Pbr               mPbrMetallicRoughness;
369   TextureInfo       mNormalTexture;
370   TextureInfo       mOcclusionTexture;
371   TextureInfo       mEmissiveTexture;
372   Dali::Vector3     mEmissiveFactor;
373   AlphaMode::Type   mAlphaMode   = AlphaMode::OPAQUE;
374   float             mAlphaCutoff = .5f;
375   bool              mDoubleSided = false;
376
377   //extensions
378   MaterialExtensions mMaterialExtensions;
379   //TODO: extras
380 };
381
382 struct Mesh : Named
383 {
384   struct Primitive
385   {
386     enum Mode
387     {
388       POINTS,
389       LINES,
390       LINE_LOOP,
391       LINE_STRIP,
392       TRIANGLES,
393       TRIANGLE_STRIP,
394       TRIANGLE_FAN,
395       INVALID
396     };
397
398     std::map<Attribute::Type, Ref<Accessor>>              mAttributes;
399     std::vector<std::map<Attribute::Type, Ref<Accessor>>> mTargets;
400     Ref<Accessor>                                         mIndices;
401     Ref<Material>                                         mMaterial;
402     Mode                                                  mMode = TRIANGLES;
403
404     //TODO: [morph] targets
405     //TODO: extras
406     //TODO: extensions
407   };
408
409   std::vector<Primitive> mPrimitives;
410   std::vector<float>     mWeights;
411   //TODO: extras
412   //TODO: extensions
413 };
414
415 struct Node;
416
417 struct Skin : Named
418 {
419   Ref<Accessor>          mInverseBindMatrices;
420   Ref<Node>              mSkeleton;
421   std::vector<Ref<Node>> mJoints;
422   //TODO: extras
423   //TODO: extensions
424 };
425
426 struct Camera : Named
427 {
428   struct Perspective
429   {
430     float mAspectRatio;
431     float mYFov;
432     float mZFar;
433     float mZNear;
434     //TODO: extras
435     //TODO: extensions
436   };
437
438   struct Orthographic
439   {
440     float mXMag;
441     float mYMag;
442     float mZFar;
443     float mZNear;
444     //TODO: extras
445     //TODO: extensions
446   };
447
448   std::string_view mType;
449   Perspective      mPerspective;
450   Orthographic     mOrthographic;
451   //TODO: extras
452   //TODO: extensions
453 };
454
455 struct Node : Named
456 {
457   Dali::Vector3    mTranslation = Dali::Vector3::ZERO;
458   Dali::Quaternion mRotation    = Dali::Quaternion::IDENTITY;
459   Dali::Vector3    mScale       = Dali::Vector3::ONE;
460
461   Ref<Camera>            mCamera;
462   std::vector<Ref<Node>> mChildren;
463   Ref<Mesh>              mMesh;
464
465   Ref<Skin> mSkin;
466   //TODO: [morph] weights
467   //TODO: extras
468   //TODO: extensions
469
470   void SetMatrix(const Dali::Matrix& m);
471 };
472
473 struct Animation : Named
474 {
475   struct Sampler
476   {
477     struct Interpolation
478     {
479       enum Type
480       {
481         STEP,
482         LINEAR,
483         CUBICSPLINE,
484         INVALID
485       };
486       static Type FromString(const char* s, size_t len);
487     };
488
489     Ref<Accessor>       mInput;
490     Ref<Accessor>       mOutput;
491     Interpolation::Type mInterpolation;
492
493     //TODO: extras
494     //TODO: extensions
495   };
496
497   struct Channel
498   {
499     struct Target
500     {
501       enum Type
502       {
503         TRANSLATION,
504         ROTATION,
505         SCALE,
506         WEIGHTS,
507         INVALID
508       };
509
510       static Type FromString(const char* s, size_t len);
511
512       Ref<Node> mNode;
513       Type      mPath;
514     };
515
516     Ref<Sampler> mSampler;
517     Target       mTarget;
518     //TODO: extras
519     //TODO: extensions
520   };
521
522   std::vector<Sampler> mSamplers;
523   std::vector<Channel> mChannels;
524 };
525
526 struct Scene : Named
527 {
528   std::vector<Ref<Node>> mNodes;
529 };
530
531 struct Document
532 {
533   Asset mAsset;
534
535   std::vector<Buffer>     mBuffers;
536   std::vector<BufferView> mBufferViews;
537   std::vector<Accessor>   mAccessors;
538
539   std::vector<Image>    mImages;
540   std::vector<Sampler>  mSamplers;
541   std::vector<Texture>  mTextures;
542   std::vector<Material> mMaterials;
543
544   std::vector<Mesh> mMeshes;
545   std::vector<Skin> mSkins;
546
547   std::vector<Camera> mCameras;
548   std::vector<Node>   mNodes;
549
550   std::vector<Animation> mAnimations;
551
552   std::vector<Scene> mScenes;
553   Ref<Scene>         mScene;
554
555   Document()                = default;
556   Document(const Document&) = delete;
557   Document(Document&&)      = default;
558
559   Document& operator=(const Document&) = delete;
560   Document& operator=(Document&&) = default;
561 };
562
563 /**
564  * @brief Provides a json::Property<T>::ReadFn for interpreting unsigned integers
565  *  as a Ref<U> into a std::vector<U> data member of a type T.
566  */
567 template<typename T>
568 struct RefReader
569 {
570   static T* sObject;
571
572   template<typename U, std::vector<U> T::*V>
573   static Ref<U> Read(const json_value_s& j)
574   {
575     uint32_t index = json::Read::Number<uint32_t>(j);
576     return Ref<U>(sObject->*V, index);
577   }
578 };
579
580 template<typename T>
581 T* RefReader<T>::sObject = nullptr;
582
583 /**
584  * @brief Convenience method to set the object for RefReader.
585  */
586 template<typename T>
587 void SetRefReaderObject(T& object)
588 {
589   RefReader<T>::sObject = &object;
590 }
591
592 /**
593  * @brief Reads a string and attempts to convert it to an enum.
594  * @note The enum must: 1, be called Type, nested to T, 2, provide a FromString static method taking a const char*
595  *  (string data) and a size_t (string length) and returning T::Type.
596  */
597 template<typename T> // T must have a nested enum called Type and a static Type FromString(const char*) method.
598 typename T::Type ReadStringEnum(const json_value_s& j)
599 {
600   auto str = json::Read::StringView(j);
601
602   return T::FromString(str.data(), str.size());
603 }
604
605 /**
606  * @brief Convenience method to attempt to create a Dali vector type T from an array of floats.
607  * @note T must provide an AsFloat() member method returning the non-const array of its
608  *  float components.
609  */
610 template<typename T>
611 inline T ReadDaliVector(const json_value_s& j)
612 {
613   std::vector<float> floats = json::Read::Array<float, json::Read::Number<float>>(j);
614   T                  result;
615   std::copy(floats.begin(), std::min(floats.end(), floats.begin() + sizeof(T) / sizeof(float)), result.AsFloat());
616   return result;
617 }
618
619 /**
620  * @brief Convenience method to attemt to read a Quaternion, which implicitly converts
621  *  to Vector4 but fails to provide an AsFloat() method.
622  */
623 Dali::Quaternion ReadQuaternion(const json_value_s& j);
624
625 } // namespace gltf2
626
627 #endif //DALI_SCENE3D_LOADER_GLTF2_ASSET_H_