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