5f90d7f84937c20055be491440dd42651aef67df
[platform/core/uifw/dali-core.git] / dali / internal / event / modeling / model-data-impl.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali/internal/event/modeling/model-data-impl.h>
20
21 // EXTERNAL INCLUDES
22 #include <stdio.h>
23 #include <algorithm>
24
25 // INTERNAL INCLUDES
26 #include <dali/public-api/common/light.h>
27 #include <dali/integration-api/debug.h>
28 #include <dali/integration-api/platform-abstraction.h>
29 #include <dali/internal/event/common/thread-local-storage.h>
30 #include <dali/internal/event/modeling/entity-impl.h>
31 #include <dali/internal/event/modeling/material-impl.h>
32 #include <dali/internal/event/modeling/mesh-impl.h>
33 #include <dali/internal/event/modeling/model-archive.h>
34 #include <dali/internal/update/modeling/internal-mesh-data.h>
35
36 namespace
37 {
38 const unsigned int ModelDataFormatVersion = 0x10004;
39 }
40
41 namespace Dali
42 {
43
44 namespace Internal
45 {
46
47 using Dali::Vector4;
48 using namespace Serialize;
49
50 ModelData::ModelData()
51 : mRoot(),
52   mUnpacked( false )
53 {
54   DALI_LOG_TRACE_METHOD(Debug::Filter::gModel);
55 }
56
57 ModelDataPtr ModelData::New(const std::string& name)
58 {
59   DALI_LOG_TRACE_METHOD(Debug::Filter::gModel);
60
61   ModelDataPtr modelData(new ModelData());
62   modelData->SetName(name);
63   return modelData;
64 }
65
66 ModelData::~ModelData()
67 {
68   DALI_LOG_TRACE_METHOD(Debug::Filter::gModel);
69
70   mMeshes.Clear();
71   mMaterials.clear();
72   mAnimationMaps.clear();
73   mLights.clear();
74 }
75
76 void ModelData::SetName(const std::string& name)
77 {
78   mName = name;
79 }
80
81 const std::string& ModelData::GetName() const
82 {
83   return mName;
84 }
85
86 void ModelData::SetRootEntity(Dali::Entity root)
87 {
88   mRoot = root;
89 }
90
91 Dali::Entity ModelData::GetRootEntity() const
92 {
93   return mRoot;
94 }
95
96 void ModelData::AddMesh(const Dali::MeshData& mesh)
97 {
98   mMeshes.PushBack( new Dali::MeshData( mesh ) );
99 }
100
101 void ModelData::AddMeshTicket(ResourceTicketPtr ticket)
102 {
103   mMeshTickets.push_back(ticket);
104 }
105
106 const Dali::MeshData& ModelData::GetMesh(unsigned int index) const
107 {
108   DALI_ASSERT_ALWAYS( index < mMeshes.Size() && "Mesh index out of bounds" );
109   return *mMeshes[index];
110 }
111
112 Dali::MeshData& ModelData::GetMesh(unsigned int index)
113 {
114   DALI_ASSERT_ALWAYS( index < mMeshes.Size() && "Mesh index out of bounds" );
115   return *mMeshes[index];
116 }
117
118 const ResourceTicketPtr ModelData::GetMeshTicket(unsigned int index) const
119 {
120   DALI_ASSERT_ALWAYS( index < mMeshTickets.size() && "Mesh index out of bounds" );
121   return mMeshTickets[index];
122 }
123
124 unsigned int ModelData::NumberOfMeshes() const
125 {
126   return mMeshes.Size();
127 }
128
129 void ModelData::AddMaterial(Dali::Material material)
130 {
131   mMaterials.push_back(material);
132 }
133
134 Dali::Material ModelData::GetMaterial(unsigned int index) const
135 {
136   DALI_ASSERT_DEBUG(index < mMaterials.size());
137
138   return mMaterials[index];
139 }
140
141 unsigned int ModelData::NumberOfMaterials() const
142 {
143   return mMaterials.size();
144 }
145
146 ModelAnimationMapContainer& ModelData::GetAnimationMapContainer()
147 {
148   return mAnimationMaps;
149 }
150
151 const ModelAnimationMap* ModelData::GetAnimationMap (unsigned int index) const
152 {
153   const ModelAnimationMap* found(NULL);
154   if( index < mAnimationMaps.size() )
155   {
156     found = &mAnimationMaps[index];
157   }
158   return found;
159 }
160
161 const ModelAnimationMap* ModelData::GetAnimationMap (const std::string& name) const
162 {
163   const ModelAnimationMap* found(NULL);
164
165   for(ModelAnimationMapContainer::const_iterator iter=mAnimationMaps.begin();
166       iter != mAnimationMaps.end();
167       ++iter)
168   {
169     const ModelAnimationMap& animData = *iter;
170     if(animData.name == name)
171     {
172       found = &(*iter);
173       break;
174     }
175   }
176
177   return found;
178 }
179
180 bool ModelData::FindAnimation (const std::string& name, unsigned int& index) const
181 {
182   bool found = false;
183
184   index = 0;
185   for(ModelAnimationMapContainer::const_iterator iter=mAnimationMaps.begin();
186       iter != mAnimationMaps.end();
187       ++iter, ++index)
188   {
189     const ModelAnimationMap& animData(*iter);
190     if(animData.name == name)
191     {
192       found = true;
193       break;
194     }
195   }
196   return found;
197 }
198
199 float ModelData::GetAnimationDuration(size_t animationIndex) const
200 {
201   DALI_ASSERT_DEBUG (animationIndex < mAnimationMaps.size ());
202   const ModelAnimationMap& animData( mAnimationMaps[animationIndex] );
203   return animData.duration;
204 }
205
206 unsigned int ModelData::NumberOfAnimationMaps() const
207 {
208   return mAnimationMaps.size();
209 }
210
211 void ModelData::AddLight(Dali::Light light)
212 {
213   mLights.push_back(light);
214 }
215
216 Dali::Light ModelData::GetLight(unsigned int index) const
217 {
218   Dali::Light light;
219   if (index < mLights.size())
220   {
221     light = mLights[index];
222   }
223   return light;
224 }
225
226 unsigned int ModelData::NumberOfLights() const
227 {
228   return mLights.size();
229 }
230
231 void ModelData::Unpack( ResourceClient& resourceClient )
232 {
233   ResourcePolicy::DataRetention dataRetentionPolicy = resourceClient.GetResourceDataRetentionPolicy();
234   ResourcePolicy::Discardable discardable = (dataRetentionPolicy == ResourcePolicy::DALI_DISCARDS_ALL_DATA ) ? ResourcePolicy::DISCARD : ResourcePolicy::RETAIN;
235
236   bool scalable = false; /* scaling is transmitted through parent Node */
237
238   // Only unpack once
239   if ( !mUnpacked )
240   {
241     // Ensure that mesh tickets are in same order as the meshes they represent
242     for ( size_t meshIdx = 0; meshIdx < NumberOfMeshes(); meshIdx++ )
243     {
244       // Copy the mesh-data into an internal structure, and pass ownership to the resourceClient
245       OwnerPointer<MeshData> meshDataPtr( new MeshData( GetMesh( meshIdx ), discardable, scalable ));
246       ResourceTicketPtr meshTicket = resourceClient.AllocateMesh( meshDataPtr );
247
248       AddMeshTicket( meshTicket );
249     }
250
251     // TODO: Update to use image tickets directly. Would need access to ImageFactory.
252     for ( size_t materialIdx = 0; materialIdx < NumberOfMaterials(); materialIdx++ )
253     {
254       Dali::Material material = GetMaterial( materialIdx );
255       const std::string& diffuseFileName = material.GetDiffuseFileName();
256       if( ! diffuseFileName.empty() )
257       {
258         material.SetDiffuseTexture( Dali::Image::New( diffuseFileName ) );
259       }
260
261       const std::string& opacityFileName = material.GetOpacityTextureFileName();
262       if( ! opacityFileName.empty() )
263       {
264         material.SetOpacityTexture( Dali::Image::New( opacityFileName ) );
265       }
266
267       const std::string& normalMapFileName = material.GetNormalMapFileName();
268       if( ! normalMapFileName.empty() )
269       {
270         material.SetNormalMap( Dali::Image::New( normalMapFileName ) );
271       }
272     }
273
274     mUnpacked = true;
275   }
276 }
277
278 bool ModelData::Read(std::streambuf& buf)
279 {
280   InputArchive ar(buf, ModelDataFormatVersion);
281   ar >> *this;
282   return ar.GetResult();
283 }
284
285 bool ModelData::Write(std::streambuf& buf) const
286 {
287   OutputArchive ar(buf, ModelDataFormatVersion);
288   ar << *this;
289   return ar.GetResult();
290 }
291
292 } // namespace Internal
293
294 } // namespace Dali