2 * Copyright (c) 2014 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/internal/event/modeling/model-archive.h>
22 #include <dali/public-api/common/stage.h>
23 #include <dali/internal/event/animation/key-frames-impl.h>
24 #include <dali/internal/event/modeling/entity-impl.h>
25 #include <dali/internal/event/render-tasks/render-task-impl.h>
26 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
27 #include <dali/integration-api/debug.h>
31 #define FOURCC(a,b,c,d) \
33 (((b) & 0xff) << 8) | \
34 (((c) & 0xff) << 16) | \
45 /*------ serialization overrides of operator<< () and operator>> () ------*/
47 //---------- MaterialProperties ----------//
48 Archive& operator<< (Archive& ar, const MaterialProperties& t)
52 ar << t.mAmbientColor;
53 ar << t.mDiffuseColor;
54 ar << t.mSpecularColor;
55 ar << t.mEmissiveColor;
58 ar << t.mDiffuseUVIndex;
59 ar << t.mOpacityUVIndex;
60 ar << t.mNormalUVIndex;
61 ar << t.mHasHeightMap;
66 Archive& operator>> (Archive& ar, MaterialProperties& t)
70 ar >> t.mAmbientColor;
71 ar >> t.mDiffuseColor;
72 ar >> t.mSpecularColor;
73 ar >> t.mEmissiveColor;
76 ar >> t.mDiffuseUVIndex;
77 ar >> t.mOpacityUVIndex;
78 ar >> t.mNormalUVIndex;
79 ar >> t.mHasHeightMap;
84 //---------- Material ----------//
85 Archive& operator<< (Archive& ar, const Material& t)
87 ar.OpenChunk(FOURCC('M', 'A', 'T', '_'));
92 // Diffuse texture file name
93 ar << t.GetDiffuseTextureFileName();
95 // Opacity texture file name
96 ar << t.GetOpacityTextureFileName();
98 // Normal map file name
99 ar << t.GetNormalMapFileName();
101 // Material properties
102 ar << t.GetProperties();
104 ar.CloseChunk(); // MAT_
109 Archive& operator>> (Archive& ar, Material& t)
113 if( ar.GetResult() &&
114 ar.OpenChunk(FOURCC('M', 'A', 'T', '_')) )
120 // Diffuse texture file name
122 t.SetDiffuseTextureFileName(name);
124 // Opacity texture file name
126 t.SetOpacityTextureFileName(name);
128 // Normal map file name
130 t.SetNormalMapFileName(name);
132 // Material properties
133 MaterialProperties properties;
135 t.SetProperties(properties);
137 ar.CloseChunk(); // MAT_
145 Archive& operator<< (Archive& ar, const Dali::MeshData::Vertex& t)
148 ar << t.x << t.y << t.z;
150 // Texture coordinates
154 ar << t.nX << t.nY << t.nZ;
157 for( unsigned int i = 0; i < Dali::MeshData::Vertex::MAX_BONE_INFLUENCE; ++i)
159 ar << t.boneIndices[i];
162 for( unsigned int i = 0; i < Dali::MeshData::Vertex::MAX_BONE_INFLUENCE; ++i)
164 ar << t.boneWeights[i];
170 Archive& operator>> (Archive& ar, MeshData::Vertex& t)
173 ar >> t.x >> t.y >> t.z;
175 // Texture coordinates
179 ar >> t.nX >> t.nY >> t.nZ;
182 for( unsigned int i = 0; i < Dali::MeshData::Vertex::MAX_BONE_INFLUENCE; ++i)
184 ar >> t.boneIndices[i];
187 for( unsigned int i = 0; i < Dali::MeshData::Vertex::MAX_BONE_INFLUENCE; ++i)
189 ar >> t.boneWeights[i];
197 Archive& operator<< (Archive& ar, const Dali::Light& t)
199 ar.OpenChunk(FOURCC('L', 'I', 'T', '_'));
202 ar << static_cast<unsigned int>(t.GetType());
203 ar << t.GetFallOff();
204 ar << t.GetSpotAngle();
205 ar << t.GetAmbientColor();
206 ar << t.GetDiffuseColor();
207 ar << t.GetSpecularColor();
208 ar << t.GetDirection();
210 ar.CloseChunk(); // LIT_
214 Archive& operator>> (Archive& ar, Dali::Light& t)
220 if( ar.GetResult() &&
221 ar.OpenChunk(FOURCC('L', 'I', 'T', '_')) )
228 t.SetFallOff(v2Value);
230 t.SetSpotAngle(v2Value);
232 t.SetAmbientColor(v3Value);
234 t.SetDiffuseColor(v3Value);
236 t.SetSpecularColor(v3Value);
238 t.SetDirection(v3Value);
240 ar.CloseChunk(); // LIT_
248 Archive& operator<< (Archive& ar, const Dali::Bone& t)
250 ar.OpenChunk(FOURCC('B', 'O', 'N', 'E'));
253 ar << t.GetOffsetMatrix();
255 ar.CloseChunk(); // BONE
259 Archive& operator>> (Archive& ar, Bone& t)
261 if( ar.GetResult() &&
262 ar.OpenChunk(FOURCC('B', 'O', 'N', 'E')) )
268 t = Bone( name, offsetMatrix );
269 ar.CloseChunk(); // BONE
274 /*---- MeshData ----*/
276 Archive& operator<< (Archive& ar, const Dali::MeshData& meshData)
278 ar.OpenChunk(FOURCC('M', 'E', 'S', 'H'));
283 ar.OpenChunk(FOURCC('V', 'R', 'T', 'S'));
284 // definition of a vertex
285 ar.OpenChunk(FOURCC('D', 'E', 'F', '_'));
286 ar << static_cast<unsigned char>(VET_Position);
287 ar << static_cast<unsigned char>(VET_UV);
288 ar << static_cast<unsigned char>(VET_Normal);
289 ar << static_cast<unsigned char>(VET_BoneIndices);
290 ar << static_cast<unsigned char>(VET_BoneWeights);
291 ar.CloseChunk(); // DEF_
292 count = meshData.GetVertexCount();
296 const Dali::MeshData::VertexContainer& vertices(meshData.GetVertices());
297 for( unsigned int i = 0; i < count; ++i)
302 ar.CloseChunk(); // VRTS
305 ar.OpenChunk(FOURCC('F', 'C', 'E', 'S'));
306 count = meshData.GetFaceCount();
307 count *= 3; // 3 elements per triangular face
311 const Dali::MeshData::FaceIndices& faces(meshData.GetFaces());
312 for( unsigned int i = 0; i < count; ++i)
317 ar.CloseChunk(); // FCES
320 ar.OpenChunk(FOURCC('B', 'N', 'E', 'S'));
321 count = meshData.GetBoneCount();
325 const Dali::BoneContainer& bones(meshData.GetBones());
326 for( unsigned int i = 0; i < count; ++i)
331 ar.CloseChunk(); // BNES
333 // write material (just write the material's name)
334 ar << meshData.GetMaterial().GetName();
336 // write texturing options
337 ar << meshData.HasTextureCoords();
338 ar << meshData.HasNormals();
341 ar << meshData.GetBoundingBoxMin();
342 ar << meshData.GetBoundingBoxMax();
344 ar.CloseChunk(); // MESH
348 Archive& operator>> (Archive& ar, MeshData& meshData)
350 Dali::MeshData::VertexContainer vertices;
351 Dali::MeshData::FaceIndices faces;
352 Dali::BoneContainer bones;
353 Dali::Material material;
354 Dali::MeshData::Vertex vertex;
355 Dali::MeshData::FaceIndex faceIndex;
358 unsigned int count = 0;
360 if( ar.GetResult() &&
361 ar.OpenChunk(FOURCC('M', 'E', 'S', 'H')) )
364 if( ar.OpenChunk(FOURCC('V', 'R', 'T', 'S')) )
366 // Version 1 has fixed vertex elements, so skip definition
367 ar.SkipChunk(FOURCC('D', 'E', 'F', '_'));
371 vertices.reserve(count);
373 for( unsigned int i = 0; i < count; ++i )
376 vertices.push_back(vertex);
379 ar.CloseChunk(); // VRTS
383 if( ar.GetResult() &&
384 ar.OpenChunk(FOURCC('F', 'C', 'E', 'S')) )
389 faces.reserve(count);
391 for( unsigned int i = 0; i < count; ++i )
394 faces.push_back(faceIndex);
397 ar.CloseChunk(); // FCES
401 if( ar.GetResult() &&
402 ar.OpenChunk(FOURCC('B', 'N', 'E', 'S')) )
407 bones.reserve(count);
409 for( unsigned int i = 0; i < count; ++i )
412 bones.push_back(bone);
415 ar.CloseChunk(); // BNES
420 material = Dali::Material::New(name);
422 meshData.SetData(vertices, faces, bones, material);
424 // write texturing options
427 meshData.SetHasTextureCoords(option);
429 meshData.SetHasNormals(option);
435 meshData.SetBoundingBoxMin(bounds);
438 meshData.SetBoundingBoxMax(bounds);
440 ar.CloseChunk(); // MESH
445 /*---- EntityAnimatorMap ----*/
446 Archive& operator<< (Archive& ar, const Dali::EntityAnimatorMap& t)
448 ar.OpenChunk(FOURCC('E', 'A', 'N', 'I'));
450 ar << t.GetEntityName();
451 ar << t.GetDuration();
453 unsigned int count = 0;
455 const KeyFrameVector3* positionKeyFrames = NULL;
456 GetSpecialization(GetImplementation(t.GetPositionKeyFrames()), positionKeyFrames);
457 if( positionKeyFrames )
459 count = positionKeyFrames->GetNumberOfKeyFrames();
463 for( unsigned int i = 0; i < count; ++i)
467 positionKeyFrames->GetKeyFrame(i, progress, position);
469 ar << progress << position;
478 const KeyFrameVector3* scaleKeyFrames = NULL;
479 GetSpecialization(GetImplementation(t.GetScaleKeyFrames()), scaleKeyFrames);
482 count = scaleKeyFrames->GetNumberOfKeyFrames();
486 for( unsigned int i = 0; i < count; ++i)
490 scaleKeyFrames->GetKeyFrame(i, progress, scale);
492 ar << progress << scale;
501 const KeyFrameQuaternion* rotationKeyFrames = NULL;
502 GetSpecialization(GetImplementation(t.GetRotationKeyFrames()), rotationKeyFrames);
503 if( rotationKeyFrames )
505 count = rotationKeyFrames->GetNumberOfKeyFrames();
509 for( unsigned int i = 0; i < count; ++i)
513 rotationKeyFrames->GetKeyFrame(i, progress, rotation);
515 ar << progress << rotation;
524 ar.CloseChunk(); // EANI
528 Archive& operator>> (Archive& ar, Dali::EntityAnimatorMap& t)
531 unsigned int count = 0;
532 float floatValue = 0.0f;
534 Quaternion quatValue;
536 if( ar.GetResult() &&
537 ar.OpenChunk(FOURCC('E', 'A', 'N', 'I')) )
540 t.SetEntityName(name);
542 t.SetDuration(floatValue);
545 Dali::KeyFrames positionKeyFrames = Dali::KeyFrames::New();
549 for( unsigned int i = 0; i < count; ++i )
553 Property::Value value(vec3Value);
554 positionKeyFrames.Add(floatValue, value);
556 t.SetPositionKeyFrames(positionKeyFrames);
559 Dali::KeyFrames scaleKeyFrames = Dali::KeyFrames::New();
563 for( unsigned int i = 0; i < count; ++i )
567 Property::Value value(vec3Value);
568 scaleKeyFrames.Add(floatValue, value);
570 t.SetScaleKeyFrames(scaleKeyFrames);
573 Dali::KeyFrames rotationKeyFrames = Dali::KeyFrames::New();
577 for( unsigned int i = 0; i < count; ++i )
581 Property::Value value(quatValue);
582 rotationKeyFrames.Add(floatValue, value);
584 t.SetRotationKeyFrames(rotationKeyFrames);
587 ar.CloseChunk(); // EANI
593 /*---- ModelAnimationMap ----*/
594 Archive& operator<< (Archive& ar, const Dali::ModelAnimationMap& t)
596 ar.OpenChunk(FOURCC('A', 'N', 'I', 'M'));
601 unsigned int count = t.animators.size();
605 for( unsigned int i = 0; i < count; ++i)
607 const EntityAnimatorMap& entityAnimatorMap(t.animators[i]);
609 ar << entityAnimatorMap;
616 ar.CloseChunk(); // ANIM
620 Archive& operator>> (Archive& ar, ModelAnimationMap& t)
623 unsigned int count = 0;
625 if( ar.GetResult() &&
626 ar.OpenChunk(FOURCC('A', 'N', 'I', 'M')) )
634 t.animators.reserve(count);
635 for( unsigned int i = 0; i < count; ++i)
637 EntityAnimatorMap entityAnimator("");
638 ar >> entityAnimator;
639 t.animators.push_back(entityAnimator);
646 ar.CloseChunk(); // ANIM
653 Archive& operator<< (Archive& ar, const Dali::Entity& t)
655 ar.OpenChunk(FOURCC('E', 'N', 'T', 'Y'));
662 count = t.NumberOfMeshes();
666 const EntityMeshIndices& meshes = t.GetMeshes();
667 for( unsigned int i = 0; i < count; ++i)
674 ar << t.GetTransformMatrix();
677 ar << t.GetLowerBounds();
678 ar << t.GetUpperBounds();
681 ar << static_cast<unsigned int>(t.GetType());
684 count = t.NumberOfChildren();
688 const EntityContainer& entities = t.GetChildren();
689 for( unsigned int i = 0; i < count; ++i )
695 ar.CloseChunk(); // ENTY
699 Archive& operator>> (Archive& ar, Dali::Entity& t)
701 unsigned int count = 0;
702 unsigned int uintValue = 0;
707 if( ar.GetResult() &&
708 ar.OpenChunk(FOURCC('E', 'N', 'T', 'Y')) )
717 t.SetMeshCapacity(count);
718 for( unsigned int i = 0; i < count; ++i)
721 t.AddMeshIndex(uintValue);
727 t.SetTransformMatrix(mat4Value);
731 GetImplementation(t).SetLowerBounds(vec3Value);
733 GetImplementation(t).SetUpperBounds(vec3Value);
737 t.SetType(static_cast<Dali::Entity::EntityType>(uintValue));
743 for( unsigned int i = 0; i < count; ++i )
745 Dali::Entity child(Dali::Entity::New(""));
749 t.AddToBounds(child);
753 ar.CloseChunk(); // ENTY
759 /*---- ModelData ----*/
761 Archive& operator<< (Archive& ar, const ModelData& t)
765 ar.OpenChunk(FOURCC('D', 'A', 'L', 'I'));
767 ar.OpenChunk(FOURCC('T', 'Y', 'P', 'E'));
768 std::string info("Dali Binary Model");
770 ar.CloseChunk(); // TYPE
772 ar.OpenChunk(FOURCC('V', 'E', 'R', 'S'));
773 ar << ar.GetVersion();
774 ar.CloseChunk(); // VERS
776 ar.OpenChunk(FOURCC('N', 'A', 'M', 'E'));
778 ar.CloseChunk(); // NAME
781 ar.OpenChunk(FOURCC('M', 'A', 'T', 'S'));
782 count = t.NumberOfMaterials();
784 for( unsigned int i = 0; i < count; ++i)
786 Dali::Material material = t.GetMaterial(i);
787 ar << static_cast<const Material&>(material.GetBaseObject());
789 ar.CloseChunk(); // MATS
792 ar.OpenChunk(FOURCC('M', 'S', 'H', 'S'));
793 count = t.NumberOfMeshes();
795 for( unsigned int i = 0; i < count; ++i)
797 const Dali::MeshData& mesh(t.GetMesh(i));
801 ar.CloseChunk(); // MSHS
804 ar.OpenChunk(FOURCC('L', 'I', 'T', 'S'));
805 count = t.NumberOfLights();
807 for( unsigned int i = 0; i < count; ++i)
811 ar.CloseChunk(); // LITS
814 ar.OpenChunk(FOURCC('E', 'N', 'T', 'S'));
815 ar << t.GetRootEntity();
816 ar.CloseChunk(); // ENTS
819 ar.OpenChunk(FOURCC('A', 'N', 'I', 'S'));
820 count = t.NumberOfAnimationMaps();
824 for( unsigned int i = 0; i < count; ++i)
826 ar << *t.GetAnimationMap(i);
829 ar.CloseChunk(); // ANIS
831 ar.CloseChunk(); // DALI
835 Archive& operator>> (Archive& ar, ModelData& t)
837 unsigned int count = 0;
838 unsigned int uintValue = 0;
840 if( ar.GetResult() &&
841 ar.OpenChunk(FOURCC('D', 'A', 'L', 'I')) )
843 DALI_ASSERT_DEBUG( ar.PeekChunk() == FOURCC('T', 'Y', 'P', 'E') );
844 // ar.OpenChunk(FOURCC('T', 'Y', 'P', 'E'));
845 ar.SkipChunk(FOURCC('T', 'Y', 'P', 'E'));
847 if( ar.GetResult() &&
848 ar.OpenChunk(FOURCC('V', 'E', 'R', 'S')) )
851 static_cast<InputArchive&>(ar).SetFileVersion(uintValue);
853 // Set archive failure if there is a version mismatch
854 if( uintValue != ar.GetVersion() )
856 ar.SetResultFailed();
860 // ar.OpenChunk(FOURCC('N', 'A', 'M', 'E'));
861 ar.SkipChunk(FOURCC('N', 'A', 'M', 'E'));
864 if( ar.GetResult() &&
865 ar.OpenChunk(FOURCC('M', 'A', 'T', 'S')) )
868 for( unsigned int i = 0; i < count; ++i)
870 Dali::Material material = Dali::Material::New("");
871 ar >> static_cast<Material&>(material.GetBaseObject());
872 t.AddMaterial(material);
878 if( ar.GetResult() &&
879 ar.OpenChunk(FOURCC('M', 'S', 'H', 'S')) )
882 for( unsigned int i = 0; i < count; ++i)
884 Dali::MeshData meshData;
887 for( unsigned j = 0; j < t.NumberOfMaterials(); ++j)
889 Dali::Material material = t.GetMaterial(j);
890 if( material.GetName() == meshData.GetMaterial().GetName() )
892 meshData.SetMaterial(material);
897 ar.CloseChunk(); // MSHS
900 if( ar.GetResult() &&
901 ar.OpenChunk(FOURCC('L', 'I', 'T', 'S')) )
906 for( unsigned int i = 0; i < count; ++i )
908 Dali::Light light(Dali::Light::New(""));
913 ar.CloseChunk(); // LITS
917 if( ar.GetResult() &&
918 ar.OpenChunk(FOURCC('E', 'N', 'T', 'S')) )
920 Dali::Entity root(Dali::Entity::New(""));
922 t.SetRootEntity(root);
923 ar.CloseChunk(); // ENTS
927 if( ar.GetResult() &&
928 ar.OpenChunk(FOURCC('A', 'N', 'I', 'S')) )
933 ModelAnimationMapContainer& mapContainer( t.GetAnimationMapContainer() );
934 mapContainer.reserve(count);
935 for( unsigned int i = 0; i < count; ++i)
937 ModelAnimationMap animation;
939 mapContainer.push_back(animation);
942 ar.CloseChunk(); // ANIS
945 ar.CloseChunk(); // DALI
950 } // namespace Serialize