1 #ifndef DALI_SCENE3D_LOADER_GLTF2_ASSET_H_
2 #define DALI_SCENE3D_LOADER_GLTF2_ASSET_H_
4 * Copyright (c) 2023 Samsung Electronics Co., Ltd.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 #include <dali-scene3d/internal/loader/json-reader.h>
22 #include <dali-scene3d/public-api/loader/index.h>
25 #include <dali/devel-api/common/map-wrapper.h>
26 #include <dali/public-api/common/vector-wrapper.h>
27 #include <dali/public-api/math/quaternion.h>
28 #include <dali/public-api/math/vector4.h>
32 #define ENUM_STRING_MAPPING(t, x) \
37 #define ENUM_TYPE_FROM_STRING(structName, table) \
38 structName::Type structName::FromString(const char* s, size_t len) \
40 std::string target(s, len); \
41 std::transform(target.begin(), target.end(), target.begin(), ::toupper); \
43 auto iFind = table.find(std::string_view(target.c_str(), len)); \
44 if(iFind != table.end()) \
46 return iFind->second; \
48 return structName::INVALID; \
53 using Index = Dali::Scene3D::Loader::Index;
54 constexpr float UNDEFINED_FLOAT_VALUE = -1.0f; ///< Special marker for some non-negative only float values.
61 Ref(std::vector<T>& v, Index i)
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.
72 Index GetIndex() const
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.
81 void UpdateVector(std::vector<T>& v)
88 return mVector != nullptr;
92 return &(*mVector)[mIndex];
96 return (*mVector)[mIndex];
99 bool operator==(const Ref<T>& other) const
101 return mVector == other.mVector && mIndex == other.mIndex;
104 bool operator!=(const Ref<T>& other) const
106 return !operator==(other);
110 std::vector<T>* mVector = nullptr;
111 Index mIndex = Dali::Scene3D::Loader::INVALID_INDEX;
116 std::string_view mGenerator;
117 std::string_view mVersion;
125 UNSIGNED_BYTE = 5121,
127 UNSIGNED_SHORT = 5123,
133 static bool IsUnsigned(Type t);
134 static uint32_t Size(Type t);
136 Component() = delete;
153 static uint32_t ElementCount(Type t);
155 static Type FromString(const char* s, size_t len);
157 AccessorType() = delete;
170 static Type FromString(const char* s, size_t len);
172 AlphaMode() = delete;
190 static Type FromString(const char* s, size_t len);
192 Attribute() = delete;
197 uint32_t mByteLength;
198 std::string_view mUri;
210 ARRAY_BUFFER = 34962,
211 ELEMENT_ARRAY_BUFFER = 34963
218 uint32_t mByteOffset = 0;
219 uint32_t mByteLength;
220 uint32_t mByteStride = 0; // if 0 after reading, it needs to be calculated
226 struct BufferViewClient
228 Ref<BufferView> mBufferView;
229 uint32_t mByteOffset = 0;
232 struct ComponentTypedBufferViewClient : BufferViewClient
234 Component::Type mComponentType = Component::INVALID;
236 uint32_t GetBytesPerComponent() const;
241 std::string_view mName;
247 struct Accessor : ComponentTypedBufferViewClient, Named
252 ComponentTypedBufferViewClient mIndices;
253 BufferViewClient mValues;
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;
267 uint32_t GetElementSizeBytes() const
269 return GetBytesPerComponent() * AccessorType::ElementCount(mType);
272 uint32_t GetBytesLength() const
274 return GetElementSizeBytes() * mCount;
277 void SetSparse(const Sparse& s)
279 mSparse.reset(new Sparse(s));
285 std::string_view mUri;
286 std::string_view mMimeType;
287 Ref<BufferView> mBufferView;
298 NEAREST_MIPMAP_NEAREST = 9984,
299 NEAREST_MIPMAP_LINEAR = 9985,
300 LINEAR_MIPMAP_NEAREST = 9986,
301 LINEAR_MIPMAP_LINEAR = 9987,
312 CLAMP_TO_EDGE = 33071,
313 MIRRORED_REPEAT = 33648,
321 Filter::Type mMinFilter = Filter::LINEAR;
322 Filter::Type mMagFilter = Filter::LINEAR;
323 Wrap::Type mWrapS = Wrap::REPEAT;
324 Wrap::Type mWrapT = Wrap::REPEAT;
332 Ref<Sampler> mSampler;
337 Ref<gltf2::Texture> mTexture;
338 uint32_t mTexCoord = 0;
340 float mStrength = 1.f;
342 operator bool() const
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
354 float mIor = UNDEFINED_FLOAT_VALUE;
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
361 struct MaterialSpecular
363 float mSpecularFactor = 1.0f;
364 TextureInfo mSpecularTexture;
365 Dali::Vector3 mSpecularColorFactor = Dali::Vector3::ONE;
366 TextureInfo mSpecularColorTexture;
369 struct MaterialExtensions
371 MaterialSpecular mMaterialSpecular;
372 MaterialIor mMaterialIor;
375 struct Material : Named
377 struct Pbr // MetallicRoughness
379 Dali::Vector4 mBaseColorFactor = Dali::Vector4::ONE;
380 TextureInfo mBaseColorTexture;
381 float mMetallicFactor = 1.f;
382 float mRoughnessFactor = 1.f;
383 TextureInfo mMetallicRoughnessTexture;
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;
398 MaterialExtensions mMaterialExtensions;
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;
424 //TODO: [morph] targets
429 std::vector<Primitive> mPrimitives;
430 std::vector<float> mWeights;
439 Ref<Accessor> mInverseBindMatrices;
441 std::vector<Ref<Node>> mJoints;
446 struct Camera : Named
450 float mAspectRatio = UNDEFINED_FLOAT_VALUE;
451 float mYFov = UNDEFINED_FLOAT_VALUE;
452 float mZFar = UNDEFINED_FLOAT_VALUE;
453 float mZNear = UNDEFINED_FLOAT_VALUE;
460 float mXMag = UNDEFINED_FLOAT_VALUE;
461 float mYMag = UNDEFINED_FLOAT_VALUE;
462 float mZFar = UNDEFINED_FLOAT_VALUE;
463 float mZNear = UNDEFINED_FLOAT_VALUE;
468 std::string_view mType;
469 Perspective mPerspective;
470 Orthographic mOrthographic;
477 Dali::Vector3 mTranslation = Dali::Vector3::ZERO;
478 Dali::Quaternion mRotation = Dali::Quaternion::IDENTITY;
479 Dali::Vector3 mScale = Dali::Vector3::ONE;
482 std::vector<Ref<Node>> mChildren;
486 //TODO: [morph] weights
490 void SetMatrix(const Dali::Matrix& m);
493 struct Animation : Named
506 static Type FromString(const char* s, size_t len);
509 Ref<Accessor> mInput;
510 Ref<Accessor> mOutput;
511 Interpolation::Type mInterpolation;
530 static Type FromString(const char* s, size_t len);
536 Ref<Sampler> mSampler;
542 std::vector<Sampler> mSamplers;
543 std::vector<Channel> mChannels;
548 std::vector<Ref<Node>> mNodes;
555 std::vector<Buffer> mBuffers;
556 std::vector<BufferView> mBufferViews;
557 std::vector<Accessor> mAccessors;
559 std::vector<Image> mImages;
560 std::vector<Sampler> mSamplers;
561 std::vector<Texture> mTextures;
562 std::vector<Material> mMaterials;
564 std::vector<Mesh> mMeshes;
565 std::vector<Skin> mSkins;
567 std::vector<Camera> mCameras;
568 std::vector<Node> mNodes;
570 std::vector<Animation> mAnimations;
572 std::vector<Scene> mScenes;
575 Document() = default;
576 Document(const Document&) = delete;
577 Document(Document&&) = default;
579 Document& operator=(const Document&) = delete;
580 Document& operator=(Document&&) = default;
584 * @brief Provides a json::Property<T>::ReadFn for interpreting unsigned integers
585 * as a Ref<U> into a std::vector<U> data member of a type T.
592 template<typename U, std::vector<U> T::*V>
593 static Ref<U> Read(const json_value_s& j)
595 uint32_t index = json::Read::Number<uint32_t>(j);
596 return Ref<U>(sObject->*V, index);
601 T* RefReader<T>::sObject = nullptr;
604 * @brief Convenience method to set the object for RefReader.
607 void SetRefReaderObject(T& object)
609 RefReader<T>::sObject = &object;
613 * @brief Reads a string and attempts to convert it to an enum.
614 * @note The enum must: 1, be called Type, nested to T, 2, provide a FromString static method taking a const char*
615 * (string data) and a size_t (string length) and returning T::Type.
617 template<typename T> // T must have a nested enum called Type and a static Type FromString(const char*) method.
618 typename T::Type ReadStringEnum(const json_value_s& j)
620 auto str = json::Read::StringView(j);
622 return T::FromString(str.data(), str.size());
626 * @brief Convenience method to attempt to create a Dali vector type T from an array of floats.
627 * @note T must provide an AsFloat() member method returning the non-const array of its
631 inline T ReadDaliVector(const json_value_s& j)
633 std::vector<float> floats = json::Read::Array<float, json::Read::Number<float>>(j);
635 std::copy(floats.begin(), std::min(floats.end(), floats.begin() + sizeof(T) / sizeof(float)), result.AsFloat());
640 * @brief Convenience method to attemt to read a Quaternion, which implicitly converts
641 * to Vector4 but fails to provide an AsFloat() method.
643 Dali::Quaternion ReadQuaternion(const json_value_s& j);
647 #endif //DALI_SCENE3D_LOADER_GLTF2_ASSET_H_