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 size_t readCount = 0;
235 Dali::FileStream fileStream(url, FileStream::READ | FileStream::BINARY);
236 FILE* fp = fileStream.GetFile();
239 dataBuffer.Resize(count);
240 if(!fseek(fp, offset, SEEK_SET))
242 readCount = fread(&dataBuffer[0], sizeof(T), count, fp);
243 dataBuffer.Resize(readCount);
247 return (readCount > 0);
251 void LoadDataFromAccessor(int32_t accessorIdx, Dali::Vector<T>& bufferData, std::string path, std::vector<AccessorInfo>& accessorArray, std::vector<BufferViewInfo>& bufferViewArray, std::vector<BufferInfo>& bufferArray)
253 AccessorInfo accessor = accessorArray[accessorIdx];
254 BufferViewInfo bufferView = bufferViewArray[accessor.bufferView];
255 std::string load_uri = bufferArray[bufferView.buffer].uri;
257 // In the glTF 2.0 Specification, 5121 is UNSIGNED BYTE, 5123 is UNSIGNED SHORT
258 int32_t elementByteSize = (accessor.componentType <= 5121) ? 1 : ((accessor.componentType <= 5123) ? 2 : 4);
259 int32_t elementNum = 1;
260 if(accessor.type == "VEC2")
264 else if(accessor.type == "VEC3")
268 else if(accessor.type == "VEC4" || accessor.type == "MAT2")
272 else if(accessor.type == "MAT3")
276 else if(accessor.type == "MAT4")
284 int32_t elementNumOfByteStride = elementNum;
285 if(bufferView.byteStride > 0)
287 elementNumOfByteStride = bufferView.byteStride / elementByteSize;
291 * glTF 2.0 Specification
294 * 5121 : UNSIGNED_BYTE
296 * 5123 : UNSIGNED_SHORT
297 * 5125 : UNSIGNED_INT
300 if(accessor.componentType == 5120)
302 Dali::Vector<int8_t> inputBufferData;
303 if(ReadBinFile<int8_t>(inputBufferData, path + load_uri, bufferView.byteOffset + accessor.byteOffset, elementNumOfByteStride * accessor.count))
305 FitBuffer(bufferData, inputBufferData, accessor.count, elementNumOfByteStride, accessor.normalized);
308 else if(accessor.componentType == 5121)
310 Dali::Vector<uint8_t> inputBufferData;
311 if(ReadBinFile<uint8_t>(inputBufferData, path + load_uri, bufferView.byteOffset + accessor.byteOffset, elementNumOfByteStride * accessor.count))
313 FitBuffer(bufferData, inputBufferData, accessor.count, elementNumOfByteStride, accessor.normalized);
316 else if(accessor.componentType == 5122)
318 Dali::Vector<int16_t> inputBufferData;
319 if(ReadBinFile<int16_t>(inputBufferData, path + load_uri, bufferView.byteOffset + accessor.byteOffset, elementNumOfByteStride * accessor.count))
321 FitBuffer(bufferData, inputBufferData, accessor.count, elementNumOfByteStride, accessor.normalized);
324 else if(accessor.componentType == 5123)
326 Dali::Vector<uint16_t> inputBufferData;
327 if(ReadBinFile<uint16_t>(inputBufferData, path + load_uri, bufferView.byteOffset + accessor.byteOffset, elementNumOfByteStride * accessor.count))
329 FitBuffer(bufferData, inputBufferData, accessor.count, elementNumOfByteStride, accessor.normalized);
332 else if(accessor.componentType == 5125)
334 Dali::Vector<uint32_t> inputBufferData;
335 if(ReadBinFile<uint32_t>(inputBufferData, path + load_uri, bufferView.byteOffset + accessor.byteOffset, elementNumOfByteStride * accessor.count))
337 FitBuffer(bufferData, inputBufferData, accessor.count, elementNumOfByteStride, accessor.normalized);
340 else if(accessor.componentType == 5126)
342 Dali::Vector<float> inputBufferData;
343 if(ReadBinFile<float>(inputBufferData, path + load_uri, bufferView.byteOffset + accessor.byteOffset, elementNumOfByteStride * accessor.count))
345 FitBuffer(bufferData, inputBufferData, accessor.count, elementNumOfByteStride, accessor.normalized);
350 void SetMeshInfoAndCanonize(MeshInfo& meshInfo, Dali::Vector<Dali::Vector3>& vertexBufferData)
352 Vector3 pointMin(std::numeric_limits<float>::max(), std::numeric_limits<float>::max(), std::numeric_limits<float>::max());
353 Vector3 pointMax(std::numeric_limits<float>::min(), std::numeric_limits<float>::min(), std::numeric_limits<float>::min());
354 for(auto&& data : vertexBufferData)
356 pointMin.x = std::min(data.x, pointMin.x);
357 pointMin.y = std::min(data.y, pointMin.y);
358 pointMin.z = std::min(data.z, pointMin.z);
360 pointMax.x = std::max(data.x, pointMax.x);
361 pointMax.y = std::max(data.y, pointMax.y);
362 pointMax.z = std::max(data.z, pointMax.z);
364 meshInfo.size = pointMax - pointMin;
365 meshInfo.pivot.x = (-pointMin.x) / (pointMax.x - pointMin.x);
366 meshInfo.pivot.y = (-pointMin.y) / (pointMax.y - pointMin.y);
367 meshInfo.pivot.z = (-pointMin.z) / (pointMax.z - pointMin.z);
369 Vector3 center = meshInfo.size * 0.5 + pointMin;
370 for(auto&& data : vertexBufferData)
372 data = data - center;
373 data.x = data.x / meshInfo.size.x;
374 data.y = data.y / meshInfo.size.y;
375 data.z = data.z / meshInfo.size.z;
380 VertexBuffer CreateVertexBuffer(Vector<T> bufferData, std::string map, int32_t type)
382 Property::Map positionMap;
383 positionMap[map] = type;
385 VertexBuffer vertexBuffer = VertexBuffer::New(positionMap);
386 vertexBuffer.SetData(bufferData.Begin(), bufferData.Count());
390 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)
394 Dali::Vector<Vector3> bufferData;
395 LoadDataFromAccessor(accessorIdx, bufferData, path, accessorArray, bufferViewArray, bufferArray);
396 SetMeshInfoAndCanonize(meshInfo, bufferData);
398 VertexBuffer vertexBuffer = CreateVertexBuffer<Vector3>(bufferData, map, type);
399 meshInfo.geometry.AddVertexBuffer(vertexBuffer);
404 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)
408 Dali::Vector<T> bufferData;
409 LoadDataFromAccessor(accessorIdx, bufferData, path, accessorArray, bufferViewArray, bufferArray);
411 VertexBuffer vertexBuffer = CreateVertexBuffer<T>(bufferData, map, type);
412 meshInfo.geometry.AddVertexBuffer(vertexBuffer);
416 void SetIndexBuffersData(MeshInfo& meshInfo, std::string path, std::vector<AccessorInfo>& accessorArray, std::vector<BufferViewInfo>& bufferViewArray, std::vector<BufferInfo>& bufferArray, int32_t indexIdx)
418 Dali::Vector<uint16_t> indexBufferData;
419 LoadDataFromAccessor(indexIdx, indexBufferData, path, accessorArray, bufferViewArray, bufferArray);
420 meshInfo.geometry.SetIndexBuffer(&indexBufferData[0], indexBufferData.Size());
424 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)
426 Dali::Vector<float> inputBufferData;
427 Dali::Vector<T> outputBufferData;
429 LoadDataFromAccessor<float>(currentSampler.input, inputBufferData, path, accessorArray, bufferViewArray, bufferArray);
430 LoadDataFromAccessor<T>(currentSampler.output, outputBufferData, path, accessorArray, bufferViewArray, bufferArray);
432 uint32_t keyframeNum = inputBufferData.Size();
433 float lengthAnimation = inputBufferData[inputBufferData.Size() - 1];
434 for(uint32_t i = 0; i < keyframeNum; i++)
436 if(propIndex == Dali::Actor::Property::ORIENTATION)
438 Vector4 vectorOrientation(outputBufferData[i]);
439 float vW = vectorOrientation.w;
440 vW = (vW < 0.0f) ? std::max(vW, -1.0f) : std::min(vW, 1.0f);
441 vectorOrientation.w = vW;
442 keyframes.Add(inputBufferData[i] / lengthAnimation, Quaternion(Vector4(vectorOrientation)));
444 else if(propIndex == Dali::Actor::Property::POSITION)
446 keyframes.Add(inputBufferData[i] / lengthAnimation, Vector3(outputBufferData[i]));
448 else if(propIndex == Dali::Actor::Property::SCALE)
450 keyframes.Add(inputBufferData[i] / lengthAnimation, Vector3(outputBufferData[i]));
453 return lengthAnimation;
456 bool LoadBuffer(const TreeNode& buffer, std::vector<BufferInfo>& bufferArray)
458 BufferInfo bufferInfo;
460 const TreeNode* uriNode = buffer.GetChild("uri");
463 ReadString(uriNode, bufferInfo.uri);
466 const TreeNode* byteLengthNode = buffer.GetChild("byteLength");
469 ReadInt(byteLengthNode, bufferInfo.byteLength);
470 if(bufferInfo.byteLength < 0)
476 const TreeNode* nameNode = buffer.GetChild("name");
479 ReadString(nameNode, bufferInfo.name);
482 bufferArray.push_back(bufferInfo);
487 bool LoadBufferView(const TreeNode& buffer, std::vector<BufferViewInfo>& bufferViewArray)
489 BufferViewInfo bufferViewInfo;
491 const TreeNode* bufferNode = buffer.GetChild("buffer");
494 ReadInt(bufferNode, bufferViewInfo.buffer);
495 if(bufferViewInfo.buffer < 0)
501 const TreeNode* byteOffsetNode = buffer.GetChild("byteOffset");
504 ReadInt(byteOffsetNode, bufferViewInfo.byteOffset);
507 const TreeNode* byteLengthNode = buffer.GetChild("byteLength");
510 ReadInt(byteLengthNode, bufferViewInfo.byteLength);
511 if(bufferViewInfo.byteLength < 0)
517 const TreeNode* byteStrideNode = buffer.GetChild("byteStride");
520 ReadInt(byteStrideNode, bufferViewInfo.byteStride);
523 const TreeNode* targetNode = buffer.GetChild("target");
526 ReadInt(targetNode, bufferViewInfo.target);
529 const TreeNode* nameNode = buffer.GetChild("name");
532 ReadString(nameNode, bufferViewInfo.name);
535 bufferViewArray.push_back(bufferViewInfo);
540 bool LoadAccessor(const TreeNode& buffer, std::vector<AccessorInfo>& accessorArray)
542 AccessorInfo accessorInfo;
544 const TreeNode* bufferViewNode = buffer.GetChild("bufferView");
547 ReadInt(bufferViewNode, accessorInfo.bufferView);
550 const TreeNode* byteOffsetNode = buffer.GetChild("byteOffset");
553 ReadInt(byteOffsetNode, accessorInfo.byteOffset);
556 const TreeNode* componentTypeNode = buffer.GetChild("componentType");
557 if(componentTypeNode)
559 ReadInt(componentTypeNode, accessorInfo.componentType);
560 if(accessorInfo.componentType < 0)
566 const TreeNode* normalizedNode = buffer.GetChild("normalized");
569 ReadBool(normalizedNode, accessorInfo.normalized);
572 const TreeNode* countNode = buffer.GetChild("count");
575 ReadInt(countNode, accessorInfo.count);
576 if(accessorInfo.count < 0)
582 const TreeNode* typeNode = buffer.GetChild("type");
585 ReadString(typeNode, accessorInfo.type);
586 if(accessorInfo.type == "")
592 const TreeNode* maxNode = buffer.GetChild("max");
595 ReadInt(maxNode, accessorInfo.max);
598 const TreeNode* minNode = buffer.GetChild("min");
601 ReadInt(minNode, accessorInfo.min);
604 const TreeNode* nameNode = buffer.GetChild("name");
607 ReadString(nameNode, accessorInfo.name);
610 accessorArray.push_back(accessorInfo);
615 bool LoadBinaryData(const TreeNode& root, std::vector<BufferInfo>& bufferArray, std::vector<BufferViewInfo>& bufferViewArray, std::vector<AccessorInfo>& accessorArray)
617 const TreeNode* buffersNode = root.GetChild("buffers");
622 for(auto bufferIter = buffersNode->CBegin(), end = buffersNode->CEnd(); bufferIter != end; ++bufferIter)
624 LoadBuffer((*bufferIter).second, bufferArray);
627 const TreeNode* bufferViewsNode = root.GetChild("bufferViews");
632 for(auto bufferViewIter = bufferViewsNode->CBegin(), end = bufferViewsNode->CEnd(); bufferViewIter != end; ++bufferViewIter)
634 LoadBufferView((*bufferViewIter).second, bufferViewArray);
637 const TreeNode* accessorsNode = root.GetChild("accessors");
642 for(auto accesorIter = accessorsNode->CBegin(), end = accessorsNode->CEnd(); accesorIter != end; ++accesorIter)
644 LoadAccessor((*accesorIter).second, accessorArray);
650 FilterMode::Type GetFilterMode(uint32_t mode)
652 FilterMode::Type retValue = FilterMode::DEFAULT;
654 * glTF 2.0 Specification
658 * 9984 : NEAREST_MIPMAP_NEAREST
659 * 9985 : LINEAR_MIPMAP_NEAREST
660 * 9986 : NEAREST_MIPMAP_LINEAR
661 * 9987 : LINEAR_MIPMAP_LINEAR
667 retValue = FilterMode::NEAREST;
672 retValue = FilterMode::LINEAR;
677 retValue = FilterMode::NEAREST_MIPMAP_NEAREST;
682 retValue = FilterMode::LINEAR_MIPMAP_NEAREST;
687 retValue = FilterMode::NEAREST_MIPMAP_LINEAR;
692 retValue = FilterMode::LINEAR_MIPMAP_LINEAR;
700 WrapMode::Type GetWrapMode(uint32_t mode)
702 WrapMode::Type retValue = WrapMode::REPEAT;
704 * glTF 2.0 Specification
706 * 33071 : CLAMP_TO_EDGE
707 * 33648 : MIRRORED_REPEAT
714 retValue = WrapMode::CLAMP_TO_EDGE;
719 retValue = WrapMode::MIRRORED_REPEAT;
724 retValue = WrapMode::REPEAT;
732 Texture LoadTexture(const char* imageUrl, bool generateMipmaps)
735 Devel::PixelBuffer pixelBuffer = LoadImageFromFile(imageUrl);
738 texture = Texture::New(TextureType::TEXTURE_2D, pixelBuffer.GetPixelFormat(), pixelBuffer.GetWidth(), pixelBuffer.GetHeight());
739 PixelData pixelData = Devel::PixelBuffer::Convert(pixelBuffer);
740 texture.Upload(pixelData);
744 texture.GenerateMipmaps();
751 Sampler LoadSampler(const TreeNode& samplerNode)
753 Sampler sampler = Sampler::New();
755 FilterMode::Type minFilter = FilterMode::DEFAULT;
756 FilterMode::Type magFilter = FilterMode::DEFAULT;
757 const TreeNode* magFilterNode = samplerNode.GetChild("magFilter");
760 int32_t magFilter_integer = 0;
761 ReadInt(magFilterNode, magFilter_integer);
762 magFilter = GetFilterMode(magFilter_integer);
765 const TreeNode* minFilterNode = samplerNode.GetChild("minFilter");
768 int32_t minFilter_integer = 0;
769 ReadInt(minFilterNode, minFilter_integer);
770 minFilter = GetFilterMode(minFilter_integer);
773 WrapMode::Type wrapR = WrapMode::REPEAT;
774 WrapMode::Type wrapS = WrapMode::REPEAT;
775 WrapMode::Type wrapT = WrapMode::REPEAT;
776 const TreeNode* wrapNode = samplerNode.GetChild("wrapS");
779 wrapS = GetWrapMode(wrapNode->GetInteger());
782 wrapNode = samplerNode.GetChild("wrapT");
785 wrapT = GetWrapMode(wrapNode->GetInteger());
788 sampler.SetFilterMode(minFilter, magFilter);
789 sampler.SetWrapMode(wrapR, wrapS, wrapT);
794 bool LoadTextureArray(const TreeNode& root, std::string path, std::vector<Texture>& sourceArray, std::vector<Sampler>& samplerArray, std::vector<TextureInfo>& textureArray)
796 const TreeNode* imagesNode = root.GetChild("images");
799 for(auto imageIter = imagesNode->CBegin(), end = imagesNode->CEnd(); imageIter != end; ++imageIter)
801 std::string imageUrl;
802 const TreeNode* uriNode = (&((*imageIter).second))->GetChild("uri");
806 ReadString(uriNode, uri);
807 imageUrl = path + uri;
810 sourceArray.push_back(LoadTexture(imageUrl.c_str(), true));
814 const TreeNode* samplersNode = root.GetChild("samplers");
817 for(auto samplerIter = samplersNode->CBegin(), end = samplersNode->CEnd(); samplerIter != end; ++samplerIter)
819 samplerArray.push_back(LoadSampler(((*samplerIter).second)));
823 const TreeNode* texturesNode = root.GetChild("textures");
826 for(auto textureIter = texturesNode->CBegin(), end = texturesNode->CEnd(); textureIter != end; ++textureIter)
828 const TreeNode* TextureNode = &((*textureIter).second);
831 const TreeNode* sourceNode = TextureNode->GetChild("source");
834 ReadInt(sourceNode, texture.sourceIdx);
837 const TreeNode* samplerNode = TextureNode->GetChild("sampler");
840 ReadInt(samplerNode, texture.samplerIdx);
843 textureArray.push_back(texture);
849 bool LoadPbrMetallicRoughness(const TreeNode& material, MaterialInfo& materialInfo)
852 const TreeNode* pbrMetallicRoughnessNode = material.GetChild("pbrMetallicRoughness");
853 if(!pbrMetallicRoughnessNode)
858 const TreeNode* tempNode;
859 tempNode = pbrMetallicRoughnessNode->GetChild("metallicFactor");
862 ReadFloat(tempNode, materialInfo.metallicFactor);
865 tempNode = pbrMetallicRoughnessNode->GetChild("roughnessFactor");
868 ReadFloat(tempNode, materialInfo.roughnessFactor);
871 tempNode = pbrMetallicRoughnessNode->GetChild("baseColorFactor");
872 if(tempNode && ReadVector(tempNode, floatVec, 4))
874 materialInfo.baseColorFactor = Vector4(floatVec[0], floatVec[1], floatVec[2], floatVec[3]);
877 const TreeNode* baseColorTextureNode = pbrMetallicRoughnessNode->GetChild("baseColorTexture");
878 if(baseColorTextureNode)
880 tempNode = baseColorTextureNode->GetChild("index");
883 materialInfo.baseColorTexture.index = tempNode->GetInteger();
886 tempNode = baseColorTextureNode->GetChild("texCoord");
889 materialInfo.baseColorTexture.texCoord = tempNode->GetInteger();
893 const TreeNode* metallicRoughnessTextureNode = pbrMetallicRoughnessNode->GetChild("metallicRoughnessTexture");
894 if(metallicRoughnessTextureNode)
896 tempNode = metallicRoughnessTextureNode->GetChild("index");
899 materialInfo.metallicRoughnessTexture.index = tempNode->GetInteger();
902 tempNode = metallicRoughnessTextureNode->GetChild("texCoord");
905 materialInfo.metallicRoughnessTexture.texCoord = tempNode->GetInteger();
912 bool LoadMaterialSetArray(const TreeNode& root, std::vector<MaterialInfo>& materialArray)
914 const TreeNode* materialsNode = root.GetChild("materials");
920 for(auto materialIter = materialsNode->CBegin(), end = materialsNode->CEnd(); materialIter != end; ++materialIter)
922 MaterialInfo materialInfo;
923 LoadPbrMetallicRoughness(((*materialIter).second), materialInfo);
925 const TreeNode* materialNode = &((*materialIter).second);
926 const TreeNode* tempNode = materialNode->GetChild("name");
929 ReadString(tempNode, materialInfo.name);
932 materialInfo.alphaMode = "OPAQUE";
933 tempNode = materialNode->GetChild("alphaMode");
936 ReadString(tempNode, materialInfo.alphaMode);
939 materialInfo.alphaCutoff = 1.0;
940 tempNode = materialNode->GetChild("alphaCutoff");
943 ReadFloat(tempNode, materialInfo.alphaCutoff);
946 materialInfo.doubleSided = false;
947 tempNode = materialNode->GetChild("doubleSided");
950 ReadBool(tempNode, materialInfo.doubleSided);
954 tempNode = materialNode->GetChild("emissiveFactor");
955 if(tempNode && ReadVector(tempNode, floatVec, 3))
957 materialInfo.emissiveFactor = Vector3(floatVec[0], floatVec[1], floatVec[2]);
960 const TreeNode* texture = materialNode->GetChild("normalTexture");
963 tempNode = texture->GetChild("index");
966 materialInfo.normalTexture.index = tempNode->GetInteger();
969 tempNode = texture->GetChild("texCoord");
972 materialInfo.normalTexture.texCoord = tempNode->GetInteger();
975 materialInfo.normalTexture.value = 1.0;
976 tempNode = texture->GetChild("scale");
979 ReadFloat(tempNode, materialInfo.normalTexture.value);
983 texture = materialNode->GetChild("occlusionTexture");
986 tempNode = texture->GetChild("index");
989 materialInfo.occlusionTexture.index = tempNode->GetInteger();
992 tempNode = texture->GetChild("texCoord");
995 materialInfo.occlusionTexture.texCoord = tempNode->GetInteger();
998 tempNode = texture->GetChild("strength");
1001 ReadFloat(tempNode, materialInfo.occlusionTexture.value);
1005 texture = materialNode->GetChild("emissiveTexture");
1008 tempNode = texture->GetChild("index");
1011 materialInfo.emissiveTexture.index = tempNode->GetInteger();
1014 tempNode = texture->GetChild("texCoord");
1017 materialInfo.emissiveTexture.texCoord = tempNode->GetInteger();
1020 materialArray.push_back(materialInfo);
1025 bool LoadAttribute(const TreeNode* primitive, MeshInfo& meshInfo)
1027 const TreeNode* attrbuteNode = primitive->GetChild("attributes");
1033 const TreeNode* tempNode;
1034 tempNode = attrbuteNode->GetChild("POSITION");
1037 meshInfo.attribute.POSITION = tempNode->GetInteger();
1040 tempNode = attrbuteNode->GetChild("NORMAL");
1043 meshInfo.attribute.NORMAL = tempNode->GetInteger();
1046 tempNode = attrbuteNode->GetChild("TANGENT");
1049 meshInfo.attribute.TANGENT = tempNode->GetInteger();
1053 meshInfo.attribute.TEXCOORD.clear();
1054 tempNode = attrbuteNode->GetChild("TEXCOORD_" + std::to_string(index));
1057 uint32_t value = tempNode->GetInteger();
1058 meshInfo.attribute.TEXCOORD.push_back(value);
1059 tempNode = attrbuteNode->GetChild("TEXCOORD_" + std::to_string(++index));
1063 meshInfo.attribute.COLOR.clear();
1064 tempNode = attrbuteNode->GetChild("COLOR_" + std::to_string(index));
1067 uint32_t value = tempNode->GetInteger();
1068 meshInfo.attribute.COLOR.push_back(value);
1069 tempNode = attrbuteNode->GetChild("COLOR" + std::to_string(++index));
1075 bool LoadPrimitive(const TreeNode& mesh, MeshInfo& meshInfo)
1077 const TreeNode* primitivesNode = mesh.GetChild("primitives");
1083 for(auto primitiveIter = primitivesNode->CBegin(), end = primitivesNode->CEnd(); primitiveIter != end; ++primitiveIter)
1085 const TreeNode* primitiveNode = (&(*primitiveIter).second);
1086 const TreeNode* tempNode;
1088 tempNode = primitiveNode->GetChild("indices");
1091 meshInfo.indicesIdx = tempNode->GetInteger();
1094 tempNode = primitiveNode->GetChild("material");
1097 meshInfo.materialsIdx = tempNode->GetInteger();
1100 tempNode = primitiveNode->GetChild("mode");
1103 meshInfo.mode = tempNode->GetInteger();
1106 LoadAttribute(primitiveNode, meshInfo);
1112 bool SetGeometry(MeshInfo& meshInfo, std::string path, std::vector<BufferInfo>& bufferArray, std::vector<BufferViewInfo>& bufferViewArray, std::vector<AccessorInfo>& accessorArray)
1114 int32_t indicesIdx = meshInfo.indicesIdx;
1116 if(meshInfo.mode != 0)
1118 meshInfo.geometry.SetType((Dali::Geometry::Type)meshInfo.mode);
1123 SetIndexBuffersData(meshInfo, path, accessorArray, bufferViewArray, bufferArray, indicesIdx);
1126 SetVertexBufferData(meshInfo, path, accessorArray, bufferViewArray, bufferArray, meshInfo.attribute.POSITION, "aPosition", Property::VECTOR3);
1127 SetAttributeBufferData<Vector3>(meshInfo, path, accessorArray, bufferViewArray, bufferArray, meshInfo.attribute.NORMAL, "aNormal", Property::VECTOR3);
1128 SetAttributeBufferData<Vector4>(meshInfo, path, accessorArray, bufferViewArray, bufferArray, meshInfo.attribute.TANGENT, "aTangent", Property::VECTOR4);
1130 for(uint32_t i = 0; i < meshInfo.attribute.TEXCOORD.size(); ++i)
1132 int32_t accessorIdx = meshInfo.attribute.TEXCOORD[i];
1133 std::ostringstream texCoordString;
1134 texCoordString << "aTexCoord" << i;
1135 SetAttributeBufferData<Vector2>(meshInfo, path, accessorArray, bufferViewArray, bufferArray, accessorIdx, texCoordString.str(), Property::VECTOR2);
1138 for(auto&& accessorIdx : meshInfo.attribute.COLOR)
1145 if(accessorArray[accessorIdx].type == "VEC3")
1147 Dali::Vector<Vector3> inputBufferData;
1148 LoadDataFromAccessor(accessorIdx, inputBufferData, path, accessorArray, bufferViewArray, bufferArray);
1150 Dali::Vector<Vector4> bufferData;
1151 bufferData.Resize(inputBufferData.Size());
1152 for(uint32_t i = 0; i < inputBufferData.Size(); ++i)
1154 bufferData[i].x = inputBufferData[i].x;
1155 bufferData[i].y = inputBufferData[i].y;
1156 bufferData[i].z = inputBufferData[i].z;
1157 bufferData[i].w = 1.0;
1159 VertexBuffer vertexBuffer = CreateVertexBuffer<Vector4>(bufferData, "aVertexColor", Property::VECTOR4);
1160 meshInfo.geometry.AddVertexBuffer(vertexBuffer);
1162 else if(accessorArray[accessorIdx].type == "VEC4")
1164 SetAttributeBufferData<Vector4>(meshInfo, path, accessorArray, bufferViewArray, bufferArray, accessorIdx, "aVertexColor", Property::VECTOR4);
1170 bool LoadMeshArray(const TreeNode& root, std::string path, std::vector<MeshInfo>& meshArray, std::vector<BufferInfo>& bufferArray, std::vector<BufferViewInfo>& bufferViewArray, std::vector<AccessorInfo>& accessorArray)
1172 const TreeNode* meshesNode = root.GetChild("meshes");
1178 for(auto meshIter = meshesNode->CBegin(), end = meshesNode->CEnd(); meshIter != end; ++meshIter)
1181 const TreeNode* nameNode = (&(*meshIter).second)->GetChild("name");
1184 ReadString(nameNode, meshInfo.name);
1186 meshInfo.geometry = Geometry::New();
1188 //Need to add weights for Morph targets.
1189 LoadPrimitive((*meshIter).second, meshInfo);
1190 SetGeometry(meshInfo, path, bufferArray, bufferViewArray, accessorArray);
1191 meshArray.push_back(meshInfo);
1209 bool Loader::LoadScene(const std::string& filePath, Internal::Scene3dView& scene3dView)
1211 // Extracting directory path from full path to load resources.
1212 if(std::string::npos != filePath.rfind('/'))
1214 mPath = filePath.substr(0, filePath.rfind('/')) + "/";
1217 if(!ParseGltf(filePath))
1219 DALI_LOG_ERROR("Fail to parse json file\n");
1223 mRoot = mParser.GetRoot();
1226 CreateScene(scene3dView))
1233 bool Loader::ParseGltf(const std::string& filePath)
1235 std::streampos bufferSize = 0;
1236 Dali::Vector<char> buffer;
1237 std::string fileBuffer;
1238 if(!Dali::FileLoader::ReadFile(filePath, bufferSize, buffer, FileLoader::FileType::BINARY))
1243 fileBuffer.assign(&buffer[0], bufferSize);
1244 mParser = Dali::Toolkit::JsonParser::New();
1245 return mParser.Parse(fileBuffer);
1248 bool Loader::LoadAssets()
1250 if(LoadBinaryData(*mRoot, mBufferArray, mBufferViewArray, mAccessorArray) &&
1251 LoadTextureArray(*mRoot, mPath, mSourceArray, mSamplerArray, mTextureArray) &&
1252 LoadMaterialSetArray(*mRoot, mMaterialArray) &&
1253 LoadMeshArray(*mRoot, mPath, mMeshArray, mBufferArray, mBufferViewArray, mAccessorArray))
1260 bool Loader::CreateScene(Internal::Scene3dView& scene3dView)
1262 scene3dView.SetDefaultCamera(Dali::Camera::LOOK_AT_TARGET, 0.01, Vector3::ZERO);
1263 LoadCamera(scene3dView);
1265 if(LoadSceneNodes(scene3dView) &&
1266 LoadAnimation(scene3dView))
1273 void Loader::LoadCamera(Scene3dView& scene3dView)
1275 const TreeNode* camerasNode = mRoot->GetChild("cameras");
1281 for(auto cameraIter = camerasNode->CBegin(), end = camerasNode->CEnd(); cameraIter != end; ++cameraIter)
1283 const TreeNode* tempNode = (&(*cameraIter).second)->GetChild("name");
1284 CameraInfo cameraInfo;
1287 ReadString(tempNode, cameraInfo.name);
1290 tempNode = (&(*cameraIter).second)->GetChild("type");
1293 ReadString(tempNode, cameraInfo.type);
1296 CameraActor cameraActor = CameraActor::New();
1297 cameraActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
1298 cameraActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
1300 if(cameraInfo.type == "orthographic")
1302 LoadOrthoGraphic((*cameraIter).second, cameraInfo);
1303 float xMag_2 = cameraInfo.orthographic.xmag / 2.0;
1304 float yMag_2 = cameraInfo.orthographic.ymag / 2.0;
1305 cameraActor.SetOrthographicProjection(-xMag_2, xMag_2, yMag_2, -yMag_2, cameraInfo.orthographic.znear, cameraInfo.orthographic.zfar);
1307 else if(cameraInfo.type == "perspective")
1309 if(!LoadPerspective((*cameraIter).second, cameraInfo))
1313 cameraActor.SetProjectionMode(Dali::Camera::PERSPECTIVE_PROJECTION);
1314 cameraActor.SetFieldOfView(cameraInfo.perspective.yfov);
1315 cameraActor.SetNearClippingPlane(cameraInfo.perspective.znear);
1317 if(cameraInfo.perspective.zfar > 0.0)
1319 cameraActor.SetFarClippingPlane(cameraInfo.perspective.zfar);
1321 if(cameraInfo.perspective.aspectRatio > 0.0)
1323 cameraActor.SetAspectRatio(cameraInfo.perspective.aspectRatio);
1327 scene3dView.AddCamera(cameraActor);
1331 bool Loader::LoadOrthoGraphic(const TreeNode& camera, CameraInfo& cameraInfo)
1333 const TreeNode* orthographicNode = camera.GetChild("orthographic");
1334 if(!orthographicNode)
1339 const TreeNode* tempNode;
1340 tempNode = orthographicNode->GetChild("xmag");
1343 ReadFloat(tempNode, cameraInfo.orthographic.xmag);
1346 tempNode = orthographicNode->GetChild("ymag");
1349 ReadFloat(tempNode, cameraInfo.orthographic.ymag);
1352 tempNode = orthographicNode->GetChild("zfar");
1355 ReadFloat(tempNode, cameraInfo.orthographic.zfar);
1358 tempNode = orthographicNode->GetChild("znear");
1361 ReadFloat(tempNode, cameraInfo.orthographic.znear);
1367 bool Loader::LoadPerspective(const TreeNode& camera, CameraInfo& cameraInfo)
1369 const TreeNode* perspectiveNode = camera.GetChild("perspective");
1370 if(!perspectiveNode)
1375 const TreeNode* tempNode;
1376 tempNode = perspectiveNode->GetChild("aspectRatio");
1379 ReadFloat(tempNode, cameraInfo.perspective.aspectRatio);
1382 tempNode = perspectiveNode->GetChild("yfov");
1385 ReadFloat(tempNode, cameraInfo.perspective.yfov);
1388 tempNode = perspectiveNode->GetChild("zfar");
1391 ReadFloat(tempNode, cameraInfo.perspective.zfar);
1394 tempNode = perspectiveNode->GetChild("znear");
1397 ReadFloat(tempNode, cameraInfo.perspective.znear);
1403 bool Loader::LoadSceneNodes(Scene3dView& scene3dView)
1405 const TreeNode* sceneNode = mRoot->GetChild("scene");
1406 uint32_t sceneNum = 0;
1409 sceneNum = sceneNode->GetInteger();
1412 const TreeNode* scenesNode = mRoot->GetChild("scenes");
1413 if(!(scenesNode && (mNodes = mRoot->GetChild("nodes"))))
1418 const TreeNode* tempNode = Tidx(scenesNode, sceneNum);
1424 tempNode = tempNode->GetChild("nodes");
1430 for(auto nodeIter = tempNode->CBegin(), end = tempNode->CEnd(); nodeIter != end; ++nodeIter)
1432 Actor actor = AddNode(scene3dView, ((*nodeIter).second).GetInteger());
1433 actor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
1434 scene3dView.GetRoot().Add(actor);
1440 Actor Loader::AddNode(Scene3dView& scene3dView, uint32_t index)
1442 const TreeNode* node = Tidx(mNodes, index);
1443 Actor actor = Actor::New();
1444 Vector3 actorSize(Vector3::ONE);
1446 Vector3 translation = Vector3(0.0, 0.0, 0.0);
1447 Vector3 scale = Vector3(1.0, 1.0, 1.0);
1448 Quaternion orientation(Vector4(0.0, 0.0, 0.0, 1.0));
1450 Vector3 anchorPoint = AnchorPoint::CENTER;
1452 const TreeNode* tempNode = NULL;
1453 if((tempNode = node->GetChild("translation")))
1455 float floatVec[3] = {0.0, 0.0, 0.0};
1456 if(tempNode && ReadVector(tempNode, floatVec, 3))
1458 translation = Vector3(floatVec[0], floatVec[1], floatVec[2]);
1462 if((tempNode = node->GetChild("scale")))
1464 float floatVec[3] = {1.0, 1.0, 1.0};
1465 if(tempNode && ReadVector(tempNode, floatVec, 3))
1467 scale = Vector3(floatVec[0], floatVec[1], floatVec[2]);
1471 if((tempNode = node->GetChild("rotation")))
1473 float floatVec[4] = {0.0, 0.0, 0.0, 1.0};
1474 if(tempNode && ReadVector(tempNode, floatVec, 4))
1476 orientation = Quaternion(Vector4(floatVec[0], floatVec[1], floatVec[2], floatVec[3]));
1480 if((tempNode = node->GetChild("matrix")))
1482 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};
1483 if(tempNode && ReadVector(tempNode, floatVec, 16))
1485 Matrix nodeMatrix = Matrix(floatVec);
1486 nodeMatrix.GetTransformComponents(translation, orientation, scale);
1490 if((tempNode = node->GetChild("mesh")))
1492 MeshInfo meshInfo = mMeshArray[tempNode->GetInteger()];
1493 bool isMaterial = (meshInfo.materialsIdx >= 0);
1495 TextureSet textureSet;
1496 textureSet = TextureSet::New();
1499 int32_t shaderTypeIndex = 0;
1500 int32_t maxMipmapLevel = 0;
1501 bool isBaseColorTexture = false;
1502 bool isMetallicRoughnessTexture = false;
1503 bool isNormalTexture = false;
1504 bool isOcclusionTexture = false;
1505 bool isEmissiveTexture = false;
1507 std::string VERTEX_SHADER, FRAGMENT_SHADER;
1508 VERTEX_SHADER = SHADER_GLTF_GLES_VERSION_300_DEF.data();
1509 VERTEX_SHADER += SHADER_GLTF_PHYSICALLY_BASED_SHADER_VERT.data();
1510 FRAGMENT_SHADER = SHADER_GLTF_GLES_VERSION_300_DEF.data();
1512 bool useIBL = (scene3dView.GetLightType() >= Toolkit::Scene3dView::LightType::IMAGE_BASED_LIGHT);
1515 MaterialInfo materialInfo = mMaterialArray[meshInfo.materialsIdx];
1516 if(SetTextureAndSampler(textureSet, materialInfo.baseColorTexture.index, FRAGMENT_SHADER, SHADER_GLTF_BASECOLOR_TEXTURE_DEF.data(), addIdx))
1518 shaderTypeIndex += static_cast<int32_t>(ShaderType::BASECOLOR_SHADER);
1519 isBaseColorTexture = true;
1521 if(SetTextureAndSampler(textureSet, materialInfo.metallicRoughnessTexture.index, FRAGMENT_SHADER, SHADER_GLTF_METALLICROUGHNESS_TEXTURE_DEF.data(), addIdx))
1523 shaderTypeIndex += static_cast<int32_t>(ShaderType::METALLICROUGHNESS_SHADER);
1524 isMetallicRoughnessTexture = true;
1526 if(SetTextureAndSampler(textureSet, materialInfo.normalTexture.index, FRAGMENT_SHADER, SHADER_GLTF_NORMAL_TEXTURE_DEF.data(), addIdx))
1528 shaderTypeIndex += static_cast<int32_t>(ShaderType::NORMAL_SHADER);
1529 isNormalTexture = true;
1531 if(SetTextureAndSampler(textureSet, materialInfo.occlusionTexture.index, FRAGMENT_SHADER, SHADER_GLTF_OCCULUSION_TEXTURE_DEF.data(), addIdx))
1533 shaderTypeIndex += static_cast<int32_t>(ShaderType::OCCLUSION_SHADER);
1534 isOcclusionTexture = true;
1536 if(SetTextureAndSampler(textureSet, materialInfo.emissiveTexture.index, FRAGMENT_SHADER, SHADER_GLTF_EMIT_TEXTURE_DEF.data(), addIdx))
1538 shaderTypeIndex += static_cast<int32_t>(ShaderType::EMIT_SHADER);
1539 isEmissiveTexture = true;
1544 shaderTypeIndex += static_cast<int32_t>(ShaderType::IBL_SHADER);
1545 FRAGMENT_SHADER += SHADER_GLTF_IBL_TEXTURE_DEF.data();
1547 Sampler sampler = Sampler::New();
1548 sampler.SetFilterMode(FilterMode::DEFAULT, FilterMode::DEFAULT);
1549 sampler.SetWrapMode(WrapMode::REPEAT, WrapMode::REPEAT, WrapMode::REPEAT);
1551 textureSet.SetTexture(addIdx, scene3dView.GetBRDFTexture());
1552 textureSet.SetSampler(addIdx++, sampler);
1553 Sampler samplerIBL = Sampler::New();
1554 samplerIBL.SetFilterMode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR);
1555 samplerIBL.SetWrapMode(WrapMode::CLAMP_TO_EDGE, WrapMode::CLAMP_TO_EDGE, WrapMode::CLAMP_TO_EDGE);
1556 textureSet.SetTexture(addIdx, scene3dView.GetDiffuseTexture());
1557 textureSet.SetSampler(addIdx++, samplerIBL);
1558 Texture specularTexture = scene3dView.GetSpecularTexture();
1559 textureSet.SetTexture(addIdx, specularTexture);
1560 textureSet.SetSampler(addIdx++, samplerIBL);
1562 int32_t textureSize = std::min(specularTexture.GetWidth(), specularTexture.GetHeight());
1564 while(textureSize >= 1)
1572 FRAGMENT_SHADER += SHADER_GLTF_PHYSICALLY_BASED_SHADER_FRAG.data();
1573 if(!mShaderCache[shaderTypeIndex])
1575 mShaderCache[shaderTypeIndex] = Shader::New(VERTEX_SHADER, FRAGMENT_SHADER);
1576 scene3dView.AddShader(mShaderCache[shaderTypeIndex]);
1578 Shader shader = mShaderCache[shaderTypeIndex];
1580 Renderer renderer = Renderer::New(meshInfo.geometry, shader);
1581 renderer.SetProperty(Renderer::Property::DEPTH_WRITE_MODE, DepthWriteMode::ON);
1582 renderer.SetProperty(Renderer::Property::DEPTH_TEST_MODE, DepthTestMode::ON);
1583 renderer.SetTextures(textureSet);
1585 anchorPoint = meshInfo.pivot;
1586 actor.SetProperty(Actor::Property::ANCHOR_POINT, anchorPoint);
1588 actor.SetProperty(Actor::Property::SIZE, Vector3(meshInfo.size.x, meshInfo.size.y, meshInfo.size.z));
1589 actor.AddRenderer(renderer);
1591 actor.SetProperty(Actor::Property::SCALE, scale);
1592 actor.RotateBy(orientation);
1593 actor.SetProperty(Actor::Property::POSITION, translation);
1595 shader.RegisterProperty("uLightType", (scene3dView.GetLightType() & ~Toolkit::Scene3dView::LightType::IMAGE_BASED_LIGHT));
1596 shader.RegisterProperty("uLightVector", scene3dView.GetLightVector());
1597 shader.RegisterProperty("uLightColor", scene3dView.GetLightColor());
1599 actor.RegisterProperty("uIsColor", meshInfo.attribute.COLOR.size() > 0);
1602 MaterialInfo materialInfo = mMaterialArray[meshInfo.materialsIdx];
1603 actor.RegisterProperty("uBaseColorFactor", materialInfo.baseColorFactor);
1604 actor.RegisterProperty("uMetallicRoughnessFactors", Vector2(materialInfo.metallicFactor, materialInfo.roughnessFactor));
1606 if(materialInfo.alphaMode == "OPAQUE")
1608 actor.RegisterProperty("alphaMode", 0);
1610 else if(materialInfo.alphaMode == "MASK")
1612 actor.RegisterProperty("alphaMode", 1);
1616 actor.RegisterProperty("alphaMode", 2);
1618 actor.RegisterProperty("alphaCutoff", materialInfo.alphaCutoff);
1620 if(isBaseColorTexture)
1622 actor.RegisterProperty("uBaseColorTexCoordIndex", materialInfo.baseColorTexture.texCoord);
1624 if(isMetallicRoughnessTexture)
1626 actor.RegisterProperty("uMetallicRoughnessTexCoordIndex", materialInfo.metallicRoughnessTexture.texCoord);
1630 actor.RegisterProperty("uNormalScale", materialInfo.normalTexture.value);
1631 actor.RegisterProperty("uNormalTexCoordIndex", materialInfo.normalTexture.texCoord);
1633 if(isOcclusionTexture)
1635 actor.RegisterProperty("uOcclusionTexCoordIndex", materialInfo.occlusionTexture.texCoord);
1636 actor.RegisterProperty("uOcclusionStrength", materialInfo.occlusionTexture.value);
1638 if(isEmissiveTexture)
1640 actor.RegisterProperty("uEmissiveTexCoordIndex", materialInfo.emissiveTexture.texCoord);
1641 actor.RegisterProperty("uEmissiveFactor", materialInfo.emissiveFactor);
1645 if(isMaterial && useIBL)
1647 actor.RegisterProperty("uScaleIBLAmbient", scene3dView.GetIBLScaleFactor());
1648 actor.RegisterProperty("uMipmapLevel", static_cast<float>(maxMipmapLevel));
1653 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
1654 actor.SetProperty(Actor::Property::POSITION, translation);
1655 actor.RotateBy(orientation);
1656 actor.SetProperty(Actor::Property::SIZE, actorSize);
1659 tempNode = node->GetChild("camera");
1662 int32_t cameraNum = tempNode->GetInteger();
1663 CameraActor cameraActor = scene3dView.GetCamera(cameraNum);
1666 actor.Add(cameraActor);
1670 tempNode = node->GetChild("name");
1673 std::string nameString;
1674 ReadString(tempNode, nameString);
1675 actor.SetProperty(Dali::Actor::Property::NAME, nameString);
1678 SetActorCache(actor, index);
1679 if((tempNode = node->GetChild("children")))
1681 for(auto childIter = tempNode->CBegin(), end = tempNode->CEnd(); childIter != end; ++childIter)
1683 Actor childActor = AddNode(scene3dView, ((*childIter).second).GetInteger());
1684 childActor.SetProperty(Actor::Property::PARENT_ORIGIN, anchorPoint);
1685 actor.Add(childActor);
1692 void Loader::SetActorCache(Actor& actor, uint32_t index)
1694 if(mActorCache.size() < index + 1)
1696 mActorCache.resize(index + 1);
1698 mActorCache[index] = actor;
1701 bool Loader::SetTextureAndSampler(TextureSet& textureSet, int32_t textureIdx, std::string& toShader, std::string shader, int32_t& addIdx)
1706 TextureInfo textureInfo = mTextureArray[textureIdx];
1707 if(textureInfo.sourceIdx >= 0)
1709 textureSet.SetTexture(addIdx, mSourceArray[textureInfo.sourceIdx]);
1711 if(textureInfo.samplerIdx >= 0)
1713 textureSet.SetSampler(addIdx, mSamplerArray[textureInfo.samplerIdx]);
1717 Sampler sampler = Sampler::New();
1718 sampler.SetFilterMode(FilterMode::DEFAULT, FilterMode::DEFAULT);
1719 sampler.SetWrapMode(WrapMode::REPEAT, WrapMode::REPEAT, WrapMode::REPEAT);
1720 textureSet.SetSampler(addIdx, sampler);
1728 bool Loader::LoadAnimation(Scene3dView& scene3dView)
1730 const TreeNode* animationsNode = mRoot->GetChild("animations");
1736 for(auto animationIter = animationsNode->CBegin(), end = animationsNode->CEnd(); animationIter != end; ++animationIter)
1738 const TreeNode* nameNode = (&(*animationIter).second)->GetChild("name");
1739 AnimationInfo animationInfo;
1742 ReadString(nameNode, animationInfo.name);
1745 Property::Index propIndex = Property::INVALID_INDEX;
1746 LoadAnimationChannels((*animationIter).second, animationInfo);
1747 if(animationInfo.channelArray.size() == 0)
1752 LoadAnimationSamplers((*animationIter).second, animationInfo);
1754 for(auto&& currentChannel : animationInfo.channelArray)
1756 if(currentChannel.path == "rotation")
1758 propIndex = Dali::Actor::Property::ORIENTATION;
1760 else if(currentChannel.path == "translation")
1762 propIndex = Dali::Actor::Property::POSITION;
1764 else if(currentChannel.path == "scale")
1766 propIndex = Dali::Actor::Property::SCALE;
1769 float duration = 0.0f;
1770 KeyFrames keyframes = KeyFrames::New();
1771 if(propIndex == Dali::Actor::Property::ORIENTATION)
1773 duration = LoadKeyFrames<Vector4>(animationInfo.samplerArray[currentChannel.sampler], propIndex, keyframes, mPath, mAccessorArray, mBufferViewArray, mBufferArray);
1777 duration = LoadKeyFrames<Vector3>(animationInfo.samplerArray[currentChannel.sampler], propIndex, keyframes, mPath, mAccessorArray, mBufferViewArray, mBufferArray);
1780 Animation animation = Animation::New(duration);
1781 Animation::Interpolation interpolation = Animation::Interpolation::LINEAR;
1782 if(animationInfo.samplerArray[currentChannel.sampler].interpolation == "CUBICSPLINE")
1784 interpolation = Animation::Interpolation::CUBIC;
1786 if(animationInfo.samplerArray[currentChannel.sampler].interpolation == "STEP")
1790 animation.AnimateBetween(Property(mActorCache[currentChannel.targetNode], propIndex), keyframes, interpolation);
1792 animation.SetLooping(false);
1793 scene3dView.AddAnimation(animation);
1800 bool Loader::LoadAnimationChannels(const TreeNode& animation, AnimationInfo& animationInfo)
1802 const TreeNode* channelsNode = animation.GetChild("channels");
1808 for(auto channelIter = channelsNode->CBegin(), end = channelsNode->CEnd(); channelIter != end; ++channelIter)
1810 AnimationChannelInfo animationChannelInfo;
1811 const TreeNode* channelNode = (&(*channelIter).second);
1812 const TreeNode* samplerNode = channelNode->GetChild("sampler");
1815 animationChannelInfo.sampler = samplerNode->GetInteger();
1818 const TreeNode* targetNode = channelNode->GetChild("target");
1821 const TreeNode* tempNode = targetNode->GetChild("node");
1824 animationChannelInfo.targetNode = tempNode->GetInteger();
1831 tempNode = targetNode->GetChild("path");
1834 ReadString(tempNode, animationChannelInfo.path);
1838 animationInfo.channelArray.push_back(animationChannelInfo);
1843 bool Loader::LoadAnimationSamplers(const TreeNode& animation, AnimationInfo& animationInfo)
1845 const TreeNode* samplersNode = animation.GetChild("samplers");
1851 for(auto sampler = samplersNode->CBegin(), end = samplersNode->CEnd(); sampler != end; ++sampler)
1853 AnimationSamplerInfo animationSamplerInfo;
1854 const TreeNode* samplerNode = (&(*sampler).second);
1855 const TreeNode* tempNode = samplerNode->GetChild("input");
1858 animationSamplerInfo.input = tempNode->GetInteger();
1861 tempNode = samplerNode->GetChild("output");
1864 animationSamplerInfo.output = tempNode->GetInteger();
1867 tempNode = samplerNode->GetChild("interpolation");
1870 ReadString(tempNode, animationSamplerInfo.interpolation);
1873 animationInfo.samplerArray.push_back(animationSamplerInfo);
1881 } //namespace Internal
1883 } //namespace Toolkit