X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali-scene-loader%2Fpublic-api%2Fgltf2-loader.cpp;h=923d0e4af62d6450314ffde0fb7b7cf22dbaeb51;hb=8031d58099c45584640676693f4b904e81008081;hp=451060b807a19820e08107b680fd1442957b66cc;hpb=02557f62f8d171115d885c87c138faec2a3cb923;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git diff --git a/dali-scene-loader/public-api/gltf2-loader.cpp b/dali-scene-loader/public-api/gltf2-loader.cpp index 451060b..923d0e4 100644 --- a/dali-scene-loader/public-api/gltf2-loader.cpp +++ b/dali-scene-loader/public-api/gltf2-loader.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,17 +14,20 @@ * limitations under the License. * */ +#include "dali-scene-loader/public-api/gltf2-loader.h" +#include +#include "dali-scene-loader/internal/gltf2-asset.h" #include "dali-scene-loader/public-api/load-result.h" -#include "dali-scene-loader/public-api/scene-definition.h" #include "dali-scene-loader/public-api/resource-bundle.h" -#include "dali-scene-loader/public-api/gltf2-loader.h" -#include "dali-scene-loader/public-api/utils.h" +#include "dali-scene-loader/public-api/scene-definition.h" #include "dali-scene-loader/public-api/shader-definition-factory.h" -#include "dali-scene-loader/internal/gltf2-asset.h" +#include "dali-scene-loader/public-api/utils.h" #include "dali/public-api/math/quaternion.h" -#include -#define ENUM_STRING_MAPPING(t, x) { #x, t::x } +#define ENUM_STRING_MAPPING(t, x) \ + { \ +#x, t::x \ + } namespace gt = gltf2; namespace js = json; @@ -40,6 +43,11 @@ const std::string ORIENTATION_PROPERTY("orientation"); const std::string SCALE_PROPERTY("scale"); const std::string BLEND_SHAPE_WEIGHTS_UNIFORM("uBlendShapeWeight"); +const std::string MRENDERER_MODEL_IDENTIFICATION("M-Renderer"); + +const std::string ROOT_NODE_NAME("RootNode"); +const Vector3 SCALE_TO_ADJUST(100.0f, 100.0f, 100.0f); + const Geometry::Type GLTF2_TO_DALI_PRIMITIVES[]{ Geometry::POINTS, Geometry::LINES, @@ -47,20 +55,19 @@ const Geometry::Type GLTF2_TO_DALI_PRIMITIVES[]{ Geometry::LINE_STRIP, Geometry::TRIANGLES, Geometry::TRIANGLE_STRIP, - Geometry::TRIANGLE_FAN -}; //...because Dali swaps the last two. + Geometry::TRIANGLE_FAN}; //...because Dali swaps the last two. struct AttributeMapping { - gt::Attribute::Type mType; - MeshDefinition::Accessor MeshDefinition::* mAccessor; - uint16_t mElementSizeRequired; + gt::Attribute::Type mType; + MeshDefinition::Accessor MeshDefinition::*mAccessor; + uint16_t mElementSizeRequired; } ATTRIBUTE_MAPPINGS[]{ - { gt::Attribute::NORMAL, &MeshDefinition::mNormals, sizeof(Vector3) }, - { gt::Attribute::TANGENT, &MeshDefinition::mTangents, sizeof(Vector3) }, - { gt::Attribute::TEXCOORD_0, &MeshDefinition::mTexCoords, sizeof(Vector2) }, - { gt::Attribute::JOINTS_0, &MeshDefinition::mJoints0, sizeof(Vector4) }, - { gt::Attribute::WEIGHTS_0, &MeshDefinition::mWeights0, sizeof(Vector4) }, + {gt::Attribute::NORMAL, &MeshDefinition::mNormals, sizeof(Vector3)}, + {gt::Attribute::TANGENT, &MeshDefinition::mTangents, sizeof(Vector3)}, + {gt::Attribute::TEXCOORD_0, &MeshDefinition::mTexCoords, sizeof(Vector2)}, + {gt::Attribute::JOINTS_0, &MeshDefinition::mJoints0, sizeof(Vector4)}, + {gt::Attribute::WEIGHTS_0, &MeshDefinition::mWeights0, sizeof(Vector4)}, }; std::vector ReadAnimationArray(const json_value_s& j) @@ -70,9 +77,9 @@ std::vector ReadAnimationArray(const json_value_s& j) auto results = js::Read::Array::Read>(j); - for (auto& animation : results) + for(auto& animation : results) { - for (auto& channel : animation.mChannels) + for(auto& channel : animation.mChannels) { channel.mSampler.UpdateVector(animation.mSamplers); } @@ -89,124 +96,110 @@ void ApplyAccessorMinMax(const gt::Accessor& acc, float* values) } const auto BUFFER_READER = std::move(js::Reader() - .Register(*js::MakeProperty("byteLength", js::Read::Number, >::Buffer::mByteLength)) - .Register(*js::MakeProperty("uri", js::Read::StringView, >::Buffer::mUri)) -); + .Register(*js::MakeProperty("byteLength", js::Read::Number, >::Buffer::mByteLength)) + .Register(*js::MakeProperty("uri", js::Read::StringView, >::Buffer::mUri))); const auto BUFFER_VIEW_READER = std::move(js::Reader() - .Register(*js::MakeProperty("buffer", gt::RefReader::Read, >::BufferView::mBuffer)) - .Register(*js::MakeProperty("byteOffset", js::Read::Number, >::BufferView::mByteOffset)) - .Register(*js::MakeProperty("byteLength", js::Read::Number, >::BufferView::mByteLength)) - .Register(*js::MakeProperty("byteStride", js::Read::Number, >::BufferView::mByteStride)) - .Register(*js::MakeProperty("target", js::Read::Number, >::BufferView::mTarget)) -); + .Register(*js::MakeProperty("buffer", gt::RefReader::Read, >::BufferView::mBuffer)) + .Register(*js::MakeProperty("byteOffset", js::Read::Number, >::BufferView::mByteOffset)) + .Register(*js::MakeProperty("byteLength", js::Read::Number, >::BufferView::mByteLength)) + .Register(*js::MakeProperty("byteStride", js::Read::Number, >::BufferView::mByteStride)) + .Register(*js::MakeProperty("target", js::Read::Number, >::BufferView::mTarget))); const auto BUFFER_VIEW_CLIENT_READER = std::move(js::Reader() - .Register(*js::MakeProperty("bufferView", gt::RefReader::Read, >::BufferViewClient::mBufferView)) - .Register(*js::MakeProperty("byteOffset", js::Read::Number, >::BufferViewClient::mByteOffset)) -); + .Register(*js::MakeProperty("bufferView", gt::RefReader::Read, >::BufferViewClient::mBufferView)) + .Register(*js::MakeProperty("byteOffset", js::Read::Number, >::BufferViewClient::mByteOffset))); const auto COMPONENT_TYPED_BUFFER_VIEW_CLIENT_READER = std::move(js::Reader() - .Register(*new js::Property>("bufferView", gt::RefReader::Read, >::ComponentTypedBufferViewClient::mBufferView)) - .Register(*new js::Property("byteOffset", js::Read::Number, >::ComponentTypedBufferViewClient::mByteOffset)) - .Register(*js::MakeProperty("componentType", js::Read::Enum, >::ComponentTypedBufferViewClient::mComponentType)) -); + .Register(*new js::Property>("bufferView", gt::RefReader::Read, >::ComponentTypedBufferViewClient::mBufferView)) + .Register(*new js::Property("byteOffset", js::Read::Number, >::ComponentTypedBufferViewClient::mByteOffset)) + .Register(*js::MakeProperty("componentType", js::Read::Enum, >::ComponentTypedBufferViewClient::mComponentType))); const auto ACCESSOR_SPARSE_READER = std::move(js::Reader() - .Register(*js::MakeProperty("count", js::Read::Number, >::Accessor::Sparse::mCount)) - .Register(*js::MakeProperty("indices", js::ObjectReader::Read, - >::Accessor::Sparse::mIndices)) - .Register(*js::MakeProperty("values", js::ObjectReader::Read, - >::Accessor::Sparse::mValues)) -); + .Register(*js::MakeProperty("count", js::Read::Number, >::Accessor::Sparse::mCount)) + .Register(*js::MakeProperty("indices", js::ObjectReader::Read, >::Accessor::Sparse::mIndices)) + .Register(*js::MakeProperty("values", js::ObjectReader::Read, >::Accessor::Sparse::mValues))); const auto ACCESSOR_READER = std::move(js::Reader() - .Register(*new js::Property>("bufferView", - gt::RefReader::Read, >::Accessor::mBufferView)) - .Register(*new js::Property("byteOffset", - js::Read::Number, >::Accessor::mByteOffset)) - .Register(*new js::Property("componentType", - js::Read::Enum, >::Accessor::mComponentType)) - .Register(*new js::Property("name", js::Read::StringView, >::Accessor::mName)) - .Register(*js::MakeProperty("count", js::Read::Number, >::Accessor::mCount)) - .Register(*js::MakeProperty("normalized", js::Read::Boolean, >::Accessor::mNormalized)) - .Register(*js::MakeProperty("type", gt::ReadStringEnum, >::Accessor::mType)) - .Register(*js::MakeProperty("min", js::Read::Array, >::Accessor::mMin)) - .Register(*js::MakeProperty("max", js::Read::Array, >::Accessor::mMax)) - .Register(*new js::Property("sparse", js::ObjectReader::Read, - >::Accessor::SetSparse)) -); + .Register(*new js::Property>("bufferView", + gt::RefReader::Read, + >::Accessor::mBufferView)) + .Register(*new js::Property("byteOffset", + js::Read::Number, + >::Accessor::mByteOffset)) + .Register(*new js::Property("componentType", + js::Read::Enum, + >::Accessor::mComponentType)) + .Register(*new js::Property("name", js::Read::StringView, >::Accessor::mName)) + .Register(*js::MakeProperty("count", js::Read::Number, >::Accessor::mCount)) + .Register(*js::MakeProperty("normalized", js::Read::Boolean, >::Accessor::mNormalized)) + .Register(*js::MakeProperty("type", gt::ReadStringEnum, >::Accessor::mType)) + .Register(*js::MakeProperty("min", js::Read::Array, >::Accessor::mMin)) + .Register(*js::MakeProperty("max", js::Read::Array, >::Accessor::mMax)) + .Register(*new js::Property("sparse", js::ObjectReader::Read, >::Accessor::SetSparse))); const auto IMAGE_READER = std::move(js::Reader() - .Register(*new js::Property("name", js::Read::StringView, >::Material::mName)) - .Register(*js::MakeProperty("uri", js::Read::StringView, >::Image::mUri)) - .Register(*js::MakeProperty("mimeType", js::Read::StringView, >::Image::mMimeType)) - .Register(*js::MakeProperty("bufferView", gt::RefReader::Read, >::Image::mBufferView)) -); + .Register(*new js::Property("name", js::Read::StringView, >::Material::mName)) + .Register(*js::MakeProperty("uri", js::Read::StringView, >::Image::mUri)) + .Register(*js::MakeProperty("mimeType", js::Read::StringView, >::Image::mMimeType)) + .Register(*js::MakeProperty("bufferView", gt::RefReader::Read, >::Image::mBufferView))); const auto SAMPLER_READER = std::move(js::Reader() - .Register(*js::MakeProperty("minFilter", js::Read::Enum, >::Sampler::mMinFilter)) - .Register(*js::MakeProperty("magFilter", js::Read::Enum, >::Sampler::mMagFilter)) - .Register(*js::MakeProperty("wrapS", js::Read::Enum, >::Sampler::mWrapS)) - .Register(*js::MakeProperty("wrapT", js::Read::Enum, >::Sampler::mWrapT)) -); + .Register(*js::MakeProperty("minFilter", js::Read::Enum, >::Sampler::mMinFilter)) + .Register(*js::MakeProperty("magFilter", js::Read::Enum, >::Sampler::mMagFilter)) + .Register(*js::MakeProperty("wrapS", js::Read::Enum, >::Sampler::mWrapS)) + .Register(*js::MakeProperty("wrapT", js::Read::Enum, >::Sampler::mWrapT))); const auto TEXURE_READER = std::move(js::Reader() - .Register(*js::MakeProperty("source", gt::RefReader::Read, >::Texture::mSource)) - .Register(*js::MakeProperty("sampler", gt::RefReader::Read, >::Texture::mSampler)) -); + .Register(*js::MakeProperty("source", gt::RefReader::Read, >::Texture::mSource)) + .Register(*js::MakeProperty("sampler", gt::RefReader::Read, >::Texture::mSampler))); const auto TEXURE_INFO_READER = std::move(js::Reader() - .Register(*js::MakeProperty("index", gt::RefReader::Read, >::TextureInfo::mTexture)) - .Register(*js::MakeProperty("texCoord", js::Read::Number, >::TextureInfo::mTexCoord)) - .Register(*js::MakeProperty("scale", js::Read::Number, >::TextureInfo::mScale)) -); + .Register(*js::MakeProperty("index", gt::RefReader::Read, >::TextureInfo::mTexture)) + .Register(*js::MakeProperty("texCoord", js::Read::Number, >::TextureInfo::mTexCoord)) + .Register(*js::MakeProperty("scale", js::Read::Number, >::TextureInfo::mScale))); const auto MATERIAL_PBR_READER = std::move(js::Reader() - .Register(*js::MakeProperty("baseColorFactor", gt::ReadDaliVector, >::Material::Pbr::mBaseColorFactor)) - .Register(*js::MakeProperty("baseColorTexture", js::ObjectReader::Read, - >::Material::Pbr::mBaseColorTexture)) - .Register(*js::MakeProperty("metallicFactor", js::Read::Number, >::Material::Pbr::mMetallicFactor)) - .Register(*js::MakeProperty("roughnessFactor", js::Read::Number, >::Material::Pbr::mRoughnessFactor)) - .Register(*js::MakeProperty("metallicRoughnessTexture", js::ObjectReader::Read, - >::Material::Pbr::mMetallicRoughnessTexture)) -); + .Register(*js::MakeProperty("baseColorFactor", gt::ReadDaliVector, >::Material::Pbr::mBaseColorFactor)) + .Register(*js::MakeProperty("baseColorTexture", js::ObjectReader::Read, >::Material::Pbr::mBaseColorTexture)) + .Register(*js::MakeProperty("metallicFactor", js::Read::Number, >::Material::Pbr::mMetallicFactor)) + .Register(*js::MakeProperty("roughnessFactor", js::Read::Number, >::Material::Pbr::mRoughnessFactor)) + .Register(*js::MakeProperty("metallicRoughnessTexture", js::ObjectReader::Read, >::Material::Pbr::mMetallicRoughnessTexture))); const auto MATERIAL_READER = std::move(js::Reader() - .Register(*new js::Property("name", js::Read::StringView, >::Material::mName)) - .Register(*js::MakeProperty("pbrMetallicRoughness", js::ObjectReader::Read, >::Material::mPbrMetallicRoughness)) - .Register(*js::MakeProperty("normalTexture", js::ObjectReader::Read, >::Material::mNormalTexture)) - .Register(*js::MakeProperty("occlusionTexture", js::ObjectReader::Read, >::Material::mOcclusionTexture)) - .Register(*js::MakeProperty("emissiveTexture", js::ObjectReader::Read, >::Material::mEmissiveTexture)) - .Register(*js::MakeProperty("emissiveFactor", gt::ReadDaliVector, >::Material::mEmissiveFactor)) - .Register(*js::MakeProperty("alphaMode", gt::ReadStringEnum, >::Material::mAlphaMode)) - .Register(*js::MakeProperty("alphaCutoff", js::Read::Number, >::Material::mAlphaCutoff)) -); + .Register(*new js::Property("name", js::Read::StringView, >::Material::mName)) + .Register(*js::MakeProperty("pbrMetallicRoughness", js::ObjectReader::Read, >::Material::mPbrMetallicRoughness)) + .Register(*js::MakeProperty("normalTexture", js::ObjectReader::Read, >::Material::mNormalTexture)) + .Register(*js::MakeProperty("occlusionTexture", js::ObjectReader::Read, >::Material::mOcclusionTexture)) + .Register(*js::MakeProperty("emissiveTexture", js::ObjectReader::Read, >::Material::mEmissiveTexture)) + .Register(*js::MakeProperty("emissiveFactor", gt::ReadDaliVector, >::Material::mEmissiveFactor)) + .Register(*js::MakeProperty("alphaMode", gt::ReadStringEnum, >::Material::mAlphaMode)) + .Register(*js::MakeProperty("alphaCutoff", js::Read::Number, >::Material::mAlphaCutoff))); std::map> ReadMeshPrimitiveAttributes(const json_value_s& j) { - auto& jo = js::Cast(j); + auto& jo = js::Cast(j); std::map> result; auto i = jo.start; - while (i) + while(i) { - auto jstr = *i->name; + auto jstr = *i->name; result[gt::Attribute::FromString(jstr.string, jstr.string_size)] = gt::RefReader::Read(*i->value); - i = i->next; + i = i->next; } return result; } std::vector>> ReadMeshPrimitiveTargets(const json_value_s& j) { - auto& jo = js::Cast(j); + auto& jo = js::Cast(j); std::vector>> result; result.reserve(jo.length); auto i = jo.start; - while (i) + while(i) { result.push_back(std::move(ReadMeshPrimitiveAttributes(*i->value))); i = i->next; @@ -216,128 +209,129 @@ std::vector>> ReadMeshPrimit } const auto MESH_PRIMITIVE_READER = std::move(js::Reader() - .Register(*js::MakeProperty("attributes", ReadMeshPrimitiveAttributes, >::Mesh::Primitive::mAttributes)) - .Register(*js::MakeProperty("indices", gt::RefReader::Read, >::Mesh::Primitive::mIndices)) - .Register(*js::MakeProperty("material", gt::RefReader::Read, >::Mesh::Primitive::mMaterial)) - .Register(*js::MakeProperty("mode", js::Read::Enum, >::Mesh::Primitive::mMode)) - .Register(*js::MakeProperty("targets", ReadMeshPrimitiveTargets, >::Mesh::Primitive::mTargets)) -); + .Register(*js::MakeProperty("attributes", ReadMeshPrimitiveAttributes, >::Mesh::Primitive::mAttributes)) + .Register(*js::MakeProperty("indices", gt::RefReader::Read, >::Mesh::Primitive::mIndices)) + .Register(*js::MakeProperty("material", gt::RefReader::Read, >::Mesh::Primitive::mMaterial)) + .Register(*js::MakeProperty("mode", js::Read::Enum, >::Mesh::Primitive::mMode)) + .Register(*js::MakeProperty("targets", ReadMeshPrimitiveTargets, >::Mesh::Primitive::mTargets))); const auto MESH_READER = std::move(js::Reader() - .Register(*new js::Property("name", js::Read::StringView, >::Mesh::mName)) - .Register(*js::MakeProperty("primitives", - js::Read::Array::Read>, >::Mesh::mPrimitives)) - .Register(*js::MakeProperty("weights", js::Read::Array, >::Mesh::mWeights)) -); + .Register(*new js::Property("name", js::Read::StringView, >::Mesh::mName)) + .Register(*js::MakeProperty("primitives", + js::Read::Array::Read>, + >::Mesh::mPrimitives)) + .Register(*js::MakeProperty("weights", js::Read::Array, >::Mesh::mWeights))); const auto SKIN_READER = std::move(js::Reader() - .Register(*new js::Property("name", js::Read::StringView, >::Skin::mName)) - .Register(*js::MakeProperty("inverseBindMatrices", - gt::RefReader::Read, >::Skin::mInverseBindMatrices)) - .Register(*js::MakeProperty("skeleton", - gt::RefReader::Read, >::Skin::mSkeleton)) - .Register(*js::MakeProperty("joints", - js::Read::Array, gt::RefReader::Read>, >::Skin::mJoints)) -); + .Register(*new js::Property("name", js::Read::StringView, >::Skin::mName)) + .Register(*js::MakeProperty("inverseBindMatrices", + gt::RefReader::Read, + >::Skin::mInverseBindMatrices)) + .Register(*js::MakeProperty("skeleton", + gt::RefReader::Read, + >::Skin::mSkeleton)) + .Register(*js::MakeProperty("joints", + js::Read::Array, gt::RefReader::Read>, + >::Skin::mJoints))); const auto CAMERA_PERSPECTIVE_READER = std::move(js::Reader() - .Register(*js::MakeProperty("aspectRatio", js::Read::Number, >::Camera::Perspective::mAspectRatio)) - .Register(*js::MakeProperty("yfov", js::Read::Number, >::Camera::Perspective::mYFov)) - .Register(*js::MakeProperty("zfar", js::Read::Number, >::Camera::Perspective::mZFar)) - .Register(*js::MakeProperty("znear", js::Read::Number, >::Camera::Perspective::mZNear)) -); // TODO: infinite perspective projection, where znear is omitted + .Register(*js::MakeProperty("aspectRatio", js::Read::Number, >::Camera::Perspective::mAspectRatio)) + .Register(*js::MakeProperty("yfov", js::Read::Number, >::Camera::Perspective::mYFov)) + .Register(*js::MakeProperty("zfar", js::Read::Number, >::Camera::Perspective::mZFar)) + .Register(*js::MakeProperty("znear", js::Read::Number, >::Camera::Perspective::mZNear))); // TODO: infinite perspective projection, where znear is omitted const auto CAMERA_ORTHOGRAPHIC_READER = std::move(js::Reader() - .Register(*js::MakeProperty("xmag", js::Read::Number, >::Camera::Orthographic::mXMag)) - .Register(*js::MakeProperty("ymag", js::Read::Number, >::Camera::Orthographic::mXMag)) - .Register(*js::MakeProperty("zfar", js::Read::Number, >::Camera::Orthographic::mZFar)) - .Register(*js::MakeProperty("znear", js::Read::Number, >::Camera::Orthographic::mZNear)) -); + .Register(*js::MakeProperty("xmag", js::Read::Number, >::Camera::Orthographic::mXMag)) + .Register(*js::MakeProperty("ymag", js::Read::Number, >::Camera::Orthographic::mXMag)) + .Register(*js::MakeProperty("zfar", js::Read::Number, >::Camera::Orthographic::mZFar)) + .Register(*js::MakeProperty("znear", js::Read::Number, >::Camera::Orthographic::mZNear))); const auto CAMERA_READER = std::move(js::Reader() - .Register(*new js::Property("name", js::Read::StringView, >::Camera::mName)) - .Register(*js::MakeProperty("type", js::Read::StringView, >::Camera::mType)) - .Register(*js::MakeProperty("perspective", js::ObjectReader::Read, >::Camera::mPerspective)) - .Register(*js::MakeProperty("orthographic", js::ObjectReader::Read, >::Camera::mOrthographic)) -); + .Register(*new js::Property("name", js::Read::StringView, >::Camera::mName)) + .Register(*js::MakeProperty("type", js::Read::StringView, >::Camera::mType)) + .Register(*js::MakeProperty("perspective", js::ObjectReader::Read, >::Camera::mPerspective)) + .Register(*js::MakeProperty("orthographic", js::ObjectReader::Read, >::Camera::mOrthographic))); const auto NODE_READER = std::move(js::Reader() - .Register(*new js::Property("name", js::Read::StringView, >::Node::mName)) - .Register(*js::MakeProperty("translation", gt::ReadDaliVector, >::Node::mTranslation)) - .Register(*js::MakeProperty("rotation", gt::ReadQuaternion, >::Node::mRotation)) - .Register(*js::MakeProperty("scale", gt::ReadDaliVector, >::Node::mScale)) - .Register(*new js::Property("matrix", gt::ReadDaliVector, >::Node::SetMatrix)) - .Register(*js::MakeProperty("camera", gt::RefReader::Read, - >::Node::mCamera)) - .Register(*js::MakeProperty("children", js::Read::Array, gt::RefReader::Read>, - >::Node::mChildren)) - .Register(*js::MakeProperty("mesh", gt::RefReader::Read, >::Node::mMesh)) - .Register(*js::MakeProperty("skin", gt::RefReader::Read, >::Node::mSkin)) -); + .Register(*new js::Property("name", js::Read::StringView, >::Node::mName)) + .Register(*js::MakeProperty("translation", gt::ReadDaliVector, >::Node::mTranslation)) + .Register(*js::MakeProperty("rotation", gt::ReadQuaternion, >::Node::mRotation)) + .Register(*js::MakeProperty("scale", gt::ReadDaliVector, >::Node::mScale)) + .Register(*new js::Property("matrix", gt::ReadDaliVector, >::Node::SetMatrix)) + .Register(*js::MakeProperty("camera", gt::RefReader::Read, >::Node::mCamera)) + .Register(*js::MakeProperty("children", js::Read::Array, gt::RefReader::Read>, >::Node::mChildren)) + .Register(*js::MakeProperty("mesh", gt::RefReader::Read, >::Node::mMesh)) + .Register(*js::MakeProperty("skin", gt::RefReader::Read, >::Node::mSkin))); const auto ANIMATION_SAMPLER_READER = std::move(js::Reader() - .Register(*js::MakeProperty("input", gt::RefReader::Read, - >::Animation::Sampler::mInput)) - .Register(*js::MakeProperty("output", gt::RefReader::Read, - >::Animation::Sampler::mOutput)) - .Register(*js::MakeProperty("interpolation", gt::ReadStringEnum, >::Animation::Sampler::mInterpolation)) -); + .Register(*js::MakeProperty("input", gt::RefReader::Read, >::Animation::Sampler::mInput)) + .Register(*js::MakeProperty("output", gt::RefReader::Read, >::Animation::Sampler::mOutput)) + .Register(*js::MakeProperty("interpolation", gt::ReadStringEnum, >::Animation::Sampler::mInterpolation))); const auto ANIMATION_TARGET_READER = std::move(js::Reader() - .Register(*js::MakeProperty("node", gt::RefReader::Read, - >::Animation::Channel::Target::mNode)) - .Register(*js::MakeProperty("path", gt::ReadStringEnum, - >::Animation::Channel::Target::mPath)) -); + .Register(*js::MakeProperty("node", gt::RefReader::Read, >::Animation::Channel::Target::mNode)) + .Register(*js::MakeProperty("path", gt::ReadStringEnum, >::Animation::Channel::Target::mPath))); const auto ANIMATION_CHANNEL_READER = std::move(js::Reader() - .Register(*js::MakeProperty("target", js::ObjectReader::Read, >::Animation::Channel::mTarget)) - .Register(*js::MakeProperty("sampler", gt::RefReader::Read, >::Animation::Channel::mSampler)) -); + .Register(*js::MakeProperty("target", js::ObjectReader::Read, >::Animation::Channel::mTarget)) + .Register(*js::MakeProperty("sampler", gt::RefReader::Read, >::Animation::Channel::mSampler))); const auto ANIMATION_READER = std::move(js::Reader() - .Register(*new js::Property("name", js::Read::StringView, >::Animation::mName)) - .Register(*js::MakeProperty("samplers", - js::Read::Array::Read>, >::Animation::mSamplers)) - .Register(*js::MakeProperty("channels", - js::Read::Array::Read>, >::Animation::mChannels)) -); + .Register(*new js::Property("name", js::Read::StringView, >::Animation::mName)) + .Register(*js::MakeProperty("samplers", + js::Read::Array::Read>, + >::Animation::mSamplers)) + .Register(*js::MakeProperty("channels", + js::Read::Array::Read>, + >::Animation::mChannels))); const auto SCENE_READER = std::move(js::Reader() - .Register(*new js::Property("name", js::Read::StringView, >::Scene::mName)) - .Register(*js::MakeProperty("nodes", - js::Read::Array, gt::RefReader::Read>, >::Scene::mNodes)) -); + .Register(*new js::Property("name", js::Read::StringView, >::Scene::mName)) + .Register(*js::MakeProperty("nodes", + js::Read::Array, gt::RefReader::Read>, + >::Scene::mNodes))); const auto DOCUMENT_READER = std::move(js::Reader() - .Register(*js::MakeProperty("buffers", - js::Read::Array::Read>, >::Document::mBuffers)) - .Register(*js::MakeProperty("bufferViews", - js::Read::Array::Read>, >::Document::mBufferViews)) - .Register(*js::MakeProperty("accessors", - js::Read::Array::Read>, >::Document::mAccessors)) - .Register(*js::MakeProperty("images", - js::Read::Array::Read>, >::Document::mImages)) - .Register(*js::MakeProperty("samplers", - js::Read::Array::Read>, >::Document::mSamplers)) - .Register(*js::MakeProperty("textures", - js::Read::Array::Read>, >::Document::mTextures)) - .Register(*js::MakeProperty("materials", - js::Read::Array::Read>, >::Document::mMaterials)) - .Register(*js::MakeProperty("meshes", - js::Read::Array::Read>, >::Document::mMeshes)) - .Register(*js::MakeProperty("skins", - js::Read::Array::Read>, >::Document::mSkins)) - .Register(*js::MakeProperty("cameras", - js::Read::Array::Read>, >::Document::mCameras)) - .Register(*js::MakeProperty("nodes", - js::Read::Array::Read>, >::Document::mNodes)) - .Register(*js::MakeProperty("animations", - ReadAnimationArray, >::Document::mAnimations)) - .Register(*js::MakeProperty("scenes", - js::Read::Array::Read>, >::Document::mScenes)) - .Register(*js::MakeProperty("scene", gt::RefReader::Read, >::Document::mScene)) -); + .Register(*js::MakeProperty("buffers", + js::Read::Array::Read>, + >::Document::mBuffers)) + .Register(*js::MakeProperty("bufferViews", + js::Read::Array::Read>, + >::Document::mBufferViews)) + .Register(*js::MakeProperty("accessors", + js::Read::Array::Read>, + >::Document::mAccessors)) + .Register(*js::MakeProperty("images", + js::Read::Array::Read>, + >::Document::mImages)) + .Register(*js::MakeProperty("samplers", + js::Read::Array::Read>, + >::Document::mSamplers)) + .Register(*js::MakeProperty("textures", + js::Read::Array::Read>, + >::Document::mTextures)) + .Register(*js::MakeProperty("materials", + js::Read::Array::Read>, + >::Document::mMaterials)) + .Register(*js::MakeProperty("meshes", + js::Read::Array::Read>, + >::Document::mMeshes)) + .Register(*js::MakeProperty("skins", + js::Read::Array::Read>, + >::Document::mSkins)) + .Register(*js::MakeProperty("cameras", + js::Read::Array::Read>, + >::Document::mCameras)) + .Register(*js::MakeProperty("nodes", + js::Read::Array::Read>, + >::Document::mNodes)) + .Register(*js::MakeProperty("animations", + ReadAnimationArray, + >::Document::mAnimations)) + .Register(*js::MakeProperty("scenes", + js::Read::Array::Read>, + >::Document::mScenes)) + .Register(*js::MakeProperty("scene", gt::RefReader::Read, >::Document::mScene))); struct NodeMapping { @@ -353,7 +347,7 @@ bool operator<(const NodeMapping& mapping, Index gltfIdx) class NodeIndexMapper { public: - NodeIndexMapper() = default; + NodeIndexMapper() = default; NodeIndexMapper(const NodeIndexMapper&) = delete; NodeIndexMapper& operator=(const NodeIndexMapper&) = delete; @@ -362,18 +356,18 @@ public: /// save growing a vector. void RegisterMapping(Index gltfIdx, Index runtimeIdx) { - if (gltfIdx != runtimeIdx) + if(gltfIdx != runtimeIdx) { auto iInsert = std::lower_bound(mNodes.begin(), mNodes.end(), gltfIdx); DALI_ASSERT_DEBUG(iInsert == mNodes.end() || iInsert->gltfIdx != gltfIdx); - mNodes.insert(iInsert, NodeMapping{ gltfIdx, runtimeIdx }); + mNodes.insert(iInsert, NodeMapping{gltfIdx, runtimeIdx}); } } ///@brief Retrieves the runtime index of a Node, mapped to the given @a gltfIdx. Index GetRuntimeId(Index gltfIdx) const { - auto iFind = std::lower_bound(mNodes.begin(), mNodes.end(), gltfIdx); // using custom operator< + auto iFind = std::lower_bound(mNodes.begin(), mNodes.end(), gltfIdx); // using custom operator< return (iFind != mNodes.end() && iFind->gltfIdx == gltfIdx) ? iFind->runtimeIdx : gltfIdx; } @@ -383,39 +377,35 @@ private: struct ConversionContext { - LoadResult& mOutput; + LoadResult& mOutput; std::string mPath; - Index mDefaultMaterial; + Index mDefaultMaterial; - std::vector mMeshIds; - NodeIndexMapper mNodeIndices; + std::vector mMeshIds; + NodeIndexMapper mNodeIndices; }; SamplerFlags::Type ConvertWrapMode(gt::Wrap::Type w) { - switch (w) + switch(w) { - case gt::Wrap::REPEAT: - return SamplerFlags::WRAP_REPEAT; - case gt::Wrap::CLAMP_TO_EDGE: - return SamplerFlags::WRAP_CLAMP; - case gt::Wrap::MIRRORED_REPEAT: - return SamplerFlags::WRAP_MIRROR; - default: - throw std::runtime_error("Invalid wrap type."); + case gt::Wrap::REPEAT: + return SamplerFlags::WRAP_REPEAT; + case gt::Wrap::CLAMP_TO_EDGE: + return SamplerFlags::WRAP_CLAMP; + case gt::Wrap::MIRRORED_REPEAT: + return SamplerFlags::WRAP_MIRROR; + default: + throw std::runtime_error("Invalid wrap type."); } } SamplerFlags::Type ConvertSampler(const gt::Ref& s) { - if (s) + if(s) { - return (s->mMinFilter < gt::Filter::NEAREST_MIPMAP_NEAREST) ? (s->mMinFilter - gt::Filter::NEAREST) : - ((s->mMinFilter - gt::Filter::NEAREST_MIPMAP_NEAREST) + 2) | - ((s->mMagFilter - gt::Filter::NEAREST) << SamplerFlags::FILTER_MAG_SHIFT) | - (ConvertWrapMode(s->mWrapS) << SamplerFlags::WRAP_S_SHIFT) | - (ConvertWrapMode(s->mWrapT) << SamplerFlags::WRAP_T_SHIFT); + return (s->mMinFilter < gt::Filter::NEAREST_MIPMAP_NEAREST) ? (s->mMinFilter - gt::Filter::NEAREST) : ((s->mMinFilter - gt::Filter::NEAREST_MIPMAP_NEAREST) + 2) | ((s->mMagFilter - gt::Filter::NEAREST) << SamplerFlags::FILTER_MAG_SHIFT) | (ConvertWrapMode(s->mWrapS) << SamplerFlags::WRAP_S_SHIFT) | (ConvertWrapMode(s->mWrapT) << SamplerFlags::WRAP_T_SHIFT); } else { @@ -424,13 +414,13 @@ SamplerFlags::Type ConvertSampler(const gt::Ref& s) // "What is an auto filtering", I hear you ask. Since there's nothing else to determine mipmapping from - including glTF image // properties, if not in some extension -, we will simply assume linear filtering. return SamplerFlags::FILTER_LINEAR | (SamplerFlags::FILTER_LINEAR << SamplerFlags::FILTER_MAG_SHIFT) | - (SamplerFlags::WRAP_REPEAT << SamplerFlags::WRAP_S_SHIFT) | (SamplerFlags::WRAP_REPEAT << SamplerFlags::WRAP_T_SHIFT); + (SamplerFlags::WRAP_REPEAT << SamplerFlags::WRAP_S_SHIFT) | (SamplerFlags::WRAP_REPEAT << SamplerFlags::WRAP_T_SHIFT); } } TextureDefinition ConvertTextureInfo(const gt::TextureInfo& mm) { - return TextureDefinition{ std::string(mm.mTexture->mSource->mUri), ConvertSampler(mm.mTexture->mSampler) }; + return TextureDefinition{std::string(mm.mTexture->mSource->mUri), ConvertSampler(mm.mTexture->mSampler)}; } void ConvertMaterial(const gt::Material& m, decltype(ResourceBundle::mMaterials)& outMaterials) @@ -438,12 +428,12 @@ void ConvertMaterial(const gt::Material& m, decltype(ResourceBundle::mMaterials) MaterialDefinition matDef; auto& pbr = m.mPbrMetallicRoughness; - if (m.mAlphaMode != gt::AlphaMode::OPAQUE || pbr.mBaseColorFactor.a < 1.f) + if(m.mAlphaMode != gt::AlphaMode::OPAQUE || pbr.mBaseColorFactor.a < 1.f) { matDef.mFlags |= MaterialDefinition::TRANSPARENCY; } - if (m.mAlphaMode == gt::AlphaMode::MASK) + if(m.mAlphaMode == gt::AlphaMode::MASK) { matDef.SetAlphaCutoff(std::min(1.f, std::max(0.f, m.mAlphaCutoff))); } @@ -451,30 +441,30 @@ void ConvertMaterial(const gt::Material& m, decltype(ResourceBundle::mMaterials) matDef.mColor = pbr.mBaseColorFactor; matDef.mTextureStages.reserve(!!pbr.mBaseColorTexture + !!pbr.mMetallicRoughnessTexture + !!m.mNormalTexture); - if (pbr.mBaseColorTexture) + if(pbr.mBaseColorTexture) { const auto semantic = MaterialDefinition::ALBEDO; - matDef.mTextureStages.push_back({ semantic, ConvertTextureInfo(pbr.mBaseColorTexture) }); + matDef.mTextureStages.push_back({semantic, ConvertTextureInfo(pbr.mBaseColorTexture)}); // TODO: and there had better be one matDef.mFlags |= semantic; } - matDef.mMetallic = pbr.mMetallicFactor; + matDef.mMetallic = pbr.mMetallicFactor; matDef.mRoughness = pbr.mRoughnessFactor; - if (pbr.mMetallicRoughnessTexture) + if(pbr.mMetallicRoughnessTexture) { const auto semantic = MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS | - MaterialDefinition::GLTF_CHANNELS; - matDef.mTextureStages.push_back({ semantic, ConvertTextureInfo(pbr.mMetallicRoughnessTexture) }); + MaterialDefinition::GLTF_CHANNELS; + matDef.mTextureStages.push_back({semantic, ConvertTextureInfo(pbr.mMetallicRoughnessTexture)}); // TODO: and there had better be one matDef.mFlags |= semantic; } - if (m.mNormalTexture) + if(m.mNormalTexture) { const auto semantic = MaterialDefinition::NORMAL; - matDef.mTextureStages.push_back({ semantic, ConvertTextureInfo(m.mNormalTexture) }); + matDef.mTextureStages.push_back({semantic, ConvertTextureInfo(m.mNormalTexture)}); // TODO: and there had better be one matDef.mFlags |= semantic; } @@ -489,7 +479,7 @@ void ConvertMaterials(const gt::Document& doc, ConversionContext& cctx) auto& outMaterials = cctx.mOutput.mResources.mMaterials; outMaterials.reserve(doc.mMaterials.size()); - for (auto& m : doc.mMaterials) + for(auto& m : doc.mMaterials) { ConvertMaterial(m, outMaterials); } @@ -498,42 +488,41 @@ void ConvertMaterials(const gt::Document& doc, ConversionContext& cctx) MeshDefinition::Accessor ConvertMeshPrimitiveAccessor(const gt::Accessor& acc) { DALI_ASSERT_ALWAYS((acc.mBufferView && - (acc.mBufferView->mByteStride < std::numeric_limits::max())) || - (acc.mSparse && !acc.mBufferView)); + (acc.mBufferView->mByteStride < std::numeric_limits::max())) || + (acc.mSparse && !acc.mBufferView)); DALI_ASSERT_ALWAYS(!acc.mSparse || - ((acc.mSparse->mIndices.mBufferView && (acc.mSparse->mIndices.mBufferView->mByteStride < std::numeric_limits::max())) && - (acc.mSparse->mValues.mBufferView && (acc.mSparse->mValues.mBufferView->mByteStride < std::numeric_limits::max())))); - + ((acc.mSparse->mIndices.mBufferView && (acc.mSparse->mIndices.mBufferView->mByteStride < std::numeric_limits::max())) && + (acc.mSparse->mValues.mBufferView && (acc.mSparse->mValues.mBufferView->mByteStride < std::numeric_limits::max())))); MeshDefinition::SparseBlob sparseBlob; - if (acc.mSparse) + if(acc.mSparse) { - const gt::Accessor::Sparse& sparse = *acc.mSparse; + const gt::Accessor::Sparse& sparse = *acc.mSparse; const gt::ComponentTypedBufferViewClient& indices = sparse.mIndices; - const gt::BufferViewClient& values = sparse.mValues; + const gt::BufferViewClient& values = sparse.mValues; MeshDefinition::Blob indicesBlob( indices.mBufferView->mByteOffset + indices.mByteOffset, sparse.mCount * indices.GetBytesPerComponent(), static_cast(indices.mBufferView->mByteStride), static_cast(indices.GetBytesPerComponent()), - {}, {} - ); + {}, + {}); MeshDefinition::Blob valuesBlob( values.mBufferView->mByteOffset + values.mByteOffset, sparse.mCount * acc.GetElementSizeBytes(), static_cast(values.mBufferView->mByteStride), static_cast(acc.GetElementSizeBytes()), - {}, {} - ); + {}, + {}); sparseBlob = std::move(MeshDefinition::SparseBlob(std::move(indicesBlob), std::move(valuesBlob), acc.mSparse->mCount)); } uint32_t bufferViewOffset = 0u; uint32_t bufferViewStride = 0u; - if (acc.mBufferView) + if(acc.mBufferView) { bufferViewOffset = acc.mBufferView->mByteOffset; bufferViewStride = acc.mBufferView->mByteStride; @@ -541,19 +530,19 @@ MeshDefinition::Accessor ConvertMeshPrimitiveAccessor(const gt::Accessor& acc) return MeshDefinition::Accessor{ std::move(MeshDefinition::Blob{bufferViewOffset + acc.mByteOffset, - acc.GetBytesLength(), - static_cast(bufferViewStride), - static_cast(acc.GetElementSizeBytes()), - acc.mMin, - acc.mMax}), - std::move(sparseBlob) }; + acc.GetBytesLength(), + static_cast(bufferViewStride), + static_cast(acc.GetElementSizeBytes()), + acc.mMin, + acc.mMax}), + std::move(sparseBlob)}; } void ConvertMeshes(const gt::Document& doc, ConversionContext& cctx) { uint32_t meshCount = 0; cctx.mMeshIds.reserve(doc.mMeshes.size()); - for (auto& m : doc.mMeshes) + for(auto& m : doc.mMeshes) { cctx.mMeshIds.push_back(meshCount); meshCount += m.mPrimitives.size(); @@ -561,94 +550,94 @@ void ConvertMeshes(const gt::Document& doc, ConversionContext& cctx) auto& outMeshes = cctx.mOutput.mResources.mMeshes; outMeshes.reserve(meshCount); - for (auto& m : doc.mMeshes) + for(auto& m : doc.mMeshes) { - for (auto& p : m.mPrimitives) + for(auto& p : m.mPrimitives) { MeshDefinition meshDef; - auto& attribs = p.mAttributes; - meshDef.mUri = attribs.begin()->second->mBufferView->mBuffer->mUri; + auto& attribs = p.mAttributes; + meshDef.mUri = attribs.begin()->second->mBufferView->mBuffer->mUri; meshDef.mPrimitiveType = GLTF2_TO_DALI_PRIMITIVES[p.mMode]; auto& accPositions = *attribs.find(gt::Attribute::POSITION)->second; meshDef.mPositions = ConvertMeshPrimitiveAccessor(accPositions); const bool needNormalsTangents = accPositions.mType == gt::AccessorType::VEC3; - for (auto& am : ATTRIBUTE_MAPPINGS) + for(auto& am : ATTRIBUTE_MAPPINGS) { auto iFind = attribs.find(am.mType); - if (iFind != attribs.end()) + if(iFind != attribs.end()) { DALI_ASSERT_DEBUG(iFind->second->mBufferView->mBuffer->mUri.compare(meshDef.mUri) == 0); auto& accessor = meshDef.*(am.mAccessor); - accessor = ConvertMeshPrimitiveAccessor(*iFind->second); + accessor = ConvertMeshPrimitiveAccessor(*iFind->second); // Fixing up -- a few of glTF2 sample models have VEC4 tangents; we need VEC3s. - if (iFind->first == gt::Attribute::TANGENT && (accessor.mBlob.mElementSizeHint > am.mElementSizeRequired)) + if(iFind->first == gt::Attribute::TANGENT && (accessor.mBlob.mElementSizeHint > am.mElementSizeRequired)) { - accessor.mBlob.mStride = std::max(static_cast(accessor.mBlob.mStride + accessor.mBlob.mElementSizeHint - am.mElementSizeRequired), - accessor.mBlob.mElementSizeHint); + accessor.mBlob.mStride = std::max(static_cast(accessor.mBlob.mStride + accessor.mBlob.mElementSizeHint - am.mElementSizeRequired), + accessor.mBlob.mElementSizeHint); accessor.mBlob.mElementSizeHint = am.mElementSizeRequired; } - if (iFind->first == gt::Attribute::JOINTS_0) + if(iFind->first == gt::Attribute::JOINTS_0) { meshDef.mFlags |= (iFind->second->mComponentType == gt::Component::UNSIGNED_SHORT) * MeshDefinition::U16_JOINT_IDS; DALI_ASSERT_DEBUG(MaskMatch(meshDef.mFlags, MeshDefinition::U16_JOINT_IDS) || iFind->second->mComponentType == gt::Component::FLOAT); } } - else if (needNormalsTangents) + else if(needNormalsTangents) { - switch (am.mType) + switch(am.mType) { - case gt::Attribute::NORMAL: - meshDef.RequestNormals(); - break; + case gt::Attribute::NORMAL: + meshDef.RequestNormals(); + break; - case gt::Attribute::TANGENT: - meshDef.RequestTangents(); - break; + case gt::Attribute::TANGENT: + meshDef.RequestTangents(); + break; - default: - break; + default: + break; } } } - if (p.mIndices) + if(p.mIndices) { meshDef.mIndices = ConvertMeshPrimitiveAccessor(*p.mIndices); meshDef.mFlags |= (p.mIndices->mComponentType == gt::Component::UNSIGNED_INT) * MeshDefinition::U32_INDICES; DALI_ASSERT_DEBUG(MaskMatch(meshDef.mFlags, MeshDefinition::U32_INDICES) || p.mIndices->mComponentType == gt::Component::UNSIGNED_SHORT); } - if (!p.mTargets.empty()) + if(!p.mTargets.empty()) { meshDef.mBlendShapes.reserve(p.mTargets.size()); meshDef.mBlendShapeVersion = BlendShapes::Version::VERSION_2_0; - for (const auto& target : p.mTargets) + for(const auto& target : p.mTargets) { MeshDefinition::BlendShape blendShape; auto endIt = target.end(); - auto it = target.find(gt::Attribute::POSITION); - if (it != endIt) + auto it = target.find(gt::Attribute::POSITION); + if(it != endIt) { blendShape.deltas = ConvertMeshPrimitiveAccessor(*it->second); } it = target.find(gt::Attribute::NORMAL); - if (it != endIt) + if(it != endIt) { blendShape.normals = ConvertMeshPrimitiveAccessor(*it->second); } it = target.find(gt::Attribute::TANGENT); - if (it != endIt) + if(it != endIt) { blendShape.tangents = ConvertMeshPrimitiveAccessor(*it->second); } - if (!m.mWeights.empty()) + if(!m.mWeights.empty()) { blendShape.weight = m.mWeights[meshDef.mBlendShapes.size()]; } @@ -657,7 +646,7 @@ void ConvertMeshes(const gt::Document& doc, ConversionContext& cctx) } } - outMeshes.push_back({ std::move(meshDef), MeshGeometry{} }); + outMeshes.push_back({std::move(meshDef), MeshGeometry{}}); } } } @@ -666,15 +655,15 @@ ModelNode* MakeModelNode(const gt::Mesh::Primitive& prim, ConversionContext& cct { auto modelNode = new ModelNode(); - modelNode->mShaderIdx = 0; // TODO: further thought + modelNode->mShaderIdx = 0; // TODO: further thought auto materialIdx = prim.mMaterial.GetIndex(); - if (INVALID_INDEX == materialIdx) + if(INVALID_INDEX == materialIdx) { // https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#default-material - if (INVALID_INDEX == cctx.mDefaultMaterial) + if(INVALID_INDEX == cctx.mDefaultMaterial) { - auto& outMaterials = cctx.mOutput.mResources.mMaterials; + auto& outMaterials = cctx.mOutput.mResources.mMaterials; cctx.mDefaultMaterial = outMaterials.size(); ConvertMaterial(gt::Material{}, outMaterials); @@ -691,51 +680,56 @@ ModelNode* MakeModelNode(const gt::Mesh::Primitive& prim, ConversionContext& cct void ConvertCamera(const gt::Camera& camera, CameraParameters& camParams) { camParams.isPerspective = camera.mType.compare("perspective") == 0; - if (camParams.isPerspective) + if(camParams.isPerspective) { auto& perspective = camera.mPerspective; - camParams.yFov = Degree(Radian(perspective.mYFov)).degree; - camParams.zNear = perspective.mZNear; - camParams.zFar = perspective.mZFar; + camParams.yFov = Degree(Radian(perspective.mYFov)).degree; + camParams.zNear = perspective.mZNear; + camParams.zFar = perspective.mZFar; // TODO: yes, we seem to ignore aspectRatio in CameraParameters. } else { - auto& ortho = camera.mOrthographic; + auto& ortho = camera.mOrthographic; camParams.orthographicSize = Vector4(-ortho.mXMag, ortho.mXMag, ortho.mYMag, -ortho.mYMag) * .5f; - camParams.zNear = ortho.mZNear; - camParams.zFar = ortho.mZFar; + camParams.zNear = ortho.mZNear; + camParams.zFar = ortho.mZFar; } } -void ConvertNode(gt::Node const& node, const Index gltfIdx, Index parentIdx, ConversionContext& cctx) +void ConvertNode(gt::Node const& node, const Index gltfIdx, Index parentIdx, ConversionContext& cctx, bool isMRendererModel) { - auto& output = cctx.mOutput; - auto& scene = output.mScene; + auto& output = cctx.mOutput; + auto& scene = output.mScene; auto& resources = output.mResources; - const auto idx = scene.GetNodeCount(); - auto weakNode = scene.AddNode([&]() { - std::unique_ptr nodeDef{ new NodeDefinition() }; + const auto idx = scene.GetNodeCount(); + auto weakNode = scene.AddNode([&]() { + std::unique_ptr nodeDef{new NodeDefinition()}; nodeDef->mParentIdx = parentIdx; - nodeDef->mName = node.mName; - if (nodeDef->mName.empty()) + nodeDef->mName = node.mName; + if(nodeDef->mName.empty()) { // TODO: Production quality generation of unique names. nodeDef->mName = std::to_string(reinterpret_cast(nodeDef.get())); } - if (!node.mSkin) // Nodes with skinned meshes are not supposed to have local transforms. + if(!node.mSkin) // Nodes with skinned meshes are not supposed to have local transforms. { - nodeDef->mPosition = node.mTranslation; + nodeDef->mPosition = node.mTranslation; nodeDef->mOrientation = node.mRotation; - nodeDef->mScale = node.mScale; + nodeDef->mScale = node.mScale; + + if(isMRendererModel && node.mName == ROOT_NODE_NAME && node.mScale == SCALE_TO_ADJUST) + { + nodeDef->mScale *= 0.01f; + } } return nodeDef; }()); - if (!weakNode) + if(!weakNode) { ExceptionFlinger(ASSERT_LOCATION) << "Node name '" << node.mName << "' is not unique; scene is invalid."; } @@ -743,25 +737,25 @@ void ConvertNode(gt::Node const& node, const Index gltfIdx, Index parentIdx, Con cctx.mNodeIndices.RegisterMapping(gltfIdx, idx); Index skeletonIdx = node.mSkin ? node.mSkin.GetIndex() : INVALID_INDEX; - if (node.mMesh && !node.mMesh->mPrimitives.empty()) + if(node.mMesh && !node.mMesh->mPrimitives.empty()) { auto& mesh = *node.mMesh; - auto iPrim = mesh.mPrimitives.begin(); - auto modelNode = MakeModelNode(*iPrim, cctx); - auto meshIdx = cctx.mMeshIds[node.mMesh.GetIndex()]; + auto iPrim = mesh.mPrimitives.begin(); + auto modelNode = MakeModelNode(*iPrim, cctx); + auto meshIdx = cctx.mMeshIds[node.mMesh.GetIndex()]; modelNode->mMeshIdx = meshIdx; weakNode->mRenderable.reset(modelNode); DALI_ASSERT_DEBUG(resources.mMeshes[meshIdx].first.mSkeletonIdx == INVALID_INDEX || - resources.mMeshes[meshIdx].first.mSkeletonIdx == skeletonIdx); + resources.mMeshes[meshIdx].first.mSkeletonIdx == skeletonIdx); resources.mMeshes[meshIdx].first.mSkeletonIdx = skeletonIdx; // As does model-exporter, we'll create anonymous child nodes for additional mesh( primitiv)es. - while (++iPrim != mesh.mPrimitives.end()) + while(++iPrim != mesh.mPrimitives.end()) { - std::unique_ptr child{ new NodeDefinition }; + std::unique_ptr child{new NodeDefinition}; child->mParentIdx = idx; auto childModel = MakeModelNode(*iPrim, cctx); @@ -774,12 +768,12 @@ void ConvertNode(gt::Node const& node, const Index gltfIdx, Index parentIdx, Con scene.AddNode(std::move(child)); DALI_ASSERT_DEBUG(resources.mMeshes[meshIdx].first.mSkeletonIdx == INVALID_INDEX || - resources.mMeshes[meshIdx].first.mSkeletonIdx == skeletonIdx); + resources.mMeshes[meshIdx].first.mSkeletonIdx == skeletonIdx); resources.mMeshes[meshIdx].first.mSkeletonIdx = skeletonIdx; } } - if (node.mCamera) + if(node.mCamera) { CameraParameters camParams; ConvertCamera(*node.mCamera, camParams); @@ -788,64 +782,64 @@ void ConvertNode(gt::Node const& node, const Index gltfIdx, Index parentIdx, Con output.mCameraParameters.push_back(camParams); } - for (auto& n : node.mChildren) + for(auto& n : node.mChildren) { - ConvertNode(*n, n.GetIndex(), idx, cctx); + ConvertNode(*n, n.GetIndex(), idx, cctx, isMRendererModel); } } -void ConvertSceneNodes(const gt::Scene& scene, ConversionContext& cctx) +void ConvertSceneNodes(const gt::Scene& scene, ConversionContext& cctx, bool isMRendererModel) { auto& outScene = cctx.mOutput.mScene; - Index rootIdx = outScene.GetNodeCount(); - switch (scene.mNodes.size()) + Index rootIdx = outScene.GetNodeCount(); + switch(scene.mNodes.size()) { - case 0: - break; + case 0: + break; - case 1: - ConvertNode(*scene.mNodes[0], scene.mNodes[0].GetIndex(), INVALID_INDEX, cctx); - outScene.AddRootNode(rootIdx); - break; + case 1: + ConvertNode(*scene.mNodes[0], scene.mNodes[0].GetIndex(), INVALID_INDEX, cctx, isMRendererModel); + outScene.AddRootNode(rootIdx); + break; - default: + default: { - std::unique_ptr sceneRoot{ new NodeDefinition() }; + std::unique_ptr sceneRoot{new NodeDefinition()}; sceneRoot->mName = "GLTF_LOADER_SCENE_ROOT_" + std::to_string(outScene.GetRoots().size()); outScene.AddNode(std::move(sceneRoot)); outScene.AddRootNode(rootIdx); - for (auto& n : scene.mNodes) + for(auto& n : scene.mNodes) { - ConvertNode(*n, n.GetIndex(), rootIdx, cctx); + ConvertNode(*n, n.GetIndex(), rootIdx, cctx, isMRendererModel); } break; } } } -void ConvertNodes(const gt::Document& doc, ConversionContext& cctx) +void ConvertNodes(const gt::Document& doc, ConversionContext& cctx, bool isMRendererModel) { - ConvertSceneNodes(*doc.mScene, cctx); + ConvertSceneNodes(*doc.mScene, cctx, isMRendererModel); - for (uint32_t i = 0, i1 = doc.mScene.GetIndex(); i < i1; ++i) + for(uint32_t i = 0, i1 = doc.mScene.GetIndex(); i < i1; ++i) { - ConvertSceneNodes(doc.mScenes[i], cctx); + ConvertSceneNodes(doc.mScenes[i], cctx, isMRendererModel); } - for (uint32_t i = doc.mScene.GetIndex() + 1; i < doc.mScenes.size(); ++i) + for(uint32_t i = doc.mScene.GetIndex() + 1; i < doc.mScenes.size(); ++i) { - ConvertSceneNodes(doc.mScenes[i], cctx); + ConvertSceneNodes(doc.mScenes[i], cctx, isMRendererModel); } } -template +template void LoadDataFromAccessor(const std::string& path, Vector& dataBuffer, uint32_t offset, uint32_t size) { std::ifstream animationBinaryFile(path, std::ifstream::binary); - if (!animationBinaryFile.is_open()) + if(!animationBinaryFile.is_open()) { throw std::runtime_error("Failed to load " + path); } @@ -855,19 +849,17 @@ void LoadDataFromAccessor(const std::string& path, Vector& dataBuffer, uint32 animationBinaryFile.close(); } -template +template float LoadDataFromAccessors(const std::string& path, const gltf2::Accessor& input, const gltf2::Accessor& output, Vector& inputDataBuffer, Vector& outputDataBuffer) { inputDataBuffer.Resize(input.mCount); outputDataBuffer.Resize(output.mCount); - const uint32_t inputDataBufferSize = input.GetBytesLength(); + const uint32_t inputDataBufferSize = input.GetBytesLength(); const uint32_t outputDataBufferSize = output.GetBytesLength(); - LoadDataFromAccessor(path + std::string(input.mBufferView->mBuffer->mUri), inputDataBuffer, - input.mBufferView->mByteOffset + input.mByteOffset, inputDataBufferSize); - LoadDataFromAccessor(path + std::string(output.mBufferView->mBuffer->mUri), outputDataBuffer, - output.mBufferView->mByteOffset + output.mByteOffset, outputDataBufferSize); + LoadDataFromAccessor(path + std::string(input.mBufferView->mBuffer->mUri), inputDataBuffer, input.mBufferView->mByteOffset + input.mByteOffset, inputDataBufferSize); + LoadDataFromAccessor(path + std::string(output.mBufferView->mBuffer->mUri), outputDataBuffer, output.mBufferView->mByteOffset + output.mByteOffset, outputDataBufferSize); ApplyAccessorMinMax(output, reinterpret_cast(outputDataBuffer.begin())); return inputDataBuffer[input.mCount - 1u]; @@ -876,15 +868,15 @@ float LoadDataFromAccessors(const std::string& path, const gltf2::Accessor& inpu template float LoadKeyFrames(const std::string& path, const gt::Animation::Channel& channel, KeyFrames& keyFrames, gt::Animation::Channel::Target::Type type) { - const gltf2::Accessor& input = *channel.mSampler->mInput; + const gltf2::Accessor& input = *channel.mSampler->mInput; const gltf2::Accessor& output = *channel.mSampler->mOutput; Vector inputDataBuffer; - Vector outputDataBuffer; + Vector outputDataBuffer; const float duration = LoadDataFromAccessors(path, input, output, inputDataBuffer, outputDataBuffer); - for (uint32_t i = 0; i < input.mCount; ++i) + for(uint32_t i = 0; i < input.mCount; ++i) { keyFrames.Add(inputDataBuffer[i] / duration, outputDataBuffer[i]); } @@ -894,7 +886,7 @@ float LoadKeyFrames(const std::string& path, const gt::Animation::Channel& chann float LoadBlendShapeKeyFrames(const std::string& path, const gt::Animation::Channel& channel, const std::string& nodeName, uint32_t& propertyIndex, std::vector& properties) { - const gltf2::Accessor& input = *channel.mSampler->mInput; + const gltf2::Accessor& input = *channel.mSampler->mInput; const gltf2::Accessor& output = *channel.mSampler->mOutput; Vector inputDataBuffer; @@ -902,11 +894,11 @@ float LoadBlendShapeKeyFrames(const std::string& path, const gt::Animation::Chan const float duration = LoadDataFromAccessors(path, input, output, inputDataBuffer, outputDataBuffer); - char weightNameBuffer[32]; - auto prefixSize = snprintf(weightNameBuffer, sizeof(weightNameBuffer), "%s[", BLEND_SHAPE_WEIGHTS_UNIFORM.c_str()); - char* const pWeightName = weightNameBuffer + prefixSize; - const auto remainingSize = sizeof(weightNameBuffer) - prefixSize; - for (uint32_t weightIndex = 0u, endWeightIndex = channel.mSampler->mOutput->mCount / channel.mSampler->mInput->mCount; weightIndex < endWeightIndex; ++weightIndex) + char weightNameBuffer[32]; + auto prefixSize = snprintf(weightNameBuffer, sizeof(weightNameBuffer), "%s[", BLEND_SHAPE_WEIGHTS_UNIFORM.c_str()); + char* const pWeightName = weightNameBuffer + prefixSize; + const auto remainingSize = sizeof(weightNameBuffer) - prefixSize; + for(uint32_t weightIndex = 0u, endWeightIndex = channel.mSampler->mOutput->mCount / channel.mSampler->mInput->mCount; weightIndex < endWeightIndex; ++weightIndex) { AnimatedProperty& animatedProperty = properties[propertyIndex++]; @@ -915,12 +907,12 @@ float LoadBlendShapeKeyFrames(const std::string& path, const gt::Animation::Chan animatedProperty.mPropertyName = std::string(weightNameBuffer); animatedProperty.mKeyFrames = KeyFrames::New(); - for (uint32_t i = 0; i < input.mCount; ++i) + for(uint32_t i = 0; i < input.mCount; ++i) { - animatedProperty.mKeyFrames.Add(inputDataBuffer[i] / duration, outputDataBuffer[i*endWeightIndex + weightIndex]); + animatedProperty.mKeyFrames.Add(inputDataBuffer[i] / duration, outputDataBuffer[i * endWeightIndex + weightIndex]); } - animatedProperty.mTimePeriod = { 0.f, duration }; + animatedProperty.mTimePeriod = {0.f, duration}; } return duration; @@ -932,78 +924,78 @@ void ConvertAnimations(const gt::Document& doc, ConversionContext& cctx) output.mAnimationDefinitions.reserve(output.mAnimationDefinitions.size() + doc.mAnimations.size()); - for (const auto& animation : doc.mAnimations) + for(const auto& animation : doc.mAnimations) { AnimationDefinition animationDef; - if (!animation.mName.empty()) + if(!animation.mName.empty()) { animationDef.mName = animation.mName; } uint32_t numberOfProperties = 0u; - for (const auto& channel : animation.mChannels) + for(const auto& channel : animation.mChannels) { numberOfProperties += channel.mSampler->mOutput->mCount; } animationDef.mProperties.resize(numberOfProperties); Index propertyIndex = 0u; - for (const auto& channel : animation.mChannels) + for(const auto& channel : animation.mChannels) { std::string nodeName; - if (!channel.mTarget.mNode->mName.empty()) + if(!channel.mTarget.mNode->mName.empty()) { nodeName = channel.mTarget.mNode->mName; } else { Index index = cctx.mNodeIndices.GetRuntimeId(channel.mTarget.mNode.GetIndex()); - nodeName = cctx.mOutput.mScene.GetNode(index)->mName; + nodeName = cctx.mOutput.mScene.GetNode(index)->mName; } float duration = 0.f; - switch (channel.mTarget.mPath) + switch(channel.mTarget.mPath) { case gt::Animation::Channel::Target::TRANSLATION: { AnimatedProperty& animatedProperty = animationDef.mProperties[propertyIndex]; - animatedProperty.mNodeName = nodeName; + animatedProperty.mNodeName = nodeName; animatedProperty.mPropertyName = POSITION_PROPERTY; animatedProperty.mKeyFrames = KeyFrames::New(); - duration = LoadKeyFrames(cctx.mPath, channel, animatedProperty.mKeyFrames, channel.mTarget.mPath); + duration = LoadKeyFrames(cctx.mPath, channel, animatedProperty.mKeyFrames, channel.mTarget.mPath); - animatedProperty.mTimePeriod = { 0.f, duration }; + animatedProperty.mTimePeriod = {0.f, duration}; break; } case gt::Animation::Channel::Target::ROTATION: { AnimatedProperty& animatedProperty = animationDef.mProperties[propertyIndex]; - animatedProperty.mNodeName = nodeName; + animatedProperty.mNodeName = nodeName; animatedProperty.mPropertyName = ORIENTATION_PROPERTY; animatedProperty.mKeyFrames = KeyFrames::New(); - duration = LoadKeyFrames(cctx.mPath, channel, animatedProperty.mKeyFrames, channel.mTarget.mPath); + duration = LoadKeyFrames(cctx.mPath, channel, animatedProperty.mKeyFrames, channel.mTarget.mPath); - animatedProperty.mTimePeriod = { 0.f, duration }; + animatedProperty.mTimePeriod = {0.f, duration}; break; } case gt::Animation::Channel::Target::SCALE: { AnimatedProperty& animatedProperty = animationDef.mProperties[propertyIndex]; - animatedProperty.mNodeName = nodeName; + animatedProperty.mNodeName = nodeName; animatedProperty.mPropertyName = SCALE_PROPERTY; animatedProperty.mKeyFrames = KeyFrames::New(); - duration = LoadKeyFrames(cctx.mPath, channel, animatedProperty.mKeyFrames, channel.mTarget.mPath); + duration = LoadKeyFrames(cctx.mPath, channel, animatedProperty.mKeyFrames, channel.mTarget.mPath); - animatedProperty.mTimePeriod = { 0.f, duration }; + animatedProperty.mTimePeriod = {0.f, duration}; break; } case gt::Animation::Channel::Target::WEIGHTS: @@ -1035,13 +1027,15 @@ void ProcessSkins(const gt::Document& doc, ConversionContext& cctx) // otherwise we'll set identity matrices for inverse bind pose. struct IInverseBindMatrixProvider { - virtual ~IInverseBindMatrixProvider() {} + virtual ~IInverseBindMatrixProvider() + { + } virtual void Provide(Matrix& ibm) = 0; }; struct InverseBindMatrixAccessor : public IInverseBindMatrixProvider { - std::ifstream mStream; + std::ifstream mStream; const uint32_t mElementSizeBytes; InverseBindMatrixAccessor(const gt::Accessor& accessor, const std::string& path) @@ -1071,10 +1065,10 @@ void ProcessSkins(const gt::Document& doc, ConversionContext& cctx) auto& resources = cctx.mOutput.mResources; resources.mSkeletons.reserve(doc.mSkins.size()); - for (auto& s : doc.mSkins) + for(auto& s : doc.mSkins) { std::unique_ptr ibmProvider; - if (s.mInverseBindMatrices) + if(s.mInverseBindMatrices) { ibmProvider.reset(new InverseBindMatrixAccessor(*s.mInverseBindMatrices, cctx.mPath)); } @@ -1084,14 +1078,14 @@ void ProcessSkins(const gt::Document& doc, ConversionContext& cctx) } SkeletonDefinition skeleton; - if (s.mSkeleton.GetIndex() != INVALID_INDEX) + if(s.mSkeleton.GetIndex() != INVALID_INDEX) { skeleton.mRootNodeIdx = cctx.mNodeIndices.GetRuntimeId(s.mSkeleton.GetIndex()); } skeleton.mJoints.resize(s.mJoints.size()); auto iJoint = skeleton.mJoints.begin(); - for (auto& j : s.mJoints) + for(auto& j : s.mJoints) { iJoint->mNodeIdx = cctx.mNodeIndices.GetRuntimeId(j.GetIndex()); @@ -1106,10 +1100,10 @@ void ProcessSkins(const gt::Document& doc, ConversionContext& cctx) void ProduceShaders(ShaderDefinitionFactory& shaderFactory, SceneDefinition& scene) { - for (size_t i0 = 0, i1 = scene.GetNodeCount(); i0 != i1; ++i0) + for(size_t i0 = 0, i1 = scene.GetNodeCount(); i0 != i1; ++i0) { auto nodeDef = scene.GetNode(i0); - if (auto renderable = nodeDef->mRenderable.get()) + if(auto renderable = nodeDef->mRenderable.get()) { renderable->mShaderIdx = shaderFactory.ProduceShader(*nodeDef); } @@ -1144,25 +1138,25 @@ void SetObjectReaders() js::SetObjectReader(SCENE_READER); } -} // nonamespace +} // namespace void LoadGltfScene(const std::string& url, ShaderDefinitionFactory& shaderFactory, LoadResult& params) { bool failed = false; - auto js = LoadTextFile(url.c_str(), &failed); - if (failed) + auto js = LoadTextFile(url.c_str(), &failed); + if(failed) { throw std::runtime_error("Failed to load " + url); } json::unique_ptr root(json_parse(js.c_str(), js.size())); - if (!root) + if(!root) { throw std::runtime_error("Failed to parse " + url); } static bool setObjectReaders = true; - if (setObjectReaders) + if(setObjectReaders) { // NOTE: only referencing own, anonymous namespace, const objects; the pointers will never need to change. SetObjectReaders(); @@ -1172,19 +1166,32 @@ void LoadGltfScene(const std::string& url, ShaderDefinitionFactory& shaderFactor gt::Document doc; auto& rootObj = js::Cast(*root); - auto jsAsset = js::FindObjectChild("asset", rootObj); + auto jsAsset = js::FindObjectChild("asset", rootObj); + auto jsAssetVersion = js::FindObjectChild("version", js::Cast(*jsAsset)); - doc.mAsset.mVersion = js::Read::StringView(*jsAssetVersion); + if(jsAssetVersion) + { + doc.mAsset.mVersion = js::Read::StringView(*jsAssetVersion); + } + + bool isMRendererModel(false); + auto jsAssetGenerator = js::FindObjectChild("generator", js::Cast(*jsAsset)); + if(jsAssetGenerator) + { + doc.mAsset.mGenerator = js::Read::StringView(*jsAssetGenerator); + isMRendererModel = (doc.mAsset.mGenerator.find(MRENDERER_MODEL_IDENTIFICATION) != std::string_view::npos); + } + gt::SetRefReaderObject(doc); DOCUMENT_READER.Read(rootObj, doc); - auto path = url.substr(0, url.rfind('/') + 1); - ConversionContext cctx{ params, path, INVALID_INDEX }; + auto path = url.substr(0, url.rfind('/') + 1); + ConversionContext cctx{params, path, INVALID_INDEX}; ConvertMaterials(doc, cctx); ConvertMeshes(doc, cctx); - ConvertNodes(doc, cctx); + ConvertNodes(doc, cctx, isMRendererModel); ConvertAnimations(doc, cctx); ProcessSkins(doc, cctx); @@ -1193,5 +1200,5 @@ void LoadGltfScene(const std::string& url, ShaderDefinitionFactory& shaderFactor params.mScene.EnsureUniqueSkinningShaderInstances(params.mResources); } -} -} +} // namespace SceneLoader +} // namespace Dali