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