2 * Copyright (c) 2020 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <dali-toolkit/internal/controls/scene3d-view/gltf-loader.h>
20 #include <dali-toolkit/internal/controls/scene3d-view/gltf-shader.h>
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-stream.h>
43 const TreeNode* Tidx( const TreeNode *node, uint32_t index )
46 for( auto it = node->CBegin(), end = node->CEnd(); it != end; ++it, ++i )
50 return &( ( *it ).second );
56 bool ReadBool( const TreeNode* node, bool& num )
62 bool returnValue = false;
64 if( node->GetType() == TreeNode::BOOLEAN )
66 num = node->GetBoolean();
73 bool ReadInt( const TreeNode* node, int32_t& num )
79 bool returnValue = false;
80 if( node->GetType() == TreeNode::INTEGER )
82 num = node->GetInteger();
85 else if( node->GetType() == TreeNode::FLOAT )
87 num = node->GetFloat();
94 bool ReadFloat( const TreeNode* node, float& num )
100 bool returnValue = false;
102 if( node->GetType() == TreeNode::FLOAT )
104 num = node->GetFloat();
107 else if( node->GetType() == TreeNode::INTEGER )
110 ReadInt( node, tempNum );
111 num = static_cast<float>( tempNum );
118 bool ReadVector( const TreeNode* node, float* num, uint32_t size )
124 bool returnValue = false;
126 if( ( node->Size() >= size ) && ( node->GetType() == TreeNode::ARRAY ) )
128 uint32_t offset = 0u;
129 for( auto it = node->CBegin(); offset < size; ++it, ++offset )
131 const TreeNode& coord = ( *it ).second;
132 if( !ReadFloat( &coord, *( num + offset ) ) )
143 bool ReadString( const TreeNode* node, std::string& strValue )
149 bool returnValue = false;
150 if( node->GetType() == TreeNode::STRING )
152 strValue = node->GetString();
158 template <typename T>
159 float IntToFloat( T element, bool normalize )
163 return static_cast<float>( element );
166 if( std::is_same<T, int8_t>::value )
168 return std::max( static_cast<float>( element ) / 127.0, -1.0 );
170 if( std::is_same<T, uint8_t>::value )
172 return static_cast<float>( element ) / 255.0;
174 if( std::is_same<T, int16_t>::value )
176 return std::max( static_cast<float>( element ) / 32767.0, -1.0 );
178 if( std::is_same<T, uint16_t>::value )
180 return static_cast<float>( element ) / 65535.0;
185 template <typename Td, typename Ts>
186 void FitBuffer( Dali::Vector<Td>& bufferDestination, Dali::Vector<Ts>& bufferSource, int32_t bufferSize, int32_t elementNumOfByteStride, bool normalize )
188 bufferDestination.Resize( bufferSize );
189 int32_t count = bufferSource.Size() / elementNumOfByteStride;
190 for( int32_t i = 0; i<count; ++i )
192 bufferDestination[i] = static_cast<Td>( bufferSource[i * elementNumOfByteStride] );
196 template <typename T>
197 void FitBuffer( Dali::Vector<Vector2>& bufferDestination, Dali::Vector<T>& bufferSource, int32_t bufferSize, int32_t elementNumOfByteStride, bool normalize )
199 bufferDestination.Resize( bufferSize );
200 int32_t count = bufferSource.Size() / elementNumOfByteStride;
201 for( int32_t i = 0; i<count; ++i )
203 bufferDestination[i].x = IntToFloat( bufferSource[i * elementNumOfByteStride], normalize );
204 bufferDestination[i].y = IntToFloat( bufferSource[i * elementNumOfByteStride + 1], normalize );
208 template <typename T>
209 void FitBuffer( Dali::Vector<Vector3>& bufferDestination, Dali::Vector<T>& bufferSource, int32_t bufferSize, int32_t elementNumOfByteStride, bool normalize )
211 bufferDestination.Resize( bufferSize );
212 int32_t count = bufferSource.Size() / elementNumOfByteStride;
213 for( int32_t i = 0; i<count; ++i )
215 bufferDestination[i].x = IntToFloat( bufferSource[i * elementNumOfByteStride], normalize );
216 bufferDestination[i].y = IntToFloat( bufferSource[i * elementNumOfByteStride + 1], normalize );
217 bufferDestination[i].z = IntToFloat( bufferSource[i * elementNumOfByteStride + 2], normalize );
221 template <typename T>
222 void FitBuffer( Dali::Vector<Vector4>& bufferDestination, Dali::Vector<T>& bufferSource, int32_t bufferSize, int32_t elementNumOfByteStride, bool normalize )
224 bufferDestination.Resize( bufferSize );
225 int32_t count = bufferSource.Size() / elementNumOfByteStride;
226 for( int32_t i = 0; i<count; ++i )
228 bufferDestination[i].x = IntToFloat( bufferSource[i * elementNumOfByteStride], normalize );
229 bufferDestination[i].y = IntToFloat( bufferSource[i * elementNumOfByteStride + 1], normalize );
230 bufferDestination[i].z = IntToFloat( bufferSource[i * elementNumOfByteStride + 2], normalize );
231 bufferDestination[i].w = IntToFloat( bufferSource[i * elementNumOfByteStride + 3], normalize );
235 // Template functions
236 template <typename T>
237 bool ReadBinFile( Vector<T> &dataBuffer, std::string url, int32_t offset, int32_t count )
239 Dali::FileStream fileStream( url, FileStream::READ | FileStream::BINARY );
240 FILE* fp = fileStream.GetFile();
246 dataBuffer.Resize( count );
248 if( !fseek( fp, offset, SEEK_SET ) )
250 result = fread( &dataBuffer[0], sizeof( T ), count, fp );
253 return ( result >= 0 );
256 template <typename T>
257 void LoadDataFromAccessor( int32_t accessorIdx, Dali::Vector<T>& bufferData, std::string path, std::vector<AccessorInfo>& accessorArray, std::vector<BufferViewInfo>& bufferViewArray, std::vector<BufferInfo>& bufferArray )
259 AccessorInfo accessor = accessorArray[accessorIdx];
260 BufferViewInfo bufferView = bufferViewArray[accessor.bufferView];
261 std::string load_uri = bufferArray[bufferView.buffer].uri;
263 // In the glTF 2.0 Specification, 5121 is UNSIGNED BYTE, 5123 is UNSIGNED SHORT
264 int32_t elementByteSize = ( accessor.componentType <= 5121 ) ? 1 :
265 ( ( accessor.componentType <= 5123 ) ? 2 : 4 );
266 int32_t elementNum = 1;
267 if( accessor.type == "VEC2" )
271 else if( accessor.type == "VEC3" )
275 else if( accessor.type == "VEC4" || accessor.type == "MAT2" )
279 else if( accessor.type == "MAT3" )
283 else if( accessor.type == "MAT4" )
291 int32_t elementNumOfByteStride = elementNum;
292 if( bufferView.byteStride > 0 )
294 elementNumOfByteStride = bufferView.byteStride / elementByteSize;
298 * glTF 2.0 Specification
301 * 5121 : UNSIGNED_BYTE
303 * 5123 : UNSIGNED_SHORT
304 * 5125 : UNSIGNED_INT
307 if( accessor.componentType == 5120 )
309 Dali::Vector<int8_t> inputBufferData;
310 ReadBinFile<int8_t>( inputBufferData, path + load_uri, bufferView.byteOffset + accessor.byteOffset, elementNumOfByteStride * accessor.count );
311 FitBuffer( bufferData, inputBufferData, accessor.count, elementNumOfByteStride, accessor.normalized );
313 else if( accessor.componentType == 5121 )
315 Dali::Vector<uint8_t> inputBufferData;
316 ReadBinFile<uint8_t>( inputBufferData, path + load_uri, bufferView.byteOffset + accessor.byteOffset, elementNumOfByteStride * accessor.count );
317 FitBuffer( bufferData, inputBufferData, accessor.count, elementNumOfByteStride, accessor.normalized );
319 else if( accessor.componentType == 5122 )
321 Dali::Vector<int16_t> inputBufferData;
322 ReadBinFile<int16_t>( inputBufferData, path + load_uri, bufferView.byteOffset + accessor.byteOffset, elementNumOfByteStride * accessor.count );
323 FitBuffer( bufferData, inputBufferData, accessor.count, elementNumOfByteStride, accessor.normalized );
325 else if( accessor.componentType == 5123 )
327 Dali::Vector<uint16_t> inputBufferData;
328 ReadBinFile<uint16_t>( inputBufferData, path + load_uri, bufferView.byteOffset + accessor.byteOffset, elementNumOfByteStride * accessor.count );
329 FitBuffer( bufferData, inputBufferData, accessor.count, elementNumOfByteStride, accessor.normalized );
331 else if( accessor.componentType == 5125 )
333 Dali::Vector<uint32_t> inputBufferData;
334 ReadBinFile<uint32_t>( inputBufferData, path + load_uri, bufferView.byteOffset + accessor.byteOffset, elementNumOfByteStride * accessor.count );
335 FitBuffer( bufferData, inputBufferData, accessor.count, elementNumOfByteStride, accessor.normalized );
337 else if( accessor.componentType == 5126 )
339 Dali::Vector<float> inputBufferData;
340 ReadBinFile<float>( inputBufferData, path + load_uri, bufferView.byteOffset + accessor.byteOffset, elementNumOfByteStride * accessor.count );
341 FitBuffer( bufferData, inputBufferData, accessor.count, elementNumOfByteStride, accessor.normalized );
345 void SetMeshInfoAndCanonize( MeshInfo& meshInfo, Dali::Vector<Dali::Vector3> &vertexBufferData )
347 Vector3 pointMin( std::numeric_limits<float>::max(), std::numeric_limits<float>::max(), std::numeric_limits<float>::max() );
348 Vector3 pointMax( std::numeric_limits<float>::min(), std::numeric_limits<float>::min(), std::numeric_limits<float>::min() );
349 for( auto&& data : vertexBufferData )
351 pointMin.x = std::min( data.x, pointMin.x );
352 pointMin.y = std::min( data.y, pointMin.y );
353 pointMin.z = std::min( data.z, pointMin.z );
355 pointMax.x = std::max( data.x, pointMax.x );
356 pointMax.y = std::max( data.y, pointMax.y );
357 pointMax.z = std::max( data.z, pointMax.z );
359 meshInfo.size = pointMax - pointMin;
360 meshInfo.pivot.x = ( -pointMin.x ) / ( pointMax.x - pointMin.x );
361 meshInfo.pivot.y = ( -pointMin.y ) / ( pointMax.y - pointMin.y );
362 meshInfo.pivot.z = ( -pointMin.z ) / ( pointMax.z - pointMin.z );
364 Vector3 center = meshInfo.size * 0.5 + pointMin;
365 for( auto&& data : vertexBufferData )
367 data = data - center;
368 data.x = data.x / meshInfo.size.x;
369 data.y = data.y / meshInfo.size.y;
370 data.z = data.z / meshInfo.size.z;
374 template <typename T>
375 PropertyBuffer CreatePropertyBuffer( Vector<T> bufferData, std::string map, int32_t type )
377 Property::Map positionMap;
378 positionMap[map] = type;
380 PropertyBuffer propertyBuffer = PropertyBuffer::New( positionMap );
381 propertyBuffer.SetData( bufferData.Begin(), bufferData.Count() );
382 return propertyBuffer;
385 void SetVertexBufferData( MeshInfo& meshInfo, std::string path, std::vector<AccessorInfo>& accessorArray, std::vector<BufferViewInfo>& bufferViewArray, std::vector<BufferInfo>& bufferArray, int32_t accessorIdx, std::string map, int32_t type )
387 if( accessorIdx >= 0 )
389 Dali::Vector<Vector3> bufferData;
390 LoadDataFromAccessor( accessorIdx, bufferData, path, accessorArray, bufferViewArray, bufferArray );
391 SetMeshInfoAndCanonize( meshInfo, bufferData );
393 PropertyBuffer propertyBuffer = CreatePropertyBuffer<Vector3>( bufferData, map, type );
394 meshInfo.geometry.AddVertexBuffer( propertyBuffer );
398 template <typename T>
399 void SetAttributeBufferData( MeshInfo& meshInfo, std::string path, std::vector<AccessorInfo>& accessorArray, std::vector<BufferViewInfo>& bufferViewArray, std::vector<BufferInfo>& bufferArray, int32_t accessorIdx, std::string map, int32_t type )
401 if( accessorIdx >= 0 )
403 Dali::Vector<T> bufferData;
404 LoadDataFromAccessor( accessorIdx, bufferData, path, accessorArray, bufferViewArray, bufferArray );
406 PropertyBuffer propertyBuffer = CreatePropertyBuffer<T>( bufferData, map, type );
407 meshInfo.geometry.AddVertexBuffer( propertyBuffer );
411 void SetIndexBuffersData( MeshInfo& meshInfo, std::string path, std::vector<AccessorInfo>& accessorArray, std::vector<BufferViewInfo>& bufferViewArray, std::vector<BufferInfo>& bufferArray, int32_t indexIdx )
413 Dali::Vector<uint16_t> indexBufferData;
414 LoadDataFromAccessor( indexIdx, indexBufferData, path, accessorArray, bufferViewArray, bufferArray );
415 meshInfo.geometry.SetIndexBuffer( &indexBufferData[0], indexBufferData.Size() );
419 float LoadKeyFrames( const AnimationSamplerInfo& currentSampler, const Property::Index propIndex, KeyFrames& keyframes, std::string path, std::vector<AccessorInfo>& accessorArray, std::vector<BufferViewInfo>& bufferViewArray, std::vector<BufferInfo>& bufferArray )
421 Dali::Vector<float> inputBufferData;
422 Dali::Vector<T> outputBufferData;
424 LoadDataFromAccessor<float>( currentSampler.input, inputBufferData, path, accessorArray, bufferViewArray, bufferArray );
425 LoadDataFromAccessor<T>( currentSampler.output, outputBufferData, path, accessorArray, bufferViewArray, bufferArray );
427 uint32_t keyframeNum = inputBufferData.Size();
428 float lengthAnimation = inputBufferData[inputBufferData.Size() - 1];
429 for( uint32_t i = 0; i < keyframeNum; i++ )
431 if( propIndex == Dali::Actor::Property::ORIENTATION )
433 Vector4 vectorOrientation( outputBufferData[i] );
434 float vW = vectorOrientation.w;
435 vW = ( vW < 0.0f ) ? std::max( vW, -1.0f ) : std::min( vW, 1.0f );
436 vectorOrientation.w = vW;
437 keyframes.Add( inputBufferData[i] / lengthAnimation, Quaternion( Vector4( vectorOrientation ) ) );
439 else if( propIndex == Dali::Actor::Property::POSITION )
441 keyframes.Add( inputBufferData[i] / lengthAnimation, Vector3( outputBufferData[i] ) );
443 else if( propIndex == Dali::Actor::Property::SCALE )
445 keyframes.Add( inputBufferData[i] / lengthAnimation, Vector3( outputBufferData[i] ) );
448 return lengthAnimation;
451 bool LoadBuffer( const TreeNode& buffer, std::vector<BufferInfo>& bufferArray )
453 BufferInfo bufferInfo;
455 const TreeNode* uriNode = buffer.GetChild( "uri" );
458 ReadString( uriNode, bufferInfo.uri );
461 const TreeNode* byteLengthNode = buffer.GetChild( "byteLength" );
464 ReadInt( byteLengthNode, bufferInfo.byteLength );
465 if( bufferInfo.byteLength < 0 )
471 const TreeNode* nameNode = buffer.GetChild( "name" );
474 ReadString( nameNode, bufferInfo.name );
477 bufferArray.push_back( bufferInfo );
482 bool LoadBufferView( const TreeNode& buffer, std::vector<BufferViewInfo>& bufferViewArray )
484 BufferViewInfo bufferViewInfo;
486 const TreeNode* bufferNode = buffer.GetChild( "buffer" );
489 ReadInt( bufferNode, bufferViewInfo.buffer );
490 if( bufferViewInfo.buffer < 0 )
496 const TreeNode* byteOffsetNode = buffer.GetChild( "byteOffset" );
499 ReadInt( byteOffsetNode, bufferViewInfo.byteOffset );
502 const TreeNode* byteLengthNode = buffer.GetChild( "byteLength" );
505 ReadInt( byteLengthNode, bufferViewInfo.byteLength );
506 if( bufferViewInfo.byteLength < 0 )
512 const TreeNode* byteStrideNode = buffer.GetChild( "byteStride" );
515 ReadInt( byteStrideNode, bufferViewInfo.byteStride );
518 const TreeNode* targetNode = buffer.GetChild( "target" );
521 ReadInt( targetNode, bufferViewInfo.target );
524 const TreeNode* nameNode = buffer.GetChild( "name" );
527 ReadString( nameNode, bufferViewInfo.name );
530 bufferViewArray.push_back( bufferViewInfo );
535 bool LoadAccessor( const TreeNode& buffer, std::vector<AccessorInfo>& accessorArray )
537 AccessorInfo accessorInfo;
539 const TreeNode* bufferViewNode = buffer.GetChild( "bufferView" );
542 ReadInt( bufferViewNode, accessorInfo.bufferView );
545 const TreeNode* byteOffsetNode = buffer.GetChild( "byteOffset" );
548 ReadInt( byteOffsetNode, accessorInfo.byteOffset );
551 const TreeNode* componentTypeNode = buffer.GetChild( "componentType" );
552 if( componentTypeNode )
554 ReadInt( componentTypeNode, accessorInfo.componentType );
555 if( accessorInfo.componentType < 0 )
561 const TreeNode* normalizedNode = buffer.GetChild( "normalized" );
564 ReadBool( normalizedNode, accessorInfo.normalized );
567 const TreeNode* countNode = buffer.GetChild( "count" );
570 ReadInt( countNode, accessorInfo.count );
571 if( accessorInfo.count < 0 )
577 const TreeNode* typeNode = buffer.GetChild( "type" );
580 ReadString( typeNode, accessorInfo.type );
581 if( accessorInfo.type == "" )
587 const TreeNode* maxNode = buffer.GetChild( "max" );
590 ReadInt( maxNode, accessorInfo.max );
593 const TreeNode* minNode = buffer.GetChild( "min" );
596 ReadInt( minNode, accessorInfo.min );
599 const TreeNode* nameNode = buffer.GetChild( "name" );
602 ReadString( nameNode, accessorInfo.name );
605 accessorArray.push_back( accessorInfo );
610 bool LoadBinaryData( const TreeNode& root, std::vector<BufferInfo>& bufferArray, std::vector<BufferViewInfo>& bufferViewArray, std::vector<AccessorInfo>& accessorArray )
612 const TreeNode* buffersNode = root.GetChild( "buffers" );
617 for( auto bufferIter = buffersNode->CBegin(), end = buffersNode->CEnd(); bufferIter != end; ++bufferIter )
619 LoadBuffer( ( *bufferIter ).second, bufferArray );
622 const TreeNode* bufferViewsNode = root.GetChild( "bufferViews" );
623 if( !bufferViewsNode )
627 for( auto bufferViewIter = bufferViewsNode->CBegin(), end = bufferViewsNode->CEnd(); bufferViewIter != end; ++bufferViewIter )
629 LoadBufferView( ( *bufferViewIter ).second, bufferViewArray );
632 const TreeNode* accessorsNode = root.GetChild( "accessors" );
637 for( auto accesorIter = accessorsNode->CBegin(), end = accessorsNode->CEnd(); accesorIter != end; ++accesorIter )
639 LoadAccessor( ( *accesorIter ).second, accessorArray );
645 FilterMode::Type GetFilterMode( uint32_t mode )
647 FilterMode::Type retValue = FilterMode::DEFAULT;
649 * glTF 2.0 Specification
653 * 9984 : NEAREST_MIPMAP_NEAREST
654 * 9985 : LINEAR_MIPMAP_NEAREST
655 * 9986 : NEAREST_MIPMAP_LINEAR
656 * 9987 : LINEAR_MIPMAP_LINEAR
662 retValue = FilterMode::NEAREST;
667 retValue = FilterMode::LINEAR;
672 retValue = FilterMode::NEAREST_MIPMAP_NEAREST;
677 retValue = FilterMode::LINEAR_MIPMAP_NEAREST;
682 retValue = FilterMode::NEAREST_MIPMAP_LINEAR;
687 retValue = FilterMode::LINEAR_MIPMAP_LINEAR;
695 WrapMode::Type GetWrapMode( uint32_t mode )
697 WrapMode::Type retValue = WrapMode::REPEAT;
699 * glTF 2.0 Specification
701 * 33071 : CLAMP_TO_EDGE
702 * 33648 : MIRRORED_REPEAT
709 retValue = WrapMode::CLAMP_TO_EDGE;
714 retValue = WrapMode::MIRRORED_REPEAT;
719 retValue = WrapMode::REPEAT;
727 Texture LoadTexture( const char* imageUrl, bool generateMipmaps )
730 Devel::PixelBuffer pixelBuffer = LoadImageFromFile( imageUrl );
733 texture = Texture::New( TextureType::TEXTURE_2D, pixelBuffer.GetPixelFormat(), pixelBuffer.GetWidth(), pixelBuffer.GetHeight() );
734 PixelData pixelData = Devel::PixelBuffer::Convert( pixelBuffer );
735 texture.Upload( pixelData );
737 if( generateMipmaps )
739 texture.GenerateMipmaps();
746 Sampler LoadSampler( const TreeNode& samplerNode )
748 Sampler sampler = Sampler::New();
750 FilterMode::Type minFilter = FilterMode::DEFAULT;
751 FilterMode::Type magFilter = FilterMode::DEFAULT;
752 const TreeNode* magFilterNode = samplerNode.GetChild( "magFilter" );
755 int32_t magFilter_integer = 0;
756 ReadInt( magFilterNode, magFilter_integer );
757 magFilter = GetFilterMode( magFilter_integer );
760 const TreeNode* minFilterNode = samplerNode.GetChild( "minFilter" );
763 int32_t minFilter_integer = 0;
764 ReadInt( minFilterNode, minFilter_integer );
765 minFilter = GetFilterMode( minFilter_integer );
768 WrapMode::Type wrapR = WrapMode::REPEAT;
769 WrapMode::Type wrapS = WrapMode::REPEAT;
770 WrapMode::Type wrapT = WrapMode::REPEAT;
771 const TreeNode* wrapNode = samplerNode.GetChild( "wrapS" );
774 wrapS = GetWrapMode( wrapNode->GetInteger() );
777 wrapNode = samplerNode.GetChild( "wrapT" );
780 wrapT = GetWrapMode( wrapNode->GetInteger() );
783 sampler.SetFilterMode( minFilter, magFilter );
784 sampler.SetWrapMode( wrapR, wrapS, wrapT );
789 bool LoadTextureArray( const TreeNode& root, std::string path, std::vector<Texture>& sourceArray, std::vector<Sampler>& samplerArray, std::vector<TextureInfo>& textureArray )
791 const TreeNode* imagesNode = root.GetChild( "images" );
794 for( auto imageIter = imagesNode->CBegin(), end = imagesNode->CEnd(); imageIter != end; ++imageIter )
796 std::string imageUrl;
797 const TreeNode* uriNode = ( &( ( *imageIter ).second ) )->GetChild( "uri" );
801 ReadString( uriNode, uri );
802 imageUrl = path + uri;
805 sourceArray.push_back( LoadTexture( imageUrl.c_str(), true ) );
809 const TreeNode* samplersNode = root.GetChild( "samplers" );
812 for( auto samplerIter = samplersNode->CBegin(), end = samplersNode->CEnd(); samplerIter != end; ++samplerIter )
814 samplerArray.push_back( LoadSampler( ( ( *samplerIter ).second ) ) );
818 const TreeNode* texturesNode = root.GetChild( "textures" );
821 for( auto textureIter = texturesNode->CBegin(), end = texturesNode->CEnd(); textureIter != end; ++textureIter )
823 const TreeNode* TextureNode = &( ( *textureIter ).second );
826 const TreeNode* sourceNode = TextureNode->GetChild( "source" );
829 ReadInt( sourceNode, texture.sourceIdx );
832 const TreeNode* samplerNode = TextureNode->GetChild( "sampler" );
835 ReadInt( samplerNode, texture.samplerIdx );
838 textureArray.push_back( texture );
844 bool LoadPbrMetallicRoughness( const TreeNode& material, MaterialInfo& materialInfo )
847 const TreeNode* pbrMetallicRoughnessNode = material.GetChild( "pbrMetallicRoughness" );
848 if( !pbrMetallicRoughnessNode )
853 const TreeNode* tempNode;
854 tempNode = pbrMetallicRoughnessNode->GetChild( "metallicFactor" );
857 ReadFloat( tempNode, materialInfo.metallicFactor );
860 tempNode = pbrMetallicRoughnessNode->GetChild( "roughnessFactor" );
863 ReadFloat( tempNode, materialInfo.roughnessFactor );
866 tempNode = pbrMetallicRoughnessNode->GetChild( "baseColorFactor" );
867 if( tempNode && ReadVector( tempNode, floatVec, 4 ) )
869 materialInfo.baseColorFactor = Vector4( floatVec[0], floatVec[1], floatVec[2], floatVec[3] );
872 const TreeNode* baseColorTextureNode = pbrMetallicRoughnessNode->GetChild( "baseColorTexture" );
873 if( baseColorTextureNode )
875 tempNode = baseColorTextureNode->GetChild( "index" );
878 materialInfo.baseColorTexture.index = tempNode->GetInteger();
881 tempNode = baseColorTextureNode->GetChild( "texCoord" );
884 materialInfo.baseColorTexture.texCoord = tempNode->GetInteger();
888 const TreeNode* metallicRoughnessTextureNode = pbrMetallicRoughnessNode->GetChild( "metallicRoughnessTexture" );
889 if( metallicRoughnessTextureNode )
891 tempNode = metallicRoughnessTextureNode->GetChild( "index" );
894 materialInfo.metallicRoughnessTexture.index = tempNode->GetInteger();
897 tempNode = metallicRoughnessTextureNode->GetChild( "texCoord" );
900 materialInfo.metallicRoughnessTexture.texCoord = tempNode->GetInteger();
907 bool LoadMaterialSetArray( const TreeNode& root, std::vector<MaterialInfo>& materialArray )
909 const TreeNode* materialsNode = root.GetChild( "materials" );
915 for( auto materialIter = materialsNode->CBegin(), end = materialsNode->CEnd(); materialIter != end; ++materialIter )
917 MaterialInfo materialInfo;
918 LoadPbrMetallicRoughness( ( ( *materialIter ).second ), materialInfo );
920 const TreeNode* materialNode = &( ( *materialIter ).second );
921 const TreeNode* tempNode = materialNode->GetChild( "name" );
924 ReadString( tempNode, materialInfo.name );
927 materialInfo.alphaMode = "OPAQUE";
928 tempNode = materialNode->GetChild( "alphaMode" );
931 ReadString( tempNode, materialInfo.alphaMode );
934 materialInfo.alphaCutoff = 1.0;
935 tempNode = materialNode->GetChild( "alphaCutoff" );
938 ReadFloat( tempNode, materialInfo.alphaCutoff );
941 materialInfo.doubleSided = false;
942 tempNode = materialNode->GetChild( "doubleSided" );
945 ReadBool( tempNode, materialInfo.doubleSided );
949 tempNode = materialNode->GetChild( "emissiveFactor" );
950 if( tempNode && ReadVector( tempNode, floatVec, 3 ) )
952 materialInfo.emissiveFactor = Vector3( floatVec[0], floatVec[1], floatVec[2] );
955 const TreeNode* texture = materialNode->GetChild( "normalTexture" );
958 tempNode = texture->GetChild( "index" );
961 materialInfo.normalTexture.index = tempNode->GetInteger();
964 tempNode = texture->GetChild( "texCoord" );
967 materialInfo.normalTexture.texCoord = tempNode->GetInteger();
970 materialInfo.normalTexture.value = 1.0;
971 tempNode = texture->GetChild( "scale" );
974 ReadFloat( tempNode, materialInfo.normalTexture.value );
978 texture = materialNode->GetChild( "occlusionTexture" );
981 tempNode = texture->GetChild( "index" );
984 materialInfo.occlusionTexture.index = tempNode->GetInteger();
987 tempNode = texture->GetChild( "texCoord" );
990 materialInfo.occlusionTexture.texCoord = tempNode->GetInteger();
994 tempNode = texture->GetChild( "strength" );
997 ReadFloat( tempNode, materialInfo.occlusionTexture.value );
1001 texture = materialNode->GetChild( "emissiveTexture" );
1004 tempNode = texture->GetChild( "index" );
1007 materialInfo.emissiveTexture.index = tempNode->GetInteger();
1010 tempNode = texture->GetChild( "texCoord" );
1013 materialInfo.emissiveTexture.texCoord = tempNode->GetInteger();
1016 materialArray.push_back( materialInfo );
1021 bool LoadAttribute( const TreeNode* primitive, MeshInfo& meshInfo )
1023 const TreeNode* attrbuteNode = primitive->GetChild( "attributes" );
1029 const TreeNode* tempNode;
1030 tempNode = attrbuteNode->GetChild( "POSITION" );
1033 meshInfo.attribute.POSITION = tempNode->GetInteger();
1036 tempNode = attrbuteNode->GetChild( "NORMAL" );
1039 meshInfo.attribute.NORMAL = tempNode->GetInteger();
1042 tempNode = attrbuteNode->GetChild( "TANGENT" );
1045 meshInfo.attribute.TANGENT = tempNode->GetInteger();
1049 meshInfo.attribute.TEXCOORD.clear();
1050 tempNode = attrbuteNode->GetChild( "TEXCOORD_" + std::to_string( index ) );
1053 uint32_t value = tempNode->GetInteger();
1054 meshInfo.attribute.TEXCOORD.push_back( value );
1055 tempNode = attrbuteNode->GetChild( "TEXCOORD_" + std::to_string( ++index ) );
1059 meshInfo.attribute.COLOR.clear();
1060 tempNode = attrbuteNode->GetChild( "COLOR_" + std::to_string( index ) );
1063 uint32_t value = tempNode->GetInteger();
1064 meshInfo.attribute.COLOR.push_back( value );
1065 tempNode = attrbuteNode->GetChild( "COLOR" + std::to_string( ++index ) );
1071 bool LoadPrimitive( const TreeNode& mesh, MeshInfo& meshInfo )
1073 const TreeNode* primitivesNode = mesh.GetChild( "primitives" );
1074 if( !primitivesNode )
1079 for( auto primitiveIter = primitivesNode->CBegin(), end = primitivesNode->CEnd(); primitiveIter != end; ++primitiveIter )
1081 const TreeNode* primitiveNode = ( &( *primitiveIter ).second );
1082 const TreeNode* tempNode;
1084 tempNode = primitiveNode->GetChild( "indices" );
1087 meshInfo.indicesIdx = tempNode->GetInteger();
1090 tempNode = primitiveNode->GetChild( "material" );
1093 meshInfo.materialsIdx = tempNode->GetInteger();
1096 tempNode = primitiveNode->GetChild( "mode" );
1099 meshInfo.mode = tempNode->GetInteger();
1102 LoadAttribute( primitiveNode, meshInfo );
1108 bool SetGeometry( MeshInfo& meshInfo, std::string path, std::vector<BufferInfo>& bufferArray, std::vector<BufferViewInfo>& bufferViewArray, std::vector<AccessorInfo>& accessorArray )
1110 int32_t indicesIdx = meshInfo.indicesIdx;
1112 if( meshInfo.mode != 0 )
1114 meshInfo.geometry.SetType( ( Dali::Geometry::Type )meshInfo.mode );
1117 if( indicesIdx >= 0 )
1119 SetIndexBuffersData( meshInfo, path, accessorArray, bufferViewArray, bufferArray, indicesIdx );
1122 SetVertexBufferData( meshInfo, path, accessorArray, bufferViewArray, bufferArray, meshInfo.attribute.POSITION, "aPosition", Property::VECTOR3 );
1123 SetAttributeBufferData<Vector3>( meshInfo, path, accessorArray, bufferViewArray, bufferArray, meshInfo.attribute.NORMAL, "aNormal", Property::VECTOR3 );
1124 SetAttributeBufferData<Vector4>( meshInfo, path, accessorArray, bufferViewArray, bufferArray, meshInfo.attribute.TANGENT, "aTangent", Property::VECTOR4 );
1126 for( uint32_t i = 0; i < meshInfo.attribute.TEXCOORD.size(); ++i )
1128 int32_t accessorIdx = meshInfo.attribute.TEXCOORD[i];
1129 std::ostringstream texCoordString;
1130 texCoordString << "aTexCoord" << i;
1131 SetAttributeBufferData<Vector2>( meshInfo, path, accessorArray, bufferViewArray, bufferArray, accessorIdx, texCoordString.str(), Property::VECTOR2 );
1134 for( auto&& accessorIdx : meshInfo.attribute.COLOR )
1136 if( accessorIdx < 0 )
1141 if( accessorArray[accessorIdx].type == "VEC3" )
1143 Dali::Vector<Vector3> inputBufferData;
1144 LoadDataFromAccessor( accessorIdx, inputBufferData, path, accessorArray, bufferViewArray, bufferArray );
1146 Dali::Vector<Vector4> bufferData;
1147 bufferData.Resize( inputBufferData.Size() );
1148 for( uint32_t i = 0; i<inputBufferData.Size(); ++i )
1150 bufferData[i].x = inputBufferData[i].x;
1151 bufferData[i].y = inputBufferData[i].y;
1152 bufferData[i].z = inputBufferData[i].z;
1153 bufferData[i].w = 1.0;
1155 PropertyBuffer propertyBuffer = CreatePropertyBuffer<Vector4>( bufferData, "aVertexColor", Property::VECTOR4 );
1156 meshInfo.geometry.AddVertexBuffer( propertyBuffer );
1158 else if( accessorArray[accessorIdx].type == "VEC4" )
1160 SetAttributeBufferData<Vector4>( meshInfo, path, accessorArray, bufferViewArray, bufferArray, accessorIdx, "aVertexColor", Property::VECTOR4 );
1166 bool LoadMeshArray( const TreeNode& root, std::string path, std::vector<MeshInfo>& meshArray, std::vector<BufferInfo>& bufferArray, std::vector<BufferViewInfo>& bufferViewArray, std::vector<AccessorInfo>& accessorArray )
1168 const TreeNode* meshesNode = root.GetChild( "meshes" );
1174 for( auto meshIter = meshesNode->CBegin(), end = meshesNode->CEnd(); meshIter != end; ++meshIter )
1177 const TreeNode* nameNode = ( &( *meshIter ).second )->GetChild( "name" );
1180 ReadString( nameNode, meshInfo.name );
1182 meshInfo.geometry = Geometry::New();
1184 //Need to add weights for Morph targets.
1185 LoadPrimitive( ( *meshIter ).second, meshInfo );
1186 SetGeometry( meshInfo, path, bufferArray, bufferViewArray, accessorArray );
1187 meshArray.push_back( meshInfo );
1205 bool Loader::LoadScene( const std::string& filePath, Internal::Scene3dView& scene3dView )
1207 // Extracting directory path from full path to load resources.
1208 if( std::string::npos != filePath.rfind('/') )
1210 mPath = filePath.substr( 0, filePath.rfind('/') ) + "/";
1213 if( !ParseGltf( filePath ) )
1215 DALI_LOG_ERROR( "Fail to parse json file\n" );
1219 mRoot = mParser.GetRoot();
1222 CreateScene( scene3dView ) )
1229 bool Loader::ParseGltf( const std::string& filePath )
1231 std::streampos bufferSize = 0;
1232 Dali::Vector<char> buffer;
1233 std::string fileBuffer;
1234 if( !Dali::FileLoader::ReadFile( filePath, bufferSize, buffer, FileLoader::FileType::BINARY ) )
1239 fileBuffer.assign( &buffer[0], bufferSize );
1240 mParser = Dali::Toolkit::JsonParser::New();
1241 return mParser.Parse( fileBuffer );
1244 bool Loader::LoadAssets()
1246 if( LoadBinaryData( *mRoot, mBufferArray, mBufferViewArray, mAccessorArray ) &&
1247 LoadTextureArray( *mRoot, mPath, mSourceArray, mSamplerArray, mTextureArray ) &&
1248 LoadMaterialSetArray( *mRoot, mMaterialArray ) &&
1249 LoadMeshArray( *mRoot, mPath, mMeshArray, mBufferArray, mBufferViewArray, mAccessorArray )
1257 bool Loader::CreateScene( Internal::Scene3dView& scene3dView )
1259 scene3dView.SetDefaultCamera( Dali::Camera::LOOK_AT_TARGET, 0.01, Vector3::ZERO );
1260 LoadCamera( scene3dView );
1262 if( LoadSceneNodes( scene3dView ) &&
1263 LoadAnimation( scene3dView ) )
1270 void Loader::LoadCamera( Scene3dView& scene3dView )
1272 const TreeNode* camerasNode = mRoot->GetChild( "cameras" );
1278 for( auto cameraIter = camerasNode->CBegin(), end = camerasNode->CEnd(); cameraIter != end; ++cameraIter )
1280 const TreeNode* tempNode = ( &( *cameraIter ).second )->GetChild( "name" );
1281 CameraInfo cameraInfo;
1284 ReadString( tempNode, cameraInfo.name );
1287 tempNode = ( &( *cameraIter ).second )->GetChild( "type" );
1290 ReadString( tempNode, cameraInfo.type );
1293 CameraActor cameraActor = CameraActor::New();
1294 cameraActor.SetParentOrigin( ParentOrigin::CENTER );
1295 cameraActor.SetAnchorPoint( AnchorPoint::CENTER );
1297 if( cameraInfo.type == "orthographic" )
1299 LoadOrthoGraphic( ( *cameraIter ).second, cameraInfo );
1300 float xMag_2 = cameraInfo.orthographic.xmag / 2.0;
1301 float yMag_2 = cameraInfo.orthographic.ymag / 2.0;
1302 cameraActor.SetOrthographicProjection( -xMag_2, xMag_2, yMag_2, -yMag_2,
1303 cameraInfo.orthographic.znear, cameraInfo.orthographic.zfar );
1305 else if( cameraInfo.type == "perspective" )
1307 if( !LoadPerspective( ( *cameraIter ).second, cameraInfo ) )
1311 cameraActor.SetProjectionMode( Dali::Camera::PERSPECTIVE_PROJECTION );
1312 cameraActor.SetFieldOfView( cameraInfo.perspective.yfov );
1313 cameraActor.SetNearClippingPlane( cameraInfo.perspective.znear );
1315 if( cameraInfo.perspective.zfar > 0.0 )
1317 cameraActor.SetFarClippingPlane( cameraInfo.perspective.zfar );
1319 if( cameraInfo.perspective.aspectRatio > 0.0 )
1321 cameraActor.SetAspectRatio( cameraInfo.perspective.aspectRatio );
1325 scene3dView.AddCamera( cameraActor );
1329 bool Loader::LoadOrthoGraphic( const TreeNode& camera, CameraInfo& cameraInfo )
1331 const TreeNode* orthographicNode = camera.GetChild( "orthographic" );
1332 if( !orthographicNode )
1337 const TreeNode* tempNode;
1338 tempNode = orthographicNode->GetChild( "xmag" );
1341 ReadFloat( tempNode, cameraInfo.orthographic.xmag );
1344 tempNode = orthographicNode->GetChild( "ymag" );
1347 ReadFloat( tempNode, cameraInfo.orthographic.ymag );
1350 tempNode = orthographicNode->GetChild( "zfar" );
1353 ReadFloat( tempNode, cameraInfo.orthographic.zfar );
1356 tempNode = orthographicNode->GetChild( "znear" );
1359 ReadFloat( tempNode, cameraInfo.orthographic.znear );
1365 bool Loader::LoadPerspective( const TreeNode& camera, CameraInfo& cameraInfo )
1367 const TreeNode* perspectiveNode = camera.GetChild( "perspective" );
1368 if( !perspectiveNode )
1373 const TreeNode* tempNode;
1374 tempNode = perspectiveNode->GetChild( "aspectRatio" );
1377 ReadFloat( tempNode, cameraInfo.perspective.aspectRatio );
1380 tempNode = perspectiveNode->GetChild( "yfov" );
1383 ReadFloat( tempNode, cameraInfo.perspective.yfov );
1386 tempNode = perspectiveNode->GetChild( "zfar" );
1389 ReadFloat( tempNode, cameraInfo.perspective.zfar );
1392 tempNode = perspectiveNode->GetChild( "znear" );
1395 ReadFloat( tempNode, cameraInfo.perspective.znear );
1401 bool Loader::LoadSceneNodes( Scene3dView& scene3dView )
1403 const TreeNode* sceneNode = mRoot->GetChild( "scene" );
1404 uint32_t sceneNum = 0;
1407 sceneNum = sceneNode->GetInteger();
1410 const TreeNode* scenesNode = mRoot->GetChild( "scenes" );
1411 if( !( scenesNode && ( mNodes = mRoot->GetChild( "nodes" ) ) ) )
1416 const TreeNode* tempNode = Tidx( scenesNode, sceneNum );
1422 tempNode = tempNode->GetChild( "nodes" );
1428 for( auto nodeIter = tempNode->CBegin(), end = tempNode->CEnd(); nodeIter != end; ++nodeIter )
1430 Actor actor = AddNode( scene3dView, ( ( *nodeIter ).second ).GetInteger() );
1431 actor.SetParentOrigin( ParentOrigin::CENTER );
1432 scene3dView.GetRoot().Add( actor );
1438 Actor Loader::AddNode( Scene3dView& scene3dView, uint32_t index )
1440 const TreeNode* node = Tidx( mNodes, index );
1441 Actor actor = Actor::New();
1442 Vector3 actorSize( Vector3::ONE );
1444 Vector3 translation = Vector3( 0.0, 0.0, 0.0 );
1445 Vector3 scale = Vector3( 1.0, 1.0, 1.0 );
1446 Quaternion orientation( Vector4( 0.0, 0.0, 0.0, 1.0 ) );
1448 Vector3 anchorPoint = AnchorPoint::CENTER;
1450 const TreeNode* tempNode = NULL;
1451 if( ( tempNode = node->GetChild( "translation" ) ) )
1453 float floatVec[3] = { 0.0, 0.0, 0.0 };
1454 if( tempNode && ReadVector( tempNode, floatVec, 3 ) )
1456 translation = Vector3( floatVec[0], floatVec[1], floatVec[2] );
1460 if( ( tempNode = node->GetChild( "scale" ) ) )
1462 float floatVec[3] = { 1.0, 1.0, 1.0 };
1463 if( tempNode && ReadVector( tempNode, floatVec, 3 ) )
1465 scale = Vector3( floatVec[0], floatVec[1], floatVec[2] );
1469 if( ( tempNode = node->GetChild( "rotation" ) ) )
1471 float floatVec[4] = { 0.0, 0.0, 0.0, 1.0 };
1472 if( tempNode && ReadVector( tempNode, floatVec, 4 ) )
1474 orientation = Quaternion( Vector4( floatVec[0], floatVec[1], floatVec[2], floatVec[3] ) );
1478 if( ( tempNode = node->GetChild( "matrix" ) ) )
1480 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 };
1481 if( tempNode && ReadVector( tempNode, floatVec, 16 ) )
1483 Matrix nodeMatrix = Matrix( floatVec );
1484 nodeMatrix.GetTransformComponents( translation, orientation, scale );
1488 if( ( tempNode = node->GetChild( "mesh" ) ) )
1490 MeshInfo meshInfo = mMeshArray[tempNode->GetInteger()];
1491 bool isMaterial = ( meshInfo.materialsIdx >= 0 );
1493 TextureSet textureSet;
1494 textureSet = TextureSet::New();
1497 int32_t shaderTypeIndex = 0;
1498 int32_t maxMipmapLevel = 0;
1499 bool isBaseColorTexture = false;
1500 bool isMetallicRoughnessTexture = false;
1501 bool isNormalTexture = false;
1502 bool isOcclusionTexture = false;
1503 bool isEmissiveTexture = false;
1505 std::string VERTEX_SHADER, FRAGMENT_SHADER;
1506 VERTEX_SHADER = GLES_VERSION_300;
1507 VERTEX_SHADER += PHYSICALLY_BASED_VERTEX_SHADER;
1508 FRAGMENT_SHADER = GLES_VERSION_300;
1510 bool useIBL = ( scene3dView.GetLightType() >= Toolkit::Scene3dView::LightType::IMAGE_BASED_LIGHT );
1513 MaterialInfo materialInfo = mMaterialArray[meshInfo.materialsIdx];
1514 if( SetTextureAndSampler( textureSet, materialInfo.baseColorTexture.index, FRAGMENT_SHADER, DEFINE_BASECOLOR_TEXTURE, addIdx ) )
1516 shaderTypeIndex += static_cast<int32_t>( ShaderType::BASECOLOR_SHADER );
1517 isBaseColorTexture = true;
1519 if( SetTextureAndSampler( textureSet, materialInfo.metallicRoughnessTexture.index, FRAGMENT_SHADER, DEFINE_METALLICROUGHNESS_TEXTURE, addIdx ) )
1521 shaderTypeIndex += static_cast<int32_t>( ShaderType::METALLICROUGHNESS_SHADER );
1522 isMetallicRoughnessTexture = true;
1524 if( SetTextureAndSampler( textureSet, materialInfo.normalTexture.index, FRAGMENT_SHADER, DEFINE_NORMAL_TEXTURE, addIdx ) )
1526 shaderTypeIndex += static_cast<int32_t>( ShaderType::NORMAL_SHADER );
1527 isNormalTexture = true;
1529 if( SetTextureAndSampler( textureSet, materialInfo.occlusionTexture.index, FRAGMENT_SHADER, DEFINE_OCCLUSION_TEXTURE, addIdx ) )
1531 shaderTypeIndex += static_cast<int32_t>( ShaderType::OCCLUSION_SHADER );
1532 isOcclusionTexture = true;
1534 if( SetTextureAndSampler( textureSet, materialInfo.emissiveTexture.index, FRAGMENT_SHADER, DEFINE_EMIT_TEXTURE, addIdx ) )
1536 shaderTypeIndex += static_cast<int32_t>( ShaderType::EMIT_SHADER );
1537 isEmissiveTexture = true;
1542 shaderTypeIndex += static_cast<int32_t>( ShaderType::IBL_SHADER );
1543 FRAGMENT_SHADER += DEFINE_IBL_TEXTURE;
1545 Sampler sampler = Sampler::New();
1546 sampler.SetFilterMode( FilterMode::DEFAULT, FilterMode::DEFAULT );
1547 sampler.SetWrapMode( WrapMode::REPEAT, WrapMode::REPEAT, WrapMode::REPEAT );
1549 textureSet.SetTexture( addIdx, scene3dView.GetBRDFTexture() );
1550 textureSet.SetSampler( addIdx++, sampler );
1551 Sampler samplerIBL = Sampler::New();
1552 samplerIBL.SetFilterMode( FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR );
1553 samplerIBL.SetWrapMode( WrapMode::CLAMP_TO_EDGE, WrapMode::CLAMP_TO_EDGE, WrapMode::CLAMP_TO_EDGE );
1554 textureSet.SetTexture( addIdx, scene3dView.GetDiffuseTexture() );
1555 textureSet.SetSampler( addIdx++, samplerIBL );
1556 Texture specularTexture = scene3dView.GetSpecularTexture();
1557 textureSet.SetTexture( addIdx, specularTexture );
1558 textureSet.SetSampler( addIdx++, samplerIBL );
1560 int32_t textureSize = std::min( specularTexture.GetWidth(), specularTexture.GetHeight() );
1562 while( textureSize >= 1 )
1570 FRAGMENT_SHADER += PHYSICALLY_BASED_FRAGMENT_SHADER;
1571 if( !mShaderCache[shaderTypeIndex] )
1573 mShaderCache[shaderTypeIndex] = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
1574 scene3dView.AddShader( mShaderCache[shaderTypeIndex] );
1576 Shader shader = mShaderCache[shaderTypeIndex];
1578 Renderer renderer = Renderer::New( meshInfo.geometry, shader );
1579 renderer.SetProperty( Renderer::Property::DEPTH_WRITE_MODE, DepthWriteMode::ON );
1580 renderer.SetProperty( Renderer::Property::DEPTH_TEST_MODE, DepthTestMode::ON );
1581 renderer.SetTextures( textureSet );
1583 anchorPoint = meshInfo.pivot;
1584 actor.SetAnchorPoint( anchorPoint );
1586 actor.SetSize( Vector3( meshInfo.size.x, meshInfo.size.y, meshInfo.size.z ) );
1587 actor.AddRenderer( renderer );
1589 actor.SetScale( scale );
1590 actor.RotateBy( orientation );
1591 actor.SetPosition( translation );
1593 shader.RegisterProperty( "uLightType", ( scene3dView.GetLightType() & ~Toolkit::Scene3dView::LightType::IMAGE_BASED_LIGHT ) );
1594 shader.RegisterProperty( "uLightVector", scene3dView.GetLightVector() );
1595 shader.RegisterProperty( "uLightColor", scene3dView.GetLightColor() );
1597 actor.RegisterProperty( "uIsColor", meshInfo.attribute.COLOR.size() > 0 );
1600 MaterialInfo materialInfo = mMaterialArray[meshInfo.materialsIdx];
1601 actor.RegisterProperty( "uBaseColorFactor", materialInfo.baseColorFactor );
1602 actor.RegisterProperty( "uMetallicRoughnessFactors", Vector2( materialInfo.metallicFactor, materialInfo.roughnessFactor ) );
1604 if( materialInfo.alphaMode == "OPAQUE" )
1606 actor.RegisterProperty( "alphaMode", 0 );
1608 else if( materialInfo.alphaMode == "MASK" )
1610 actor.RegisterProperty( "alphaMode", 1 );
1614 actor.RegisterProperty( "alphaMode", 2 );
1616 actor.RegisterProperty( "alphaCutoff", materialInfo.alphaCutoff );
1618 if( isBaseColorTexture )
1620 actor.RegisterProperty( "uBaseColorTexCoordIndex", materialInfo.baseColorTexture.texCoord );
1622 if( isMetallicRoughnessTexture )
1624 actor.RegisterProperty( "uMetallicRoughnessTexCoordIndex", materialInfo.metallicRoughnessTexture.texCoord );
1626 if( isNormalTexture )
1628 actor.RegisterProperty( "uNormalScale", materialInfo.normalTexture.value );
1629 actor.RegisterProperty( "uNormalTexCoordIndex", materialInfo.normalTexture.texCoord );
1631 if( isOcclusionTexture )
1633 actor.RegisterProperty( "uOcclusionTexCoordIndex", materialInfo.occlusionTexture.texCoord );
1634 actor.RegisterProperty( "uOcclusionStrength", materialInfo.occlusionTexture.value );
1636 if( isEmissiveTexture )
1638 actor.RegisterProperty( "uEmissiveTexCoordIndex", materialInfo.emissiveTexture.texCoord );
1639 actor.RegisterProperty( "uEmissiveFactor", materialInfo.emissiveFactor );
1643 if( isMaterial && useIBL )
1645 actor.RegisterProperty( "uScaleIBLAmbient", scene3dView.GetIBLScaleFactor() );
1646 actor.RegisterProperty( "uMipmapLevel", static_cast<float>( maxMipmapLevel ) );
1651 actor.SetAnchorPoint( AnchorPoint::CENTER );
1652 actor.SetPosition( translation );
1653 actor.RotateBy( orientation );
1654 actor.SetSize( actorSize );
1657 tempNode = node->GetChild( "camera" );
1660 int32_t cameraNum = tempNode->GetInteger();
1661 CameraActor cameraActor = scene3dView.GetCamera( cameraNum );
1664 actor.Add( cameraActor );
1668 tempNode = node->GetChild( "name" );
1671 std::string nameString;
1672 ReadString( tempNode, nameString );
1673 actor.SetName( nameString );
1676 SetActorCache( actor, index );
1677 if( ( tempNode = node->GetChild( "children" ) ) )
1679 for( auto childIter = tempNode->CBegin(), end = tempNode->CEnd(); childIter != end; ++childIter )
1681 Actor childActor = AddNode( scene3dView, ( ( *childIter ).second ).GetInteger() );
1682 childActor.SetParentOrigin( anchorPoint );
1683 actor.Add( childActor );
1690 void Loader::SetActorCache( Actor& actor, uint32_t index )
1692 if( mActorCache.size() < index + 1 )
1694 mActorCache.resize( index + 1 );
1696 mActorCache[index] = actor;
1699 bool Loader::SetTextureAndSampler( TextureSet& textureSet, int32_t textureIdx, std::string& toShader, std::string shader, int32_t& addIdx )
1701 if( textureIdx >= 0 )
1704 TextureInfo textureInfo = mTextureArray[textureIdx];
1705 if( textureInfo.sourceIdx >= 0 )
1707 textureSet.SetTexture( addIdx, mSourceArray[textureInfo.sourceIdx] );
1709 if( textureInfo.samplerIdx >= 0 )
1711 textureSet.SetSampler( addIdx, mSamplerArray[textureInfo.samplerIdx] );
1715 Sampler sampler = Sampler::New();
1716 sampler.SetFilterMode( FilterMode::DEFAULT, FilterMode::DEFAULT );
1717 sampler.SetWrapMode( WrapMode::REPEAT, WrapMode::REPEAT, WrapMode::REPEAT );
1718 textureSet.SetSampler( addIdx, sampler );
1726 bool Loader::LoadAnimation( Scene3dView& scene3dView )
1728 const TreeNode* animationsNode = mRoot->GetChild( "animations" );
1729 if( !animationsNode )
1734 for( auto animationIter = animationsNode->CBegin(), end = animationsNode->CEnd(); animationIter != end; ++animationIter )
1736 const TreeNode* nameNode = ( &( *animationIter ).second )->GetChild( "name" );
1737 AnimationInfo animationInfo;
1740 ReadString( nameNode, animationInfo.name );
1743 Property::Index propIndex = Property::INVALID_INDEX;
1744 LoadAnimationChannels( ( *animationIter ).second, animationInfo );
1745 if( animationInfo.channelArray.size() == 0 )
1750 LoadAnimationSamplers( ( *animationIter ).second, animationInfo );
1752 for( auto&& currentChannel : animationInfo.channelArray )
1754 if( currentChannel.path == "rotation" )
1756 propIndex = Dali::Actor::Property::ORIENTATION;
1758 else if( currentChannel.path == "translation" )
1760 propIndex = Dali::Actor::Property::POSITION;
1762 else if( currentChannel.path == "scale" )
1764 propIndex = Dali::Actor::Property::SCALE;
1767 float duration = 0.0f;
1768 KeyFrames keyframes = KeyFrames::New();
1769 if( propIndex == Dali::Actor::Property::ORIENTATION )
1771 duration = LoadKeyFrames<Vector4>( animationInfo.samplerArray[currentChannel.sampler], propIndex, keyframes, mPath, mAccessorArray, mBufferViewArray, mBufferArray );
1775 duration = LoadKeyFrames<Vector3>( animationInfo.samplerArray[currentChannel.sampler], propIndex, keyframes, mPath, mAccessorArray, mBufferViewArray, mBufferArray );
1778 Animation animation = Animation::New( duration );
1779 Animation::Interpolation interpolation = Animation::Interpolation::Linear;
1780 if( animationInfo.samplerArray[currentChannel.sampler].interpolation == "CUBICSPLINE" )
1782 interpolation = Animation::Interpolation::Cubic;
1784 if( animationInfo.samplerArray[currentChannel.sampler].interpolation == "STEP" )
1788 animation.AnimateBetween( Property( mActorCache[currentChannel.targetNode], propIndex ), keyframes, interpolation );
1790 animation.SetLooping( false );
1791 scene3dView.AddAnimation( animation );
1798 bool Loader::LoadAnimationChannels( const TreeNode& animation, AnimationInfo& animationInfo )
1800 const TreeNode* channelsNode = animation.GetChild( "channels" );
1806 for( auto channelIter = channelsNode->CBegin(), end = channelsNode->CEnd(); channelIter != end; ++channelIter )
1808 AnimationChannelInfo animationChannelInfo;
1809 const TreeNode* channelNode = ( &( *channelIter ).second );
1810 const TreeNode* samplerNode = channelNode->GetChild( "sampler" );
1813 animationChannelInfo.sampler = samplerNode->GetInteger();
1816 const TreeNode* targetNode = channelNode->GetChild( "target" );
1819 const TreeNode* tempNode = targetNode->GetChild( "node" );
1822 animationChannelInfo.targetNode = tempNode->GetInteger();
1829 tempNode = targetNode->GetChild( "path" );
1832 ReadString( tempNode, animationChannelInfo.path );
1836 animationInfo.channelArray.push_back( animationChannelInfo );
1841 bool Loader::LoadAnimationSamplers( const TreeNode& animation, AnimationInfo& animationInfo )
1843 const TreeNode* samplersNode = animation.GetChild( "samplers" );
1849 for( auto sampler = samplersNode->CBegin(), end = samplersNode->CEnd(); sampler != end; ++sampler )
1851 AnimationSamplerInfo animationSamplerInfo;
1852 const TreeNode* samplerNode = ( &( *sampler ).second );
1853 const TreeNode* tempNode = samplerNode->GetChild( "input" );
1856 animationSamplerInfo.input = tempNode->GetInteger();
1859 tempNode = samplerNode->GetChild( "output" );
1862 animationSamplerInfo.output = tempNode->GetInteger();
1865 tempNode = samplerNode->GetChild( "interpolation" );
1868 ReadString( tempNode, animationSamplerInfo.interpolation );
1871 animationInfo.samplerArray.push_back( animationSamplerInfo );
1879 }//namespace Internal
1881 }//namespace Toolkit