diff --git a/build/tizen/CMakeLists.txt b/build/tizen/CMakeLists.txt
index f6d8ad8..838f3c3 100644
--- a/build/tizen/CMakeLists.txt
+++ b/build/tizen/CMakeLists.txt
@@ -11,8 +11,8 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
endif()
endif()
-SET(ROOT_SRC_DIR ${CMAKE_SOURCE_DIR}/../..)
-SET(DEMO_SHARED ${CMAKE_SOURCE_DIR}/../../shared)
+SET(ROOT_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../..)
+SET(DEMO_SHARED ${CMAKE_CURRENT_SOURCE_DIR}/../../shared)
SET(PREFIX ${CMAKE_INSTALL_PREFIX})
@@ -177,7 +177,7 @@ SET(PO_DIR ${RESOURCE_DIR}/po)
FILE(GLOB PO_FILES RELATIVE "${PO_DIR}" "${PO_DIR}/*.po")
SET(MSGFMT "/usr/bin/msgfmt")
-SET(MO_FILES_DIR ${CMAKE_BINARY_DIR}/mo)
+SET(MO_FILES_DIR ${CMAKE_CURRENT_BINARY_DIR}/mo)
FILE(MAKE_DIRECTORY ${MO_FILES_DIR})
FOREACH(PO_FILE ${PO_FILES})
diff --git a/com.samsung.dali-demo.xml b/com.samsung.dali-demo.xml
index 4bdee68..55c7471 100644
--- a/com.samsung.dali-demo.xml
+++ b/com.samsung.dali-demo.xml
@@ -187,6 +187,9 @@
+
+
+
diff --git a/demo/dali-demo.cpp b/demo/dali-demo.cpp
index 2884a32..a6bee7a 100644
--- a/demo/dali-demo.cpp
+++ b/demo/dali-demo.cpp
@@ -50,6 +50,7 @@ int DALI_EXPORT_API main(int argc, char **argv)
demo.AddExample(Example("metaball-refrac.example", DALI_DEMO_STR_TITLE_METABALL_REFRAC));
demo.AddExample(Example("motion-blur.example", DALI_DEMO_STR_TITLE_MOTION_BLUR));
demo.AddExample(Example("page-turn-view.example", DALI_DEMO_STR_TITLE_PAGE_TURN));
+ demo.AddExample(Example("reflection-demo.example", DALI_DEMO_STR_TITLE_REFLECTION));
demo.AddExample(Example("refraction-effect.example", DALI_DEMO_STR_TITLE_REFRACTION));
demo.AddExample(Example("renderer-stencil.example", DALI_DEMO_STR_TITLE_RENDERER_STENCIL));
demo.AddExample(Example("shadows-and-lights.example", DALI_DEMO_STR_TITLE_LIGHTS_AND_SHADOWS));
diff --git a/examples/contact-cards/contact-card.h b/examples/contact-cards/contact-card.h
index c922e58..cee4000 100644
--- a/examples/contact-cards/contact-card.h
+++ b/examples/contact-cards/contact-card.h
@@ -26,7 +26,7 @@
#include
#include
-class ContactCardLayoutInfo;
+struct ContactCardLayoutInfo;
/**
* @brief Creates and sets up animations for a contact card
diff --git a/examples/point-mesh/point-mesh-example.cpp b/examples/point-mesh/point-mesh-example.cpp
index 7d9fe0b..0313f86 100644
--- a/examples/point-mesh/point-mesh-example.cpp
+++ b/examples/point-mesh/point-mesh-example.cpp
@@ -82,7 +82,7 @@ Geometry CreateGeometry()
// Create vertices
struct Vertex { Vector2 position; float hue; };
- unsigned int numSides = 20;
+ const unsigned int numSides = 20;
Vertex polyhedraVertexData[numSides];
float angle=0;
float sectorAngle = 2.0f * Math::PI / (float) numSides;
diff --git a/examples/reflection-demo/gltf-scene.cpp b/examples/reflection-demo/gltf-scene.cpp
new file mode 100644
index 0000000..424ffa2
--- /dev/null
+++ b/examples/reflection-demo/gltf-scene.cpp
@@ -0,0 +1,588 @@
+/*
+ * Copyright (c) 2020 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include
+
+#include "gltf-scene.h"
+
+#include "pico-json.h"
+
+namespace
+{
+// string contains enum type index encoded matching glTFAttributeType
+const std::vector GLTF_STR_ATTRIBUTE_TYPE = {
+ "POSITION",
+ "NORMAL",
+ "TEXCOORD_0"
+};
+
+const std::vector> GLTF_STR_COMPONENT_TYPE = {
+ std::make_pair( "VEC2", 2 ),
+ std::make_pair( "VEC3", 3 ),
+ std::make_pair( "VEC4", 4 ),
+ std::make_pair( "SCALAR", 1 )
+};
+
+glTFAttributeType glTFAttributeTypeStrToEnum( const std::string& name )
+{
+ int index = -1;
+ auto iter = std::find_if( GLTF_STR_ATTRIBUTE_TYPE.begin(), GLTF_STR_ATTRIBUTE_TYPE.end(),
+ [name, &index]( const std::string& val )
+ {
+ index++;
+ return val == name;
+ });
+ if( iter == GLTF_STR_ATTRIBUTE_TYPE.end() )
+ {
+ return glTFAttributeType::UNDEFINED;
+ }
+
+ return static_cast(index);
+}
+
+uint32_t glTFComponentTypeStrToNum( const std::string& name )
+{
+ auto iter = std::find_if( GLTF_STR_COMPONENT_TYPE.begin(), GLTF_STR_COMPONENT_TYPE.end(),
+ [name]( const std::pair& val )
+ {
+ return val.first == name;
+ });
+ if( iter == GLTF_STR_COMPONENT_TYPE.end() )
+ {
+ return 0;
+ }
+
+ return iter->second;
+}
+
+template
+struct JsonResult
+{
+ bool success;
+ T result;
+ operator T() const
+ {
+ return static_cast(result);
+ }
+};
+
+template<>
+struct JsonResult
+{
+ bool success;
+ bool result;
+
+ operator bool() const
+ {
+ return result;
+ }
+};
+
+template
+JsonResult JsonFindValue( const picojson::object& object, const std::string& name )
+{
+ auto iter = find_if(object.begin(), object.end(), [name](decltype(*object.begin())& item)
+ {
+ return item.first == name;
+ });
+
+ if(iter == object.end())
+ {
+ return {false};
+ }
+
+ return {true, iter->second};
+};
+
+
+template
+JsonResult JsonGetValue( const picojson::value& val, const std::string& name, const Converted& onFail )
+{
+ if( val.contains(name) )
+ {
+ return {true, static_cast(val.get(name).get())};
+ }
+ return {false, onFail};
+}
+
+template
+bool JsonGetValueOut( const picojson::value& val, const std::string& name, Converted& writeOut )
+{
+ if( val.contains(name) )
+ {
+ writeOut = static_cast(val.get(name).get());
+ return true;
+ }
+ return false;
+}
+
+
+/**
+ * Safe json value accessor
+ */
+template
+JsonResult> JsonGetArray( const picojson::value& val, const std::string& name, std::vector valueOnFail = {} )
+{
+ if(val.contains(name) )
+ {
+ const auto& array = val.get(name).get();
+ std::vector result{};
+ for( const auto& item : array )
+ {
+ result.emplace_back( static_cast(item.get()) );
+ }
+ return {true, result};
+ }
+ return {false, valueOnFail};
+}
+
+}
+
+glTF::glTF(const std::string& filename)
+{
+ LoadFromFile(filename);
+ ParseJSON();
+}
+
+void glTF::LoadFromFile( const std::string& filename )
+{
+ std::string jsonFile( filename );
+ jsonFile += ".gltf";
+ std::string binFile( filename );
+ binFile += ".bin";
+
+ // load binary
+
+ GLTF_LOG("LoadFromFile: %s", binFile.c_str());
+ mBuffer = LoadFile(binFile);
+ jsonBuffer = LoadFile(jsonFile);
+
+ // Log errors
+ if(mBuffer.empty())
+ {
+ GLTF_LOG("Error, buffer empty!");
+ }
+ else
+ {
+ GLTF_LOG( "GLTF[BIN]: %s loaded, size = %d", binFile.c_str(), int(mBuffer.size()));
+ }
+ if(jsonBuffer.empty())
+ {
+ GLTF_LOG("Error, buffer GLTF empty!");
+ }
+ else
+ {
+ GLTF_LOG( "GLTF: %s loaded, size = %d", binFile.c_str(), int(mBuffer.size()));
+ }
+
+ // Abort if errors
+ if(jsonBuffer.empty() || mBuffer.empty())
+ {
+ return;
+ }
+
+ // parse json
+ auto err = picojson::parse(jsonNode, std::string(reinterpret_cast(jsonBuffer.data())));
+ if(!err.empty())
+ {
+ GLTF_LOG( "GLTF: Error parsing %s, error: %s", jsonFile.c_str(), err.c_str());
+ return;
+ }
+ else
+ {
+ GLTF_LOG( "GLTF: %s loaded, size = %d", jsonFile.c_str(), int(jsonBuffer.size()));
+ }
+}
+
+bool glTF::ParseJSON()
+{
+ if (!jsonNode.is())
+ {
+ return false;
+ }
+
+ // Add dummy first node to nodes (scene node)
+ mNodes.emplace_back();
+
+ // Sources for textures to be resolved later
+ std::vector textureSources{};
+ std::vector images{};
+
+ for( auto& val : jsonNode.get() )
+ {
+ GLTF_LOG( "node: %s", val.first.c_str());
+
+ // Parse bufferviews
+ if( val.first == "bufferViews" )
+ {
+ auto bufferViews = val.second;
+ for( auto& view : bufferViews.get() )
+ {
+ auto bufferIndex = uint32_t(view.get("buffer").get());
+ auto byteLength = uint32_t(view.get("byteLength").get());
+ auto byteOffset = uint32_t(view.get("byteOffset").get());
+
+ glTF_BufferView bufferView{};
+ bufferView.bufferIndex = bufferIndex;
+ bufferView.byteLength = byteLength;
+ bufferView.byteOffset = byteOffset;
+
+ mBufferViews.emplace_back( bufferView );
+ }
+ }
+
+ // parse accessors
+ else if( val.first == "accessors" )
+ {
+ for( const auto& accessor : val.second.get() )
+ {
+ auto gltfAccessor = glTF_Accessor{};
+ gltfAccessor.bufferView = uint32_t(accessor.get( "bufferView" ).get());
+ gltfAccessor.componentType = uint32_t(accessor.get( "componentType" ).get());
+ gltfAccessor.count = uint32_t(accessor.get( "count" ).get());
+ gltfAccessor.type = accessor.get( "type" ).get();
+ gltfAccessor.componentSize = glTFComponentTypeStrToNum( gltfAccessor.type );
+ mAccessors.emplace_back( gltfAccessor );
+ }
+ }
+
+ // parse meshes
+ else if( val.first == "meshes" )
+ {
+ for( const auto& mesh : val.second.get() )
+ {
+ glTF_Mesh gltfMesh{};
+ gltfMesh.name = mesh.get( "name" ).get();
+
+ // get primitives (in this implementation assuming single mesh consists of
+ // one and only one primitive)
+ const auto& primitive = mesh.get("primitives").get()[0];
+ const auto& attrs = primitive.get("attributes").get();
+ for( const auto& attr : attrs )
+ {
+ auto type = glTFAttributeTypeStrToEnum( attr.first );
+ auto bvIndex = uint32_t(attr.second.get());
+ gltfMesh.attributes.emplace_back( std::make_pair( type, bvIndex ) );
+ GLTF_LOG("GLTF: ATTR: type: %d, index: %d", int(type), int(bvIndex));
+ }
+
+ gltfMesh.indices = uint32_t(primitive.get("indices").get());
+ gltfMesh.material = uint32_t(primitive.get("material").get());
+ mMeshes.emplace_back( gltfMesh );
+ }
+ }
+ // parse cameras
+ else if( val.first == "cameras" )
+ {
+ glTF_Camera tgifCamera{};
+ for( const auto& camera : val.second.get() )
+ {
+ tgifCamera.name = camera.get( "name" ).to_str();
+ tgifCamera.isPerspective = (camera.get( "type" ).to_str() == "perspective" );
+ if(tgifCamera.isPerspective)
+ {
+ const auto& perspective = camera.get( "perspective" );
+ tgifCamera.yfov = static_cast(perspective.get( "yfov" ).get());
+ tgifCamera.zfar = static_cast(perspective.get( "zfar" ).get());
+ tgifCamera.znear = static_cast(perspective.get( "znear" ).get());
+ }
+
+ mCameras.emplace_back( tgifCamera );
+ }
+ }
+ // parse nodes
+ else if( val.first == "nodes" )
+ {
+ auto nodeIndex = 1u;
+ for( const auto& node : val.second.get() )
+ {
+ glTF_Node gltfNode{};
+ gltfNode.name = node.get( "name" ).to_str();
+ auto rotation = JsonGetArray( node, "rotation", {0.0f, 0.0f, 0.0f, 1.0f} );
+ auto translation = JsonGetArray( node, "translation", {0.0f, 0.0f, 0.0f} );
+ auto scale = JsonGetArray( node, "scale", {1.0f, 1.0f, 1.0f} );
+ std::copy( rotation.result.begin(), rotation.result.end(), gltfNode.rotationQuaternion );
+ std::copy( translation.result.begin(), translation.result.end(), gltfNode.translation );
+ std::copy( scale.result.begin(), scale.result.end(), gltfNode.scale );
+
+ auto children = JsonGetArray( node, "children" );
+ if(children.success)
+ {
+ gltfNode.children = std::move(children.result);
+ }
+ gltfNode.index = nodeIndex;
+ gltfNode.cameraId = 0xffffffff;
+ gltfNode.meshId = 0xffffffff;
+
+ auto cameraId = JsonGetValue( node, "camera", 0xffffffff );
+ if( cameraId.success )
+ {
+ gltfNode.cameraId = cameraId.result;
+ }
+ auto meshId = JsonGetValue( node, "mesh", 0xffffffff );
+ if( meshId.success )
+ {
+ gltfNode.meshId = meshId.result;
+ }
+ mNodes.emplace_back( gltfNode );
+ ++nodeIndex;
+ }
+
+ }
+ // parse scenes, note: only first scene is being parsed
+ else if( val.first == "scenes" )
+ {
+ auto& sceneNode = mNodes[0];
+ const auto& scene = val.second.get()[0];
+ sceneNode.name = JsonGetValue( scene, "name", std::string() );
+ auto result = JsonGetArray( scene, "nodes" );
+ sceneNode.children = result.result;
+ sceneNode.index = 0;
+ }
+ else if( val.first == "materials" )
+ {
+ for( const auto& node : val.second.get() )
+ {
+ // Get pbr material, base color texture
+ glTF_Material material{};
+ material.doubleSided = JsonGetValue( node, "doubleSided", false ).result;
+ material.name = JsonGetValue( node, "name", std::string() ).result;
+ if( node.contains("pbrMetallicRoughness") )
+ {
+ const auto& node0 = node.get("pbrMetallicRoughness");
+ if(node0.contains("baseColorTexture"))
+ {
+ const auto& node1 = node0.get("baseColorTexture");
+ auto index = uint32_t(node1.get("index").get());
+ auto texCoord = uint32_t(node1.get("texCoord").get());
+ material.pbrMetallicRoughness.enabled = true;
+ material.pbrMetallicRoughness.baseTextureColor.index = index;
+ material.pbrMetallicRoughness.baseTextureColor.texCoord = texCoord;
+ }
+ }
+ mMaterials.emplace_back( material );
+ }
+ }
+ else if( val.first == "textures" )
+ {
+ for(const auto& item : val.second.get() )
+ {
+ auto source = JsonGetValue( item, "source", 0xffffffff );
+ textureSources.emplace_back( source.result );
+ }
+ }
+ else if( val.first == "images" )
+ {
+ for(const auto& item : val.second.get() )
+ {
+ glTF_Texture tex{};
+ JsonGetValueOut( item, "name", tex.name );
+ JsonGetValueOut( item, "uri", tex.uri );
+ images.emplace_back( tex );
+ }
+ }
+ }
+
+ // Resolve cross-referencing
+ for( const auto& source : textureSources )
+ {
+ mTextures.emplace_back( images[source] );
+ }
+
+ return true;
+}
+
+glTF_Buffer glTF::LoadFile( const std::string& filename )
+{
+ Dali::FileStream fileStream( filename.c_str(), Dali::FileStream::READ | Dali::FileStream::BINARY );
+ FILE* fin = fileStream.GetFile();
+ std::vector buffer;
+ if( fin )
+ {
+ fseek( fin, 0, SEEK_END );
+ auto size = ftell(fin);
+ fseek( fin, 0, SEEK_SET );
+ buffer.resize(unsigned(size));
+ auto result = fread( buffer.data(), 1, size_t(size), fin );
+ if( result < 0 )
+ {
+ GLTF_LOG("LoadFile: Result: %d", int(result));
+ // return empty buffer
+ return {};
+ }
+ }
+ else
+ {
+ GLTF_LOG("LoadFile: Can't open file: errno = %d", errno);
+ }
+
+ return buffer;
+}
+
+std::vector glTF::GetMeshes() const
+{
+ std::vector retval;
+ for( auto& mesh : mMeshes )
+ {
+ retval.emplace_back( &mesh );
+ }
+ return retval;
+}
+
+std::vector glTF::GetCameras()
+{
+ std::vector cameras;
+ for( const auto& cam : mCameras )
+ {
+ cameras.emplace_back( &cam );
+ }
+ return cameras;
+}
+
+std::vector glTF::GetMeshAttributeBuffer( const glTF_Mesh& mesh, const std::vector& attrTypes )
+{
+ // find buffer views
+ struct Data
+ {
+ uint32_t accessorIndex{0u};
+ uint32_t byteStride{0u};
+ char* srcPtr{ nullptr };
+ };
+ std::vector data{};
+ for( const auto& attrType : attrTypes )
+ {
+ std::find_if( mesh.attributes.begin(), mesh.attributes.end(), [&data, &attrType]( const std::pair& item ){
+ if( item.first == attrType )
+ {
+ data.emplace_back();
+ data.back().accessorIndex = item.second;
+ }
+ return false;
+ });
+ }
+
+ if(data.empty())
+ {
+ return {};
+ }
+
+ // number of attributes is same for the whole mesh so using very first
+ // accessor
+
+ glTF_Buffer retval{};
+
+ // data is interleaved
+ if( data.size() > 1 )
+ {
+ auto attributeCount = mAccessors[data[0].accessorIndex].count;// / mAccessors[data[0].accessorIndex].componentSize;
+ uint32_t attributeStride = 0;
+ // now find buffer view stride for particular accessor
+ for( auto& item : data )
+ {
+ auto& accessor = mAccessors[item.accessorIndex];
+
+ // Update byte stride for this buffer view
+ auto& bufferView = mBufferViews[accessor.bufferView];
+ item.byteStride = bufferView.byteLength / attributeCount;
+ attributeStride += item.byteStride;
+ item.srcPtr = reinterpret_cast(mBuffer.data()) + bufferView.byteOffset;
+ }
+
+ // now allocate final buffer and interleave data
+ retval.resize( attributeStride * attributeCount );
+ auto* dstPtr = retval.data();
+ for( auto i = 0u; i < attributeCount; ++i )
+ {
+ for(auto& item : data )
+ {
+ std::copy( item.srcPtr,
+ item.srcPtr + item.byteStride,
+ reinterpret_cast(dstPtr) );
+ dstPtr += item.byteStride;
+ item.srcPtr += item.byteStride;
+ }
+ }
+ }
+ else // copy data directly as single buffer
+ {
+ auto& bufferView = mBufferViews[mAccessors[data[0].accessorIndex].bufferView];
+ retval.resize( bufferView.byteLength );
+ std::copy( mBuffer.begin() + bufferView.byteOffset,
+ mBuffer.begin() + bufferView.byteOffset + bufferView.byteLength,
+ retval.begin());
+
+ }
+ return retval;
+}
+
+
+const glTF_Mesh* glTF::FindMeshByName( const std::string& name ) const
+{
+ for( const auto& mesh : mMeshes )
+ {
+ if(mesh.name == name)
+ return &mesh;
+ }
+ return nullptr;
+}
+
+uint32_t glTF::GetMeshAttributeCount( const glTF_Mesh* mesh ) const
+{
+ const auto& accessor = mAccessors[mesh->attributes[0].second];
+ return accessor.count;// / accessor.componentSize;
+}
+
+std::vector glTF::GetMeshIndexBuffer( const glTF_Mesh* mesh ) const
+{
+ // check GL component type
+ const auto& accessor = mAccessors[mesh->indices];
+ if( accessor.componentType == 0x1403 ) // GL_UNSIGNED_SHORT
+ {
+ std::vector retval{};
+ retval.resize( accessor.count );
+ const auto& bufferView = mBufferViews[accessor.bufferView];
+ const auto* srcPtr = reinterpret_cast
+ (reinterpret_cast(mBuffer.data()) + bufferView.byteOffset);
+ std::copy( srcPtr, srcPtr + accessor.count, retval.data() );
+ return retval;
+ }
+ return {};
+}
+
+const glTF_Node* glTF::FindNodeByName( const std::string& name ) const
+{
+ auto iter = std::find_if( mNodes.begin(), mNodes.end(), [name]( const glTF_Node& node )
+ {
+ return !name.compare( node.name );
+ });
+
+ if(iter == mNodes.end())
+ {
+ return nullptr;
+ }
+
+ return &*iter;
+}
+
+const std::vector& glTF::GetMaterials() const
+{
+ return mMaterials;
+}
+
+const std::vector& glTF::GetTextures() const
+{
+ return mTextures;
+}
diff --git a/examples/reflection-demo/gltf-scene.h b/examples/reflection-demo/gltf-scene.h
new file mode 100644
index 0000000..faecea8
--- /dev/null
+++ b/examples/reflection-demo/gltf-scene.h
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2020 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GLTF_SCENE_H
+#define GLTF_SCENE_H
+
+#include
+
+#include
+
+#include "pico-json.h"
+
+#define GLTF_LOG(...) {DALI_LOG_ERROR( __VA_ARGS__ );}
+
+enum class glTFAttributeType
+{
+ POSITION = 0,
+ NORMAL = 1,
+ TEXCOORD_0 = 2,
+ UNDEFINED,
+};
+
+struct glTF_Camera
+{
+ std::string name;
+
+ // perspective setup
+ float yfov;
+ float zfar;
+ float znear;
+
+ bool isPerspective;
+};
+
+struct glTF_BufferView
+{
+ uint32_t bufferIndex;
+ uint32_t byteLength;
+ uint32_t byteOffset;
+ void* data;
+};
+
+struct glTF_Accessor
+{
+ uint32_t bufferView;
+ uint32_t componentType;
+ uint32_t count;
+ uint32_t componentSize;
+ std::string type;
+};
+
+struct glTF_Mesh
+{
+ std::string name;
+ std::vector> attributes;
+ uint32_t indices;
+ uint32_t material;
+};
+
+struct glTF_Texture
+{
+ std::string uri;
+ std::string name;
+};
+
+struct glTF_Material
+{
+ bool doubleSided;
+ std::string name;
+ struct pbrMetallicRoughness
+ {
+ bool enabled {false};
+ struct baseTextureColor
+ {
+ uint32_t index;
+ uint32_t texCoord;
+ } baseTextureColor;
+ } pbrMetallicRoughness;
+};
+
+struct glTF_Node
+{
+ uint32_t index{0u};
+ std::string name{};
+ uint32_t meshId { 0xffffffff };
+ uint32_t cameraId{ 0xffffffff };
+ glTF_Node* parent { nullptr };
+ std::vector children {};
+
+ // Transform
+ float rotationQuaternion[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
+ float translation[3] = { 0.0f, 0.0f, 0.0f };
+ float scale[3] = { 1.0f, 1.0f, 1.0f };
+};
+
+using glTF_Buffer = std::vector;
+
+/**
+ * Simple glTF parser
+ *
+ * This implementation requires 2 files (it doesn't decode Base64 embedded in json)
+ */
+struct glTF
+{
+
+ glTF( const std::string& filename );
+ ~glTF() = default;
+
+ std::vector GetMeshes() const;
+
+ std::vector GetCameras();
+
+ const std::vector& GetMaterials() const;
+
+ const std::vector& GetTextures() const;
+
+ const std::vector& GetNodes() const
+ {
+ return mNodes;
+ }
+
+ /**
+ * MESH interface
+ */
+ /**
+ * Returns a copy of attribute buffer
+ * @return
+ */
+ std::vector GetMeshAttributeBuffer( const glTF_Mesh& mesh, const std::vector& attrTypes );
+ uint32_t GetMeshAttributeCount( const glTF_Mesh* mesh ) const;
+ const glTF_Mesh* FindMeshByName( const std::string& name ) const;
+
+ /**
+ * Returns a copy of index buffer
+ * @return
+ */
+ std::vector GetMeshIndexBuffer( const glTF_Mesh* mesh ) const;
+
+ const glTF_Node* FindNodeByName( const std::string& name ) const;
+
+private:
+
+ void LoadFromFile( const std::string& filename );
+
+ glTF_Buffer LoadFile( const std::string& filename );
+
+ bool ParseJSON();
+
+ std::vector mMeshes;
+ std::vector mCameras;
+ std::vector mBufferViews;
+ std::vector mAccessors;
+ std::vector mNodes;
+ std::vector mMaterials;
+ std::vector mTextures;
+ glTF_Buffer mBuffer;
+ glTF_Buffer jsonBuffer;
+
+ // json nodes
+ picojson::value jsonNode;
+};
+
+
+#endif //DALI_CMAKE_GLTF_SCENE_H
diff --git a/examples/reflection-demo/pico-json.h b/examples/reflection-demo/pico-json.h
new file mode 100644
index 0000000..c1cde44
--- /dev/null
+++ b/examples/reflection-demo/pico-json.h
@@ -0,0 +1,1086 @@
+/*
+ * Copyright 2009-2010 Cybozu Labs, Inc.
+ * Copyright 2011-2014 Kazuho Oku
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef picojson_h
+#define picojson_h
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include