Emscripten/llvm related issues
[platform/core/uifw/dali-core.git] / dali / internal / event / modeling / animatable-mesh-impl.cpp
1 //
2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
3 //
4 // Licensed under the Flora License, Version 1.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://floralicense.org/license/
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 #include <dali/internal/event/common/property-index-ranges.h>
18 #include <dali/internal/event/common/stage-impl.h>
19 #include <dali/internal/event/common/thread-local-storage.h>
20 #include <dali/internal/event/modeling/animatable-mesh-impl.h>
21 #include <dali/internal/event/modeling/mesh-impl.h>
22 #include <dali/internal/event/modeling/material-impl.h>
23 #include <dali/internal/update/manager/update-manager.h>
24 #include <dali/internal/update/modeling/scene-graph-animatable-mesh.h>
25
26 namespace Dali
27 {
28
29 const Property::Index AnimatableVertex::POSITION          = 0;
30 const Property::Index AnimatableVertex::COLOR             = 1;
31 const Property::Index AnimatableVertex::TEXTURE_COORDS    = 2;
32
33 namespace Internal
34 {
35
36 namespace
37 {
38
39 const std::string DEFAULT_PROPERTY_NAMES[] =
40 {
41   "position",
42   "vertex-color",
43   "texture-coords"
44 };
45 const int VERTEX_PROPERTY_COUNT = sizeof( DEFAULT_PROPERTY_NAMES ) / sizeof( std::string );
46
47 const Property::Type DEFAULT_PROPERTY_TYPES[ VERTEX_PROPERTY_COUNT ] =
48 {
49   Property::VECTOR3,  // position
50   Property::VECTOR4,  // Color
51   Property::VECTOR2,  // Texture Coords
52 };
53
54 } // namespace
55
56 AnimatableMesh::DefaultPropertyLookup* AnimatableMesh::mDefaultPropertyLookup = NULL;
57
58
59 AnimatableMesh::AnimatableMesh(
60   SceneGraph::UpdateManager& updateManager,
61   SceneGraph::AnimatableMesh* sceneObject,
62   MeshIPtr mesh,
63   int numberOfVertices )
64 : mUpdateManager( updateManager ),
65   mSceneObject( sceneObject ),
66   mMesh( mesh ),
67   mNumberOfVertices( numberOfVertices ),
68   mPropertyCount( numberOfVertices * VERTEX_PROPERTY_COUNT )
69 {
70   // Transfer animatable ownership to a scene message
71   AddAnimatableMeshMessage( mUpdateManager, *mSceneObject );
72 }
73
74
75 AnimatableMeshPtr AnimatableMesh::New(
76   unsigned int numVertices,
77   const Dali::AnimatableMesh::Faces& faceIndices )
78 {
79   return New( numVertices, faceIndices, Dali::Material::New("dummy material"), true );
80 }
81
82 AnimatableMeshPtr AnimatableMesh::New(
83   unsigned int numVertices,
84   const Dali::AnimatableMesh::Faces& faceIndices,
85   Dali::Material material)
86 {
87   return New( numVertices, faceIndices, material, false );
88 }
89
90
91 AnimatableMeshPtr AnimatableMesh::New(
92   unsigned int numVertices,
93   const Dali::AnimatableMesh::Faces& faceIndices,
94   Dali::Material material,
95   bool useVertexColor )
96 {
97   DALI_ASSERT_ALWAYS( numVertices > 0 && "Mesh has no vertices" );
98   DALI_ASSERT_ALWAYS( ( numVertices * 3 ) < DEFAULT_PROPERTY_MAX_COUNT && "Mesh exceeds maximum supported vertices" );
99   DALI_ASSERT_ALWAYS( faceIndices.size() > 0 && "Mesh has no faces" );
100   for( Dali::AnimatableMesh::FacesConstIter faceIter=faceIndices.begin();
101        faceIter != faceIndices.end();
102        ++faceIter )
103   {
104     unsigned int faceIndex = *faceIter;
105     DALI_ASSERT_ALWAYS( faceIndex < numVertices && "Face index out of range" );
106   }
107
108   ThreadLocalStorage& tls = ThreadLocalStorage::Get();
109   SceneGraph::UpdateManager& updateManager = tls.GetUpdateManager();
110   ResourceManager& resourceManager = tls.GetResourceManager();
111
112   Dali::MeshData meshData;
113
114   // We need a valid mesh data object to create the scene graph mesh
115   Dali::MeshData::VertexContainer vertices( numVertices );
116   BoneContainer bones;
117   meshData.SetData(vertices, faceIndices, bones, material);
118   bool useColor = false;
119   if(useVertexColor)
120   {
121     useColor=true;
122   }
123   meshData.SetHasColor(useColor);
124   meshData.SetHasNormals(false);
125   meshData.SetHasTextureCoords(true);
126
127   MeshIPtr mesh( Mesh::New( meshData, false /* not discardable, data is updated in the update thread */, true /* Scaling is required */ ) );
128
129   // Create the scene object
130   SceneGraph::AnimatableMesh* sceneObject = new SceneGraph::AnimatableMesh( resourceManager, mesh->GetResourceId(), meshData.GetVertices() );
131
132   // Create the event object
133   AnimatableMeshPtr animatableMeshPtr( new AnimatableMesh( updateManager, sceneObject, mesh, meshData.GetVertexCount() ) );
134
135   return animatableMeshPtr;
136 }
137
138
139 AnimatableMesh::~AnimatableMesh()
140 {
141   DALI_ASSERT_DEBUG( mSceneObject != NULL );
142
143   // Guard to allow handle destruction after Core has been destroyed
144   if ( Stage::IsInstalled() )
145   {
146     RemoveAnimatableMeshMessage( mUpdateManager, *mSceneObject );
147   }
148 }
149
150 unsigned int AnimatableMesh::GetNumberOfVertices() const
151 {
152   return mNumberOfVertices;
153 }
154
155 Property::Index AnimatableMesh::GetVertexPropertyIndex(
156   unsigned int vertex,
157   Property::Index property ) const
158 {
159   DALI_ASSERT_DEBUG(property < VERTEX_PROPERTY_COUNT );
160   return ( vertex * VERTEX_PROPERTY_COUNT ) + property;
161 }
162
163 void AnimatableMesh::SetPosition( unsigned int vertexIndex, const Vector3& position)
164 {
165   StagePtr stage = Stage::GetCurrent();
166   BakeVertexPositionMessage( stage->GetUpdateInterface(), *mSceneObject, vertexIndex, position );
167 }
168
169 void AnimatableMesh::SetColor( unsigned int vertexIndex, const Vector4& color)
170 {
171   StagePtr stage = Stage::GetCurrent();
172   BakeVertexColorMessage( stage->GetUpdateInterface(), *mSceneObject, vertexIndex, color );
173 }
174
175 void AnimatableMesh::SetTextureCoords( unsigned int vertexIndex, const Vector2& coords)
176 {
177   StagePtr stage = Stage::GetCurrent();
178   BakeVertexTextureCoordsMessage( stage->GetUpdateInterface(), *mSceneObject, vertexIndex, coords );
179 }
180
181 const Vector3& AnimatableMesh::GetCurrentPosition( unsigned int vertexIndex) const
182 {
183   StagePtr stage = Stage::GetCurrent();
184   return mSceneObject->GetPosition(stage->GetEventBufferIndex(), vertexIndex);
185 }
186
187 const Vector4& AnimatableMesh::GetCurrentColor( unsigned int vertexIndex) const
188 {
189   StagePtr stage = Stage::GetCurrent();
190   return mSceneObject->GetColor(stage->GetEventBufferIndex(), vertexIndex);
191 }
192
193 const Vector2& AnimatableMesh::GetCurrentTextureCoords( unsigned int vertexIndex) const
194 {
195   StagePtr stage = Stage::GetCurrent();
196   return mSceneObject->GetTextureCoords(stage->GetEventBufferIndex(), vertexIndex);
197 }
198
199 MeshIPtr AnimatableMesh::GetMesh()
200 {
201   return mMesh;
202 }
203
204 /********************************************************************************
205  ********************************************************************************
206  ********************************   PROPERTY METHODS   **************************
207  ********************************************************************************
208  ********************************************************************************/
209
210 bool AnimatableMesh::Supports( Capability capability ) const
211 {
212   return false;
213 }
214
215 bool AnimatableMesh::IsSceneObjectRemovable() const
216 {
217   return false; // The scene object is permanently "on stage" whilst this object is alive
218 }
219
220 unsigned int AnimatableMesh::GetDefaultPropertyCount() const
221 {
222   return mPropertyCount;
223 }
224
225 void AnimatableMesh::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
226 {
227   indices.reserve( mPropertyCount );
228
229   for ( int i = 0; i < mPropertyCount; ++i )
230   {
231     indices.push_back( i );
232   }
233 }
234
235 const std::string& AnimatableMesh::GetDefaultPropertyName( Property::Index index ) const
236 {
237   if ( ( index >= 0 ) && ( index < mPropertyCount ) )
238   {
239     return DEFAULT_PROPERTY_NAMES[index % VERTEX_PROPERTY_COUNT];
240   }
241   else
242   {
243     // Index out-of-range... return empty string.
244     static const std::string INVALID_PROPERTY_NAME;
245     return INVALID_PROPERTY_NAME;
246   }
247 }
248
249 Property::Index AnimatableMesh::GetDefaultPropertyIndex(const std::string& name) const
250 {
251   Property::Index index = Property::INVALID_INDEX;
252
253   // TODO: Property names should be modified to append the vertex index
254
255   return index;
256 }
257
258 bool AnimatableMesh::IsDefaultPropertyWritable(Property::Index index) const
259 {
260   return true;
261 }
262
263 bool AnimatableMesh::IsDefaultPropertyAnimatable(Property::Index index) const
264 {
265   return true;
266 }
267
268 Property::Type AnimatableMesh::GetDefaultPropertyType(Property::Index index) const
269 {
270   if ( ( index >= 0 ) && ( index < mPropertyCount ) )
271   {
272     return DEFAULT_PROPERTY_TYPES[index % VERTEX_PROPERTY_COUNT ];
273   }
274   else
275   {
276     // Index out-of-bounds
277     return Property::NONE;
278   }
279 }
280
281 void AnimatableMesh::SetDefaultProperty( Property::Index index, const Property::Value& property )
282 {
283   DALI_ASSERT_ALWAYS( ( index >= 0 ) && ( index < mPropertyCount ) );
284
285   int vertexProperty = index % VERTEX_PROPERTY_COUNT;
286   int vertexIndex    = index / VERTEX_PROPERTY_COUNT;
287   switch ( vertexProperty )
288   {
289     case Dali::AnimatableVertex::POSITION:
290     {
291       SetPosition( vertexIndex, property.Get<Vector3>() );
292       break;
293     }
294     case Dali::AnimatableVertex::COLOR:
295     {
296       SetColor( vertexIndex, property.Get<Vector4>() );
297       break;
298     }
299     case Dali::AnimatableVertex::TEXTURE_COORDS:
300     {
301       SetTextureCoords( vertexIndex, property.Get<Vector2>() );
302       break;
303     }
304     default:
305     {
306       DALI_ASSERT_ALWAYS(false && "AnimatableMesh property index out of range"); // should not come here
307       break;
308     }
309   }
310 }
311
312 void AnimatableMesh::SetCustomProperty( Property::Index /*index*/, const CustomProperty& /*entry*/, const Property::Value& /*value*/ )
313 {
314   DALI_ASSERT_ALWAYS( 0 && "AnimatableMesh does not support custom properties");
315 }
316
317 Property::Value AnimatableMesh::GetDefaultProperty(Property::Index index) const
318 {
319   Property::Value value;
320   int vertexProperty = index % VERTEX_PROPERTY_COUNT;
321   int vertexIndex    = index / VERTEX_PROPERTY_COUNT;
322
323   switch ( vertexProperty )
324   {
325     case Dali::AnimatableVertex::POSITION:
326     {
327       value = GetCurrentPosition(vertexIndex);
328       break;
329     }
330     case Dali::AnimatableVertex::COLOR:
331     {
332       value = GetCurrentColor(vertexIndex);
333       break;
334     }
335     case Dali::AnimatableVertex::TEXTURE_COORDS:
336     {
337       value = GetCurrentTextureCoords(vertexIndex);
338       break;
339     }
340     default:
341     {
342       DALI_ASSERT_ALWAYS(false && "AnimatableMesh property index out of range"); // should not come here
343       break;
344     }
345   }
346
347   return value;
348 }
349
350 void AnimatableMesh::InstallSceneObjectProperty( SceneGraph::PropertyBase& newProperty, const std::string& name, unsigned int index )
351 {
352   DALI_ASSERT_ALWAYS( 0 && "AnimatableMesh does not support custom properties" );
353 }
354
355 const SceneGraph::PropertyOwner* AnimatableMesh::GetSceneObject() const
356 {
357   return mSceneObject;
358 }
359
360 const SceneGraph::PropertyBase* AnimatableMesh::GetSceneObjectAnimatableProperty( Property::Index index ) const
361 {
362   DALI_ASSERT_ALWAYS( IsPropertyAnimatable(index) && "Property is not animatable" );
363
364   const SceneGraph::PropertyBase* property( NULL );
365
366   // This method should only return a property which is part of the scene-graph
367   if( mSceneObject != NULL )
368   {
369     int vertexProperty = index % VERTEX_PROPERTY_COUNT;
370     int vertexIndex    = index / VERTEX_PROPERTY_COUNT;
371
372     switch ( vertexProperty )
373     {
374       case Dali::AnimatableVertex::POSITION:
375         property = &mSceneObject->mVertices[vertexIndex].position;
376         break;
377       case Dali::AnimatableVertex::COLOR:
378         property = &mSceneObject->mVertices[vertexIndex].color;
379         break;
380       case Dali::AnimatableVertex::TEXTURE_COORDS:
381         property = &mSceneObject->mVertices[vertexIndex].textureCoords;
382         break;
383
384       default:
385         DALI_ASSERT_DEBUG( 0 && "Index out of bounds" );
386         break;
387     }
388   }
389
390   return property;
391 }
392
393 const PropertyInputImpl* AnimatableMesh::GetSceneObjectInputProperty( Property::Index index ) const
394 {
395   const PropertyInputImpl* property( NULL );
396   if( mSceneObject != NULL )
397   {
398     int vertexProperty = index % VERTEX_PROPERTY_COUNT;
399     int vertexIndex    = index / VERTEX_PROPERTY_COUNT;
400
401     switch ( vertexProperty )
402     {
403       case Dali::AnimatableVertex::POSITION:
404         property = &mSceneObject->mVertices[vertexIndex].position;
405         break;
406       case Dali::AnimatableVertex::COLOR:
407         property = &mSceneObject->mVertices[vertexIndex].color;
408         break;
409       case Dali::AnimatableVertex::TEXTURE_COORDS:
410         property = &mSceneObject->mVertices[vertexIndex].textureCoords;
411         break;
412
413       default:
414         break;
415     }
416   }
417
418   return property;
419 }
420
421 } // internal
422 } // dali