2 * Copyright (c) 2018 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>
24 #include <dali/integration-api/debug.h>
25 #include <dali/devel-api/adaptor-framework/image-loading.h>
26 #include <dali/devel-api/adaptor-framework/file-loader.h>
44 const TreeNode* Tidx( const TreeNode *node, uint32_t index )
47 for( auto it = node->CBegin(), end = node->CEnd(); it != end; ++it, ++i )
51 return &( ( *it ).second );
57 bool ReadBool( const TreeNode* node, bool& num )
63 bool returnValue = false;
65 if( node->GetType() == TreeNode::BOOLEAN )
67 num = node->GetBoolean();
74 bool ReadInt( const TreeNode* node, int32_t& num )
80 bool returnValue = false;
81 if( node->GetType() == TreeNode::INTEGER )
83 num = node->GetInteger();
86 else if( node->GetType() == TreeNode::FLOAT )
88 num = node->GetFloat();
95 bool ReadFloat( const TreeNode* node, float& num )
101 bool returnValue = false;
103 if( node->GetType() == TreeNode::FLOAT )
105 num = node->GetFloat();
108 else if( node->GetType() == TreeNode::INTEGER )
111 ReadInt( node, tempNum );
112 num = static_cast<float>( tempNum );
119 bool ReadVector( const TreeNode* node, float* num, uint32_t size )
125 bool returnValue = false;
127 if( ( node->Size() >= size ) && ( node->GetType() == TreeNode::ARRAY ) )
129 uint32_t offset = 0u;
130 for( auto it = node->CBegin(); offset < size; ++it, ++offset )
132 const TreeNode& coord = ( *it ).second;
133 if( !ReadFloat( &coord, *( num + offset ) ) )
144 bool ReadString( const TreeNode* node, std::string& strValue )
150 bool returnValue = false;
151 if( node->GetType() == TreeNode::STRING )
153 strValue = node->GetString();
159 template <typename T>
160 float IntToFloat( T element, bool normalize )
164 return static_cast<float>( element );
167 if( std::is_same<T, int8_t>::value )
169 return std::max( static_cast<float>( element ) / 127.0, -1.0 );
171 if( std::is_same<T, uint8_t>::value )
173 return static_cast<float>( element ) / 255.0;
175 if( std::is_same<T, int16_t>::value )
177 return std::max( static_cast<float>( element ) / 32767.0, -1.0 );
179 if( std::is_same<T, uint16_t>::value )
181 return static_cast<float>( element ) / 65535.0;
186 template <typename Td, typename Ts>
187 void FitBuffer( Dali::Vector<Td>& bufferDestination, Dali::Vector<Ts>& bufferSource, int32_t bufferSize, int32_t elementNumOfByteStride, bool normalize )
189 bufferDestination.Resize( bufferSize );
190 int32_t count = bufferSource.Size() / elementNumOfByteStride;
191 for( int32_t i = 0; i<count; ++i )
193 bufferDestination[i] = static_cast<Td>( bufferSource[i * elementNumOfByteStride] );
197 template <typename T>
198 void FitBuffer( Dali::Vector<Vector2>& bufferDestination, Dali::Vector<T>& bufferSource, int32_t bufferSize, int32_t elementNumOfByteStride, bool normalize )
200 bufferDestination.Resize( bufferSize );
201 int32_t count = bufferSource.Size() / elementNumOfByteStride;
202 for( int32_t i = 0; i<count; ++i )
204 bufferDestination[i].x = IntToFloat( bufferSource[i * elementNumOfByteStride], normalize );
205 bufferDestination[i].y = IntToFloat( bufferSource[i * elementNumOfByteStride + 1], normalize );
209 template <typename T>
210 void FitBuffer( Dali::Vector<Vector3>& bufferDestination, Dali::Vector<T>& bufferSource, int32_t bufferSize, int32_t elementNumOfByteStride, bool normalize )
212 bufferDestination.Resize( bufferSize );
213 int32_t count = bufferSource.Size() / elementNumOfByteStride;
214 for( int32_t i = 0; i<count; ++i )
216 bufferDestination[i].x = IntToFloat( bufferSource[i * elementNumOfByteStride], normalize );
217 bufferDestination[i].y = IntToFloat( bufferSource[i * elementNumOfByteStride + 1], normalize );
218 bufferDestination[i].z = IntToFloat( bufferSource[i * elementNumOfByteStride + 2], normalize );
222 template <typename T>
223 void FitBuffer( Dali::Vector<Vector4>& bufferDestination, Dali::Vector<T>& bufferSource, int32_t bufferSize, int32_t elementNumOfByteStride, bool normalize )
225 bufferDestination.Resize( bufferSize );
226 int32_t count = bufferSource.Size() / elementNumOfByteStride;
227 for( int32_t i = 0; i<count; ++i )
229 bufferDestination[i].x = IntToFloat( bufferSource[i * elementNumOfByteStride], normalize );
230 bufferDestination[i].y = IntToFloat( bufferSource[i * elementNumOfByteStride + 1], normalize );
231 bufferDestination[i].z = IntToFloat( bufferSource[i * elementNumOfByteStride + 2], normalize );
232 bufferDestination[i].w = IntToFloat( bufferSource[i * elementNumOfByteStride + 3], normalize );
236 // Template functions
237 template <typename T>
238 bool ReadBinFile( Vector<T> &dataBuffer, std::string url, int32_t offset, int32_t count )
240 dataBuffer.Resize( count );
241 FILE* fp = fopen( url.c_str(), "rb" );
247 if( !fseek( fp, offset, SEEK_SET ) )
249 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::ifstream fileStream( filePath.c_str() );
1232 std::string fileBuffer( ( std::istreambuf_iterator<char>( fileStream ) ),
1233 ( std::istreambuf_iterator<char>() ) );
1234 mParser = Dali::Toolkit::JsonParser::New();
1236 return mParser.Parse( fileBuffer );
1239 bool Loader::LoadAssets()
1241 if( LoadBinaryData( *mRoot, mBufferArray, mBufferViewArray, mAccessorArray ) &&
1242 LoadTextureArray( *mRoot, mPath, mSourceArray, mSamplerArray, mTextureArray ) &&
1243 LoadMaterialSetArray( *mRoot, mMaterialArray ) &&
1244 LoadMeshArray( *mRoot, mPath, mMeshArray, mBufferArray, mBufferViewArray, mAccessorArray )
1252 bool Loader::CreateScene( Internal::Scene3dView& scene3dView )
1254 scene3dView.SetDefaultCamera( Dali::Camera::LOOK_AT_TARGET, 0.01, Vector3::ZERO );
1255 LoadCamera( scene3dView );
1257 if( LoadSceneNodes( scene3dView ) &&
1258 LoadAnimation( scene3dView ) )
1265 void Loader::LoadCamera( Scene3dView& scene3dView )
1267 const TreeNode* camerasNode = mRoot->GetChild( "cameras" );
1273 for( auto cameraIter = camerasNode->CBegin(), end = camerasNode->CEnd(); cameraIter != end; ++cameraIter )
1275 const TreeNode* tempNode = ( &( *cameraIter ).second )->GetChild( "name" );
1276 CameraInfo cameraInfo;
1279 ReadString( tempNode, cameraInfo.name );
1282 tempNode = ( &( *cameraIter ).second )->GetChild( "type" );
1285 ReadString( tempNode, cameraInfo.type );
1288 CameraActor cameraActor = CameraActor::New();
1289 cameraActor.SetParentOrigin( ParentOrigin::CENTER );
1290 cameraActor.SetAnchorPoint( AnchorPoint::CENTER );
1292 if( cameraInfo.type == "orthographic" )
1294 LoadOrthoGraphic( ( *cameraIter ).second, cameraInfo );
1295 float xMag_2 = cameraInfo.orthographic.xmag / 2.0;
1296 float yMag_2 = cameraInfo.orthographic.ymag / 2.0;
1297 cameraActor.SetOrthographicProjection( -xMag_2, xMag_2, yMag_2, -yMag_2,
1298 cameraInfo.orthographic.znear, cameraInfo.orthographic.zfar );
1300 else if( cameraInfo.type == "perspective" )
1302 if( !LoadPerspective( ( *cameraIter ).second, cameraInfo ) )
1306 cameraActor.SetProjectionMode( Dali::Camera::PERSPECTIVE_PROJECTION );
1307 cameraActor.SetFieldOfView( cameraInfo.perspective.yfov );
1308 cameraActor.SetNearClippingPlane( cameraInfo.perspective.znear );
1310 if( cameraInfo.perspective.zfar > 0.0 )
1312 cameraActor.SetFarClippingPlane( cameraInfo.perspective.zfar );
1314 if( cameraInfo.perspective.aspectRatio > 0.0 )
1316 cameraActor.SetAspectRatio( cameraInfo.perspective.aspectRatio );
1320 scene3dView.AddCamera( cameraActor );
1324 bool Loader::LoadOrthoGraphic( const TreeNode& camera, CameraInfo& cameraInfo )
1326 const TreeNode* orthographicNode = camera.GetChild( "orthographic" );
1327 if( !orthographicNode )
1332 const TreeNode* tempNode;
1333 tempNode = orthographicNode->GetChild( "xmag" );
1336 ReadFloat( tempNode, cameraInfo.orthographic.xmag );
1339 tempNode = orthographicNode->GetChild( "ymag" );
1342 ReadFloat( tempNode, cameraInfo.orthographic.ymag );
1345 tempNode = orthographicNode->GetChild( "zfar" );
1348 ReadFloat( tempNode, cameraInfo.orthographic.zfar );
1351 tempNode = orthographicNode->GetChild( "znear" );
1354 ReadFloat( tempNode, cameraInfo.orthographic.znear );
1360 bool Loader::LoadPerspective( const TreeNode& camera, CameraInfo& cameraInfo )
1362 const TreeNode* perspectiveNode = camera.GetChild( "perspective" );
1363 if( !perspectiveNode )
1368 const TreeNode* tempNode;
1369 tempNode = perspectiveNode->GetChild( "aspectRatio" );
1372 ReadFloat( tempNode, cameraInfo.perspective.aspectRatio );
1375 tempNode = perspectiveNode->GetChild( "yfov" );
1378 ReadFloat( tempNode, cameraInfo.perspective.yfov );
1381 tempNode = perspectiveNode->GetChild( "zfar" );
1384 ReadFloat( tempNode, cameraInfo.perspective.zfar );
1387 tempNode = perspectiveNode->GetChild( "znear" );
1390 ReadFloat( tempNode, cameraInfo.perspective.znear );
1396 bool Loader::LoadSceneNodes( Scene3dView& scene3dView )
1398 const TreeNode* sceneNode = mRoot->GetChild( "scene" );
1399 uint32_t sceneNum = 0;
1402 sceneNum = sceneNode->GetInteger();
1405 const TreeNode* scenesNode = mRoot->GetChild( "scenes" );
1406 if( !( scenesNode && ( mNodes = mRoot->GetChild( "nodes" ) ) ) )
1411 const TreeNode* tempNode = Tidx( scenesNode, sceneNum );
1417 tempNode = tempNode->GetChild( "nodes" );
1423 for( auto nodeIter = tempNode->CBegin(), end = tempNode->CEnd(); nodeIter != end; ++nodeIter )
1425 Actor actor = AddNode( scene3dView, ( ( *nodeIter ).second ).GetInteger() );
1426 actor.SetParentOrigin( ParentOrigin::CENTER );
1427 scene3dView.GetRoot().Add( actor );
1433 Actor Loader::AddNode( Scene3dView& scene3dView, uint32_t index )
1435 const TreeNode* node = Tidx( mNodes, index );
1436 Actor actor = Actor::New();
1437 Vector3 actorSize( Vector3::ONE );
1439 Vector3 translation = Vector3( 0.0, 0.0, 0.0 );
1440 Vector3 scale = Vector3( 1.0, 1.0, 1.0 );
1441 Quaternion orientation( Vector4( 0.0, 0.0, 0.0, 1.0 ) );
1443 Vector3 anchorPoint = AnchorPoint::CENTER;
1445 const TreeNode* tempNode = NULL;
1446 if( ( tempNode = node->GetChild( "translation" ) ) )
1448 float floatVec[3] = { 0.0, 0.0, 0.0 };
1449 if( tempNode && ReadVector( tempNode, floatVec, 3 ) )
1451 translation = Vector3( floatVec[0], floatVec[1], floatVec[2] );
1455 if( ( tempNode = node->GetChild( "scale" ) ) )
1457 float floatVec[3] = { 1.0, 1.0, 1.0 };
1458 if( tempNode && ReadVector( tempNode, floatVec, 3 ) )
1460 scale = Vector3( floatVec[0], floatVec[1], floatVec[2] );
1464 if( ( tempNode = node->GetChild( "rotation" ) ) )
1466 float floatVec[4] = { 0.0, 0.0, 0.0, 1.0 };
1467 if( tempNode && ReadVector( tempNode, floatVec, 4 ) )
1469 orientation = Quaternion( Vector4( floatVec[0], floatVec[1], floatVec[2], floatVec[3] ) );
1473 if( ( tempNode = node->GetChild( "matrix" ) ) )
1475 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 };
1476 if( tempNode && ReadVector( tempNode, floatVec, 16 ) )
1478 Matrix nodeMatrix = Matrix( floatVec );
1479 nodeMatrix.GetTransformComponents( translation, orientation, scale );
1483 if( ( tempNode = node->GetChild( "mesh" ) ) )
1485 MeshInfo meshInfo = mMeshArray[tempNode->GetInteger()];
1486 bool isMaterial = ( meshInfo.materialsIdx >= 0 );
1488 TextureSet textureSet;
1489 textureSet = TextureSet::New();
1492 int32_t shaderTypeIndex = 0;
1493 int32_t maxMipmapLevel = 0;
1494 bool isBaseColorTexture = false;
1495 bool isMetallicRoughnessTexture = false;
1496 bool isNormalTexture = false;
1497 bool isOcclusionTexture = false;
1498 bool isEmissiveTexture = false;
1500 std::string VERTEX_SHADER, FRAGMENT_SHADER;
1501 VERTEX_SHADER = GLES_VERSION_300;
1502 VERTEX_SHADER += PHYSICALLY_BASED_VERTEX_SHADER;
1503 FRAGMENT_SHADER = GLES_VERSION_300;
1505 bool useIBL = ( scene3dView.GetLightType() >= Toolkit::Scene3dView::LightType::IMAGE_BASED_LIGHT );
1508 MaterialInfo materialInfo = mMaterialArray[meshInfo.materialsIdx];
1509 if( SetTextureAndSampler( textureSet, materialInfo.baseColorTexture.index, FRAGMENT_SHADER, DEFINE_BASECOLOR_TEXTURE, addIdx ) )
1511 shaderTypeIndex += static_cast<int32_t>( ShaderType::BASECOLOR_SHADER );
1512 isBaseColorTexture = true;
1514 if( SetTextureAndSampler( textureSet, materialInfo.metallicRoughnessTexture.index, FRAGMENT_SHADER, DEFINE_METALLICROUGHNESS_TEXTURE, addIdx ) )
1516 shaderTypeIndex += static_cast<int32_t>( ShaderType::METALLICROUGHNESS_SHADER );
1517 isMetallicRoughnessTexture = true;
1519 if( SetTextureAndSampler( textureSet, materialInfo.normalTexture.index, FRAGMENT_SHADER, DEFINE_NORMAL_TEXTURE, addIdx ) )
1521 shaderTypeIndex += static_cast<int32_t>( ShaderType::NORMAL_SHADER );
1522 isNormalTexture = true;
1524 if( SetTextureAndSampler( textureSet, materialInfo.occlusionTexture.index, FRAGMENT_SHADER, DEFINE_OCCLUSION_TEXTURE, addIdx ) )
1526 shaderTypeIndex += static_cast<int32_t>( ShaderType::OCCLUSION_SHADER );
1527 isOcclusionTexture = true;
1529 if( SetTextureAndSampler( textureSet, materialInfo.emissiveTexture.index, FRAGMENT_SHADER, DEFINE_EMIT_TEXTURE, addIdx ) )
1531 shaderTypeIndex += static_cast<int32_t>( ShaderType::EMIT_SHADER );
1532 isEmissiveTexture = true;
1537 shaderTypeIndex += static_cast<int32_t>( ShaderType::IBL_SHADER );
1538 FRAGMENT_SHADER += DEFINE_IBL_TEXTURE;
1540 Sampler sampler = Sampler::New();
1541 sampler.SetFilterMode( FilterMode::DEFAULT, FilterMode::DEFAULT );
1542 sampler.SetWrapMode( WrapMode::REPEAT, WrapMode::REPEAT, WrapMode::REPEAT );
1544 textureSet.SetTexture( addIdx, scene3dView.GetBRDFTexture() );
1545 textureSet.SetSampler( addIdx++, sampler );
1546 Sampler samplerIBL = Sampler::New();
1547 samplerIBL.SetFilterMode( FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR );
1548 samplerIBL.SetWrapMode( WrapMode::CLAMP_TO_EDGE, WrapMode::CLAMP_TO_EDGE, WrapMode::CLAMP_TO_EDGE );
1549 textureSet.SetTexture( addIdx, scene3dView.GetDiffuseTexture() );
1550 textureSet.SetSampler( addIdx++, samplerIBL );
1551 Texture specularTexture = scene3dView.GetSpecularTexture();
1552 textureSet.SetTexture( addIdx, specularTexture );
1553 textureSet.SetSampler( addIdx++, samplerIBL );
1555 int32_t textureSize = std::min( specularTexture.GetWidth(), specularTexture.GetHeight() );
1557 while( textureSize >= 1 )
1565 FRAGMENT_SHADER += PHYSICALLY_BASED_FRAGMENT_SHADER;
1566 if( !mShaderCache[shaderTypeIndex] )
1568 mShaderCache[shaderTypeIndex] = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
1569 scene3dView.AddShader( mShaderCache[shaderTypeIndex] );
1571 Shader shader = mShaderCache[shaderTypeIndex];
1573 Renderer renderer = Renderer::New( meshInfo.geometry, shader );
1574 renderer.SetProperty( Renderer::Property::DEPTH_WRITE_MODE, DepthWriteMode::ON );
1575 renderer.SetProperty( Renderer::Property::DEPTH_TEST_MODE, DepthTestMode::ON );
1576 renderer.SetTextures( textureSet );
1578 anchorPoint = meshInfo.pivot;
1579 actor.SetAnchorPoint( anchorPoint );
1581 actor.SetSize( Vector3( meshInfo.size.x, meshInfo.size.y, meshInfo.size.z ) );
1582 actor.AddRenderer( renderer );
1584 actor.SetScale( scale );
1585 actor.RotateBy( orientation );
1586 actor.SetPosition( translation );
1588 shader.RegisterProperty( "uLightType", ( scene3dView.GetLightType() & ~Toolkit::Scene3dView::LightType::IMAGE_BASED_LIGHT ) );
1589 shader.RegisterProperty( "uLightVector", scene3dView.GetLightVector() );
1590 shader.RegisterProperty( "uLightColor", scene3dView.GetLightColor() );
1592 actor.RegisterProperty( "uIsColor", meshInfo.attribute.COLOR.size() > 0 );
1595 MaterialInfo materialInfo = mMaterialArray[meshInfo.materialsIdx];
1596 actor.RegisterProperty( "uBaseColorFactor", materialInfo.baseColorFactor );
1597 actor.RegisterProperty( "uMetallicRoughnessFactors", Vector2( materialInfo.metallicFactor, materialInfo.roughnessFactor ) );
1599 if( materialInfo.alphaMode == "OPAQUE" )
1601 actor.RegisterProperty( "alphaMode", 0 );
1603 else if( materialInfo.alphaMode == "MASK" )
1605 actor.RegisterProperty( "alphaMode", 1 );
1609 actor.RegisterProperty( "alphaMode", 2 );
1611 actor.RegisterProperty( "alphaCutoff", materialInfo.alphaCutoff );
1613 if( isBaseColorTexture )
1615 actor.RegisterProperty( "uBaseColorTexCoordIndex", materialInfo.baseColorTexture.texCoord );
1617 if( isMetallicRoughnessTexture )
1619 actor.RegisterProperty( "uMetallicRoughnessTexCoordIndex", materialInfo.metallicRoughnessTexture.texCoord );
1621 if( isNormalTexture )
1623 actor.RegisterProperty( "uNormalScale", materialInfo.normalTexture.value );
1624 actor.RegisterProperty( "uNormalTexCoordIndex", materialInfo.normalTexture.texCoord );
1626 if( isOcclusionTexture )
1628 actor.RegisterProperty( "uOcclusionTexCoordIndex", materialInfo.occlusionTexture.texCoord );
1629 actor.RegisterProperty( "uOcclusionStrength", materialInfo.occlusionTexture.value );
1631 if( isEmissiveTexture )
1633 actor.RegisterProperty( "uEmissiveTexCoordIndex", materialInfo.emissiveTexture.texCoord );
1634 actor.RegisterProperty( "uEmissiveFactor", materialInfo.emissiveFactor );
1638 if( isMaterial && useIBL )
1640 actor.RegisterProperty( "uScaleIBLAmbient", scene3dView.GetIBLScaleFactor() );
1641 actor.RegisterProperty( "uMipmapLevel", static_cast<float>( maxMipmapLevel ) );
1646 actor.SetAnchorPoint( AnchorPoint::CENTER );
1647 actor.SetPosition( translation );
1648 actor.RotateBy( orientation );
1649 actor.SetSize( actorSize );
1652 tempNode = node->GetChild( "camera" );
1655 int32_t cameraNum = tempNode->GetInteger();
1656 CameraActor cameraActor = scene3dView.GetCamera( cameraNum );
1659 actor.Add( cameraActor );
1663 tempNode = node->GetChild( "name" );
1666 std::string nameString;
1667 ReadString( tempNode, nameString );
1668 actor.SetName( nameString );
1671 SetActorCache( actor, index );
1672 if( ( tempNode = node->GetChild( "children" ) ) )
1674 for( auto childIter = tempNode->CBegin(), end = tempNode->CEnd(); childIter != end; ++childIter )
1676 Actor childActor = AddNode( scene3dView, ( ( *childIter ).second ).GetInteger() );
1677 childActor.SetParentOrigin( anchorPoint );
1678 actor.Add( childActor );
1685 void Loader::SetActorCache( Actor& actor, uint32_t index )
1687 if( mActorCache.size() < index + 1 )
1689 mActorCache.resize( index + 1 );
1691 mActorCache[index] = actor;
1694 bool Loader::SetTextureAndSampler( TextureSet& textureSet, int32_t textureIdx, std::string& toShader, std::string shader, int32_t& addIdx )
1696 if( textureIdx >= 0 )
1699 TextureInfo textureInfo = mTextureArray[textureIdx];
1700 if( textureInfo.sourceIdx >= 0 )
1702 textureSet.SetTexture( addIdx, mSourceArray[textureInfo.sourceIdx] );
1704 if( textureInfo.samplerIdx >= 0 )
1706 textureSet.SetSampler( addIdx, mSamplerArray[textureInfo.samplerIdx] );
1710 Sampler sampler = Sampler::New();
1711 sampler.SetFilterMode( FilterMode::DEFAULT, FilterMode::DEFAULT );
1712 sampler.SetWrapMode( WrapMode::REPEAT, WrapMode::REPEAT, WrapMode::REPEAT );
1713 textureSet.SetSampler( addIdx, sampler );
1721 bool Loader::LoadAnimation( Scene3dView& scene3dView )
1723 const TreeNode* animationsNode = mRoot->GetChild( "animations" );
1724 if( !animationsNode )
1729 for( auto animationIter = animationsNode->CBegin(), end = animationsNode->CEnd(); animationIter != end; ++animationIter )
1731 const TreeNode* nameNode = ( &( *animationIter ).second )->GetChild( "name" );
1732 AnimationInfo animationInfo;
1735 ReadString( nameNode, animationInfo.name );
1738 Property::Index propIndex = Property::INVALID_INDEX;
1739 LoadAnimationChannels( ( *animationIter ).second, animationInfo );
1740 if( animationInfo.channelArray.size() == 0 )
1745 LoadAnimationSamplers( ( *animationIter ).second, animationInfo );
1747 for( auto&& currentChannel : animationInfo.channelArray )
1749 if( currentChannel.path == "rotation" )
1751 propIndex = Dali::Actor::Property::ORIENTATION;
1753 else if( currentChannel.path == "translation" )
1755 propIndex = Dali::Actor::Property::POSITION;
1757 else if( currentChannel.path == "scale" )
1759 propIndex = Dali::Actor::Property::SCALE;
1762 float duration = 0.0f;
1763 KeyFrames keyframes = KeyFrames::New();
1764 if( propIndex == Dali::Actor::Property::ORIENTATION )
1766 duration = LoadKeyFrames<Vector4>( animationInfo.samplerArray[currentChannel.sampler], propIndex, keyframes, mPath, mAccessorArray, mBufferViewArray, mBufferArray );
1770 duration = LoadKeyFrames<Vector3>( animationInfo.samplerArray[currentChannel.sampler], propIndex, keyframes, mPath, mAccessorArray, mBufferViewArray, mBufferArray );
1773 Animation animation = Animation::New( duration );
1774 Animation::Interpolation interpolation = Animation::Interpolation::Linear;
1775 if( animationInfo.samplerArray[currentChannel.sampler].interpolation == "CUBICSPLINE" )
1777 interpolation = Animation::Interpolation::Cubic;
1779 if( animationInfo.samplerArray[currentChannel.sampler].interpolation == "STEP" )
1783 animation.AnimateBetween( Property( mActorCache[currentChannel.targetNode], propIndex ), keyframes, interpolation );
1785 animation.SetLooping( false );
1786 scene3dView.AddAnimation( animation );
1793 bool Loader::LoadAnimationChannels( const TreeNode& animation, AnimationInfo& animationInfo )
1795 const TreeNode* channelsNode = animation.GetChild( "channels" );
1801 for( auto channelIter = channelsNode->CBegin(), end = channelsNode->CEnd(); channelIter != end; ++channelIter )
1803 AnimationChannelInfo animationChannelInfo;
1804 const TreeNode* channelNode = ( &( *channelIter ).second );
1805 const TreeNode* samplerNode = channelNode->GetChild( "sampler" );
1808 animationChannelInfo.sampler = samplerNode->GetInteger();
1811 const TreeNode* targetNode = channelNode->GetChild( "target" );
1814 const TreeNode* tempNode = targetNode->GetChild( "node" );
1817 animationChannelInfo.targetNode = tempNode->GetInteger();
1824 tempNode = targetNode->GetChild( "path" );
1827 ReadString( tempNode, animationChannelInfo.path );
1831 animationInfo.channelArray.push_back( animationChannelInfo );
1836 bool Loader::LoadAnimationSamplers( const TreeNode& animation, AnimationInfo& animationInfo )
1838 const TreeNode* samplersNode = animation.GetChild( "samplers" );
1844 for( auto sampler = samplersNode->CBegin(), end = samplersNode->CEnd(); sampler != end; ++sampler )
1846 AnimationSamplerInfo animationSamplerInfo;
1847 const TreeNode* samplerNode = ( &( *sampler ).second );
1848 const TreeNode* tempNode = samplerNode->GetChild( "input" );
1851 animationSamplerInfo.input = tempNode->GetInteger();
1854 tempNode = samplerNode->GetChild( "output" );
1857 animationSamplerInfo.output = tempNode->GetInteger();
1860 tempNode = samplerNode->GetChild( "interpolation" );
1863 ReadString( tempNode, animationSamplerInfo.interpolation );
1866 animationInfo.samplerArray.push_back( animationSamplerInfo );
1874 }//namespace Internal
1876 }//namespace Toolkit