2 * Copyright (c) 2021 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>
22 #include <dali-toolkit/internal/graphics/builtin-shader-extern-gen.h>
23 #include <dali/devel-api/adaptor-framework/file-stream.h>
24 #include <dali/devel-api/adaptor-framework/image-loading.h>
25 #include <dali/integration-api/debug.h>
38 const TreeNode* Tidx(const TreeNode* node, uint32_t index)
41 for(auto it = node->CBegin(), end = node->CEnd(); it != end; ++it, ++i)
45 return &((*it).second);
51 bool ReadBool(const TreeNode* node, bool& num)
57 bool returnValue = false;
59 if(node->GetType() == TreeNode::BOOLEAN)
61 num = node->GetBoolean();
68 bool ReadInt(const TreeNode* node, int32_t& num)
74 bool returnValue = false;
75 if(node->GetType() == TreeNode::INTEGER)
77 num = node->GetInteger();
80 else if(node->GetType() == TreeNode::FLOAT)
82 num = node->GetFloat();
89 bool ReadFloat(const TreeNode* node, float& num)
95 bool returnValue = false;
97 if(node->GetType() == TreeNode::FLOAT)
99 num = node->GetFloat();
102 else if(node->GetType() == TreeNode::INTEGER)
105 ReadInt(node, tempNum);
106 num = static_cast<float>(tempNum);
113 bool ReadVector(const TreeNode* node, float* num, uint32_t size)
119 bool returnValue = false;
121 if((node->Size() >= size) && (node->GetType() == TreeNode::ARRAY))
123 uint32_t offset = 0u;
124 for(auto it = node->CBegin(); offset < size; ++it, ++offset)
126 const TreeNode& coord = (*it).second;
127 if(!ReadFloat(&coord, *(num + offset)))
138 bool ReadString(const TreeNode* node, std::string& strValue)
144 bool returnValue = false;
145 if(node->GetType() == TreeNode::STRING)
147 strValue = node->GetString();
154 float IntToFloat(T element, bool normalize)
158 return static_cast<float>(element);
161 if(std::is_same<T, int8_t>::value)
163 return std::max(static_cast<float>(element) / 127.0, -1.0);
165 if(std::is_same<T, uint8_t>::value)
167 return static_cast<float>(element) / 255.0;
169 if(std::is_same<T, int16_t>::value)
171 return std::max(static_cast<float>(element) / 32767.0, -1.0);
173 if(std::is_same<T, uint16_t>::value)
175 return static_cast<float>(element) / 65535.0;
180 template<typename Td, typename Ts>
181 void FitBuffer(Dali::Vector<Td>& bufferDestination, Dali::Vector<Ts>& bufferSource, int32_t bufferSize, int32_t elementNumOfByteStride, bool normalize)
183 bufferDestination.Resize(bufferSize);
184 int32_t count = bufferSource.Size() / elementNumOfByteStride;
185 for(int32_t i = 0; i < count; ++i)
187 bufferDestination[i] = static_cast<Td>(bufferSource[i * elementNumOfByteStride]);
192 void FitBuffer(Dali::Vector<Vector2>& bufferDestination, Dali::Vector<T>& bufferSource, int32_t bufferSize, int32_t elementNumOfByteStride, bool normalize)
194 bufferDestination.Resize(bufferSize);
195 int32_t count = bufferSource.Size() / elementNumOfByteStride;
196 for(int32_t i = 0; i < count; ++i)
198 bufferDestination[i].x = IntToFloat(bufferSource[i * elementNumOfByteStride], normalize);
199 bufferDestination[i].y = IntToFloat(bufferSource[i * elementNumOfByteStride + 1], normalize);
204 void FitBuffer(Dali::Vector<Vector3>& bufferDestination, Dali::Vector<T>& bufferSource, int32_t bufferSize, int32_t elementNumOfByteStride, bool normalize)
206 bufferDestination.Resize(bufferSize);
207 int32_t count = bufferSource.Size() / elementNumOfByteStride;
208 for(int32_t i = 0; i < count; ++i)
210 bufferDestination[i].x = IntToFloat(bufferSource[i * elementNumOfByteStride], normalize);
211 bufferDestination[i].y = IntToFloat(bufferSource[i * elementNumOfByteStride + 1], normalize);
212 bufferDestination[i].z = IntToFloat(bufferSource[i * elementNumOfByteStride + 2], normalize);
217 void FitBuffer(Dali::Vector<Vector4>& bufferDestination, Dali::Vector<T>& bufferSource, int32_t bufferSize, int32_t elementNumOfByteStride, bool normalize)
219 bufferDestination.Resize(bufferSize);
220 int32_t count = bufferSource.Size() / elementNumOfByteStride;
221 for(int32_t i = 0; i < count; ++i)
223 bufferDestination[i].x = IntToFloat(bufferSource[i * elementNumOfByteStride], normalize);
224 bufferDestination[i].y = IntToFloat(bufferSource[i * elementNumOfByteStride + 1], normalize);
225 bufferDestination[i].z = IntToFloat(bufferSource[i * elementNumOfByteStride + 2], normalize);
226 bufferDestination[i].w = IntToFloat(bufferSource[i * elementNumOfByteStride + 3], normalize);
230 // Template functions
232 bool ReadBinFile(Vector<T>& dataBuffer, std::string url, int32_t offset, int32_t count)
234 Dali::FileStream fileStream(url, FileStream::READ | FileStream::BINARY);
235 FILE* fp = fileStream.GetFile();
241 dataBuffer.Resize(count);
243 if(!fseek(fp, offset, SEEK_SET))
245 result = fread(&dataBuffer[0], sizeof(T), count, fp);
248 return (result >= 0);
252 void LoadDataFromAccessor(int32_t accessorIdx, Dali::Vector<T>& bufferData, std::string path, std::vector<AccessorInfo>& accessorArray, std::vector<BufferViewInfo>& bufferViewArray, std::vector<BufferInfo>& bufferArray)
254 AccessorInfo accessor = accessorArray[accessorIdx];
255 BufferViewInfo bufferView = bufferViewArray[accessor.bufferView];
256 std::string load_uri = bufferArray[bufferView.buffer].uri;
258 // In the glTF 2.0 Specification, 5121 is UNSIGNED BYTE, 5123 is UNSIGNED SHORT
259 int32_t elementByteSize = (accessor.componentType <= 5121) ? 1 : ((accessor.componentType <= 5123) ? 2 : 4);
260 int32_t elementNum = 1;
261 if(accessor.type == "VEC2")
265 else if(accessor.type == "VEC3")
269 else if(accessor.type == "VEC4" || accessor.type == "MAT2")
273 else if(accessor.type == "MAT3")
277 else if(accessor.type == "MAT4")
285 int32_t elementNumOfByteStride = elementNum;
286 if(bufferView.byteStride > 0)
288 elementNumOfByteStride = bufferView.byteStride / elementByteSize;
292 * glTF 2.0 Specification
295 * 5121 : UNSIGNED_BYTE
297 * 5123 : UNSIGNED_SHORT
298 * 5125 : UNSIGNED_INT
301 if(accessor.componentType == 5120)
303 Dali::Vector<int8_t> inputBufferData;
304 ReadBinFile<int8_t>(inputBufferData, path + load_uri, bufferView.byteOffset + accessor.byteOffset, elementNumOfByteStride * accessor.count);
305 FitBuffer(bufferData, inputBufferData, accessor.count, elementNumOfByteStride, accessor.normalized);
307 else if(accessor.componentType == 5121)
309 Dali::Vector<uint8_t> inputBufferData;
310 ReadBinFile<uint8_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 == 5122)
315 Dali::Vector<int16_t> inputBufferData;
316 ReadBinFile<int16_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 == 5123)
321 Dali::Vector<uint16_t> inputBufferData;
322 ReadBinFile<uint16_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 == 5125)
327 Dali::Vector<uint32_t> inputBufferData;
328 ReadBinFile<uint32_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 == 5126)
333 Dali::Vector<float> inputBufferData;
334 ReadBinFile<float>(inputBufferData, path + load_uri, bufferView.byteOffset + accessor.byteOffset, elementNumOfByteStride * accessor.count);
335 FitBuffer(bufferData, inputBufferData, accessor.count, elementNumOfByteStride, accessor.normalized);
339 void SetMeshInfoAndCanonize(MeshInfo& meshInfo, Dali::Vector<Dali::Vector3>& vertexBufferData)
341 Vector3 pointMin(std::numeric_limits<float>::max(), std::numeric_limits<float>::max(), std::numeric_limits<float>::max());
342 Vector3 pointMax(std::numeric_limits<float>::min(), std::numeric_limits<float>::min(), std::numeric_limits<float>::min());
343 for(auto&& data : vertexBufferData)
345 pointMin.x = std::min(data.x, pointMin.x);
346 pointMin.y = std::min(data.y, pointMin.y);
347 pointMin.z = std::min(data.z, pointMin.z);
349 pointMax.x = std::max(data.x, pointMax.x);
350 pointMax.y = std::max(data.y, pointMax.y);
351 pointMax.z = std::max(data.z, pointMax.z);
353 meshInfo.size = pointMax - pointMin;
354 meshInfo.pivot.x = (-pointMin.x) / (pointMax.x - pointMin.x);
355 meshInfo.pivot.y = (-pointMin.y) / (pointMax.y - pointMin.y);
356 meshInfo.pivot.z = (-pointMin.z) / (pointMax.z - pointMin.z);
358 Vector3 center = meshInfo.size * 0.5 + pointMin;
359 for(auto&& data : vertexBufferData)
361 data = data - center;
362 data.x = data.x / meshInfo.size.x;
363 data.y = data.y / meshInfo.size.y;
364 data.z = data.z / meshInfo.size.z;
369 VertexBuffer CreateVertexBuffer(Vector<T> bufferData, std::string map, int32_t type)
371 Property::Map positionMap;
372 positionMap[map] = type;
374 VertexBuffer vertexBuffer = VertexBuffer::New(positionMap);
375 vertexBuffer.SetData(bufferData.Begin(), bufferData.Count());
379 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)
383 Dali::Vector<Vector3> bufferData;
384 LoadDataFromAccessor(accessorIdx, bufferData, path, accessorArray, bufferViewArray, bufferArray);
385 SetMeshInfoAndCanonize(meshInfo, bufferData);
387 VertexBuffer vertexBuffer = CreateVertexBuffer<Vector3>(bufferData, map, type);
388 meshInfo.geometry.AddVertexBuffer(vertexBuffer);
393 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)
397 Dali::Vector<T> bufferData;
398 LoadDataFromAccessor(accessorIdx, bufferData, path, accessorArray, bufferViewArray, bufferArray);
400 VertexBuffer vertexBuffer = CreateVertexBuffer<T>(bufferData, map, type);
401 meshInfo.geometry.AddVertexBuffer(vertexBuffer);
405 void SetIndexBuffersData(MeshInfo& meshInfo, std::string path, std::vector<AccessorInfo>& accessorArray, std::vector<BufferViewInfo>& bufferViewArray, std::vector<BufferInfo>& bufferArray, int32_t indexIdx)
407 Dali::Vector<uint16_t> indexBufferData;
408 LoadDataFromAccessor(indexIdx, indexBufferData, path, accessorArray, bufferViewArray, bufferArray);
409 meshInfo.geometry.SetIndexBuffer(&indexBufferData[0], indexBufferData.Size());
413 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)
415 Dali::Vector<float> inputBufferData;
416 Dali::Vector<T> outputBufferData;
418 LoadDataFromAccessor<float>(currentSampler.input, inputBufferData, path, accessorArray, bufferViewArray, bufferArray);
419 LoadDataFromAccessor<T>(currentSampler.output, outputBufferData, path, accessorArray, bufferViewArray, bufferArray);
421 uint32_t keyframeNum = inputBufferData.Size();
422 float lengthAnimation = inputBufferData[inputBufferData.Size() - 1];
423 for(uint32_t i = 0; i < keyframeNum; i++)
425 if(propIndex == Dali::Actor::Property::ORIENTATION)
427 Vector4 vectorOrientation(outputBufferData[i]);
428 float vW = vectorOrientation.w;
429 vW = (vW < 0.0f) ? std::max(vW, -1.0f) : std::min(vW, 1.0f);
430 vectorOrientation.w = vW;
431 keyframes.Add(inputBufferData[i] / lengthAnimation, Quaternion(Vector4(vectorOrientation)));
433 else if(propIndex == Dali::Actor::Property::POSITION)
435 keyframes.Add(inputBufferData[i] / lengthAnimation, Vector3(outputBufferData[i]));
437 else if(propIndex == Dali::Actor::Property::SCALE)
439 keyframes.Add(inputBufferData[i] / lengthAnimation, Vector3(outputBufferData[i]));
442 return lengthAnimation;
445 bool LoadBuffer(const TreeNode& buffer, std::vector<BufferInfo>& bufferArray)
447 BufferInfo bufferInfo;
449 const TreeNode* uriNode = buffer.GetChild("uri");
452 ReadString(uriNode, bufferInfo.uri);
455 const TreeNode* byteLengthNode = buffer.GetChild("byteLength");
458 ReadInt(byteLengthNode, bufferInfo.byteLength);
459 if(bufferInfo.byteLength < 0)
465 const TreeNode* nameNode = buffer.GetChild("name");
468 ReadString(nameNode, bufferInfo.name);
471 bufferArray.push_back(bufferInfo);
476 bool LoadBufferView(const TreeNode& buffer, std::vector<BufferViewInfo>& bufferViewArray)
478 BufferViewInfo bufferViewInfo;
480 const TreeNode* bufferNode = buffer.GetChild("buffer");
483 ReadInt(bufferNode, bufferViewInfo.buffer);
484 if(bufferViewInfo.buffer < 0)
490 const TreeNode* byteOffsetNode = buffer.GetChild("byteOffset");
493 ReadInt(byteOffsetNode, bufferViewInfo.byteOffset);
496 const TreeNode* byteLengthNode = buffer.GetChild("byteLength");
499 ReadInt(byteLengthNode, bufferViewInfo.byteLength);
500 if(bufferViewInfo.byteLength < 0)
506 const TreeNode* byteStrideNode = buffer.GetChild("byteStride");
509 ReadInt(byteStrideNode, bufferViewInfo.byteStride);
512 const TreeNode* targetNode = buffer.GetChild("target");
515 ReadInt(targetNode, bufferViewInfo.target);
518 const TreeNode* nameNode = buffer.GetChild("name");
521 ReadString(nameNode, bufferViewInfo.name);
524 bufferViewArray.push_back(bufferViewInfo);
529 bool LoadAccessor(const TreeNode& buffer, std::vector<AccessorInfo>& accessorArray)
531 AccessorInfo accessorInfo;
533 const TreeNode* bufferViewNode = buffer.GetChild("bufferView");
536 ReadInt(bufferViewNode, accessorInfo.bufferView);
539 const TreeNode* byteOffsetNode = buffer.GetChild("byteOffset");
542 ReadInt(byteOffsetNode, accessorInfo.byteOffset);
545 const TreeNode* componentTypeNode = buffer.GetChild("componentType");
546 if(componentTypeNode)
548 ReadInt(componentTypeNode, accessorInfo.componentType);
549 if(accessorInfo.componentType < 0)
555 const TreeNode* normalizedNode = buffer.GetChild("normalized");
558 ReadBool(normalizedNode, accessorInfo.normalized);
561 const TreeNode* countNode = buffer.GetChild("count");
564 ReadInt(countNode, accessorInfo.count);
565 if(accessorInfo.count < 0)
571 const TreeNode* typeNode = buffer.GetChild("type");
574 ReadString(typeNode, accessorInfo.type);
575 if(accessorInfo.type == "")
581 const TreeNode* maxNode = buffer.GetChild("max");
584 ReadInt(maxNode, accessorInfo.max);
587 const TreeNode* minNode = buffer.GetChild("min");
590 ReadInt(minNode, accessorInfo.min);
593 const TreeNode* nameNode = buffer.GetChild("name");
596 ReadString(nameNode, accessorInfo.name);
599 accessorArray.push_back(accessorInfo);
604 bool LoadBinaryData(const TreeNode& root, std::vector<BufferInfo>& bufferArray, std::vector<BufferViewInfo>& bufferViewArray, std::vector<AccessorInfo>& accessorArray)
606 const TreeNode* buffersNode = root.GetChild("buffers");
611 for(auto bufferIter = buffersNode->CBegin(), end = buffersNode->CEnd(); bufferIter != end; ++bufferIter)
613 LoadBuffer((*bufferIter).second, bufferArray);
616 const TreeNode* bufferViewsNode = root.GetChild("bufferViews");
621 for(auto bufferViewIter = bufferViewsNode->CBegin(), end = bufferViewsNode->CEnd(); bufferViewIter != end; ++bufferViewIter)
623 LoadBufferView((*bufferViewIter).second, bufferViewArray);
626 const TreeNode* accessorsNode = root.GetChild("accessors");
631 for(auto accesorIter = accessorsNode->CBegin(), end = accessorsNode->CEnd(); accesorIter != end; ++accesorIter)
633 LoadAccessor((*accesorIter).second, accessorArray);
639 FilterMode::Type GetFilterMode(uint32_t mode)
641 FilterMode::Type retValue = FilterMode::DEFAULT;
643 * glTF 2.0 Specification
647 * 9984 : NEAREST_MIPMAP_NEAREST
648 * 9985 : LINEAR_MIPMAP_NEAREST
649 * 9986 : NEAREST_MIPMAP_LINEAR
650 * 9987 : LINEAR_MIPMAP_LINEAR
656 retValue = FilterMode::NEAREST;
661 retValue = FilterMode::LINEAR;
666 retValue = FilterMode::NEAREST_MIPMAP_NEAREST;
671 retValue = FilterMode::LINEAR_MIPMAP_NEAREST;
676 retValue = FilterMode::NEAREST_MIPMAP_LINEAR;
681 retValue = FilterMode::LINEAR_MIPMAP_LINEAR;
689 WrapMode::Type GetWrapMode(uint32_t mode)
691 WrapMode::Type retValue = WrapMode::REPEAT;
693 * glTF 2.0 Specification
695 * 33071 : CLAMP_TO_EDGE
696 * 33648 : MIRRORED_REPEAT
703 retValue = WrapMode::CLAMP_TO_EDGE;
708 retValue = WrapMode::MIRRORED_REPEAT;
713 retValue = WrapMode::REPEAT;
721 Texture LoadTexture(const char* imageUrl, bool generateMipmaps)
724 Devel::PixelBuffer pixelBuffer = LoadImageFromFile(imageUrl);
727 texture = Texture::New(TextureType::TEXTURE_2D, pixelBuffer.GetPixelFormat(), pixelBuffer.GetWidth(), pixelBuffer.GetHeight());
728 PixelData pixelData = Devel::PixelBuffer::Convert(pixelBuffer);
729 texture.Upload(pixelData);
733 texture.GenerateMipmaps();
740 Sampler LoadSampler(const TreeNode& samplerNode)
742 Sampler sampler = Sampler::New();
744 FilterMode::Type minFilter = FilterMode::DEFAULT;
745 FilterMode::Type magFilter = FilterMode::DEFAULT;
746 const TreeNode* magFilterNode = samplerNode.GetChild("magFilter");
749 int32_t magFilter_integer = 0;
750 ReadInt(magFilterNode, magFilter_integer);
751 magFilter = GetFilterMode(magFilter_integer);
754 const TreeNode* minFilterNode = samplerNode.GetChild("minFilter");
757 int32_t minFilter_integer = 0;
758 ReadInt(minFilterNode, minFilter_integer);
759 minFilter = GetFilterMode(minFilter_integer);
762 WrapMode::Type wrapR = WrapMode::REPEAT;
763 WrapMode::Type wrapS = WrapMode::REPEAT;
764 WrapMode::Type wrapT = WrapMode::REPEAT;
765 const TreeNode* wrapNode = samplerNode.GetChild("wrapS");
768 wrapS = GetWrapMode(wrapNode->GetInteger());
771 wrapNode = samplerNode.GetChild("wrapT");
774 wrapT = GetWrapMode(wrapNode->GetInteger());
777 sampler.SetFilterMode(minFilter, magFilter);
778 sampler.SetWrapMode(wrapR, wrapS, wrapT);
783 bool LoadTextureArray(const TreeNode& root, std::string path, std::vector<Texture>& sourceArray, std::vector<Sampler>& samplerArray, std::vector<TextureInfo>& textureArray)
785 const TreeNode* imagesNode = root.GetChild("images");
788 for(auto imageIter = imagesNode->CBegin(), end = imagesNode->CEnd(); imageIter != end; ++imageIter)
790 std::string imageUrl;
791 const TreeNode* uriNode = (&((*imageIter).second))->GetChild("uri");
795 ReadString(uriNode, uri);
796 imageUrl = path + uri;
799 sourceArray.push_back(LoadTexture(imageUrl.c_str(), true));
803 const TreeNode* samplersNode = root.GetChild("samplers");
806 for(auto samplerIter = samplersNode->CBegin(), end = samplersNode->CEnd(); samplerIter != end; ++samplerIter)
808 samplerArray.push_back(LoadSampler(((*samplerIter).second)));
812 const TreeNode* texturesNode = root.GetChild("textures");
815 for(auto textureIter = texturesNode->CBegin(), end = texturesNode->CEnd(); textureIter != end; ++textureIter)
817 const TreeNode* TextureNode = &((*textureIter).second);
820 const TreeNode* sourceNode = TextureNode->GetChild("source");
823 ReadInt(sourceNode, texture.sourceIdx);
826 const TreeNode* samplerNode = TextureNode->GetChild("sampler");
829 ReadInt(samplerNode, texture.samplerIdx);
832 textureArray.push_back(texture);
838 bool LoadPbrMetallicRoughness(const TreeNode& material, MaterialInfo& materialInfo)
841 const TreeNode* pbrMetallicRoughnessNode = material.GetChild("pbrMetallicRoughness");
842 if(!pbrMetallicRoughnessNode)
847 const TreeNode* tempNode;
848 tempNode = pbrMetallicRoughnessNode->GetChild("metallicFactor");
851 ReadFloat(tempNode, materialInfo.metallicFactor);
854 tempNode = pbrMetallicRoughnessNode->GetChild("roughnessFactor");
857 ReadFloat(tempNode, materialInfo.roughnessFactor);
860 tempNode = pbrMetallicRoughnessNode->GetChild("baseColorFactor");
861 if(tempNode && ReadVector(tempNode, floatVec, 4))
863 materialInfo.baseColorFactor = Vector4(floatVec[0], floatVec[1], floatVec[2], floatVec[3]);
866 const TreeNode* baseColorTextureNode = pbrMetallicRoughnessNode->GetChild("baseColorTexture");
867 if(baseColorTextureNode)
869 tempNode = baseColorTextureNode->GetChild("index");
872 materialInfo.baseColorTexture.index = tempNode->GetInteger();
875 tempNode = baseColorTextureNode->GetChild("texCoord");
878 materialInfo.baseColorTexture.texCoord = tempNode->GetInteger();
882 const TreeNode* metallicRoughnessTextureNode = pbrMetallicRoughnessNode->GetChild("metallicRoughnessTexture");
883 if(metallicRoughnessTextureNode)
885 tempNode = metallicRoughnessTextureNode->GetChild("index");
888 materialInfo.metallicRoughnessTexture.index = tempNode->GetInteger();
891 tempNode = metallicRoughnessTextureNode->GetChild("texCoord");
894 materialInfo.metallicRoughnessTexture.texCoord = tempNode->GetInteger();
901 bool LoadMaterialSetArray(const TreeNode& root, std::vector<MaterialInfo>& materialArray)
903 const TreeNode* materialsNode = root.GetChild("materials");
909 for(auto materialIter = materialsNode->CBegin(), end = materialsNode->CEnd(); materialIter != end; ++materialIter)
911 MaterialInfo materialInfo;
912 LoadPbrMetallicRoughness(((*materialIter).second), materialInfo);
914 const TreeNode* materialNode = &((*materialIter).second);
915 const TreeNode* tempNode = materialNode->GetChild("name");
918 ReadString(tempNode, materialInfo.name);
921 materialInfo.alphaMode = "OPAQUE";
922 tempNode = materialNode->GetChild("alphaMode");
925 ReadString(tempNode, materialInfo.alphaMode);
928 materialInfo.alphaCutoff = 1.0;
929 tempNode = materialNode->GetChild("alphaCutoff");
932 ReadFloat(tempNode, materialInfo.alphaCutoff);
935 materialInfo.doubleSided = false;
936 tempNode = materialNode->GetChild("doubleSided");
939 ReadBool(tempNode, materialInfo.doubleSided);
943 tempNode = materialNode->GetChild("emissiveFactor");
944 if(tempNode && ReadVector(tempNode, floatVec, 3))
946 materialInfo.emissiveFactor = Vector3(floatVec[0], floatVec[1], floatVec[2]);
949 const TreeNode* texture = materialNode->GetChild("normalTexture");
952 tempNode = texture->GetChild("index");
955 materialInfo.normalTexture.index = tempNode->GetInteger();
958 tempNode = texture->GetChild("texCoord");
961 materialInfo.normalTexture.texCoord = tempNode->GetInteger();
964 materialInfo.normalTexture.value = 1.0;
965 tempNode = texture->GetChild("scale");
968 ReadFloat(tempNode, materialInfo.normalTexture.value);
972 texture = materialNode->GetChild("occlusionTexture");
975 tempNode = texture->GetChild("index");
978 materialInfo.occlusionTexture.index = tempNode->GetInteger();
981 tempNode = texture->GetChild("texCoord");
984 materialInfo.occlusionTexture.texCoord = tempNode->GetInteger();
987 tempNode = texture->GetChild("strength");
990 ReadFloat(tempNode, materialInfo.occlusionTexture.value);
994 texture = materialNode->GetChild("emissiveTexture");
997 tempNode = texture->GetChild("index");
1000 materialInfo.emissiveTexture.index = tempNode->GetInteger();
1003 tempNode = texture->GetChild("texCoord");
1006 materialInfo.emissiveTexture.texCoord = tempNode->GetInteger();
1009 materialArray.push_back(materialInfo);
1014 bool LoadAttribute(const TreeNode* primitive, MeshInfo& meshInfo)
1016 const TreeNode* attrbuteNode = primitive->GetChild("attributes");
1022 const TreeNode* tempNode;
1023 tempNode = attrbuteNode->GetChild("POSITION");
1026 meshInfo.attribute.POSITION = tempNode->GetInteger();
1029 tempNode = attrbuteNode->GetChild("NORMAL");
1032 meshInfo.attribute.NORMAL = tempNode->GetInteger();
1035 tempNode = attrbuteNode->GetChild("TANGENT");
1038 meshInfo.attribute.TANGENT = tempNode->GetInteger();
1042 meshInfo.attribute.TEXCOORD.clear();
1043 tempNode = attrbuteNode->GetChild("TEXCOORD_" + std::to_string(index));
1046 uint32_t value = tempNode->GetInteger();
1047 meshInfo.attribute.TEXCOORD.push_back(value);
1048 tempNode = attrbuteNode->GetChild("TEXCOORD_" + std::to_string(++index));
1052 meshInfo.attribute.COLOR.clear();
1053 tempNode = attrbuteNode->GetChild("COLOR_" + std::to_string(index));
1056 uint32_t value = tempNode->GetInteger();
1057 meshInfo.attribute.COLOR.push_back(value);
1058 tempNode = attrbuteNode->GetChild("COLOR" + std::to_string(++index));
1064 bool LoadPrimitive(const TreeNode& mesh, MeshInfo& meshInfo)
1066 const TreeNode* primitivesNode = mesh.GetChild("primitives");
1072 for(auto primitiveIter = primitivesNode->CBegin(), end = primitivesNode->CEnd(); primitiveIter != end; ++primitiveIter)
1074 const TreeNode* primitiveNode = (&(*primitiveIter).second);
1075 const TreeNode* tempNode;
1077 tempNode = primitiveNode->GetChild("indices");
1080 meshInfo.indicesIdx = tempNode->GetInteger();
1083 tempNode = primitiveNode->GetChild("material");
1086 meshInfo.materialsIdx = tempNode->GetInteger();
1089 tempNode = primitiveNode->GetChild("mode");
1092 meshInfo.mode = tempNode->GetInteger();
1095 LoadAttribute(primitiveNode, meshInfo);
1101 bool SetGeometry(MeshInfo& meshInfo, std::string path, std::vector<BufferInfo>& bufferArray, std::vector<BufferViewInfo>& bufferViewArray, std::vector<AccessorInfo>& accessorArray)
1103 int32_t indicesIdx = meshInfo.indicesIdx;
1105 if(meshInfo.mode != 0)
1107 meshInfo.geometry.SetType((Dali::Geometry::Type)meshInfo.mode);
1112 SetIndexBuffersData(meshInfo, path, accessorArray, bufferViewArray, bufferArray, indicesIdx);
1115 SetVertexBufferData(meshInfo, path, accessorArray, bufferViewArray, bufferArray, meshInfo.attribute.POSITION, "aPosition", Property::VECTOR3);
1116 SetAttributeBufferData<Vector3>(meshInfo, path, accessorArray, bufferViewArray, bufferArray, meshInfo.attribute.NORMAL, "aNormal", Property::VECTOR3);
1117 SetAttributeBufferData<Vector4>(meshInfo, path, accessorArray, bufferViewArray, bufferArray, meshInfo.attribute.TANGENT, "aTangent", Property::VECTOR4);
1119 for(uint32_t i = 0; i < meshInfo.attribute.TEXCOORD.size(); ++i)
1121 int32_t accessorIdx = meshInfo.attribute.TEXCOORD[i];
1122 std::ostringstream texCoordString;
1123 texCoordString << "aTexCoord" << i;
1124 SetAttributeBufferData<Vector2>(meshInfo, path, accessorArray, bufferViewArray, bufferArray, accessorIdx, texCoordString.str(), Property::VECTOR2);
1127 for(auto&& accessorIdx : meshInfo.attribute.COLOR)
1134 if(accessorArray[accessorIdx].type == "VEC3")
1136 Dali::Vector<Vector3> inputBufferData;
1137 LoadDataFromAccessor(accessorIdx, inputBufferData, path, accessorArray, bufferViewArray, bufferArray);
1139 Dali::Vector<Vector4> bufferData;
1140 bufferData.Resize(inputBufferData.Size());
1141 for(uint32_t i = 0; i < inputBufferData.Size(); ++i)
1143 bufferData[i].x = inputBufferData[i].x;
1144 bufferData[i].y = inputBufferData[i].y;
1145 bufferData[i].z = inputBufferData[i].z;
1146 bufferData[i].w = 1.0;
1148 VertexBuffer vertexBuffer = CreateVertexBuffer<Vector4>(bufferData, "aVertexColor", Property::VECTOR4);
1149 meshInfo.geometry.AddVertexBuffer(vertexBuffer);
1151 else if(accessorArray[accessorIdx].type == "VEC4")
1153 SetAttributeBufferData<Vector4>(meshInfo, path, accessorArray, bufferViewArray, bufferArray, accessorIdx, "aVertexColor", Property::VECTOR4);
1159 bool LoadMeshArray(const TreeNode& root, std::string path, std::vector<MeshInfo>& meshArray, std::vector<BufferInfo>& bufferArray, std::vector<BufferViewInfo>& bufferViewArray, std::vector<AccessorInfo>& accessorArray)
1161 const TreeNode* meshesNode = root.GetChild("meshes");
1167 for(auto meshIter = meshesNode->CBegin(), end = meshesNode->CEnd(); meshIter != end; ++meshIter)
1170 const TreeNode* nameNode = (&(*meshIter).second)->GetChild("name");
1173 ReadString(nameNode, meshInfo.name);
1175 meshInfo.geometry = Geometry::New();
1177 //Need to add weights for Morph targets.
1178 LoadPrimitive((*meshIter).second, meshInfo);
1179 SetGeometry(meshInfo, path, bufferArray, bufferViewArray, accessorArray);
1180 meshArray.push_back(meshInfo);
1198 bool Loader::LoadScene(const std::string& filePath, Internal::Scene3dView& scene3dView)
1200 // Extracting directory path from full path to load resources.
1201 if(std::string::npos != filePath.rfind('/'))
1203 mPath = filePath.substr(0, filePath.rfind('/')) + "/";
1206 if(!ParseGltf(filePath))
1208 DALI_LOG_ERROR("Fail to parse json file\n");
1212 mRoot = mParser.GetRoot();
1215 CreateScene(scene3dView))
1222 bool Loader::ParseGltf(const std::string& filePath)
1224 std::streampos bufferSize = 0;
1225 Dali::Vector<char> buffer;
1226 std::string fileBuffer;
1227 if(!Dali::FileLoader::ReadFile(filePath, bufferSize, buffer, FileLoader::FileType::BINARY))
1232 fileBuffer.assign(&buffer[0], bufferSize);
1233 mParser = Dali::Toolkit::JsonParser::New();
1234 return mParser.Parse(fileBuffer);
1237 bool Loader::LoadAssets()
1239 if(LoadBinaryData(*mRoot, mBufferArray, mBufferViewArray, mAccessorArray) &&
1240 LoadTextureArray(*mRoot, mPath, mSourceArray, mSamplerArray, mTextureArray) &&
1241 LoadMaterialSetArray(*mRoot, mMaterialArray) &&
1242 LoadMeshArray(*mRoot, mPath, mMeshArray, mBufferArray, mBufferViewArray, mAccessorArray))
1249 bool Loader::CreateScene(Internal::Scene3dView& scene3dView)
1251 scene3dView.SetDefaultCamera(Dali::Camera::LOOK_AT_TARGET, 0.01, Vector3::ZERO);
1252 LoadCamera(scene3dView);
1254 if(LoadSceneNodes(scene3dView) &&
1255 LoadAnimation(scene3dView))
1262 void Loader::LoadCamera(Scene3dView& scene3dView)
1264 const TreeNode* camerasNode = mRoot->GetChild("cameras");
1270 for(auto cameraIter = camerasNode->CBegin(), end = camerasNode->CEnd(); cameraIter != end; ++cameraIter)
1272 const TreeNode* tempNode = (&(*cameraIter).second)->GetChild("name");
1273 CameraInfo cameraInfo;
1276 ReadString(tempNode, cameraInfo.name);
1279 tempNode = (&(*cameraIter).second)->GetChild("type");
1282 ReadString(tempNode, cameraInfo.type);
1285 CameraActor cameraActor = CameraActor::New();
1286 cameraActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
1287 cameraActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
1289 if(cameraInfo.type == "orthographic")
1291 LoadOrthoGraphic((*cameraIter).second, cameraInfo);
1292 float xMag_2 = cameraInfo.orthographic.xmag / 2.0;
1293 float yMag_2 = cameraInfo.orthographic.ymag / 2.0;
1294 cameraActor.SetOrthographicProjection(-xMag_2, xMag_2, yMag_2, -yMag_2, cameraInfo.orthographic.znear, cameraInfo.orthographic.zfar);
1296 else if(cameraInfo.type == "perspective")
1298 if(!LoadPerspective((*cameraIter).second, cameraInfo))
1302 cameraActor.SetProjectionMode(Dali::Camera::PERSPECTIVE_PROJECTION);
1303 cameraActor.SetFieldOfView(cameraInfo.perspective.yfov);
1304 cameraActor.SetNearClippingPlane(cameraInfo.perspective.znear);
1306 if(cameraInfo.perspective.zfar > 0.0)
1308 cameraActor.SetFarClippingPlane(cameraInfo.perspective.zfar);
1310 if(cameraInfo.perspective.aspectRatio > 0.0)
1312 cameraActor.SetAspectRatio(cameraInfo.perspective.aspectRatio);
1316 scene3dView.AddCamera(cameraActor);
1320 bool Loader::LoadOrthoGraphic(const TreeNode& camera, CameraInfo& cameraInfo)
1322 const TreeNode* orthographicNode = camera.GetChild("orthographic");
1323 if(!orthographicNode)
1328 const TreeNode* tempNode;
1329 tempNode = orthographicNode->GetChild("xmag");
1332 ReadFloat(tempNode, cameraInfo.orthographic.xmag);
1335 tempNode = orthographicNode->GetChild("ymag");
1338 ReadFloat(tempNode, cameraInfo.orthographic.ymag);
1341 tempNode = orthographicNode->GetChild("zfar");
1344 ReadFloat(tempNode, cameraInfo.orthographic.zfar);
1347 tempNode = orthographicNode->GetChild("znear");
1350 ReadFloat(tempNode, cameraInfo.orthographic.znear);
1356 bool Loader::LoadPerspective(const TreeNode& camera, CameraInfo& cameraInfo)
1358 const TreeNode* perspectiveNode = camera.GetChild("perspective");
1359 if(!perspectiveNode)
1364 const TreeNode* tempNode;
1365 tempNode = perspectiveNode->GetChild("aspectRatio");
1368 ReadFloat(tempNode, cameraInfo.perspective.aspectRatio);
1371 tempNode = perspectiveNode->GetChild("yfov");
1374 ReadFloat(tempNode, cameraInfo.perspective.yfov);
1377 tempNode = perspectiveNode->GetChild("zfar");
1380 ReadFloat(tempNode, cameraInfo.perspective.zfar);
1383 tempNode = perspectiveNode->GetChild("znear");
1386 ReadFloat(tempNode, cameraInfo.perspective.znear);
1392 bool Loader::LoadSceneNodes(Scene3dView& scene3dView)
1394 const TreeNode* sceneNode = mRoot->GetChild("scene");
1395 uint32_t sceneNum = 0;
1398 sceneNum = sceneNode->GetInteger();
1401 const TreeNode* scenesNode = mRoot->GetChild("scenes");
1402 if(!(scenesNode && (mNodes = mRoot->GetChild("nodes"))))
1407 const TreeNode* tempNode = Tidx(scenesNode, sceneNum);
1413 tempNode = tempNode->GetChild("nodes");
1419 for(auto nodeIter = tempNode->CBegin(), end = tempNode->CEnd(); nodeIter != end; ++nodeIter)
1421 Actor actor = AddNode(scene3dView, ((*nodeIter).second).GetInteger());
1422 actor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
1423 scene3dView.GetRoot().Add(actor);
1429 Actor Loader::AddNode(Scene3dView& scene3dView, uint32_t index)
1431 const TreeNode* node = Tidx(mNodes, index);
1432 Actor actor = Actor::New();
1433 Vector3 actorSize(Vector3::ONE);
1435 Vector3 translation = Vector3(0.0, 0.0, 0.0);
1436 Vector3 scale = Vector3(1.0, 1.0, 1.0);
1437 Quaternion orientation(Vector4(0.0, 0.0, 0.0, 1.0));
1439 Vector3 anchorPoint = AnchorPoint::CENTER;
1441 const TreeNode* tempNode = NULL;
1442 if((tempNode = node->GetChild("translation")))
1444 float floatVec[3] = {0.0, 0.0, 0.0};
1445 if(tempNode && ReadVector(tempNode, floatVec, 3))
1447 translation = Vector3(floatVec[0], floatVec[1], floatVec[2]);
1451 if((tempNode = node->GetChild("scale")))
1453 float floatVec[3] = {1.0, 1.0, 1.0};
1454 if(tempNode && ReadVector(tempNode, floatVec, 3))
1456 scale = Vector3(floatVec[0], floatVec[1], floatVec[2]);
1460 if((tempNode = node->GetChild("rotation")))
1462 float floatVec[4] = {0.0, 0.0, 0.0, 1.0};
1463 if(tempNode && ReadVector(tempNode, floatVec, 4))
1465 orientation = Quaternion(Vector4(floatVec[0], floatVec[1], floatVec[2], floatVec[3]));
1469 if((tempNode = node->GetChild("matrix")))
1471 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};
1472 if(tempNode && ReadVector(tempNode, floatVec, 16))
1474 Matrix nodeMatrix = Matrix(floatVec);
1475 nodeMatrix.GetTransformComponents(translation, orientation, scale);
1479 if((tempNode = node->GetChild("mesh")))
1481 MeshInfo meshInfo = mMeshArray[tempNode->GetInteger()];
1482 bool isMaterial = (meshInfo.materialsIdx >= 0);
1484 TextureSet textureSet;
1485 textureSet = TextureSet::New();
1488 int32_t shaderTypeIndex = 0;
1489 int32_t maxMipmapLevel = 0;
1490 bool isBaseColorTexture = false;
1491 bool isMetallicRoughnessTexture = false;
1492 bool isNormalTexture = false;
1493 bool isOcclusionTexture = false;
1494 bool isEmissiveTexture = false;
1496 std::string VERTEX_SHADER, FRAGMENT_SHADER;
1497 VERTEX_SHADER = SHADER_GLTF_GLES_VERSION_300_DEF.data();
1498 VERTEX_SHADER += SHADER_GLTF_PHYSICALLY_BASED_SHADER_VERT.data();
1499 FRAGMENT_SHADER = SHADER_GLTF_GLES_VERSION_300_DEF.data();
1501 bool useIBL = (scene3dView.GetLightType() >= Toolkit::Scene3dView::LightType::IMAGE_BASED_LIGHT);
1504 MaterialInfo materialInfo = mMaterialArray[meshInfo.materialsIdx];
1505 if(SetTextureAndSampler(textureSet, materialInfo.baseColorTexture.index, FRAGMENT_SHADER, SHADER_GLTF_BASECOLOR_TEXTURE_DEF.data(), addIdx))
1507 shaderTypeIndex += static_cast<int32_t>(ShaderType::BASECOLOR_SHADER);
1508 isBaseColorTexture = true;
1510 if(SetTextureAndSampler(textureSet, materialInfo.metallicRoughnessTexture.index, FRAGMENT_SHADER, SHADER_GLTF_METALLICROUGHNESS_TEXTURE_DEF.data(), addIdx))
1512 shaderTypeIndex += static_cast<int32_t>(ShaderType::METALLICROUGHNESS_SHADER);
1513 isMetallicRoughnessTexture = true;
1515 if(SetTextureAndSampler(textureSet, materialInfo.normalTexture.index, FRAGMENT_SHADER, SHADER_GLTF_NORMAL_TEXTURE_DEF.data(), addIdx))
1517 shaderTypeIndex += static_cast<int32_t>(ShaderType::NORMAL_SHADER);
1518 isNormalTexture = true;
1520 if(SetTextureAndSampler(textureSet, materialInfo.occlusionTexture.index, FRAGMENT_SHADER, SHADER_GLTF_OCCULUSION_TEXTURE_DEF.data(), addIdx))
1522 shaderTypeIndex += static_cast<int32_t>(ShaderType::OCCLUSION_SHADER);
1523 isOcclusionTexture = true;
1525 if(SetTextureAndSampler(textureSet, materialInfo.emissiveTexture.index, FRAGMENT_SHADER, SHADER_GLTF_EMIT_TEXTURE_DEF.data(), addIdx))
1527 shaderTypeIndex += static_cast<int32_t>(ShaderType::EMIT_SHADER);
1528 isEmissiveTexture = true;
1533 shaderTypeIndex += static_cast<int32_t>(ShaderType::IBL_SHADER);
1534 FRAGMENT_SHADER += SHADER_GLTF_IBL_TEXTURE_DEF.data();
1536 Sampler sampler = Sampler::New();
1537 sampler.SetFilterMode(FilterMode::DEFAULT, FilterMode::DEFAULT);
1538 sampler.SetWrapMode(WrapMode::REPEAT, WrapMode::REPEAT, WrapMode::REPEAT);
1540 textureSet.SetTexture(addIdx, scene3dView.GetBRDFTexture());
1541 textureSet.SetSampler(addIdx++, sampler);
1542 Sampler samplerIBL = Sampler::New();
1543 samplerIBL.SetFilterMode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR);
1544 samplerIBL.SetWrapMode(WrapMode::CLAMP_TO_EDGE, WrapMode::CLAMP_TO_EDGE, WrapMode::CLAMP_TO_EDGE);
1545 textureSet.SetTexture(addIdx, scene3dView.GetDiffuseTexture());
1546 textureSet.SetSampler(addIdx++, samplerIBL);
1547 Texture specularTexture = scene3dView.GetSpecularTexture();
1548 textureSet.SetTexture(addIdx, specularTexture);
1549 textureSet.SetSampler(addIdx++, samplerIBL);
1551 int32_t textureSize = std::min(specularTexture.GetWidth(), specularTexture.GetHeight());
1553 while(textureSize >= 1)
1561 FRAGMENT_SHADER += SHADER_GLTF_PHYSICALLY_BASED_SHADER_FRAG.data();
1562 if(!mShaderCache[shaderTypeIndex])
1564 mShaderCache[shaderTypeIndex] = Shader::New(VERTEX_SHADER, FRAGMENT_SHADER);
1565 scene3dView.AddShader(mShaderCache[shaderTypeIndex]);
1567 Shader shader = mShaderCache[shaderTypeIndex];
1569 Renderer renderer = Renderer::New(meshInfo.geometry, shader);
1570 renderer.SetProperty(Renderer::Property::DEPTH_WRITE_MODE, DepthWriteMode::ON);
1571 renderer.SetProperty(Renderer::Property::DEPTH_TEST_MODE, DepthTestMode::ON);
1572 renderer.SetTextures(textureSet);
1574 anchorPoint = meshInfo.pivot;
1575 actor.SetProperty(Actor::Property::ANCHOR_POINT, anchorPoint);
1577 actor.SetProperty(Actor::Property::SIZE, Vector3(meshInfo.size.x, meshInfo.size.y, meshInfo.size.z));
1578 actor.AddRenderer(renderer);
1580 actor.SetProperty(Actor::Property::SCALE, scale);
1581 actor.RotateBy(orientation);
1582 actor.SetProperty(Actor::Property::POSITION, translation);
1584 shader.RegisterProperty("uLightType", (scene3dView.GetLightType() & ~Toolkit::Scene3dView::LightType::IMAGE_BASED_LIGHT));
1585 shader.RegisterProperty("uLightVector", scene3dView.GetLightVector());
1586 shader.RegisterProperty("uLightColor", scene3dView.GetLightColor());
1588 actor.RegisterProperty("uIsColor", meshInfo.attribute.COLOR.size() > 0);
1591 MaterialInfo materialInfo = mMaterialArray[meshInfo.materialsIdx];
1592 actor.RegisterProperty("uBaseColorFactor", materialInfo.baseColorFactor);
1593 actor.RegisterProperty("uMetallicRoughnessFactors", Vector2(materialInfo.metallicFactor, materialInfo.roughnessFactor));
1595 if(materialInfo.alphaMode == "OPAQUE")
1597 actor.RegisterProperty("alphaMode", 0);
1599 else if(materialInfo.alphaMode == "MASK")
1601 actor.RegisterProperty("alphaMode", 1);
1605 actor.RegisterProperty("alphaMode", 2);
1607 actor.RegisterProperty("alphaCutoff", materialInfo.alphaCutoff);
1609 if(isBaseColorTexture)
1611 actor.RegisterProperty("uBaseColorTexCoordIndex", materialInfo.baseColorTexture.texCoord);
1613 if(isMetallicRoughnessTexture)
1615 actor.RegisterProperty("uMetallicRoughnessTexCoordIndex", materialInfo.metallicRoughnessTexture.texCoord);
1619 actor.RegisterProperty("uNormalScale", materialInfo.normalTexture.value);
1620 actor.RegisterProperty("uNormalTexCoordIndex", materialInfo.normalTexture.texCoord);
1622 if(isOcclusionTexture)
1624 actor.RegisterProperty("uOcclusionTexCoordIndex", materialInfo.occlusionTexture.texCoord);
1625 actor.RegisterProperty("uOcclusionStrength", materialInfo.occlusionTexture.value);
1627 if(isEmissiveTexture)
1629 actor.RegisterProperty("uEmissiveTexCoordIndex", materialInfo.emissiveTexture.texCoord);
1630 actor.RegisterProperty("uEmissiveFactor", materialInfo.emissiveFactor);
1634 if(isMaterial && useIBL)
1636 actor.RegisterProperty("uScaleIBLAmbient", scene3dView.GetIBLScaleFactor());
1637 actor.RegisterProperty("uMipmapLevel", static_cast<float>(maxMipmapLevel));
1642 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
1643 actor.SetProperty(Actor::Property::POSITION, translation);
1644 actor.RotateBy(orientation);
1645 actor.SetProperty(Actor::Property::SIZE, actorSize);
1648 tempNode = node->GetChild("camera");
1651 int32_t cameraNum = tempNode->GetInteger();
1652 CameraActor cameraActor = scene3dView.GetCamera(cameraNum);
1655 actor.Add(cameraActor);
1659 tempNode = node->GetChild("name");
1662 std::string nameString;
1663 ReadString(tempNode, nameString);
1664 actor.SetProperty(Dali::Actor::Property::NAME, nameString);
1667 SetActorCache(actor, index);
1668 if((tempNode = node->GetChild("children")))
1670 for(auto childIter = tempNode->CBegin(), end = tempNode->CEnd(); childIter != end; ++childIter)
1672 Actor childActor = AddNode(scene3dView, ((*childIter).second).GetInteger());
1673 childActor.SetProperty(Actor::Property::PARENT_ORIGIN, anchorPoint);
1674 actor.Add(childActor);
1681 void Loader::SetActorCache(Actor& actor, uint32_t index)
1683 if(mActorCache.size() < index + 1)
1685 mActorCache.resize(index + 1);
1687 mActorCache[index] = actor;
1690 bool Loader::SetTextureAndSampler(TextureSet& textureSet, int32_t textureIdx, std::string& toShader, std::string shader, int32_t& addIdx)
1695 TextureInfo textureInfo = mTextureArray[textureIdx];
1696 if(textureInfo.sourceIdx >= 0)
1698 textureSet.SetTexture(addIdx, mSourceArray[textureInfo.sourceIdx]);
1700 if(textureInfo.samplerIdx >= 0)
1702 textureSet.SetSampler(addIdx, mSamplerArray[textureInfo.samplerIdx]);
1706 Sampler sampler = Sampler::New();
1707 sampler.SetFilterMode(FilterMode::DEFAULT, FilterMode::DEFAULT);
1708 sampler.SetWrapMode(WrapMode::REPEAT, WrapMode::REPEAT, WrapMode::REPEAT);
1709 textureSet.SetSampler(addIdx, sampler);
1717 bool Loader::LoadAnimation(Scene3dView& scene3dView)
1719 const TreeNode* animationsNode = mRoot->GetChild("animations");
1725 for(auto animationIter = animationsNode->CBegin(), end = animationsNode->CEnd(); animationIter != end; ++animationIter)
1727 const TreeNode* nameNode = (&(*animationIter).second)->GetChild("name");
1728 AnimationInfo animationInfo;
1731 ReadString(nameNode, animationInfo.name);
1734 Property::Index propIndex = Property::INVALID_INDEX;
1735 LoadAnimationChannels((*animationIter).second, animationInfo);
1736 if(animationInfo.channelArray.size() == 0)
1741 LoadAnimationSamplers((*animationIter).second, animationInfo);
1743 for(auto&& currentChannel : animationInfo.channelArray)
1745 if(currentChannel.path == "rotation")
1747 propIndex = Dali::Actor::Property::ORIENTATION;
1749 else if(currentChannel.path == "translation")
1751 propIndex = Dali::Actor::Property::POSITION;
1753 else if(currentChannel.path == "scale")
1755 propIndex = Dali::Actor::Property::SCALE;
1758 float duration = 0.0f;
1759 KeyFrames keyframes = KeyFrames::New();
1760 if(propIndex == Dali::Actor::Property::ORIENTATION)
1762 duration = LoadKeyFrames<Vector4>(animationInfo.samplerArray[currentChannel.sampler], propIndex, keyframes, mPath, mAccessorArray, mBufferViewArray, mBufferArray);
1766 duration = LoadKeyFrames<Vector3>(animationInfo.samplerArray[currentChannel.sampler], propIndex, keyframes, mPath, mAccessorArray, mBufferViewArray, mBufferArray);
1769 Animation animation = Animation::New(duration);
1770 Animation::Interpolation interpolation = Animation::Interpolation::LINEAR;
1771 if(animationInfo.samplerArray[currentChannel.sampler].interpolation == "CUBICSPLINE")
1773 interpolation = Animation::Interpolation::CUBIC;
1775 if(animationInfo.samplerArray[currentChannel.sampler].interpolation == "STEP")
1779 animation.AnimateBetween(Property(mActorCache[currentChannel.targetNode], propIndex), keyframes, interpolation);
1781 animation.SetLooping(false);
1782 scene3dView.AddAnimation(animation);
1789 bool Loader::LoadAnimationChannels(const TreeNode& animation, AnimationInfo& animationInfo)
1791 const TreeNode* channelsNode = animation.GetChild("channels");
1797 for(auto channelIter = channelsNode->CBegin(), end = channelsNode->CEnd(); channelIter != end; ++channelIter)
1799 AnimationChannelInfo animationChannelInfo;
1800 const TreeNode* channelNode = (&(*channelIter).second);
1801 const TreeNode* samplerNode = channelNode->GetChild("sampler");
1804 animationChannelInfo.sampler = samplerNode->GetInteger();
1807 const TreeNode* targetNode = channelNode->GetChild("target");
1810 const TreeNode* tempNode = targetNode->GetChild("node");
1813 animationChannelInfo.targetNode = tempNode->GetInteger();
1820 tempNode = targetNode->GetChild("path");
1823 ReadString(tempNode, animationChannelInfo.path);
1827 animationInfo.channelArray.push_back(animationChannelInfo);
1832 bool Loader::LoadAnimationSamplers(const TreeNode& animation, AnimationInfo& animationInfo)
1834 const TreeNode* samplersNode = animation.GetChild("samplers");
1840 for(auto sampler = samplersNode->CBegin(), end = samplersNode->CEnd(); sampler != end; ++sampler)
1842 AnimationSamplerInfo animationSamplerInfo;
1843 const TreeNode* samplerNode = (&(*sampler).second);
1844 const TreeNode* tempNode = samplerNode->GetChild("input");
1847 animationSamplerInfo.input = tempNode->GetInteger();
1850 tempNode = samplerNode->GetChild("output");
1853 animationSamplerInfo.output = tempNode->GetInteger();
1856 tempNode = samplerNode->GetChild("interpolation");
1859 ReadString(tempNode, animationSamplerInfo.interpolation);
1862 animationInfo.samplerArray.push_back(animationSamplerInfo);
1870 } //namespace Internal
1872 } //namespace Toolkit