[Tizen] Scene, Scene Loader, and glTF Loader
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / scene / gltf-loader.cpp
1 /*
2  * Copyright (c) 2018 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17 // CLASS HEADER
18 #include <dali-toolkit/internal/controls/scene/gltf-loader.h>
19 #include <dali-toolkit/internal/controls/scene/gltf-shader.h>
20
21 // EXTERNAL INCLUDES
22 #include <fstream>
23 #include <dali/integration-api/debug.h>
24 #include <dali/devel-api/adaptor-framework/image-loading.h>
25 #include <dali/devel-api/adaptor-framework/file-loader.h>
26
27 // INTERNAL INCLUDES
28 #include <dali-toolkit/devel-api/image-loader/texture-manager.h>
29
30 using namespace Dali::Toolkit::Internal::GLTF;
31
32 namespace Dali
33 {
34
35 namespace Toolkit
36 {
37
38 namespace Internal
39 {
40
41 GltfLoader::GltfLoader()
42   : mNodes( NULL ),
43   mRoot( NULL )
44 {
45 }
46
47 GltfLoader::~GltfLoader()
48 {
49 }
50
51 bool GltfLoader::LoadScene( const std::string& filePath, Internal::Scene& scene )
52 {
53   // Extracting directory path from full path to load resources.
54   if( std::string::npos != filePath.rfind('/') )
55   {
56     mPath = filePath.substr( 0, filePath.rfind('/') ) + "/";
57   }
58
59   if( !ParseGltf( filePath ) )
60   {
61     DALI_LOG_ERROR( "Fail to parse json file\n" );
62     return false;
63   }
64
65   mRoot = mParser.GetRoot();
66   if( !mRoot )
67   {
68     return false;
69   }
70
71   if( !LoadAssets() )
72   {
73     return false;
74   }
75
76   if( !CreateScene( scene ) )
77   {
78     return false;
79   }
80   return true;
81 }
82
83 bool GltfLoader::ParseGltf( const std::string& filePath )
84 {
85   std::ifstream fileStream( filePath.c_str() );
86   std::string fileBuffer( ( std::istreambuf_iterator<char>( fileStream ) ),
87     ( std::istreambuf_iterator<char>() ) );
88   mParser = Dali::Toolkit::JsonParser::New();
89
90   return mParser.Parse( fileBuffer );
91 }
92
93 bool GltfLoader::LoadAssets()
94 {
95   if( LoadBinaryData( mRoot ) &&         // pass a reference
96       LoadTextureArray( mRoot ) &&       // pass a reference
97       LoadMaterialSetArray( mRoot ) &&   // pass a reference
98       LoadMeshArray( mRoot )             // pass a reference
99     )
100   {
101     return true;
102   }
103   return false;
104 }
105
106 bool GltfLoader::LoadBinaryData( const TreeNode* root )
107 {
108   const TreeNode* buffersNode = root->GetChild( "buffers" );
109   if( !buffersNode )
110   {
111     return false;
112   }
113   for( TreeNode::ConstIterator bufferIter = ( *buffersNode ).CBegin(); bufferIter != ( *buffersNode ).CEnd(); ++bufferIter )
114   {
115     LoadBuffer( ( *bufferIter ).second );
116   }
117
118   const TreeNode* bufferViewsNode = root->GetChild( "bufferViews" );
119   if( !bufferViewsNode )
120   {
121     return false;
122   }
123   for( TreeNode::ConstIterator bufferViewIter = ( *bufferViewsNode ).CBegin(); bufferViewIter != ( *bufferViewsNode ).CEnd(); ++bufferViewIter )
124   {
125     LoadBufferView( ( *bufferViewIter ).second );
126   }
127
128   const TreeNode* accessorsNode = root->GetChild( "accessors" );
129   if( !accessorsNode )
130   {
131     return false;
132   }
133   for( TreeNode::ConstIterator accesorIter = ( *accessorsNode ).CBegin(); accesorIter != ( *accessorsNode ).CEnd(); ++accesorIter )
134   {
135     LoadAccessor( ( *accesorIter ).second );
136   }
137
138   return true;
139 }
140
141 bool GltfLoader::LoadBuffer( const TreeNode& buffer )
142 {
143   BufferInfo bufferInfo;
144
145   const TreeNode* uriNode = buffer.GetChild( "uri" );
146   if( uriNode )
147   {
148     ReadString( uriNode, bufferInfo.uri );
149   }
150
151   const TreeNode* byteLengthNode = buffer.GetChild( "byteLength" );
152   if( byteLengthNode )
153   {
154     ReadInt( byteLengthNode, bufferInfo.byteLength );
155     if( bufferInfo.byteLength < 0 )
156     {
157       return false;
158     }
159   }
160
161   const TreeNode* nameNode = buffer.GetChild( "name" );
162   if( nameNode )
163   {
164     ReadString( nameNode, bufferInfo.name );
165   }
166
167   mBufferArray.push_back( bufferInfo );
168
169   return true;
170 }
171
172 bool GltfLoader::LoadBufferView( const TreeNode& buffer )
173 {
174   BufferViewInfo bufferViewInfo;
175
176   const TreeNode* bufferNode = buffer.GetChild( "buffer" );
177   if( bufferNode )
178   {
179     ReadInt( bufferNode, bufferViewInfo.buffer );
180     if( bufferViewInfo.buffer < 0 )
181     {
182       return false;
183     }
184   }
185
186   const TreeNode* byteOffsetNode = buffer.GetChild( "byteOffset" );
187   if( byteOffsetNode )
188   {
189     ReadInt( byteOffsetNode, bufferViewInfo.byteOffset );
190   }
191
192   const TreeNode* byteLengthNode = buffer.GetChild( "byteLength" );
193   if( byteLengthNode )
194   {
195     ReadInt( byteLengthNode, bufferViewInfo.byteLength );
196     if( bufferViewInfo.byteLength < 0 )
197     {
198       return false;
199     }
200   }
201
202   const TreeNode* byteStrideNode = buffer.GetChild( "byteStride" );
203   if( byteStrideNode )
204   {
205     ReadInt( byteStrideNode, bufferViewInfo.byteStride );
206   }
207
208   const TreeNode* targetNode = buffer.GetChild( "target" );
209   if( targetNode )
210   {
211     ReadInt( targetNode, bufferViewInfo.target );
212   }
213
214   const TreeNode* nameNode = buffer.GetChild( "name" );
215   if( nameNode )
216   {
217     ReadString( nameNode, bufferViewInfo.name );
218   }
219
220   mBufferViewArray.push_back( bufferViewInfo );
221
222   return true;
223 }
224
225 bool GltfLoader::LoadAccessor( const TreeNode& buffer )
226 {
227   AccessorInfo accessorInfo;
228
229   const TreeNode* bufferViewNode = buffer.GetChild( "bufferView" );
230   if( bufferViewNode )
231   {
232     ReadInt( bufferViewNode, accessorInfo.bufferView );
233   }
234
235   const TreeNode* byteOffsetNode = buffer.GetChild( "byteOffset" );
236   if( byteOffsetNode )
237   {
238     ReadInt( byteOffsetNode, accessorInfo.byteOffset );
239   }
240
241   const TreeNode* componentTypeNode = buffer.GetChild( "componentType" );
242   if( componentTypeNode )
243   {
244     ReadInt( componentTypeNode, accessorInfo.componentType );
245     if( accessorInfo.componentType < 0 )
246     {
247       return false;
248     }
249   }
250
251   const TreeNode* normalizedNode = buffer.GetChild( "normalized" );
252   if( normalizedNode )
253   {
254     ReadBool( normalizedNode, accessorInfo.normalized );
255   }
256
257   const TreeNode* countNode = buffer.GetChild( "count" );
258   if( countNode )
259   {
260     ReadInt( countNode, accessorInfo.count );
261     if( accessorInfo.count < 0 )
262     {
263       return false;
264     }
265   }
266
267   const TreeNode* typeNode = buffer.GetChild( "type" );
268   if( typeNode )
269   {
270     ReadString( typeNode, accessorInfo.type );
271     if( accessorInfo.type == "" )
272     {
273       return false;
274     }
275   }
276
277   const TreeNode* maxNode = buffer.GetChild( "max" );
278   if( maxNode )
279   {
280     ReadInt( maxNode, accessorInfo.max );
281   }
282
283   const TreeNode* minNode = buffer.GetChild( "min" );
284   if( minNode )
285   {
286     ReadInt( minNode, accessorInfo.min );
287   }
288
289   const TreeNode* nameNode = buffer.GetChild( "name" );
290   if( nameNode )
291   {
292     ReadString( nameNode, accessorInfo.name );
293   }
294
295   mAccessorArray.push_back( accessorInfo );
296
297   return true;
298 }
299
300 bool GltfLoader::LoadTextureArray( const TreeNode* root )
301 {
302   const TreeNode* imagesNode = root->GetChild( "images" );
303   if( imagesNode )
304   {
305     for( TreeNode::ConstIterator imageIter = imagesNode->CBegin(); imageIter != imagesNode->CEnd(); ++imageIter )
306     {
307       std::string imageUrl;
308       const TreeNode* uriNode = ( &( ( *imageIter ).second ) )->GetChild( "uri" );
309       if( uriNode )
310       {
311         std::string uri;
312         ReadString( uriNode, uri );
313         imageUrl = mPath + uri;
314       }
315
316       mSourceArray.push_back( LoadTexture( imageUrl.c_str(), true ) );
317     }
318   }
319
320   const TreeNode* samplersNode = root->GetChild( "samplers" );
321   if( samplersNode )
322   {
323     for( TreeNode::ConstIterator samplerIter = samplersNode->CBegin(); samplerIter != samplersNode->CEnd(); ++samplerIter )
324     {
325       mSamplerArray.push_back( LoadSampler( ( ( *samplerIter ).second ) ) );
326     }
327   }
328
329   const TreeNode* texturesNode = root->GetChild( "textures" );
330   if( texturesNode )
331   {
332     for( TreeNode::ConstIterator textureIter = texturesNode->CBegin(); textureIter != texturesNode->CEnd(); ++textureIter )
333     {
334       const TreeNode* TextureNode = &( ( *textureIter ).second );
335
336       TextureInfo texture;
337       const TreeNode* sourceNode = TextureNode->GetChild( "source" );
338       if( sourceNode )
339       {
340         ReadInt( sourceNode, texture.sourceIdx );
341       }
342
343       const TreeNode* samplerNode = TextureNode->GetChild( "sampler" );
344       if( samplerNode )
345       {
346         ReadInt( samplerNode, texture.samplerIdx );
347       }
348
349       mTextureArray.push_back( texture );
350     }
351   }
352   return true;
353 }
354
355 Texture GltfLoader::LoadTexture( const char* imageUrl, bool generateMipmaps )
356 {
357   Texture texture;
358   Devel::PixelBuffer pixelBuffer = LoadImageFromFile( imageUrl );
359   if( pixelBuffer )
360   {
361     texture = Texture::New( TextureType::TEXTURE_2D, pixelBuffer.GetPixelFormat(), pixelBuffer.GetWidth(), pixelBuffer.GetHeight() );
362     PixelData pixelData = Devel::PixelBuffer::Convert( pixelBuffer );
363     texture.Upload( pixelData );
364
365     if( generateMipmaps )
366     {
367       texture.GenerateMipmaps();
368     }
369   }
370
371   return texture;
372 }
373
374 Sampler GltfLoader::LoadSampler( const TreeNode& samplerNode )
375 {
376   Sampler sampler = Sampler::New();
377
378   FilterMode::Type minFilter = FilterMode::DEFAULT;
379   FilterMode::Type magFilter = FilterMode::DEFAULT;
380   const TreeNode* magFilterNode = samplerNode.GetChild( "magFilter" );
381   if( magFilterNode )
382   {
383     int magFilter_integer = 0;
384     ReadInt( magFilterNode, magFilter_integer );
385     magFilter = GetFilterMode( magFilter_integer );
386   }
387
388   const TreeNode* minFilterNode = samplerNode.GetChild( "minFilter" );
389   if( minFilterNode )
390   {
391     int minFilter_integer = 0;
392     ReadInt( minFilterNode, minFilter_integer );
393     minFilter = GetFilterMode( minFilter_integer );
394   }
395
396   WrapMode::Type wrapR = WrapMode::REPEAT;
397   WrapMode::Type wrapS = WrapMode::REPEAT;
398   WrapMode::Type wrapT = WrapMode::REPEAT;
399   const TreeNode* wrapNode = samplerNode.GetChild( "wrapS" );
400   if( wrapNode )
401   {
402     wrapS = GetWrapMode( wrapNode->GetInteger() );
403   }
404
405   wrapNode = samplerNode.GetChild( "wrapT" );
406   if( wrapNode )
407   {
408     wrapT = GetWrapMode( wrapNode->GetInteger() );
409   }
410
411   sampler.SetFilterMode( minFilter, magFilter );
412   sampler.SetWrapMode( wrapR, wrapS, wrapT );
413
414   return sampler;
415 }
416
417 FilterMode::Type GltfLoader::GetFilterMode( int mode )
418 {
419   FilterMode::Type retValue = FilterMode::DEFAULT;
420   /**
421    * glTF 2.0 Specification
422    * Filter Code
423    * 9728 : NEAREST
424    * 9729 : LINEAR
425    * 9984 : NEAREST_MIPMAP_NEAREST
426    * 9985 : LINEAR_MIPMAP_NEAREST
427    * 9986 : NEAREST_MIPMAP_LINEAR
428    * 9987 : LINEAR_MIPMAP_LINEAR
429    */
430   switch( mode )
431   {
432     case 9728:
433     {
434       retValue = FilterMode::NEAREST;
435       break;
436     }
437     case 9729:
438     {
439       retValue = FilterMode::LINEAR;
440       break;
441     }
442     case 9984:
443     {
444       retValue = FilterMode::NEAREST_MIPMAP_NEAREST;
445       break;
446     }
447     case 9985:
448     {
449       retValue = FilterMode::LINEAR_MIPMAP_NEAREST;
450       break;
451     }
452     case 9986:
453     {
454       retValue = FilterMode::NEAREST_MIPMAP_LINEAR;
455       break;
456     }
457     case 9987:
458     {
459       retValue = FilterMode::LINEAR_MIPMAP_LINEAR;
460       break;
461     }
462   }
463
464   return retValue;
465 }
466
467 WrapMode::Type GltfLoader::GetWrapMode( int mode )
468 {
469   WrapMode::Type retValue = WrapMode::REPEAT;
470   /**
471    * glTF 2.0 Specification
472    * Wrapping mode Code
473    * 33071 : CLAMP_TO_EDGE
474    * 33648 : MIRRORED_REPEAT
475    * 10497 : REPEAT
476    */
477   switch( mode )
478   {
479     case 33071:
480     {
481       retValue = WrapMode::CLAMP_TO_EDGE;
482       break;
483     }
484     case 33648:
485     {
486       retValue = WrapMode::MIRRORED_REPEAT;
487       break;
488     }
489     case 10497:
490     {
491       retValue = WrapMode::REPEAT;
492       break;
493     }
494   }
495
496   return retValue;
497 }
498
499 bool GltfLoader::LoadMaterialSetArray( const TreeNode* root )
500 {
501   const TreeNode* materialsNode = root->GetChild( "materials" );
502   if( !materialsNode )
503   {
504     return false;
505   }
506
507   for( TreeNode::ConstIterator materialIter = materialsNode->CBegin(); materialIter != materialsNode->CEnd(); ++materialIter )
508   {
509     GLTF::MaterialInfo materialInfo;
510     LoadPbrMetallicRoughness( ( ( *materialIter ).second ), materialInfo );
511
512     const TreeNode* materialNode = &( ( *materialIter ).second );
513     const TreeNode* tempNode = materialNode->GetChild( "name" );
514     if( tempNode )
515     {
516       ReadString( tempNode, materialInfo.name );
517     }
518
519     materialInfo.alphaMode = "OPAQUE";
520     tempNode = materialNode->GetChild( "alphaMode" );
521     if( tempNode )
522     {
523       ReadString( tempNode, materialInfo.alphaMode );
524     }
525
526     materialInfo.alphaCutoff = 1.0;
527     tempNode = materialNode->GetChild( "alphaCutoff" );
528     if( tempNode )
529     {
530       ReadFloat( tempNode, materialInfo.alphaCutoff );
531     }
532
533     materialInfo.doubleSided = false;
534     tempNode = materialNode->GetChild( "doubleSided" );
535     if( tempNode )
536     {
537       ReadBool( tempNode, materialInfo.doubleSided );
538     }
539
540     float floatVec[3];
541     tempNode = materialNode->GetChild( "emissiveFactor" );
542     if( tempNode && ReadVector( tempNode, floatVec, 3 ) )
543     {
544       materialInfo.emissiveFactor = Vector3( floatVec[0], floatVec[1], floatVec[2] );
545     }
546
547     const TreeNode* texture = materialNode->GetChild( "normalTexture" );
548     if( texture )
549     {
550       tempNode = texture->GetChild( "index" );
551       if( tempNode )
552       {
553         materialInfo.normalTexture.index = tempNode->GetInteger();
554       }
555
556       tempNode = texture->GetChild( "texCoord" );
557       if( tempNode )
558       {
559         materialInfo.normalTexture.texCoord = tempNode->GetInteger();
560       }
561
562       materialInfo.normalTexture.value = 1.0;
563       tempNode = texture->GetChild( "scale" );
564       if( tempNode )
565       {
566         ReadFloat( tempNode, materialInfo.normalTexture.value );
567       }
568     }
569
570     texture = materialNode->GetChild( "occlusionTexture" );
571     if( texture )
572     {
573       tempNode = texture->GetChild( "index" );
574       if( tempNode )
575       {
576         materialInfo.occlusionTexture.index = tempNode->GetInteger();
577       }
578
579       tempNode = texture->GetChild( "texCoord" );
580       if( tempNode )
581       {
582         materialInfo.occlusionTexture.texCoord = tempNode->GetInteger();
583       }
584
585
586       tempNode = texture->GetChild( "strength" );
587       if( tempNode )
588       {
589         ReadFloat( tempNode, materialInfo.occlusionTexture.value );
590       }
591     }
592
593     texture = materialNode->GetChild( "emissiveTexture" );
594     if( texture )
595     {
596       tempNode = texture->GetChild( "index" );
597       if( tempNode )
598       {
599         materialInfo.emissiveTexture.index = tempNode->GetInteger();
600       }
601
602       tempNode = texture->GetChild( "texCoord" );
603       if( tempNode )
604       {
605         materialInfo.emissiveTexture.texCoord = tempNode->GetInteger();
606       }
607     }
608     mMaterialArray.push_back( materialInfo );
609   }
610   return true;
611 }
612
613 bool GltfLoader::LoadPbrMetallicRoughness( const TreeNode& material, MaterialInfo& materialInfo )
614 {
615   float floatVec[4];
616   const TreeNode* pbrMetallicRoughnessNode = material.GetChild( "pbrMetallicRoughness" );
617   if( !pbrMetallicRoughnessNode )
618   {
619     return true;
620   }
621
622   const TreeNode* tempNode;
623   tempNode = pbrMetallicRoughnessNode->GetChild( "metallicFactor" );
624   if( tempNode )
625   {
626     ReadFloat( tempNode, materialInfo.metallicFactor );
627   }
628
629   tempNode = pbrMetallicRoughnessNode->GetChild( "roughnessFactor" );
630   if( tempNode )
631   {
632     ReadFloat( tempNode, materialInfo.roughnessFactor );
633   }
634
635   tempNode = pbrMetallicRoughnessNode->GetChild( "baseColorFactor" );
636   if( tempNode && ReadVector( tempNode, floatVec, 4 ) )
637   {
638     materialInfo.baseColorFactor = Vector4( floatVec[0], floatVec[1], floatVec[2], floatVec[3] );
639   }
640
641   const TreeNode* baseColorTextureNode = pbrMetallicRoughnessNode->GetChild( "baseColorTexture" );
642   if( baseColorTextureNode )
643   {
644     tempNode = baseColorTextureNode->GetChild( "index" );
645     if( tempNode )
646     {
647       materialInfo.baseColorTexture.index = tempNode->GetInteger();
648     }
649
650     tempNode = baseColorTextureNode->GetChild( "texCoord" );
651     if( tempNode )
652     {
653       materialInfo.baseColorTexture.texCoord = tempNode->GetInteger();
654     }
655   }
656
657   const TreeNode* metallicRoughnessTextureNode = pbrMetallicRoughnessNode->GetChild( "metallicRoughnessTexture" );
658   if( metallicRoughnessTextureNode )
659   {
660     tempNode = metallicRoughnessTextureNode->GetChild( "index" );
661     if( tempNode )
662     {
663       materialInfo.metallicRoughnessTexture.index = tempNode->GetInteger();
664     }
665
666     tempNode = metallicRoughnessTextureNode->GetChild( "texCoord" );
667     if( tempNode )
668     {
669       materialInfo.metallicRoughnessTexture.texCoord = tempNode->GetInteger();
670     }
671   }
672
673   return true;
674 }
675
676 bool GltfLoader::LoadMeshArray( const TreeNode* root )
677 {
678   const TreeNode* meshesNode = root->GetChild( "meshes" );
679   if( !meshesNode )
680   {
681     return false;
682   }
683
684   for( TreeNode::ConstIterator meshIter = ( *meshesNode ).CBegin(); meshIter != ( *meshesNode ).CEnd(); ++meshIter )
685   {
686     MeshInfo meshInfo;
687     const TreeNode* nameNode = ( &( *meshIter ).second )->GetChild( "name" );
688     if( nameNode )
689     {
690       ReadString( nameNode, meshInfo.name );
691     }
692     meshInfo.geometry = Geometry::New();
693
694     //Need to add weights for Morph targets.
695     LoadPrimitive( ( *meshIter ).second, meshInfo );
696     SetGeometry( meshInfo );
697     mMeshArray.push_back( meshInfo );
698   }
699
700   return true;
701 }
702
703 bool GltfLoader::LoadPrimitive( const TreeNode& mesh, MeshInfo& meshInfo )
704 {
705   const TreeNode* primitivesNode = mesh.GetChild( "primitives" );
706   if( !primitivesNode )
707   {
708     return false;
709   }
710
711   for( TreeNode::ConstIterator primitiveIter = ( *primitivesNode ).CBegin(); primitiveIter != ( *primitivesNode ).CEnd(); ++primitiveIter )
712   {
713     const TreeNode* primitiveNode = ( &( *primitiveIter ).second );
714     const TreeNode* tempNode;
715
716     tempNode = primitiveNode->GetChild( "indices" );
717     if( tempNode )
718     {
719       meshInfo.indicesIdx = tempNode->GetInteger();
720     }
721
722     tempNode = primitiveNode->GetChild( "material" );
723     if( tempNode )
724     {
725       meshInfo.materialsIdx = tempNode->GetInteger();
726     }
727
728     tempNode = primitiveNode->GetChild( "mode" );
729     if( tempNode )
730     {
731       meshInfo.mode = tempNode->GetInteger();
732     }
733
734     LoadAttribute( primitiveNode, meshInfo );
735   }
736
737   return true;
738 }
739
740 bool GltfLoader::LoadAttribute( const TreeNode* primitive, MeshInfo& meshInfo )
741 {
742   const TreeNode* attrbuteNode = primitive->GetChild( "attributes" );
743   if( !attrbuteNode )
744   {
745     return false;
746   }
747
748   const TreeNode* tempNode;
749   tempNode = attrbuteNode->GetChild( "POSITION" );
750   if( tempNode )
751   {
752     meshInfo.attribute.POSITION = tempNode->GetInteger();
753   }
754
755   tempNode = attrbuteNode->GetChild( "NORMAL" );
756   if( tempNode )
757   {
758     meshInfo.attribute.NORMAL = tempNode->GetInteger();
759   }
760
761   tempNode = attrbuteNode->GetChild( "TANGENT" );
762   if( tempNode )
763   {
764     meshInfo.attribute.TANGENT = tempNode->GetInteger();
765   }
766
767   int index = 0;
768   meshInfo.attribute.TEXCOORD.clear();
769   tempNode = attrbuteNode->GetChild( "TEXCOORD_" + std::to_string( index ) );
770   while( tempNode )
771   {
772     int value = tempNode->GetInteger();
773     meshInfo.attribute.TEXCOORD.push_back( value );
774     tempNode = attrbuteNode->GetChild( "TEXCOORD_" + std::to_string( ++index ) );
775   }
776
777   index = 0;
778   meshInfo.attribute.COLOR.clear();
779   tempNode = attrbuteNode->GetChild( "COLOR_" + std::to_string( index ) );
780   while( tempNode )
781   {
782     int value = tempNode->GetInteger();
783     meshInfo.attribute.COLOR.push_back( value );
784     tempNode = attrbuteNode->GetChild( "COLOR" + std::to_string( ++index ) );
785   }
786
787   return true;
788 }
789
790 bool GltfLoader::SetGeometry( MeshInfo& meshInfo )
791 {
792   int indicesIdx = meshInfo.indicesIdx;
793
794   if( meshInfo.mode != 0 )
795   {
796     meshInfo.geometry.SetType( ( Dali::Geometry::Type )meshInfo.mode );
797   }
798
799   if( indicesIdx >= 0 )
800   {
801     SetIndexBuffersData( meshInfo, indicesIdx );
802   }
803
804   SetVertexBufferData( meshInfo, meshInfo.attribute.POSITION, "aPosition", Property::VECTOR3 );
805   SetAttributeBufferData<Vector3>( meshInfo, meshInfo.attribute.NORMAL, "aNormal", Property::VECTOR3 );
806   SetAttributeBufferData<Vector4>( meshInfo, meshInfo.attribute.TANGENT, "aTangent", Property::VECTOR4 );
807
808   for( unsigned int i = 0; i < meshInfo.attribute.TEXCOORD.size(); ++i )
809   {
810     int accessorIdx = meshInfo.attribute.TEXCOORD[i];
811     std::ostringstream texCoordString;
812     texCoordString << "aTexCoord" << i;
813     SetAttributeBufferData<Vector2>( meshInfo, accessorIdx, texCoordString.str(), Property::VECTOR2 );
814   }
815
816   for( unsigned int i = 0; i < meshInfo.attribute.COLOR.size(); ++i )
817   {
818     int accessorIdx = meshInfo.attribute.COLOR[i];
819     if( accessorIdx < 0 )
820     {
821       break;
822     }
823
824     if( mAccessorArray[accessorIdx].type == "VEC3" )
825     {
826       Dali::Vector<Vector3> inputBufferData;
827       LoadDataFromAccessor( accessorIdx, inputBufferData );
828
829       Dali::Vector<Vector4> bufferData;
830       bufferData.Resize( inputBufferData.Size() );
831       for( unsigned int i = 0; i<inputBufferData.Size(); ++i )
832       {
833         bufferData[i].x = inputBufferData[i].x;
834         bufferData[i].y = inputBufferData[i].y;
835         bufferData[i].z = inputBufferData[i].z;
836         bufferData[i].w = 1.0;
837       }
838       PropertyBuffer propertyBuffer = CreatePropertyBuffer<Vector4>( bufferData, "aVertexColor", Property::VECTOR4 );
839       meshInfo.geometry.AddVertexBuffer( propertyBuffer );
840     }
841     else if( mAccessorArray[accessorIdx].type == "VEC4" )
842     {
843       SetAttributeBufferData<Vector4>( meshInfo, accessorIdx, "aVertexColor", Property::VECTOR4 );
844     }
845   }
846   return true;
847 }
848
849 void GltfLoader::SetMeshInfoAndCanonize( MeshInfo& meshInfo, Dali::Vector<Dali::Vector3> &vertexBufferData )
850 {
851   Vector3 pointMin( std::numeric_limits<float>::max(), std::numeric_limits<float>::max(), std::numeric_limits<float>::max() );
852   Vector3 pointMax( std::numeric_limits<float>::min(), std::numeric_limits<float>::min(), std::numeric_limits<float>::min() );
853   unsigned int vertexSize = vertexBufferData.Size();
854   for( unsigned int i = 0; i<vertexSize; ++i )
855   {
856     pointMin.x = std::min( vertexBufferData[i].x, pointMin.x );
857     pointMin.y = std::min( vertexBufferData[i].y, pointMin.y );
858     pointMin.z = std::min( vertexBufferData[i].z, pointMin.z );
859
860     pointMax.x = std::max( vertexBufferData[i].x, pointMax.x );
861     pointMax.y = std::max( vertexBufferData[i].y, pointMax.y );
862     pointMax.z = std::max( vertexBufferData[i].z, pointMax.z );
863   }
864   meshInfo.size = pointMax - pointMin;
865   meshInfo.pivot.x = ( -pointMin.x ) / ( pointMax.x - pointMin.x );
866   meshInfo.pivot.y = ( -pointMin.y ) / ( pointMax.y - pointMin.y );
867   meshInfo.pivot.z = ( -pointMin.z ) / ( pointMax.z - pointMin.z );
868
869   Vector3 center = meshInfo.size * 0.5 + pointMin;
870   for( unsigned int i = 0; i < vertexSize; ++i )
871   {
872     vertexBufferData[i] = vertexBufferData[i] - center;
873     vertexBufferData[i].x = vertexBufferData[i].x / meshInfo.size.x;
874     vertexBufferData[i].y = vertexBufferData[i].y / meshInfo.size.y;
875     vertexBufferData[i].z = vertexBufferData[i].z / meshInfo.size.z;
876   }
877 }
878
879 bool GltfLoader::CreateScene( Internal::Scene& scene )
880 {
881   scene.SetDefaultCamera( Dali::Camera::LOOK_AT_TARGET, 0.01, Vector3::ZERO );
882   LoadCamera( scene );
883
884   if( !LoadSceneNodes( scene ) )
885   {
886     return false;
887   }
888
889   if( !LoadAnimation( scene ) )
890   {
891     return false;
892   }
893
894   return true;
895 }
896
897 void GltfLoader::LoadCamera( Scene& scene )
898 {
899   const TreeNode* camerasNode = mRoot->GetChild( "cameras" );
900   if( !camerasNode )
901   {
902     return;
903   }
904
905   for( TreeNode::ConstIterator cameraIter = ( *camerasNode ).CBegin(); cameraIter != ( *camerasNode ).CEnd(); ++cameraIter )
906   {
907     const TreeNode* tempNode = ( &( *cameraIter ).second )->GetChild( "name" );
908     CameraInfo cameraInfo;
909     if( tempNode )
910     {
911       ReadString( tempNode, cameraInfo.name );
912     }
913
914     tempNode = ( &( *cameraIter ).second )->GetChild( "type" );
915     if( tempNode )
916     {
917       ReadString( tempNode, cameraInfo.type );
918     }
919
920     CameraActor cameraActor = CameraActor::New();
921     cameraActor.SetParentOrigin( ParentOrigin::CENTER );
922     cameraActor.SetAnchorPoint( AnchorPoint::CENTER );
923
924     if( cameraInfo.type == "orthographic" )
925     {
926       LoadOrthoGraphic( ( *cameraIter ).second, cameraInfo );
927       float xMag_2 = cameraInfo.orthographic.xmag / 2.0;
928       float yMag_2 = cameraInfo.orthographic.ymag / 2.0;
929       cameraActor.SetOrthographicProjection( -xMag_2, xMag_2, yMag_2, -yMag_2,
930                                              cameraInfo.orthographic.znear, cameraInfo.orthographic.zfar );
931     }
932     else if( cameraInfo.type == "perspective" )
933     {
934       if( !LoadPerspective( ( *cameraIter ).second, cameraInfo ) )
935       {
936         return;
937       }
938       cameraActor.SetProjectionMode( Dali::Camera::PERSPECTIVE_PROJECTION );
939       cameraActor.SetFieldOfView( cameraInfo.perspective.yfov );
940       cameraActor.SetNearClippingPlane( cameraInfo.perspective.znear );
941
942       if( cameraInfo.perspective.zfar > 0.0 )
943       {
944         cameraActor.SetFarClippingPlane( cameraInfo.perspective.zfar );
945       }
946       if( cameraInfo.perspective.aspectRatio > 0.0 )
947       {
948         cameraActor.SetAspectRatio( cameraInfo.perspective.aspectRatio );
949       }
950     }
951
952     scene.AddCamera( cameraActor );
953   }
954 }
955
956 bool GltfLoader::LoadOrthoGraphic( const TreeNode& camera, CameraInfo& cameraInfo )
957 {
958   const TreeNode* orthographicNode = camera.GetChild( "orthographic" );
959   if( !orthographicNode )
960   {
961     return false;
962   }
963
964   const TreeNode* tempNode;
965   tempNode = orthographicNode->GetChild( "xmag" );
966   if( tempNode )
967   {
968     ReadFloat( tempNode, cameraInfo.orthographic.xmag );
969   }
970
971   tempNode = orthographicNode->GetChild( "ymag" );
972   if( tempNode )
973   {
974     ReadFloat( tempNode, cameraInfo.orthographic.ymag );
975   }
976
977   tempNode = orthographicNode->GetChild( "zfar" );
978   if( tempNode )
979   {
980     ReadFloat( tempNode, cameraInfo.orthographic.zfar );
981   }
982
983   tempNode = orthographicNode->GetChild( "znear" );
984   if( tempNode )
985   {
986     ReadFloat( tempNode, cameraInfo.orthographic.znear );
987   }
988
989   return true;
990 }
991
992 bool GltfLoader::LoadPerspective( const TreeNode& camera, CameraInfo& cameraInfo )
993 {
994   const TreeNode* perspectiveNode = camera.GetChild( "perspective" );
995   if( !perspectiveNode )
996   {
997     return false;
998   }
999
1000   const TreeNode* tempNode;
1001   tempNode = perspectiveNode->GetChild( "aspectRatio" );
1002   if( tempNode )
1003   {
1004     ReadFloat( tempNode, cameraInfo.perspective.aspectRatio );
1005   }
1006
1007   tempNode = perspectiveNode->GetChild( "yfov" );
1008   if( tempNode )
1009   {
1010     ReadFloat( tempNode, cameraInfo.perspective.yfov );
1011   }
1012
1013   tempNode = perspectiveNode->GetChild( "zfar" );
1014   if( tempNode )
1015   {
1016     ReadFloat( tempNode, cameraInfo.perspective.zfar );
1017   }
1018
1019   tempNode = perspectiveNode->GetChild( "znear" );
1020   if( tempNode )
1021   {
1022     ReadFloat( tempNode, cameraInfo.perspective.znear );
1023   }
1024
1025   return true;
1026 }
1027
1028 bool GltfLoader::LoadSceneNodes( Scene& scene )
1029 {
1030   const TreeNode* sceneNode = mRoot->GetChild( "scene" );
1031   int sceneNum = 0;
1032   if( sceneNode )
1033   {
1034     sceneNum = sceneNode->GetInteger();
1035   }
1036
1037   const TreeNode* scenesNode = mRoot->GetChild( "scenes" );
1038   if( !( scenesNode && ( mNodes = mRoot->GetChild( "nodes" ) ) ) )
1039   {
1040     return false;
1041   }
1042
1043   const TreeNode* tempNode = Tidx( scenesNode, sceneNum );
1044   if( !tempNode )
1045   {
1046     return false;
1047   }
1048
1049   tempNode = tempNode->GetChild( "nodes" );
1050   if( !tempNode )
1051   {
1052     return false;
1053   }
1054
1055   for( TreeNode::ConstIterator nodeIter = ( *tempNode ).CBegin(); nodeIter != ( *tempNode ).CEnd(); ++nodeIter )
1056   {
1057     Actor actor = AddNode( scene, ( ( *nodeIter ).second ).GetInteger() );
1058     actor.SetParentOrigin( ParentOrigin::CENTER );
1059     scene.GetRoot().Add( actor );
1060   }
1061
1062   return true;
1063 }
1064
1065 Actor GltfLoader::AddNode( Scene& scene, int index )
1066 {
1067   const TreeNode* node = Tidx( mNodes, index );
1068   Actor actor = Actor::New();
1069   Vector3 actorSize( Vector3::ONE );
1070
1071   Vector3 translation = Vector3( 0.0, 0.0, 0.0 );
1072   Vector3 scale = Vector3( 1.0, 1.0, 1.0 );
1073   Quaternion orientation( Vector4( 0.0, 0.0, 0.0, 1.0 ) );
1074
1075   Vector3 anchorPoint = AnchorPoint::CENTER;
1076
1077   const TreeNode* tempNode = NULL;
1078   if( ( tempNode = node->GetChild( "translation" ) ) )
1079   {
1080     float floatVec[3] = { 0.0, 0.0, 0.0 };
1081     if( tempNode && ReadVector( tempNode, floatVec, 3 ) )
1082     {
1083       translation = Vector3( floatVec[0], floatVec[1], floatVec[2] );
1084     }
1085   }
1086
1087   if( ( tempNode = node->GetChild( "scale" ) ) )
1088   {
1089     float floatVec[3] = { 1.0, 1.0, 1.0 };
1090     if( tempNode && ReadVector( tempNode, floatVec, 3 ) )
1091     {
1092       scale = Vector3( floatVec[0], floatVec[1], floatVec[2] );
1093     }
1094   }
1095
1096   if( ( tempNode = node->GetChild( "rotation" ) ) )
1097   {
1098     float floatVec[4] = { 0.0, 0.0, 0.0, 1.0 };
1099     if( tempNode && ReadVector( tempNode, floatVec, 4 ) )
1100     {
1101       orientation = Quaternion( Vector4( floatVec[0], floatVec[1], floatVec[2], floatVec[3] ) );
1102     }
1103   }
1104
1105   if( ( tempNode = node->GetChild( "matrix" ) ) )
1106   {
1107     float floatVec[16] = { 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 };
1108     if( tempNode && ReadVector( tempNode, floatVec, 16 ) )
1109     {
1110       Matrix nodeMatrix = Matrix( floatVec );
1111       nodeMatrix.GetTransformComponents( translation, orientation, scale );
1112     }
1113   }
1114
1115   if( ( tempNode = node->GetChild( "mesh" ) ) )
1116   {
1117     MeshInfo meshInfo = mMeshArray[tempNode->GetInteger()];
1118     GLTF::MaterialInfo materialInfo = mMaterialArray[meshInfo.materialsIdx];
1119     bool isMaterial = ( meshInfo.materialsIdx >= 0 );
1120
1121     TextureSet textureSet;
1122     textureSet = TextureSet::New();
1123
1124     int addIdx = 0;
1125     int shaderTypeIndex = 0;
1126     int maxMipmapLevel = 0;
1127     bool isBaseColorTexture = false;
1128     bool isMetallicRoughnessTexture = false;
1129     bool isNormalTexture = false;
1130     bool isOcclusionTexture = false;
1131     bool isEmissiveTexture = false;
1132
1133     std::string VERTEX_SHADER, FRAGMENT_SHADER;
1134     VERTEX_SHADER = GLES_VERSION_300;
1135     VERTEX_SHADER += PHYSICALLY_BASED_VERTEX_SHADER;
1136     FRAGMENT_SHADER = GLES_VERSION_300;
1137
1138     bool useIBL = ( scene.GetLightType() >= Toolkit::Scene::LightType::IMAGE_BASED_LIGHT );
1139     if( isMaterial )
1140     {
1141       if( SetTextureAndSampler( textureSet, materialInfo.baseColorTexture.index, FRAGMENT_SHADER, DEFINE_BASECOLOR_TEXTURE, addIdx ) )
1142       {
1143         shaderTypeIndex += static_cast<int>( ShaderType::BASECOLOR_SHADER );
1144         isBaseColorTexture = true;
1145       }
1146       if( SetTextureAndSampler( textureSet, materialInfo.metallicRoughnessTexture.index, FRAGMENT_SHADER, DEFINE_METALLICROUGHNESS_TEXTURE, addIdx ) )
1147       {
1148         shaderTypeIndex += static_cast<int>( ShaderType::METALLICROUGHNESS_SHADER );
1149         isMetallicRoughnessTexture = true;
1150       }
1151       if( SetTextureAndSampler( textureSet, materialInfo.normalTexture.index, FRAGMENT_SHADER, DEFINE_NORMAL_TEXTURE, addIdx ) )
1152       {
1153         shaderTypeIndex += static_cast<int>( ShaderType::NORMAL_SHADER );
1154         isNormalTexture = true;
1155       }
1156       if( SetTextureAndSampler( textureSet, materialInfo.occlusionTexture.index, FRAGMENT_SHADER, DEFINE_OCCLUSION_TEXTURE, addIdx ) )
1157       {
1158         shaderTypeIndex += static_cast<int>( ShaderType::OCCLUSION_SHADER );
1159         isOcclusionTexture = true;
1160       }
1161       if( SetTextureAndSampler( textureSet, materialInfo.emissiveTexture.index, FRAGMENT_SHADER, DEFINE_EMIT_TEXTURE, addIdx ) )
1162       {
1163         shaderTypeIndex += static_cast<int>( ShaderType::EMIT_SHADER );
1164         isEmissiveTexture = true;
1165       }
1166
1167       if( useIBL )
1168       {
1169         shaderTypeIndex += static_cast<int>( ShaderType::IBL_SHADER );
1170         FRAGMENT_SHADER += DEFINE_IBL_TEXTURE;
1171
1172         Sampler sampler = Sampler::New();
1173         sampler.SetFilterMode( FilterMode::DEFAULT, FilterMode::DEFAULT );
1174         sampler.SetWrapMode( WrapMode::REPEAT, WrapMode::REPEAT, WrapMode::REPEAT );
1175
1176         textureSet.SetTexture( addIdx, scene.GetBRDFTexture() );
1177         textureSet.SetSampler( addIdx++, sampler );
1178         Sampler samplerIBL = Sampler::New();
1179         samplerIBL.SetFilterMode( FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR );
1180         samplerIBL.SetWrapMode( WrapMode::CLAMP_TO_EDGE, WrapMode::CLAMP_TO_EDGE, WrapMode::CLAMP_TO_EDGE );
1181         textureSet.SetTexture( addIdx, scene.GetDiffuseTexture() );
1182         textureSet.SetSampler( addIdx++, samplerIBL );
1183         Texture specularTexture = scene.GetSpecularTexture();
1184         textureSet.SetTexture( addIdx, specularTexture );
1185         textureSet.SetSampler( addIdx++, samplerIBL );
1186
1187         int textureSize = std::min( specularTexture.GetWidth(), specularTexture.GetHeight() );
1188         maxMipmapLevel = 0;
1189         while( textureSize >= 1 )
1190         {
1191           maxMipmapLevel++;
1192           textureSize /= 2;
1193         }
1194       }
1195     }
1196
1197     FRAGMENT_SHADER += PHYSICALLY_BASED_FRAGMENT_SHADER;
1198     if( !mShaderCache[shaderTypeIndex] )
1199     {
1200       mShaderCache[shaderTypeIndex] = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
1201       scene.AddShader( mShaderCache[shaderTypeIndex] );
1202     }
1203     Shader shader = mShaderCache[shaderTypeIndex];
1204
1205     Renderer renderer = Renderer::New( meshInfo.geometry, shader );
1206     renderer.SetProperty( Renderer::Property::DEPTH_WRITE_MODE, DepthWriteMode::ON );
1207     renderer.SetProperty( Renderer::Property::DEPTH_TEST_MODE, DepthTestMode::ON );
1208     renderer.SetTextures( textureSet );
1209
1210     anchorPoint = meshInfo.pivot;
1211     actor.SetAnchorPoint( anchorPoint );
1212
1213     actor.SetSize( Vector3( meshInfo.size.x, meshInfo.size.y, meshInfo.size.z ) );
1214     actor.AddRenderer( renderer );
1215
1216     actor.SetScale( scale );
1217     actor.RotateBy( orientation );
1218     actor.SetPosition( translation );
1219
1220     shader.RegisterProperty( "uLightType", ( scene.GetLightType() & ~Toolkit::Scene::LightType::IMAGE_BASED_LIGHT ) );
1221     shader.RegisterProperty( "uLightVector", scene.GetLightVector() );
1222     shader.RegisterProperty( "uLightColor", scene.GetLightColor() );
1223
1224     actor.RegisterProperty( "uIsColor", meshInfo.attribute.COLOR.size() > 0 );
1225     if( isMaterial )
1226     {
1227       actor.RegisterProperty( "uBaseColorFactor", materialInfo.baseColorFactor );
1228       actor.RegisterProperty( "uMetallicRoughnessFactors", Vector2( materialInfo.metallicFactor, materialInfo.roughnessFactor ) );
1229
1230       if( materialInfo.alphaMode == "OPAQUE" )
1231       {
1232         actor.RegisterProperty( "alphaMode", 0 );
1233       }
1234       else if( materialInfo.alphaMode == "MASK" )
1235       {
1236         actor.RegisterProperty( "alphaMode", 1 );
1237       }
1238       else
1239       {
1240         actor.RegisterProperty( "alphaMode", 2 );
1241       }
1242       actor.RegisterProperty( "alphaCutoff", materialInfo.alphaCutoff );
1243
1244       if( isBaseColorTexture )
1245       {
1246         actor.RegisterProperty( "uBaseColorTexCoordIndex", materialInfo.baseColorTexture.texCoord );
1247       }
1248       if( isMetallicRoughnessTexture )
1249       {
1250         actor.RegisterProperty( "uMetallicRoughnessTexCoordIndex", materialInfo.metallicRoughnessTexture.texCoord );
1251       }
1252       if( isNormalTexture )
1253       {
1254         actor.RegisterProperty( "uNormalScale", materialInfo.normalTexture.value );
1255         actor.RegisterProperty( "uNormalTexCoordIndex", materialInfo.normalTexture.texCoord );
1256       }
1257       if( isOcclusionTexture )
1258       {
1259         actor.RegisterProperty( "uOcclusionTexCoordIndex", materialInfo.occlusionTexture.texCoord );
1260         actor.RegisterProperty( "uOcclusionStrength", materialInfo.occlusionTexture.value );
1261       }
1262       if( isEmissiveTexture )
1263       {
1264         actor.RegisterProperty( "uEmissiveTexCoordIndex", materialInfo.emissiveTexture.texCoord );
1265         actor.RegisterProperty( "uEmissiveFactor", materialInfo.emissiveFactor );
1266       }
1267     }
1268
1269     if( isMaterial && useIBL )
1270     {
1271       actor.RegisterProperty( "uScaleIBLAmbient", scene.GetIBLScaleFactor() );
1272       actor.RegisterProperty( "uMipmapLevel", static_cast<float>( maxMipmapLevel ) );
1273     }
1274   }
1275   else
1276   {
1277     actor.SetAnchorPoint( AnchorPoint::CENTER );
1278     actor.SetPosition( translation );
1279     actor.RotateBy( orientation );
1280     actor.SetSize( actorSize );
1281   }
1282
1283   tempNode = node->GetChild( "camera" );
1284   if( tempNode )
1285   {
1286     int cameraNum = tempNode->GetInteger();
1287     actor.Add( scene.GetCamera( cameraNum ) );
1288   }
1289
1290   tempNode = node->GetChild( "name" );
1291   if( tempNode )
1292   {
1293     std::string nameString;
1294     ReadString( tempNode, nameString );
1295     actor.SetName( nameString );
1296   }
1297
1298   SetActorCache( actor, index );
1299   if( ( tempNode = node->GetChild( "children" ) ) )
1300   {
1301     for( TreeNode::ConstIterator childIter = ( *tempNode ).CBegin(); childIter != ( *tempNode ).CEnd(); ++childIter )
1302     {
1303       Actor childActor = AddNode( scene, ( ( *childIter ).second ).GetInteger() );
1304       childActor.SetParentOrigin( anchorPoint );
1305       actor.Add( childActor );
1306     }
1307   }
1308
1309   return actor;
1310 }
1311
1312 void GltfLoader::SetActorCache( Actor& actor, const int index )
1313 {
1314   if( mActorCache.size() < static_cast<unsigned int>( index + 1 ) )
1315   {
1316     mActorCache.resize( index + 1 );
1317   }
1318   mActorCache[index] = actor;
1319 }
1320
1321 bool GltfLoader::SetTextureAndSampler( TextureSet& textureSet, int textureIdx, std::string& toShader, std::string shader, int& addIdx )
1322 {
1323   if( textureIdx >= 0 )
1324   {
1325     toShader += shader;
1326     TextureInfo textureInfo = mTextureArray[textureIdx];
1327     if( textureInfo.sourceIdx >= 0 )
1328     {
1329       textureSet.SetTexture( addIdx, mSourceArray[textureInfo.sourceIdx] );
1330     }
1331     if( textureInfo.samplerIdx >= 0 )
1332     {
1333       textureSet.SetSampler( addIdx, mSamplerArray[textureInfo.samplerIdx] );
1334     }
1335     else
1336     {
1337       Sampler sampler = Sampler::New();
1338       sampler.SetFilterMode( FilterMode::DEFAULT, FilterMode::DEFAULT );
1339       sampler.SetWrapMode( WrapMode::REPEAT, WrapMode::REPEAT, WrapMode::REPEAT );
1340       textureSet.SetSampler( addIdx, sampler );
1341     }
1342     addIdx++;
1343     return true;
1344   }
1345   return false;
1346 }
1347
1348 bool GltfLoader::LoadAnimation( Scene& scene )
1349 {
1350   const TreeNode* animationsNode = mRoot->GetChild( "animations" );
1351   if( !animationsNode )
1352   {
1353     return true;
1354   }
1355
1356   for( TreeNode::ConstIterator animationIter = ( *animationsNode ).CBegin(); animationIter != ( *animationsNode ).CEnd(); ++animationIter )
1357   {
1358     const TreeNode* nameNode = ( &( *animationIter ).second )->GetChild( "name" );
1359     AnimationInfo animationInfo;
1360     if( nameNode )
1361     {
1362       ReadString( nameNode, animationInfo.name );
1363     }
1364
1365     Property::Index propIndex = Property::INVALID_INDEX;
1366     LoadAnimationChannels( ( *animationIter ).second, animationInfo );
1367     if( animationInfo.channelArray.size() == 0 )
1368     {
1369       continue;
1370     }
1371
1372     LoadAnimationSamplers( ( *animationIter ).second, animationInfo );
1373
1374     int channelNum = animationInfo.channelArray.size();
1375     for( int i = 0; i < channelNum; i++ )
1376     {
1377       AnimationChannelInfo currentChannel = animationInfo.channelArray[i];
1378
1379       if( currentChannel.path == "rotation" )
1380       {
1381         propIndex = Dali::Actor::Property::ORIENTATION;
1382       }
1383       else if( currentChannel.path == "translation" )
1384       {
1385         propIndex = Dali::Actor::Property::POSITION;
1386       }
1387       else if( currentChannel.path == "scale" )
1388       {
1389         propIndex = Dali::Actor::Property::SCALE;
1390       }
1391
1392       float duration = 0.0f;
1393       KeyFrames keyframes = KeyFrames::New();
1394       if( propIndex == Dali::Actor::Property::ORIENTATION )
1395       {
1396         duration = LoadKeyFrames<Vector4>( animationInfo.samplerArray[currentChannel.sampler], propIndex, keyframes );
1397       }
1398       else
1399       {
1400         duration = LoadKeyFrames<Vector3>( animationInfo.samplerArray[currentChannel.sampler], propIndex, keyframes );
1401       }
1402
1403       Animation animation = Animation::New( duration );
1404       Animation::Interpolation interpolation = Animation::Interpolation::Linear;
1405       if( animationInfo.samplerArray[currentChannel.sampler].interpolation == "CUBICSPLINE" )
1406       {
1407         interpolation = Animation::Interpolation::Cubic;
1408       }
1409       if( animationInfo.samplerArray[currentChannel.sampler].interpolation == "STEP" )
1410       {
1411       }
1412
1413       animation.AnimateBetween( Property( mActorCache[currentChannel.targetNode], propIndex ), keyframes, interpolation );
1414
1415       animation.SetLooping( false );
1416       scene.AddAnimation( animation );
1417     }
1418   }
1419
1420   return true;
1421 }
1422
1423 bool GltfLoader::LoadAnimationChannels( const TreeNode& animation, AnimationInfo& animationInfo )
1424 {
1425   const TreeNode* channelsNode = animation.GetChild( "channels" );
1426   if( !channelsNode )
1427   {
1428     return false;
1429   }
1430
1431   for( TreeNode::ConstIterator channelIter = ( *channelsNode ).CBegin(); channelIter != ( *channelsNode ).CEnd(); ++channelIter )
1432   {
1433     AnimationChannelInfo animationChannelInfo;
1434     const TreeNode* channelNode = ( &( *channelIter ).second );
1435     const TreeNode* samplerNode = channelNode->GetChild( "sampler" );
1436     if( samplerNode )
1437     {
1438       animationChannelInfo.sampler = samplerNode->GetInteger();
1439     }
1440
1441     const TreeNode* targetNode = channelNode->GetChild( "target" );
1442     if( targetNode )
1443     {
1444       const TreeNode* tempNode = targetNode->GetChild( "node" );
1445       if( tempNode )
1446       {
1447         animationChannelInfo.targetNode = tempNode->GetInteger();
1448       }
1449       else
1450       {
1451         continue;
1452       }
1453
1454       tempNode = targetNode->GetChild( "path" );
1455       if( tempNode )
1456       {
1457         ReadString( tempNode, animationChannelInfo.path );
1458       }
1459     }
1460
1461     animationInfo.channelArray.push_back( animationChannelInfo );
1462   }
1463   return true;
1464 }
1465
1466 bool GltfLoader::LoadAnimationSamplers( const TreeNode& animation, AnimationInfo& animationInfo )
1467 {
1468   const TreeNode* samplersNode = animation.GetChild( "samplers" );
1469   if( !samplersNode )
1470   {
1471     return false;
1472   }
1473
1474   for( TreeNode::ConstIterator sampler = ( *samplersNode ).CBegin(); sampler != ( *samplersNode ).CEnd(); ++sampler )
1475   {
1476     AnimationSamplerInfo animationSamplerInfo;
1477     const TreeNode* samplerNode = ( &( *sampler ).second );
1478     const TreeNode* tempNode = samplerNode->GetChild( "input" );
1479     if( tempNode )
1480     {
1481       animationSamplerInfo.input = tempNode->GetInteger();
1482     }
1483
1484     tempNode = samplerNode->GetChild( "output" );
1485     if( tempNode )
1486     {
1487       animationSamplerInfo.output = tempNode->GetInteger();
1488     }
1489
1490     tempNode = samplerNode->GetChild( "interpolation" );
1491     if( tempNode )
1492     {
1493       ReadString( tempNode, animationSamplerInfo.interpolation );
1494     }
1495
1496     animationInfo.samplerArray.push_back( animationSamplerInfo );
1497   }
1498
1499   return true;
1500 }
1501
1502 // Template functions
1503 template <typename T>
1504 bool GltfLoader::ReadBinFile( Vector<T> &dataBuffer, std::string url, int offset, int count )
1505 {
1506   dataBuffer.Resize( count );
1507   FILE* fp = fopen( url.c_str(), "rb" );
1508   if( NULL == fp )
1509   {
1510     return false;
1511   }
1512   fseek( fp, offset, SEEK_SET );
1513   ssize_t result = fread( &dataBuffer[0], sizeof( T ), count, fp );
1514   fclose( fp );
1515
1516   return ( result >= 0 );
1517 }
1518
1519 template <typename T>
1520 float GltfLoader::IntToFloat( T element, bool normalize )
1521 {
1522   if( !normalize )
1523   {
1524     return static_cast<float>( element );
1525   }
1526
1527   if( std::is_same<T, char>::value )
1528   {
1529     return std::max( static_cast<float>( element ) / 127.0, -1.0 );
1530   }
1531   if( std::is_same<T, unsigned char>::value )
1532   {
1533     return static_cast<float>( element ) / 255.0;
1534   }
1535   if( std::is_same<T, short>::value )
1536   {
1537     return std::max( static_cast<float>( element ) / 32767.0, -1.0 );
1538   }
1539   if( std::is_same<T, unsigned short>::value )
1540   {
1541     return static_cast<float>( element ) / 65535.0;
1542   }
1543   return -1.0;
1544 }
1545
1546 template <typename Td, typename Ts>
1547 void GltfLoader::FitBuffer( Dali::Vector<Td>& bufferDestiny, Dali::Vector<Ts>& bufferSource, int bufferSize, int elementNumOfByteStride, bool normalize )
1548 {
1549   bufferDestiny.Resize( bufferSize );
1550   int count = bufferSource.Size() / elementNumOfByteStride;
1551   for( int i = 0; i<count; ++i )
1552   {
1553     bufferDestiny[i] = static_cast<Td>( bufferSource[i * elementNumOfByteStride] );
1554   }
1555 }
1556
1557 template <typename T>
1558 void GltfLoader::FitBuffer( Dali::Vector<Vector2>& bufferDestiny, Dali::Vector<T>& bufferSource, int bufferSize, int elementNumOfByteStride, bool normalize )
1559 {
1560   bufferDestiny.Resize( bufferSize );
1561   int count = bufferSource.Size() / elementNumOfByteStride;
1562   for( int i = 0; i<count; ++i )
1563   {
1564     bufferDestiny[i].x = IntToFloat( bufferSource[i * elementNumOfByteStride], normalize );
1565     bufferDestiny[i].y = IntToFloat( bufferSource[i * elementNumOfByteStride + 1], normalize );
1566   }
1567 }
1568
1569 template <typename T>
1570 void GltfLoader::FitBuffer( Dali::Vector<Vector3>& bufferDestiny, Dali::Vector<T>& bufferSource, int bufferSize, int elementNumOfByteStride, bool normalize )
1571 {
1572   bufferDestiny.Resize( bufferSize );
1573   int count = bufferSource.Size() / elementNumOfByteStride;
1574   for( int i = 0; i<count; ++i )
1575   {
1576     bufferDestiny[i].x = IntToFloat( bufferSource[i * elementNumOfByteStride], normalize );
1577     bufferDestiny[i].y = IntToFloat( bufferSource[i * elementNumOfByteStride + 1], normalize );
1578     bufferDestiny[i].z = IntToFloat( bufferSource[i * elementNumOfByteStride + 2], normalize );
1579   }
1580 }
1581
1582 template <typename T>
1583 void GltfLoader::FitBuffer( Dali::Vector<Vector4>& bufferDestiny, Dali::Vector<T>& bufferSource, int bufferSize, int elementNumOfByteStride, bool normalize )
1584 {
1585   bufferDestiny.Resize( bufferSize );
1586   int count = bufferSource.Size() / elementNumOfByteStride;
1587   for( int i = 0; i<count; ++i )
1588   {
1589     bufferDestiny[i].x = IntToFloat( bufferSource[i * elementNumOfByteStride], normalize );
1590     bufferDestiny[i].y = IntToFloat( bufferSource[i * elementNumOfByteStride + 1], normalize );
1591     bufferDestiny[i].z = IntToFloat( bufferSource[i * elementNumOfByteStride + 2], normalize );
1592     bufferDestiny[i].w = IntToFloat( bufferSource[i * elementNumOfByteStride + 3], normalize );
1593   }
1594 }
1595
1596 template <typename T>
1597 void GltfLoader::LoadDataFromAccessor( int accessorIdx, Dali::Vector<T>& bufferData )
1598 {
1599   AccessorInfo accessor = mAccessorArray[accessorIdx];
1600   BufferViewInfo bufferView = mBufferViewArray[accessor.bufferView];
1601   BufferInfo buffer = mBufferArray[bufferView.buffer];
1602   std::string load_uri = buffer.uri;
1603
1604   // In the glTF 2.0 Specification, 5121 is UNSIGNED BYTE, 5123 is UNSIGNED SHORT
1605   int elementByteSize = ( accessor.componentType <= 5121 ) ? 1 :
1606     ( ( accessor.componentType <= 5123 ) ? 2 : 4 );
1607   int elementNum = 1;
1608   if( accessor.type == "VEC2" )
1609   {
1610     elementNum = 2;
1611   }
1612   else if( accessor.type == "VEC3" )
1613   {
1614     elementNum = 3;
1615   }
1616   else if( accessor.type == "VEC4" || accessor.type == "MAT2" )
1617   {
1618     elementNum = 4;
1619   }
1620   else if( accessor.type == "MAT3" )
1621   {
1622     elementNum = 9;
1623   }
1624   else if( accessor.type == "MAT4" )
1625   {
1626     elementNum = 16;
1627   }
1628   else
1629   {
1630     elementNum = 1;
1631   }
1632   int elementNumOfByteStride = elementNum;
1633   if( bufferView.byteStride > 0 )
1634   {
1635     elementNumOfByteStride = bufferView.byteStride / elementByteSize;
1636   }
1637
1638   /**
1639    * glTF 2.0 Specification
1640    * Component Type
1641    * 5120 : BYTE
1642    * 5121 : UNSIGNED_BYTE
1643    * 5122 : SHORT
1644    * 5123 : UNSIGNED_SHORT
1645    * 5125 : UNSIGNED_INT
1646    * 5126 : FLOAT
1647    */
1648   if( accessor.componentType == 5120 )
1649   {
1650     Dali::Vector<char> inputBufferData;
1651     ReadBinFile<char>( inputBufferData, mPath + load_uri, bufferView.byteOffset + accessor.byteOffset, elementNumOfByteStride * accessor.count );
1652     FitBuffer( bufferData, inputBufferData, accessor.count, elementNumOfByteStride, accessor.normalized );
1653   }
1654   else if( accessor.componentType == 5121 )
1655   {
1656     Dali::Vector<unsigned char> inputBufferData;
1657     ReadBinFile<unsigned char>( inputBufferData, mPath + load_uri, bufferView.byteOffset + accessor.byteOffset, elementNumOfByteStride * accessor.count );
1658     FitBuffer( bufferData, inputBufferData, accessor.count, elementNumOfByteStride, accessor.normalized );
1659   }
1660   else if( accessor.componentType == 5122 )
1661   {
1662     Dali::Vector<short> inputBufferData;
1663     ReadBinFile<short>( inputBufferData, mPath + load_uri, bufferView.byteOffset + accessor.byteOffset, elementNumOfByteStride * accessor.count );
1664     FitBuffer( bufferData, inputBufferData, accessor.count, elementNumOfByteStride, accessor.normalized );
1665   }
1666   else if( accessor.componentType == 5123 )
1667   {
1668     Dali::Vector<unsigned short> inputBufferData;
1669     ReadBinFile<unsigned short>( inputBufferData, mPath + load_uri, bufferView.byteOffset + accessor.byteOffset, elementNumOfByteStride * accessor.count );
1670     FitBuffer( bufferData, inputBufferData, accessor.count, elementNumOfByteStride, accessor.normalized );
1671   }
1672   else if( accessor.componentType == 5125 )
1673   {
1674     Dali::Vector<unsigned int> inputBufferData;
1675     ReadBinFile<unsigned int>( inputBufferData, mPath + load_uri, bufferView.byteOffset + accessor.byteOffset, elementNumOfByteStride * accessor.count );
1676     FitBuffer( bufferData, inputBufferData, accessor.count, elementNumOfByteStride, accessor.normalized );
1677   }
1678   else if( accessor.componentType == 5126 )
1679   {
1680     Dali::Vector<float> inputBufferData;
1681     ReadBinFile<float>( inputBufferData, mPath + load_uri, bufferView.byteOffset + accessor.byteOffset, elementNumOfByteStride * accessor.count );
1682     FitBuffer( bufferData, inputBufferData, accessor.count, elementNumOfByteStride, accessor.normalized );
1683   }
1684 }
1685
1686 template <typename T>
1687 PropertyBuffer GltfLoader::CreatePropertyBuffer( Vector<T> bufferData, std::string map, int type )
1688 {
1689   Property::Map positionMap;
1690   positionMap[map] = type;
1691
1692   PropertyBuffer propertyBuffer = PropertyBuffer::New( positionMap );
1693   propertyBuffer.SetData( bufferData.Begin(), bufferData.Count() );
1694   return propertyBuffer;
1695 }
1696
1697
1698 void GltfLoader::SetVertexBufferData( MeshInfo& meshInfo, int accessorIdx, std::string map, int type )
1699 {
1700   if( accessorIdx >= 0 )
1701   {
1702     Dali::Vector<Vector3> bufferData;
1703     LoadDataFromAccessor( accessorIdx, bufferData );
1704     SetMeshInfoAndCanonize( meshInfo, bufferData );
1705
1706     PropertyBuffer propertyBuffer = CreatePropertyBuffer<Vector3>( bufferData, map, type );
1707     meshInfo.geometry.AddVertexBuffer( propertyBuffer );
1708   }
1709 }
1710
1711 template <typename T>
1712 void GltfLoader::SetAttributeBufferData( MeshInfo& meshInfo, int accessorIdx, std::string map, int type )
1713 {
1714   if( accessorIdx >= 0 )
1715   {
1716     Dali::Vector<T> bufferData;
1717     LoadDataFromAccessor( accessorIdx, bufferData );
1718
1719     PropertyBuffer propertyBuffer = CreatePropertyBuffer<T>( bufferData, map, type );
1720     meshInfo.geometry.AddVertexBuffer( propertyBuffer );
1721   }
1722 }
1723
1724 void GltfLoader::SetIndexBuffersData( MeshInfo& meshInfo, int indexIdx )
1725 {
1726   Dali::Vector<unsigned short> indexBufferData;
1727   LoadDataFromAccessor( indexIdx, indexBufferData );
1728   meshInfo.geometry.SetIndexBuffer( &indexBufferData[0], indexBufferData.Size() );
1729 }
1730
1731 template<typename T>
1732 float GltfLoader::LoadKeyFrames( const AnimationSamplerInfo& currentSampler, const Property::Index propIndex, KeyFrames& keyframes )
1733 {
1734   Dali::Vector<float> inputBufferData;
1735   Dali::Vector<T> outputBufferData;
1736
1737   LoadDataFromAccessor<float>( currentSampler.input, inputBufferData );
1738   LoadDataFromAccessor<T>( currentSampler.output, outputBufferData );
1739
1740   int keyframeNum = inputBufferData.Size();
1741   float lengthAnimation = inputBufferData[keyframeNum - 1];
1742   for( int i = 0; i < keyframeNum; i++ )
1743   {
1744     if( propIndex == Dali::Actor::Property::ORIENTATION )
1745     {
1746       Vector4 vectorOrientation( outputBufferData[i] );
1747       float vW = vectorOrientation.w;
1748       vW = ( vW < 0.0f ) ? std::max( vW, -1.0f ) : std::min( vW, 1.0f );
1749       vectorOrientation.w = vW;
1750       keyframes.Add( inputBufferData[i] / lengthAnimation, Quaternion( Vector4( vectorOrientation ) ) );
1751     }
1752     else if( propIndex == Dali::Actor::Property::POSITION )
1753     {
1754       keyframes.Add( inputBufferData[i] / lengthAnimation, Vector3( outputBufferData[i] ) );
1755     }
1756     else if( propIndex == Dali::Actor::Property::SCALE )
1757     {
1758       keyframes.Add( inputBufferData[i] / lengthAnimation, Vector3( outputBufferData[i] ) );
1759     }
1760   }
1761   return lengthAnimation;
1762 }
1763
1764 // Utility functions
1765 const TreeNode* GltfLoader::Tidx( const TreeNode *node, int index )
1766 {
1767   int i = 0;
1768   for( TreeNode::ConstIterator it = ( *node ).CBegin(); it != ( *node ).CEnd(); ++it, ++i )
1769   {
1770     if( i == index )
1771     {
1772       return &( ( *it ).second );
1773     }
1774   }
1775   return NULL;
1776 }
1777
1778 bool GltfLoader::ReadBool( const TreeNode* node, bool& num )
1779 {
1780   if( !node )
1781   {
1782     return false;
1783   }
1784   bool returnValue = false;
1785
1786   if( node->GetType() == TreeNode::BOOLEAN )
1787   {
1788     num = node->GetBoolean();
1789     returnValue = true;
1790   }
1791
1792   return returnValue;
1793 }
1794
1795 bool GltfLoader::ReadInt( const TreeNode* node, int& num )
1796 {
1797   if( !node )
1798   {
1799     return false;
1800   }
1801   bool returnValue = false;
1802   if( node->GetType() == TreeNode::INTEGER )
1803   {
1804     num = node->GetInteger();
1805     returnValue = true;
1806   }
1807   else  if( node->GetType() == TreeNode::FLOAT )
1808   {
1809     num = node->GetFloat();
1810     returnValue = true;
1811   }
1812
1813   return returnValue;
1814 }
1815
1816 bool GltfLoader::ReadFloat( const TreeNode* node, float& num )
1817 {
1818   if( !node )
1819   {
1820     return false;
1821   }
1822   bool returnValue = false;
1823
1824   if( node->GetType() == TreeNode::FLOAT )
1825   {
1826     num = node->GetFloat();
1827     returnValue = true;
1828   }
1829   else if( node->GetType() == TreeNode::INTEGER )
1830   {
1831     int tempNum;
1832     ReadInt( node, tempNum );
1833     num = static_cast<float>( tempNum );
1834     returnValue = true;
1835   }
1836
1837   return returnValue;
1838 }
1839
1840 bool GltfLoader::ReadVector( const TreeNode* node, float* num, unsigned int size )
1841 {
1842   if( !node )
1843   {
1844     return false;
1845   }
1846   bool returnValue = false;
1847
1848   if( ( node->Size() >= size ) && ( node->GetType() == TreeNode::ARRAY ) )
1849   {
1850     unsigned int offset = 0u;
1851     for( TreeNode::ConstIterator it = node->CBegin(); offset < size; ++it, ++offset )
1852     {
1853       const TreeNode& coord = ( *it ).second;
1854       if( !ReadFloat( &coord, *( num + offset ) ) )
1855       {
1856         return false;
1857       }
1858     }
1859     returnValue = true;
1860   }
1861
1862   return returnValue;
1863 }
1864
1865 bool GltfLoader::ReadString( const TreeNode* node, std::string& strValue )
1866 {
1867   if( !node )
1868   {
1869     return false;
1870   }
1871   bool returnValue = false;
1872   if( node->GetType() == TreeNode::STRING )
1873   {
1874     strValue = node->GetString();
1875     returnValue = true;
1876   }
1877   return returnValue;
1878 }
1879
1880 }//namespace Internal
1881
1882 }//namespace Toolkit
1883
1884 }//namespace Dali