2 * Copyright (c) 2024 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/actors/camera-actor-devel.h>
24 #include <dali/devel-api/adaptor-framework/file-stream.h>
25 #include <dali/devel-api/adaptor-framework/image-loading.h>
26 #include <dali/integration-api/debug.h>
29 #include <dali-toolkit/internal/controls/scene3d-view/scene3d-view-impl.h>
42 const TreeNode* Tidx(const TreeNode* node, uint32_t index)
45 for(auto it = node->CBegin(), end = node->CEnd(); it != end; ++it, ++i)
49 return &((*it).second);
55 bool ReadBool(const TreeNode* node, bool& num)
61 bool returnValue = false;
63 if(node->GetType() == TreeNode::BOOLEAN)
65 num = node->GetBoolean();
72 bool ReadInt(const TreeNode* node, int32_t& num)
78 bool returnValue = false;
79 if(node->GetType() == TreeNode::INTEGER)
81 num = node->GetInteger();
84 else if(node->GetType() == TreeNode::FLOAT)
86 num = node->GetFloat();
93 bool ReadFloat(const TreeNode* node, float& num)
99 bool returnValue = false;
101 if(node->GetType() == TreeNode::FLOAT)
103 num = node->GetFloat();
106 else if(node->GetType() == TreeNode::INTEGER)
109 ReadInt(node, tempNum);
110 num = static_cast<float>(tempNum);
117 bool ReadVector(const TreeNode* node, float* num, uint32_t size)
123 bool returnValue = false;
125 if((node->Size() >= size) && (node->GetType() == TreeNode::ARRAY))
127 uint32_t offset = 0u;
128 for(auto it = node->CBegin(); offset < size; ++it, ++offset)
130 const TreeNode& coord = (*it).second;
131 if(!ReadFloat(&coord, *(num + offset)))
142 bool ReadString(const TreeNode* node, std::string& strValue)
148 bool returnValue = false;
149 if(node->GetType() == TreeNode::STRING)
151 strValue = node->GetString();
158 float IntToFloat(T element, bool normalize)
162 return static_cast<float>(element);
165 if(std::is_same<T, int8_t>::value)
167 return std::max(static_cast<float>(element) / 127.0, -1.0);
169 if(std::is_same<T, uint8_t>::value)
171 return static_cast<float>(element) / 255.0;
173 if(std::is_same<T, int16_t>::value)
175 return std::max(static_cast<float>(element) / 32767.0, -1.0);
177 if(std::is_same<T, uint16_t>::value)
179 return static_cast<float>(element) / 65535.0;
184 template<typename Td, typename Ts>
185 void FitBuffer(Dali::Vector<Td>& bufferDestination, Dali::Vector<Ts>& bufferSource, int32_t bufferSize, int32_t elementNumOfByteStride, bool normalize)
187 bufferDestination.Resize(bufferSize);
188 int32_t count = bufferSource.Size() / elementNumOfByteStride;
189 for(int32_t i = 0; i < count; ++i)
191 bufferDestination[i] = static_cast<Td>(bufferSource[i * elementNumOfByteStride]);
196 void FitBuffer(Dali::Vector<Vector2>& bufferDestination, Dali::Vector<T>& bufferSource, int32_t bufferSize, int32_t elementNumOfByteStride, bool normalize)
198 bufferDestination.Resize(bufferSize);
199 int32_t count = bufferSource.Size() / elementNumOfByteStride;
200 for(int32_t i = 0; i < count; ++i)
202 bufferDestination[i].x = IntToFloat(bufferSource[i * elementNumOfByteStride], normalize);
203 bufferDestination[i].y = IntToFloat(bufferSource[i * elementNumOfByteStride + 1], normalize);
208 void FitBuffer(Dali::Vector<Vector3>& bufferDestination, Dali::Vector<T>& bufferSource, int32_t bufferSize, int32_t elementNumOfByteStride, bool normalize)
210 bufferDestination.Resize(bufferSize);
211 int32_t count = bufferSource.Size() / elementNumOfByteStride;
212 for(int32_t i = 0; i < count; ++i)
214 bufferDestination[i].x = IntToFloat(bufferSource[i * elementNumOfByteStride], normalize);
215 bufferDestination[i].y = IntToFloat(bufferSource[i * elementNumOfByteStride + 1], normalize);
216 bufferDestination[i].z = IntToFloat(bufferSource[i * elementNumOfByteStride + 2], normalize);
221 void FitBuffer(Dali::Vector<Vector4>& bufferDestination, Dali::Vector<T>& bufferSource, int32_t bufferSize, int32_t elementNumOfByteStride, bool normalize)
223 bufferDestination.Resize(bufferSize);
224 int32_t count = bufferSource.Size() / elementNumOfByteStride;
225 for(int32_t i = 0; i < count; ++i)
227 bufferDestination[i].x = IntToFloat(bufferSource[i * elementNumOfByteStride], normalize);
228 bufferDestination[i].y = IntToFloat(bufferSource[i * elementNumOfByteStride + 1], normalize);
229 bufferDestination[i].z = IntToFloat(bufferSource[i * elementNumOfByteStride + 2], normalize);
230 bufferDestination[i].w = IntToFloat(bufferSource[i * elementNumOfByteStride + 3], normalize);
234 // Template functions
236 bool ReadBinFile(Vector<T>& dataBuffer, std::string url, int32_t offset, int32_t count)
238 size_t readCount = 0;
239 Dali::FileStream fileStream(url, FileStream::READ | FileStream::BINARY);
240 FILE* fp = fileStream.GetFile();
243 dataBuffer.Resize(count);
244 if(!fseek(fp, offset, SEEK_SET))
246 readCount = fread(&dataBuffer[0], sizeof(T), count, fp);
247 dataBuffer.Resize(readCount);
251 return (readCount > 0);
255 void LoadDataFromAccessor(int32_t accessorIdx, Dali::Vector<T>& bufferData, std::string path, std::vector<AccessorInfo>& accessorArray, std::vector<BufferViewInfo>& bufferViewArray, std::vector<BufferInfo>& bufferArray)
257 AccessorInfo accessor = accessorArray[accessorIdx];
258 BufferViewInfo bufferView = bufferViewArray[accessor.bufferView];
259 std::string load_uri = bufferArray[bufferView.buffer].uri;
261 // In the glTF 2.0 Specification, 5121 is UNSIGNED BYTE, 5123 is UNSIGNED SHORT
262 int32_t elementByteSize = (accessor.componentType <= 5121) ? 1 : ((accessor.componentType <= 5123) ? 2 : 4);
263 int32_t elementNum = 1;
264 if(accessor.type == "VEC2")
268 else if(accessor.type == "VEC3")
272 else if(accessor.type == "VEC4" || accessor.type == "MAT2")
276 else if(accessor.type == "MAT3")
280 else if(accessor.type == "MAT4")
288 int32_t elementNumOfByteStride = elementNum;
289 if(bufferView.byteStride > 0)
291 elementNumOfByteStride = bufferView.byteStride / elementByteSize;
295 * glTF 2.0 Specification
298 * 5121 : UNSIGNED_BYTE
300 * 5123 : UNSIGNED_SHORT
301 * 5125 : UNSIGNED_INT
304 if(accessor.componentType == 5120)
306 Dali::Vector<int8_t> inputBufferData;
307 if(ReadBinFile<int8_t>(inputBufferData, path + load_uri, bufferView.byteOffset + accessor.byteOffset, elementNumOfByteStride * accessor.count))
309 FitBuffer(bufferData, inputBufferData, accessor.count, elementNumOfByteStride, accessor.normalized);
312 else if(accessor.componentType == 5121)
314 Dali::Vector<uint8_t> inputBufferData;
315 if(ReadBinFile<uint8_t>(inputBufferData, path + load_uri, bufferView.byteOffset + accessor.byteOffset, elementNumOfByteStride * accessor.count))
317 FitBuffer(bufferData, inputBufferData, accessor.count, elementNumOfByteStride, accessor.normalized);
320 else if(accessor.componentType == 5122)
322 Dali::Vector<int16_t> inputBufferData;
323 if(ReadBinFile<int16_t>(inputBufferData, path + load_uri, bufferView.byteOffset + accessor.byteOffset, elementNumOfByteStride * accessor.count))
325 FitBuffer(bufferData, inputBufferData, accessor.count, elementNumOfByteStride, accessor.normalized);
328 else if(accessor.componentType == 5123)
330 Dali::Vector<uint16_t> inputBufferData;
331 if(ReadBinFile<uint16_t>(inputBufferData, path + load_uri, bufferView.byteOffset + accessor.byteOffset, elementNumOfByteStride * accessor.count))
333 FitBuffer(bufferData, inputBufferData, accessor.count, elementNumOfByteStride, accessor.normalized);
336 else if(accessor.componentType == 5125)
338 Dali::Vector<uint32_t> inputBufferData;
339 if(ReadBinFile<uint32_t>(inputBufferData, path + load_uri, bufferView.byteOffset + accessor.byteOffset, elementNumOfByteStride * accessor.count))
341 FitBuffer(bufferData, inputBufferData, accessor.count, elementNumOfByteStride, accessor.normalized);
344 else if(accessor.componentType == 5126)
346 Dali::Vector<float> inputBufferData;
347 if(ReadBinFile<float>(inputBufferData, path + load_uri, bufferView.byteOffset + accessor.byteOffset, elementNumOfByteStride * accessor.count))
349 FitBuffer(bufferData, inputBufferData, accessor.count, elementNumOfByteStride, accessor.normalized);
354 void SetMeshInfoAndCanonize(MeshInfo& meshInfo, Dali::Vector<Dali::Vector3>& vertexBufferData)
356 Vector3 pointMin(std::numeric_limits<float>::max(), std::numeric_limits<float>::max(), std::numeric_limits<float>::max());
357 Vector3 pointMax(std::numeric_limits<float>::min(), std::numeric_limits<float>::min(), std::numeric_limits<float>::min());
358 for(auto&& data : vertexBufferData)
360 pointMin.x = std::min(data.x, pointMin.x);
361 pointMin.y = std::min(data.y, pointMin.y);
362 pointMin.z = std::min(data.z, pointMin.z);
364 pointMax.x = std::max(data.x, pointMax.x);
365 pointMax.y = std::max(data.y, pointMax.y);
366 pointMax.z = std::max(data.z, pointMax.z);
368 meshInfo.size = pointMax - pointMin;
369 meshInfo.pivot.x = (-pointMin.x) / (pointMax.x - pointMin.x);
370 meshInfo.pivot.y = (-pointMin.y) / (pointMax.y - pointMin.y);
371 meshInfo.pivot.z = (-pointMin.z) / (pointMax.z - pointMin.z);
373 Vector3 center = meshInfo.size * 0.5 + pointMin;
374 for(auto&& data : vertexBufferData)
376 data = data - center;
377 data.x = data.x / meshInfo.size.x;
378 data.y = data.y / meshInfo.size.y;
379 data.z = data.z / meshInfo.size.z;
384 VertexBuffer CreateVertexBuffer(Vector<T> bufferData, std::string map, int32_t type)
386 Property::Map positionMap;
387 positionMap[map] = type;
389 VertexBuffer vertexBuffer = VertexBuffer::New(positionMap);
390 vertexBuffer.SetData(bufferData.Begin(), bufferData.Count());
394 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)
398 Dali::Vector<Vector3> bufferData;
399 LoadDataFromAccessor(accessorIdx, bufferData, std::move(path), accessorArray, bufferViewArray, bufferArray);
400 SetMeshInfoAndCanonize(meshInfo, bufferData);
402 VertexBuffer vertexBuffer = CreateVertexBuffer<Vector3>(bufferData, std::move(map), type);
403 meshInfo.geometry.AddVertexBuffer(vertexBuffer);
408 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)
412 Dali::Vector<T> bufferData;
413 LoadDataFromAccessor(accessorIdx, bufferData, std::move(path), accessorArray, bufferViewArray, bufferArray);
415 VertexBuffer vertexBuffer = CreateVertexBuffer<T>(bufferData, std::move(map), type);
416 meshInfo.geometry.AddVertexBuffer(vertexBuffer);
420 void SetIndexBuffersData(MeshInfo& meshInfo, std::string path, std::vector<AccessorInfo>& accessorArray, std::vector<BufferViewInfo>& bufferViewArray, std::vector<BufferInfo>& bufferArray, int32_t indexIdx)
422 Dali::Vector<uint16_t> indexBufferData;
423 LoadDataFromAccessor(indexIdx, indexBufferData, std::move(path), accessorArray, bufferViewArray, bufferArray);
424 meshInfo.geometry.SetIndexBuffer(&indexBufferData[0], indexBufferData.Size());
428 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)
430 Dali::Vector<float> inputBufferData;
431 Dali::Vector<T> outputBufferData;
433 LoadDataFromAccessor<float>(currentSampler.input, inputBufferData, path, accessorArray, bufferViewArray, bufferArray);
434 LoadDataFromAccessor<T>(currentSampler.output, outputBufferData, path, accessorArray, bufferViewArray, bufferArray);
436 uint32_t keyframeNum = inputBufferData.Size();
437 float lengthAnimation = inputBufferData[inputBufferData.Size() - 1];
438 for(uint32_t i = 0; i < keyframeNum; i++)
440 if(propIndex == Dali::Actor::Property::ORIENTATION)
442 Vector4 vectorOrientation(outputBufferData[i]);
443 float vW = vectorOrientation.w;
444 vW = (vW < 0.0f) ? std::max(vW, -1.0f) : std::min(vW, 1.0f);
445 vectorOrientation.w = vW;
446 keyframes.Add(inputBufferData[i] / lengthAnimation, Quaternion(Vector4(vectorOrientation)));
448 else if(propIndex == Dali::Actor::Property::POSITION)
450 keyframes.Add(inputBufferData[i] / lengthAnimation, Vector3(outputBufferData[i]));
452 else if(propIndex == Dali::Actor::Property::SCALE)
454 keyframes.Add(inputBufferData[i] / lengthAnimation, Vector3(outputBufferData[i]));
457 return lengthAnimation;
460 bool LoadBuffer(const TreeNode& buffer, std::vector<BufferInfo>& bufferArray)
462 BufferInfo bufferInfo;
464 const TreeNode* uriNode = buffer.GetChild("uri");
467 ReadString(uriNode, bufferInfo.uri);
470 const TreeNode* byteLengthNode = buffer.GetChild("byteLength");
473 ReadInt(byteLengthNode, bufferInfo.byteLength);
474 if(bufferInfo.byteLength < 0)
480 const TreeNode* nameNode = buffer.GetChild("name");
483 ReadString(nameNode, bufferInfo.name);
486 bufferArray.push_back(bufferInfo);
491 bool LoadBufferView(const TreeNode& buffer, std::vector<BufferViewInfo>& bufferViewArray)
493 BufferViewInfo bufferViewInfo;
495 const TreeNode* bufferNode = buffer.GetChild("buffer");
498 ReadInt(bufferNode, bufferViewInfo.buffer);
499 if(bufferViewInfo.buffer < 0)
505 const TreeNode* byteOffsetNode = buffer.GetChild("byteOffset");
508 ReadInt(byteOffsetNode, bufferViewInfo.byteOffset);
511 const TreeNode* byteLengthNode = buffer.GetChild("byteLength");
514 ReadInt(byteLengthNode, bufferViewInfo.byteLength);
515 if(bufferViewInfo.byteLength < 0)
521 const TreeNode* byteStrideNode = buffer.GetChild("byteStride");
524 ReadInt(byteStrideNode, bufferViewInfo.byteStride);
527 const TreeNode* targetNode = buffer.GetChild("target");
530 ReadInt(targetNode, bufferViewInfo.target);
533 const TreeNode* nameNode = buffer.GetChild("name");
536 ReadString(nameNode, bufferViewInfo.name);
539 bufferViewArray.push_back(bufferViewInfo);
544 bool LoadAccessor(const TreeNode& buffer, std::vector<AccessorInfo>& accessorArray)
546 AccessorInfo accessorInfo;
548 const TreeNode* bufferViewNode = buffer.GetChild("bufferView");
551 ReadInt(bufferViewNode, accessorInfo.bufferView);
554 const TreeNode* byteOffsetNode = buffer.GetChild("byteOffset");
557 ReadInt(byteOffsetNode, accessorInfo.byteOffset);
560 const TreeNode* componentTypeNode = buffer.GetChild("componentType");
561 if(componentTypeNode)
563 ReadInt(componentTypeNode, accessorInfo.componentType);
564 if(accessorInfo.componentType < 0)
570 const TreeNode* normalizedNode = buffer.GetChild("normalized");
573 ReadBool(normalizedNode, accessorInfo.normalized);
576 const TreeNode* countNode = buffer.GetChild("count");
579 ReadInt(countNode, accessorInfo.count);
580 if(accessorInfo.count < 0)
586 const TreeNode* typeNode = buffer.GetChild("type");
589 ReadString(typeNode, accessorInfo.type);
590 if(accessorInfo.type == "")
596 const TreeNode* maxNode = buffer.GetChild("max");
599 ReadInt(maxNode, accessorInfo.max);
602 const TreeNode* minNode = buffer.GetChild("min");
605 ReadInt(minNode, accessorInfo.min);
608 const TreeNode* nameNode = buffer.GetChild("name");
611 ReadString(nameNode, accessorInfo.name);
614 accessorArray.push_back(accessorInfo);
619 bool LoadBinaryData(const TreeNode& root, std::vector<BufferInfo>& bufferArray, std::vector<BufferViewInfo>& bufferViewArray, std::vector<AccessorInfo>& accessorArray)
621 const TreeNode* buffersNode = root.GetChild("buffers");
626 for(auto bufferIter = buffersNode->CBegin(), end = buffersNode->CEnd(); bufferIter != end; ++bufferIter)
628 LoadBuffer((*bufferIter).second, bufferArray);
631 const TreeNode* bufferViewsNode = root.GetChild("bufferViews");
636 for(auto bufferViewIter = bufferViewsNode->CBegin(), end = bufferViewsNode->CEnd(); bufferViewIter != end; ++bufferViewIter)
638 LoadBufferView((*bufferViewIter).second, bufferViewArray);
641 const TreeNode* accessorsNode = root.GetChild("accessors");
646 for(auto accesorIter = accessorsNode->CBegin(), end = accessorsNode->CEnd(); accesorIter != end; ++accesorIter)
648 LoadAccessor((*accesorIter).second, accessorArray);
654 FilterMode::Type GetFilterMode(uint32_t mode)
656 FilterMode::Type retValue = FilterMode::DEFAULT;
658 * glTF 2.0 Specification
662 * 9984 : NEAREST_MIPMAP_NEAREST
663 * 9985 : LINEAR_MIPMAP_NEAREST
664 * 9986 : NEAREST_MIPMAP_LINEAR
665 * 9987 : LINEAR_MIPMAP_LINEAR
671 retValue = FilterMode::NEAREST;
676 retValue = FilterMode::LINEAR;
681 retValue = FilterMode::NEAREST_MIPMAP_NEAREST;
686 retValue = FilterMode::LINEAR_MIPMAP_NEAREST;
691 retValue = FilterMode::NEAREST_MIPMAP_LINEAR;
696 retValue = FilterMode::LINEAR_MIPMAP_LINEAR;
704 WrapMode::Type GetWrapMode(uint32_t mode)
706 WrapMode::Type retValue = WrapMode::REPEAT;
708 * glTF 2.0 Specification
710 * 33071 : CLAMP_TO_EDGE
711 * 33648 : MIRRORED_REPEAT
718 retValue = WrapMode::CLAMP_TO_EDGE;
723 retValue = WrapMode::MIRRORED_REPEAT;
728 retValue = WrapMode::REPEAT;
736 Texture LoadTexture(const char* imageUrl, bool generateMipmaps)
739 Devel::PixelBuffer pixelBuffer = LoadImageFromFile(imageUrl);
742 texture = Texture::New(TextureType::TEXTURE_2D, pixelBuffer.GetPixelFormat(), pixelBuffer.GetWidth(), pixelBuffer.GetHeight());
743 PixelData pixelData = Devel::PixelBuffer::Convert(pixelBuffer);
744 texture.Upload(pixelData);
748 texture.GenerateMipmaps();
755 Sampler LoadSampler(const TreeNode& samplerNode)
757 Sampler sampler = Sampler::New();
759 FilterMode::Type minFilter = FilterMode::DEFAULT;
760 FilterMode::Type magFilter = FilterMode::DEFAULT;
761 const TreeNode* magFilterNode = samplerNode.GetChild("magFilter");
764 int32_t magFilter_integer = 0;
765 ReadInt(magFilterNode, magFilter_integer);
766 magFilter = GetFilterMode(magFilter_integer);
769 const TreeNode* minFilterNode = samplerNode.GetChild("minFilter");
772 int32_t minFilter_integer = 0;
773 ReadInt(minFilterNode, minFilter_integer);
774 minFilter = GetFilterMode(minFilter_integer);
777 WrapMode::Type wrapR = WrapMode::REPEAT;
778 WrapMode::Type wrapS = WrapMode::REPEAT;
779 WrapMode::Type wrapT = WrapMode::REPEAT;
780 const TreeNode* wrapNode = samplerNode.GetChild("wrapS");
783 wrapS = GetWrapMode(wrapNode->GetInteger());
786 wrapNode = samplerNode.GetChild("wrapT");
789 wrapT = GetWrapMode(wrapNode->GetInteger());
792 sampler.SetFilterMode(minFilter, magFilter);
793 sampler.SetWrapMode(wrapR, wrapS, wrapT);
798 bool LoadTextureArray(const TreeNode& root, std::string path, std::vector<Texture>& sourceArray, std::vector<Sampler>& samplerArray, std::vector<TextureInfo>& textureArray)
800 const TreeNode* imagesNode = root.GetChild("images");
803 for(auto imageIter = imagesNode->CBegin(), end = imagesNode->CEnd(); imageIter != end; ++imageIter)
805 std::string imageUrl;
806 const TreeNode* uriNode = (&((*imageIter).second))->GetChild("uri");
810 ReadString(uriNode, uri);
811 imageUrl = path + uri;
814 sourceArray.push_back(LoadTexture(imageUrl.c_str(), true));
818 const TreeNode* samplersNode = root.GetChild("samplers");
821 for(auto samplerIter = samplersNode->CBegin(), end = samplersNode->CEnd(); samplerIter != end; ++samplerIter)
823 samplerArray.push_back(LoadSampler(((*samplerIter).second)));
827 const TreeNode* texturesNode = root.GetChild("textures");
830 for(auto textureIter = texturesNode->CBegin(), end = texturesNode->CEnd(); textureIter != end; ++textureIter)
832 const TreeNode* TextureNode = &((*textureIter).second);
835 const TreeNode* sourceNode = TextureNode->GetChild("source");
838 ReadInt(sourceNode, texture.sourceIdx);
841 const TreeNode* samplerNode = TextureNode->GetChild("sampler");
844 ReadInt(samplerNode, texture.samplerIdx);
847 textureArray.push_back(texture);
853 bool LoadPbrMetallicRoughness(const TreeNode& material, MaterialInfo& materialInfo)
856 const TreeNode* pbrMetallicRoughnessNode = material.GetChild("pbrMetallicRoughness");
857 if(!pbrMetallicRoughnessNode)
862 const TreeNode* tempNode;
863 tempNode = pbrMetallicRoughnessNode->GetChild("metallicFactor");
866 ReadFloat(tempNode, materialInfo.metallicFactor);
869 tempNode = pbrMetallicRoughnessNode->GetChild("roughnessFactor");
872 ReadFloat(tempNode, materialInfo.roughnessFactor);
875 tempNode = pbrMetallicRoughnessNode->GetChild("baseColorFactor");
876 if(tempNode && ReadVector(tempNode, floatVec, 4))
878 materialInfo.baseColorFactor = Vector4(floatVec[0], floatVec[1], floatVec[2], floatVec[3]);
881 const TreeNode* baseColorTextureNode = pbrMetallicRoughnessNode->GetChild("baseColorTexture");
882 if(baseColorTextureNode)
884 tempNode = baseColorTextureNode->GetChild("index");
887 materialInfo.baseColorTexture.index = tempNode->GetInteger();
890 tempNode = baseColorTextureNode->GetChild("texCoord");
893 materialInfo.baseColorTexture.texCoord = tempNode->GetInteger();
897 const TreeNode* metallicRoughnessTextureNode = pbrMetallicRoughnessNode->GetChild("metallicRoughnessTexture");
898 if(metallicRoughnessTextureNode)
900 tempNode = metallicRoughnessTextureNode->GetChild("index");
903 materialInfo.metallicRoughnessTexture.index = tempNode->GetInteger();
906 tempNode = metallicRoughnessTextureNode->GetChild("texCoord");
909 materialInfo.metallicRoughnessTexture.texCoord = tempNode->GetInteger();
916 bool LoadMaterialSetArray(const TreeNode& root, std::vector<MaterialInfo>& materialArray)
918 const TreeNode* materialsNode = root.GetChild("materials");
924 for(auto materialIter = materialsNode->CBegin(), end = materialsNode->CEnd(); materialIter != end; ++materialIter)
926 MaterialInfo materialInfo;
927 LoadPbrMetallicRoughness(((*materialIter).second), materialInfo);
929 const TreeNode* materialNode = &((*materialIter).second);
930 const TreeNode* tempNode = materialNode->GetChild("name");
933 ReadString(tempNode, materialInfo.name);
936 materialInfo.alphaMode = "OPAQUE";
937 tempNode = materialNode->GetChild("alphaMode");
940 ReadString(tempNode, materialInfo.alphaMode);
943 materialInfo.alphaCutoff = 1.0;
944 tempNode = materialNode->GetChild("alphaCutoff");
947 ReadFloat(tempNode, materialInfo.alphaCutoff);
950 materialInfo.doubleSided = false;
951 tempNode = materialNode->GetChild("doubleSided");
954 ReadBool(tempNode, materialInfo.doubleSided);
958 tempNode = materialNode->GetChild("emissiveFactor");
959 if(tempNode && ReadVector(tempNode, floatVec, 3))
961 materialInfo.emissiveFactor = Vector3(floatVec[0], floatVec[1], floatVec[2]);
964 const TreeNode* texture = materialNode->GetChild("normalTexture");
967 tempNode = texture->GetChild("index");
970 materialInfo.normalTexture.index = tempNode->GetInteger();
973 tempNode = texture->GetChild("texCoord");
976 materialInfo.normalTexture.texCoord = tempNode->GetInteger();
979 materialInfo.normalTexture.value = 1.0;
980 tempNode = texture->GetChild("scale");
983 ReadFloat(tempNode, materialInfo.normalTexture.value);
987 texture = materialNode->GetChild("occlusionTexture");
990 tempNode = texture->GetChild("index");
993 materialInfo.occlusionTexture.index = tempNode->GetInteger();
996 tempNode = texture->GetChild("texCoord");
999 materialInfo.occlusionTexture.texCoord = tempNode->GetInteger();
1002 tempNode = texture->GetChild("strength");
1005 ReadFloat(tempNode, materialInfo.occlusionTexture.value);
1009 texture = materialNode->GetChild("emissiveTexture");
1012 tempNode = texture->GetChild("index");
1015 materialInfo.emissiveTexture.index = tempNode->GetInteger();
1018 tempNode = texture->GetChild("texCoord");
1021 materialInfo.emissiveTexture.texCoord = tempNode->GetInteger();
1024 materialArray.push_back(materialInfo);
1029 bool LoadAttribute(const TreeNode* primitive, MeshInfo& meshInfo)
1031 const TreeNode* attrbuteNode = primitive->GetChild("attributes");
1037 const TreeNode* tempNode;
1038 tempNode = attrbuteNode->GetChild("POSITION");
1041 meshInfo.attribute.POSITION = tempNode->GetInteger();
1044 tempNode = attrbuteNode->GetChild("NORMAL");
1047 meshInfo.attribute.NORMAL = tempNode->GetInteger();
1050 tempNode = attrbuteNode->GetChild("TANGENT");
1053 meshInfo.attribute.TANGENT = tempNode->GetInteger();
1057 meshInfo.attribute.TEXCOORD.clear();
1058 tempNode = attrbuteNode->GetChild("TEXCOORD_" + std::to_string(index));
1061 uint32_t value = tempNode->GetInteger();
1062 meshInfo.attribute.TEXCOORD.push_back(value);
1063 tempNode = attrbuteNode->GetChild("TEXCOORD_" + std::to_string(++index));
1067 meshInfo.attribute.COLOR.clear();
1068 tempNode = attrbuteNode->GetChild("COLOR_" + std::to_string(index));
1071 uint32_t value = tempNode->GetInteger();
1072 meshInfo.attribute.COLOR.push_back(value);
1073 tempNode = attrbuteNode->GetChild("COLOR" + std::to_string(++index));
1079 bool LoadPrimitive(const TreeNode& mesh, MeshInfo& meshInfo)
1081 const TreeNode* primitivesNode = mesh.GetChild("primitives");
1087 for(auto primitiveIter = primitivesNode->CBegin(), end = primitivesNode->CEnd(); primitiveIter != end; ++primitiveIter)
1089 const TreeNode* primitiveNode = (&(*primitiveIter).second);
1090 const TreeNode* tempNode;
1092 tempNode = primitiveNode->GetChild("indices");
1095 meshInfo.indicesIdx = tempNode->GetInteger();
1098 tempNode = primitiveNode->GetChild("material");
1101 meshInfo.materialsIdx = tempNode->GetInteger();
1104 tempNode = primitiveNode->GetChild("mode");
1107 meshInfo.mode = tempNode->GetInteger();
1110 LoadAttribute(primitiveNode, meshInfo);
1116 bool SetGeometry(MeshInfo& meshInfo, std::string path, std::vector<BufferInfo>& bufferArray, std::vector<BufferViewInfo>& bufferViewArray, std::vector<AccessorInfo>& accessorArray)
1118 int32_t indicesIdx = meshInfo.indicesIdx;
1120 if(meshInfo.mode != 0)
1122 meshInfo.geometry.SetType((Dali::Geometry::Type)meshInfo.mode);
1127 SetIndexBuffersData(meshInfo, path, accessorArray, bufferViewArray, bufferArray, indicesIdx);
1130 SetVertexBufferData(meshInfo, path, accessorArray, bufferViewArray, bufferArray, meshInfo.attribute.POSITION, "aPosition", Property::VECTOR3);
1131 SetAttributeBufferData<Vector3>(meshInfo, path, accessorArray, bufferViewArray, bufferArray, meshInfo.attribute.NORMAL, "aNormal", Property::VECTOR3);
1132 SetAttributeBufferData<Vector4>(meshInfo, path, accessorArray, bufferViewArray, bufferArray, meshInfo.attribute.TANGENT, "aTangent", Property::VECTOR4);
1134 for(uint32_t i = 0; i < meshInfo.attribute.TEXCOORD.size(); ++i)
1136 int32_t accessorIdx = meshInfo.attribute.TEXCOORD[i];
1137 std::ostringstream texCoordString;
1138 texCoordString << "aTexCoord" << i;
1139 SetAttributeBufferData<Vector2>(meshInfo, path, accessorArray, bufferViewArray, bufferArray, accessorIdx, texCoordString.str(), Property::VECTOR2);
1142 for(auto&& accessorIdx : meshInfo.attribute.COLOR)
1149 if(accessorArray[accessorIdx].type == "VEC3")
1151 Dali::Vector<Vector3> inputBufferData;
1152 LoadDataFromAccessor(accessorIdx, inputBufferData, path, accessorArray, bufferViewArray, bufferArray);
1154 Dali::Vector<Vector4> bufferData;
1155 bufferData.Resize(inputBufferData.Size());
1156 for(uint32_t i = 0; i < inputBufferData.Size(); ++i)
1158 bufferData[i].x = inputBufferData[i].x;
1159 bufferData[i].y = inputBufferData[i].y;
1160 bufferData[i].z = inputBufferData[i].z;
1161 bufferData[i].w = 1.0;
1163 VertexBuffer vertexBuffer = CreateVertexBuffer<Vector4>(bufferData, "aVertexColor", Property::VECTOR4);
1164 meshInfo.geometry.AddVertexBuffer(vertexBuffer);
1166 else if(accessorArray[accessorIdx].type == "VEC4")
1168 SetAttributeBufferData<Vector4>(meshInfo, path, accessorArray, bufferViewArray, bufferArray, accessorIdx, "aVertexColor", Property::VECTOR4);
1174 bool LoadMeshArray(const TreeNode& root, std::string path, std::vector<MeshInfo>& meshArray, std::vector<BufferInfo>& bufferArray, std::vector<BufferViewInfo>& bufferViewArray, std::vector<AccessorInfo>& accessorArray)
1176 const TreeNode* meshesNode = root.GetChild("meshes");
1182 for(auto meshIter = meshesNode->CBegin(), end = meshesNode->CEnd(); meshIter != end; ++meshIter)
1185 const TreeNode* nameNode = (&(*meshIter).second)->GetChild("name");
1188 ReadString(nameNode, meshInfo.name);
1190 meshInfo.geometry = Geometry::New();
1192 //Need to add weights for Morph targets.
1193 LoadPrimitive((*meshIter).second, meshInfo);
1194 SetGeometry(meshInfo, path, bufferArray, bufferViewArray, accessorArray);
1195 meshArray.push_back(meshInfo);
1213 bool Loader::LoadScene(const std::string& filePath, Internal::Scene3dView& scene3dView)
1215 // Extracting directory path from full path to load resources.
1216 if(std::string::npos != filePath.rfind('/'))
1218 mPath = filePath.substr(0, filePath.rfind('/')) + "/";
1221 if(!ParseGltf(filePath))
1223 DALI_LOG_ERROR("Fail to parse json file\n");
1227 mRoot = mParser.GetRoot();
1230 CreateScene(scene3dView))
1237 bool Loader::ParseGltf(const std::string& filePath)
1239 std::streampos bufferSize = 0;
1240 Dali::Vector<char> buffer;
1241 std::string fileBuffer;
1242 if(!Dali::FileLoader::ReadFile(filePath, bufferSize, buffer, FileLoader::FileType::BINARY))
1247 fileBuffer.assign(&buffer[0], bufferSize);
1248 mParser = Dali::Toolkit::JsonParser::New();
1249 return mParser.Parse(fileBuffer);
1252 bool Loader::LoadAssets()
1254 if(LoadBinaryData(*mRoot, mBufferArray, mBufferViewArray, mAccessorArray) &&
1255 LoadTextureArray(*mRoot, mPath, mSourceArray, mSamplerArray, mTextureArray) &&
1256 LoadMaterialSetArray(*mRoot, mMaterialArray) &&
1257 LoadMeshArray(*mRoot, mPath, mMeshArray, mBufferArray, mBufferViewArray, mAccessorArray))
1264 bool Loader::CreateScene(Internal::Scene3dView& scene3dView)
1266 scene3dView.SetDefaultCamera(Dali::Camera::LOOK_AT_TARGET, 0.01, Vector3::ZERO);
1267 LoadCamera(scene3dView);
1269 if(LoadSceneNodes(scene3dView) &&
1270 LoadAnimation(scene3dView))
1277 void Loader::LoadCamera(Scene3dView& scene3dView)
1279 const TreeNode* camerasNode = mRoot->GetChild("cameras");
1285 for(auto cameraIter = camerasNode->CBegin(), end = camerasNode->CEnd(); cameraIter != end; ++cameraIter)
1287 const TreeNode* tempNode = (&(*cameraIter).second)->GetChild("name");
1288 CameraInfo cameraInfo;
1291 ReadString(tempNode, cameraInfo.name);
1294 tempNode = (&(*cameraIter).second)->GetChild("type");
1297 ReadString(tempNode, cameraInfo.type);
1300 CameraActor cameraActor = CameraActor::New();
1301 cameraActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
1302 cameraActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
1304 if(cameraInfo.type == "orthographic")
1306 LoadOrthoGraphic((*cameraIter).second, cameraInfo);
1307 float xMag_2 = cameraInfo.orthographic.xmag / 2.0;
1308 float yMag_2 = cameraInfo.orthographic.ymag / 2.0;
1309 const float aspect = xMag_2 / yMag_2;
1311 cameraActor.SetProjectionMode(Dali::Camera::ORTHOGRAPHIC_PROJECTION);
1312 cameraActor.SetProperty(Dali::DevelCameraActor::Property::ORTHOGRAPHIC_SIZE, yMag_2);
1314 cameraActor.SetNearClippingPlane(cameraInfo.orthographic.znear);
1315 if(cameraInfo.orthographic.zfar > 0.0)
1317 cameraActor.SetFarClippingPlane(cameraInfo.orthographic.zfar);
1319 if(aspect > 0.0f) // Avoid divide-by-zero logic
1321 cameraActor.SetAspectRatio(aspect);
1324 else if(cameraInfo.type == "perspective")
1326 if(!LoadPerspective((*cameraIter).second, cameraInfo))
1330 cameraActor.SetProjectionMode(Dali::Camera::PERSPECTIVE_PROJECTION);
1331 cameraActor.SetFieldOfView(cameraInfo.perspective.yfov);
1332 cameraActor.SetNearClippingPlane(cameraInfo.perspective.znear);
1334 if(cameraInfo.perspective.zfar > 0.0)
1336 cameraActor.SetFarClippingPlane(cameraInfo.perspective.zfar);
1338 if(cameraInfo.perspective.aspectRatio > 0.0)
1340 cameraActor.SetAspectRatio(cameraInfo.perspective.aspectRatio);
1344 scene3dView.AddCamera(cameraActor);
1348 bool Loader::LoadOrthoGraphic(const TreeNode& camera, CameraInfo& cameraInfo)
1350 const TreeNode* orthographicNode = camera.GetChild("orthographic");
1351 if(!orthographicNode)
1356 const TreeNode* tempNode;
1357 tempNode = orthographicNode->GetChild("xmag");
1360 ReadFloat(tempNode, cameraInfo.orthographic.xmag);
1363 tempNode = orthographicNode->GetChild("ymag");
1366 ReadFloat(tempNode, cameraInfo.orthographic.ymag);
1369 tempNode = orthographicNode->GetChild("zfar");
1372 ReadFloat(tempNode, cameraInfo.orthographic.zfar);
1375 tempNode = orthographicNode->GetChild("znear");
1378 ReadFloat(tempNode, cameraInfo.orthographic.znear);
1384 bool Loader::LoadPerspective(const TreeNode& camera, CameraInfo& cameraInfo)
1386 const TreeNode* perspectiveNode = camera.GetChild("perspective");
1387 if(!perspectiveNode)
1392 const TreeNode* tempNode;
1393 tempNode = perspectiveNode->GetChild("aspectRatio");
1396 ReadFloat(tempNode, cameraInfo.perspective.aspectRatio);
1399 tempNode = perspectiveNode->GetChild("yfov");
1402 ReadFloat(tempNode, cameraInfo.perspective.yfov);
1405 tempNode = perspectiveNode->GetChild("zfar");
1408 ReadFloat(tempNode, cameraInfo.perspective.zfar);
1411 tempNode = perspectiveNode->GetChild("znear");
1414 ReadFloat(tempNode, cameraInfo.perspective.znear);
1420 bool Loader::LoadSceneNodes(Scene3dView& scene3dView)
1422 const TreeNode* sceneNode = mRoot->GetChild("scene");
1423 uint32_t sceneNum = 0;
1426 sceneNum = sceneNode->GetInteger();
1429 const TreeNode* scenesNode = mRoot->GetChild("scenes");
1430 if(!(scenesNode && (mNodes = mRoot->GetChild("nodes"))))
1435 const TreeNode* tempNode = Tidx(scenesNode, sceneNum);
1441 tempNode = tempNode->GetChild("nodes");
1447 for(auto nodeIter = tempNode->CBegin(), end = tempNode->CEnd(); nodeIter != end; ++nodeIter)
1449 Actor actor = AddNode(scene3dView, ((*nodeIter).second).GetInteger());
1450 actor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
1451 scene3dView.GetRoot().Add(actor);
1457 Actor Loader::AddNode(Scene3dView& scene3dView, uint32_t index)
1459 const TreeNode* node = Tidx(mNodes, index);
1460 Actor actor = Actor::New();
1461 Vector3 actorSize(Vector3::ONE);
1463 Vector3 translation = Vector3(0.0, 0.0, 0.0);
1464 Vector3 scale = Vector3(1.0, 1.0, 1.0);
1465 Quaternion orientation(Vector4(0.0, 0.0, 0.0, 1.0));
1467 Vector3 anchorPoint = AnchorPoint::CENTER;
1469 const TreeNode* tempNode = NULL;
1470 if((tempNode = node->GetChild("translation")))
1472 float floatVec[3] = {0.0, 0.0, 0.0};
1473 if(tempNode && ReadVector(tempNode, floatVec, 3))
1475 translation = Vector3(floatVec[0], floatVec[1], floatVec[2]);
1479 if((tempNode = node->GetChild("scale")))
1481 float floatVec[3] = {1.0, 1.0, 1.0};
1482 if(tempNode && ReadVector(tempNode, floatVec, 3))
1484 scale = Vector3(floatVec[0], floatVec[1], floatVec[2]);
1488 if((tempNode = node->GetChild("rotation")))
1490 float floatVec[4] = {0.0, 0.0, 0.0, 1.0};
1491 if(tempNode && ReadVector(tempNode, floatVec, 4))
1493 orientation = Quaternion(Vector4(floatVec[0], floatVec[1], floatVec[2], floatVec[3]));
1497 if((tempNode = node->GetChild("matrix")))
1499 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};
1500 if(tempNode && ReadVector(tempNode, floatVec, 16))
1502 Matrix nodeMatrix = Matrix(floatVec);
1503 nodeMatrix.GetTransformComponents(translation, orientation, scale);
1507 if((tempNode = node->GetChild("mesh")))
1509 MeshInfo meshInfo = mMeshArray[tempNode->GetInteger()];
1510 bool isMaterial = (meshInfo.materialsIdx >= 0);
1512 TextureSet textureSet;
1513 textureSet = TextureSet::New();
1516 int32_t shaderTypeIndex = 0;
1517 int32_t maxMipmapLevel = 0;
1518 bool isBaseColorTexture = false;
1519 bool isMetallicRoughnessTexture = false;
1520 bool isNormalTexture = false;
1521 bool isOcclusionTexture = false;
1522 bool isEmissiveTexture = false;
1524 std::string VERTEX_SHADER, FRAGMENT_SHADER;
1525 VERTEX_SHADER = SHADER_GLTF_GLES_VERSION_300_DEF.data();
1526 VERTEX_SHADER += SHADER_GLTF_PHYSICALLY_BASED_SHADER_VERT.data();
1527 FRAGMENT_SHADER = SHADER_GLTF_GLES_VERSION_300_DEF.data();
1529 bool useIBL = scene3dView.HasImageBasedLighting();
1532 MaterialInfo materialInfo = mMaterialArray[meshInfo.materialsIdx];
1533 if(SetTextureAndSampler(textureSet, materialInfo.baseColorTexture.index, FRAGMENT_SHADER, SHADER_GLTF_BASECOLOR_TEXTURE_DEF.data(), addIdx))
1535 shaderTypeIndex += static_cast<int32_t>(ShaderType::BASECOLOR_SHADER);
1536 isBaseColorTexture = true;
1538 if(SetTextureAndSampler(textureSet, materialInfo.metallicRoughnessTexture.index, FRAGMENT_SHADER, SHADER_GLTF_METALLICROUGHNESS_TEXTURE_DEF.data(), addIdx))
1540 shaderTypeIndex += static_cast<int32_t>(ShaderType::METALLICROUGHNESS_SHADER);
1541 isMetallicRoughnessTexture = true;
1543 if(SetTextureAndSampler(textureSet, materialInfo.normalTexture.index, FRAGMENT_SHADER, SHADER_GLTF_NORMAL_TEXTURE_DEF.data(), addIdx))
1545 shaderTypeIndex += static_cast<int32_t>(ShaderType::NORMAL_SHADER);
1546 isNormalTexture = true;
1548 if(SetTextureAndSampler(textureSet, materialInfo.occlusionTexture.index, FRAGMENT_SHADER, SHADER_GLTF_OCCULUSION_TEXTURE_DEF.data(), addIdx))
1550 shaderTypeIndex += static_cast<int32_t>(ShaderType::OCCLUSION_SHADER);
1551 isOcclusionTexture = true;
1553 if(SetTextureAndSampler(textureSet, materialInfo.emissiveTexture.index, FRAGMENT_SHADER, SHADER_GLTF_EMIT_TEXTURE_DEF.data(), addIdx))
1555 shaderTypeIndex += static_cast<int32_t>(ShaderType::EMIT_SHADER);
1556 isEmissiveTexture = true;
1561 shaderTypeIndex += static_cast<int32_t>(ShaderType::IBL_SHADER);
1562 FRAGMENT_SHADER += SHADER_GLTF_IBL_TEXTURE_DEF.data();
1564 Sampler sampler = Sampler::New();
1565 sampler.SetFilterMode(FilterMode::DEFAULT, FilterMode::DEFAULT);
1566 sampler.SetWrapMode(WrapMode::REPEAT, WrapMode::REPEAT, WrapMode::REPEAT);
1568 textureSet.SetTexture(addIdx, scene3dView.GetBRDFTexture());
1569 textureSet.SetSampler(addIdx++, sampler);
1570 Sampler samplerIBL = Sampler::New();
1571 samplerIBL.SetFilterMode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR);
1572 samplerIBL.SetWrapMode(WrapMode::CLAMP_TO_EDGE, WrapMode::CLAMP_TO_EDGE, WrapMode::CLAMP_TO_EDGE);
1573 textureSet.SetTexture(addIdx, scene3dView.GetDiffuseTexture());
1574 textureSet.SetSampler(addIdx++, samplerIBL);
1575 Texture specularTexture = scene3dView.GetSpecularTexture();
1576 textureSet.SetTexture(addIdx, specularTexture);
1577 textureSet.SetSampler(addIdx++, samplerIBL);
1579 int32_t textureSize = std::min(specularTexture.GetWidth(), specularTexture.GetHeight());
1581 while(textureSize >= 1)
1589 FRAGMENT_SHADER += SHADER_GLTF_PHYSICALLY_BASED_SHADER_FRAG.data();
1590 if(!mShaderCache[shaderTypeIndex])
1592 std::ostringstream oss;
1593 oss << "GLTF_VIEW_" << shaderTypeIndex;
1594 mShaderCache[shaderTypeIndex] = Shader::New(VERTEX_SHADER, FRAGMENT_SHADER, Shader::Hint::NONE, oss.str());
1595 scene3dView.AddShader(mShaderCache[shaderTypeIndex]);
1597 Shader shader = mShaderCache[shaderTypeIndex];
1599 Renderer renderer = Renderer::New(meshInfo.geometry, shader);
1600 renderer.SetProperty(Renderer::Property::DEPTH_WRITE_MODE, DepthWriteMode::ON);
1601 renderer.SetProperty(Renderer::Property::DEPTH_TEST_MODE, DepthTestMode::ON);
1602 renderer.SetTextures(textureSet);
1604 anchorPoint = meshInfo.pivot;
1605 actor.SetProperty(Actor::Property::ANCHOR_POINT, anchorPoint);
1607 actor.SetProperty(Actor::Property::SIZE, Vector3(meshInfo.size.x, meshInfo.size.y, meshInfo.size.z));
1608 actor.AddRenderer(renderer);
1610 actor.SetProperty(Actor::Property::SCALE, scale);
1611 actor.RotateBy(orientation);
1612 actor.SetProperty(Actor::Property::POSITION, translation);
1614 float hasLightSource = static_cast<float>(!!(scene3dView.GetLightType() & (Toolkit::Scene3dView::LightType::POINT_LIGHT | Toolkit::Scene3dView::LightType::DIRECTIONAL_LIGHT)));
1615 float isPointLight = static_cast<float>(!!(scene3dView.GetLightType() & Toolkit::Scene3dView::LightType::POINT_LIGHT));
1616 shader.RegisterProperty("uHasLightSource", hasLightSource);
1617 shader.RegisterProperty("uIsPointLight", isPointLight);
1618 shader.RegisterProperty("uLightVector", scene3dView.GetLightVector());
1619 shader.RegisterProperty("uLightColor", scene3dView.GetLightColor());
1621 actor.RegisterProperty("uHasVertexColor", meshInfo.attribute.COLOR.size() > 0 ? 1.0f : 0.0f);
1624 MaterialInfo materialInfo = mMaterialArray[meshInfo.materialsIdx];
1625 actor.RegisterProperty("uBaseColorFactor", materialInfo.baseColorFactor);
1626 actor.RegisterProperty("uMetallicRoughnessFactors", Vector2(materialInfo.metallicFactor, materialInfo.roughnessFactor));
1628 if(materialInfo.alphaMode == "OPAQUE")
1630 actor.RegisterProperty("uAlphaMode", 0.0f);
1632 else if(materialInfo.alphaMode == "MASK")
1634 actor.RegisterProperty("uAlphaMode", 1.0f);
1638 actor.RegisterProperty("uAlphaMode", 2.0f);
1640 actor.RegisterProperty("alphaCutoff", materialInfo.alphaCutoff);
1642 if(isBaseColorTexture)
1644 actor.RegisterProperty("uBaseColorTexCoordIndex", materialInfo.baseColorTexture.texCoord);
1646 if(isMetallicRoughnessTexture)
1648 actor.RegisterProperty("uMetallicRoughnessTexCoordIndex", materialInfo.metallicRoughnessTexture.texCoord);
1652 actor.RegisterProperty("uNormalScale", materialInfo.normalTexture.value);
1653 actor.RegisterProperty("uNormalTexCoordIndex", materialInfo.normalTexture.texCoord);
1655 if(isOcclusionTexture)
1657 actor.RegisterProperty("uOcclusionTexCoordIndex", materialInfo.occlusionTexture.texCoord);
1658 actor.RegisterProperty("uOcclusionStrength", materialInfo.occlusionTexture.value);
1660 if(isEmissiveTexture)
1662 actor.RegisterProperty("uEmissiveTexCoordIndex", materialInfo.emissiveTexture.texCoord);
1663 actor.RegisterProperty("uEmissiveFactor", materialInfo.emissiveFactor);
1667 if(isMaterial && useIBL)
1669 actor.RegisterProperty("uScaleIBLAmbient", scene3dView.GetIBLScaleFactor());
1670 actor.RegisterProperty("uMipmapLevel", static_cast<float>(maxMipmapLevel));
1675 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
1676 actor.SetProperty(Actor::Property::POSITION, translation);
1677 actor.RotateBy(orientation);
1678 actor.SetProperty(Actor::Property::SIZE, actorSize);
1681 tempNode = node->GetChild("camera");
1684 int32_t cameraNum = tempNode->GetInteger();
1685 CameraActor cameraActor = scene3dView.GetCamera(cameraNum);
1688 actor.Add(cameraActor);
1692 tempNode = node->GetChild("name");
1695 std::string nameString;
1696 ReadString(tempNode, nameString);
1697 actor.SetProperty(Dali::Actor::Property::NAME, nameString);
1700 SetActorCache(actor, index);
1701 if((tempNode = node->GetChild("children")))
1703 for(auto childIter = tempNode->CBegin(), end = tempNode->CEnd(); childIter != end; ++childIter)
1705 Actor childActor = AddNode(scene3dView, ((*childIter).second).GetInteger());
1706 childActor.SetProperty(Actor::Property::PARENT_ORIGIN, anchorPoint);
1707 actor.Add(childActor);
1714 void Loader::SetActorCache(Actor& actor, uint32_t index)
1716 if(mActorCache.size() < index + 1)
1718 mActorCache.resize(index + 1);
1720 mActorCache[index] = actor;
1723 bool Loader::SetTextureAndSampler(TextureSet& textureSet, int32_t textureIdx, std::string& toShader, std::string shader, int32_t& addIdx)
1728 TextureInfo textureInfo = mTextureArray[textureIdx];
1729 if(textureInfo.sourceIdx >= 0)
1731 textureSet.SetTexture(addIdx, mSourceArray[textureInfo.sourceIdx]);
1733 if(textureInfo.samplerIdx >= 0)
1735 textureSet.SetSampler(addIdx, mSamplerArray[textureInfo.samplerIdx]);
1739 Sampler sampler = Sampler::New();
1740 sampler.SetFilterMode(FilterMode::DEFAULT, FilterMode::DEFAULT);
1741 sampler.SetWrapMode(WrapMode::REPEAT, WrapMode::REPEAT, WrapMode::REPEAT);
1742 textureSet.SetSampler(addIdx, sampler);
1750 bool Loader::LoadAnimation(Scene3dView& scene3dView)
1752 const TreeNode* animationsNode = mRoot->GetChild("animations");
1758 for(auto animationIter = animationsNode->CBegin(), end = animationsNode->CEnd(); animationIter != end; ++animationIter)
1760 const TreeNode* nameNode = (&(*animationIter).second)->GetChild("name");
1761 AnimationInfo animationInfo;
1764 ReadString(nameNode, animationInfo.name);
1767 Property::Index propIndex = Property::INVALID_INDEX;
1768 LoadAnimationChannels((*animationIter).second, animationInfo);
1769 if(animationInfo.channelArray.size() == 0)
1774 LoadAnimationSamplers((*animationIter).second, animationInfo);
1776 for(auto&& currentChannel : animationInfo.channelArray)
1778 if(currentChannel.path == "rotation")
1780 propIndex = Dali::Actor::Property::ORIENTATION;
1782 else if(currentChannel.path == "translation")
1784 propIndex = Dali::Actor::Property::POSITION;
1786 else if(currentChannel.path == "scale")
1788 propIndex = Dali::Actor::Property::SCALE;
1791 float duration = 0.0f;
1792 KeyFrames keyframes = KeyFrames::New();
1793 if(propIndex == Dali::Actor::Property::ORIENTATION)
1795 duration = LoadKeyFrames<Vector4>(animationInfo.samplerArray[currentChannel.sampler], propIndex, keyframes, mPath, mAccessorArray, mBufferViewArray, mBufferArray);
1799 duration = LoadKeyFrames<Vector3>(animationInfo.samplerArray[currentChannel.sampler], propIndex, keyframes, mPath, mAccessorArray, mBufferViewArray, mBufferArray);
1802 Animation animation = Animation::New(duration);
1803 Animation::Interpolation interpolation = Animation::Interpolation::LINEAR;
1804 if(animationInfo.samplerArray[currentChannel.sampler].interpolation == "CUBICSPLINE")
1806 interpolation = Animation::Interpolation::CUBIC;
1808 if(animationInfo.samplerArray[currentChannel.sampler].interpolation == "STEP")
1812 animation.AnimateBetween(Property(mActorCache[currentChannel.targetNode], propIndex), keyframes, interpolation);
1814 animation.SetLooping(false);
1815 scene3dView.AddAnimation(animation);
1822 bool Loader::LoadAnimationChannels(const TreeNode& animation, AnimationInfo& animationInfo)
1824 const TreeNode* channelsNode = animation.GetChild("channels");
1830 for(auto channelIter = channelsNode->CBegin(), end = channelsNode->CEnd(); channelIter != end; ++channelIter)
1832 AnimationChannelInfo animationChannelInfo;
1833 const TreeNode* channelNode = (&(*channelIter).second);
1834 const TreeNode* samplerNode = channelNode->GetChild("sampler");
1837 animationChannelInfo.sampler = samplerNode->GetInteger();
1840 const TreeNode* targetNode = channelNode->GetChild("target");
1843 const TreeNode* tempNode = targetNode->GetChild("node");
1846 animationChannelInfo.targetNode = tempNode->GetInteger();
1853 tempNode = targetNode->GetChild("path");
1856 ReadString(tempNode, animationChannelInfo.path);
1860 animationInfo.channelArray.push_back(animationChannelInfo);
1865 bool Loader::LoadAnimationSamplers(const TreeNode& animation, AnimationInfo& animationInfo)
1867 const TreeNode* samplersNode = animation.GetChild("samplers");
1873 for(auto sampler = samplersNode->CBegin(), end = samplersNode->CEnd(); sampler != end; ++sampler)
1875 AnimationSamplerInfo animationSamplerInfo;
1876 const TreeNode* samplerNode = (&(*sampler).second);
1877 const TreeNode* tempNode = samplerNode->GetChild("input");
1880 animationSamplerInfo.input = tempNode->GetInteger();
1883 tempNode = samplerNode->GetChild("output");
1886 animationSamplerInfo.output = tempNode->GetInteger();
1889 tempNode = samplerNode->GetChild("interpolation");
1892 ReadString(tempNode, animationSamplerInfo.interpolation);
1895 animationInfo.samplerArray.push_back(animationSamplerInfo);
1903 } //namespace Internal
1905 } //namespace Toolkit