2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
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
8 // http://floralicense.org/license/
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.
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>
29 const Property::Index AnimatableVertex::POSITION = 0;
30 const Property::Index AnimatableVertex::COLOR = 1;
31 const Property::Index AnimatableVertex::TEXTURE_COORDS = 2;
39 const std::string DEFAULT_PROPERTY_NAMES[] =
45 const int VERTEX_PROPERTY_COUNT = sizeof( DEFAULT_PROPERTY_NAMES ) / sizeof( std::string );
47 const Property::Type DEFAULT_PROPERTY_TYPES[ VERTEX_PROPERTY_COUNT ] =
49 Property::VECTOR3, // position
50 Property::VECTOR4, // Color
51 Property::VECTOR2, // Texture Coords
56 AnimatableMesh::DefaultPropertyLookup* AnimatableMesh::mDefaultPropertyLookup = NULL;
59 AnimatableMesh::AnimatableMesh(
60 SceneGraph::UpdateManager& updateManager,
61 SceneGraph::AnimatableMesh* sceneObject,
63 int numberOfVertices )
64 : mUpdateManager( updateManager ),
65 mSceneObject( sceneObject ),
67 mNumberOfVertices( numberOfVertices ),
68 mPropertyCount( numberOfVertices * VERTEX_PROPERTY_COUNT )
70 // Transfer animatable ownership to a scene message
71 AddAnimatableMeshMessage( mUpdateManager, *mSceneObject );
75 AnimatableMeshPtr AnimatableMesh::New(
76 unsigned int numVertices,
77 const Dali::AnimatableMesh::Faces& faceIndices )
79 return New( numVertices, faceIndices, Dali::Material::New("dummy material"), true );
82 AnimatableMeshPtr AnimatableMesh::New(
83 unsigned int numVertices,
84 const Dali::AnimatableMesh::Faces& faceIndices,
85 Dali::Material material)
87 return New( numVertices, faceIndices, material, false );
91 AnimatableMeshPtr AnimatableMesh::New(
92 unsigned int numVertices,
93 const Dali::AnimatableMesh::Faces& faceIndices,
94 Dali::Material material,
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();
104 unsigned int faceIndex = *faceIter;
105 DALI_ASSERT_ALWAYS( faceIndex < numVertices && "Face index out of range" );
108 ThreadLocalStorage& tls = ThreadLocalStorage::Get();
109 SceneGraph::UpdateManager& updateManager = tls.GetUpdateManager();
110 ResourceManager& resourceManager = tls.GetResourceManager();
112 Dali::MeshData meshData;
114 // We need a valid mesh data object to create the scene graph mesh
115 Dali::MeshData::VertexContainer vertices( numVertices );
117 meshData.SetData(vertices, faceIndices, bones, material);
118 bool useColor = false;
123 meshData.SetHasColor(useColor);
124 meshData.SetHasNormals(false);
125 meshData.SetHasTextureCoords(true);
127 MeshIPtr mesh( Mesh::New( meshData, false /* not discardable, data is updated in the update thread */, true /* Scaling is required */ ) );
129 // Create the scene object
130 SceneGraph::AnimatableMesh* sceneObject = new SceneGraph::AnimatableMesh( resourceManager, mesh->GetResourceId(), meshData.GetVertices() );
132 // Create the event object
133 AnimatableMeshPtr animatableMeshPtr( new AnimatableMesh( updateManager, sceneObject, mesh, meshData.GetVertexCount() ) );
135 return animatableMeshPtr;
139 AnimatableMesh::~AnimatableMesh()
141 DALI_ASSERT_DEBUG( mSceneObject != NULL );
143 // Guard to allow handle destruction after Core has been destroyed
144 if ( Stage::IsInstalled() )
146 RemoveAnimatableMeshMessage( mUpdateManager, *mSceneObject );
150 unsigned int AnimatableMesh::GetNumberOfVertices() const
152 return mNumberOfVertices;
155 Property::Index AnimatableMesh::GetVertexPropertyIndex(
157 Property::Index property ) const
159 DALI_ASSERT_DEBUG(property < VERTEX_PROPERTY_COUNT );
160 return ( vertex * VERTEX_PROPERTY_COUNT ) + property;
163 void AnimatableMesh::SetPosition( unsigned int vertexIndex, const Vector3& position)
165 StagePtr stage = Stage::GetCurrent();
166 BakeVertexPositionMessage( stage->GetUpdateInterface(), *mSceneObject, vertexIndex, position );
169 void AnimatableMesh::SetColor( unsigned int vertexIndex, const Vector4& color)
171 StagePtr stage = Stage::GetCurrent();
172 BakeVertexColorMessage( stage->GetUpdateInterface(), *mSceneObject, vertexIndex, color );
175 void AnimatableMesh::SetTextureCoords( unsigned int vertexIndex, const Vector2& coords)
177 StagePtr stage = Stage::GetCurrent();
178 BakeVertexTextureCoordsMessage( stage->GetUpdateInterface(), *mSceneObject, vertexIndex, coords );
181 const Vector3& AnimatableMesh::GetCurrentPosition( unsigned int vertexIndex) const
183 StagePtr stage = Stage::GetCurrent();
184 return mSceneObject->GetPosition(stage->GetEventBufferIndex(), vertexIndex);
187 const Vector4& AnimatableMesh::GetCurrentColor( unsigned int vertexIndex) const
189 StagePtr stage = Stage::GetCurrent();
190 return mSceneObject->GetColor(stage->GetEventBufferIndex(), vertexIndex);
193 const Vector2& AnimatableMesh::GetCurrentTextureCoords( unsigned int vertexIndex) const
195 StagePtr stage = Stage::GetCurrent();
196 return mSceneObject->GetTextureCoords(stage->GetEventBufferIndex(), vertexIndex);
199 MeshIPtr AnimatableMesh::GetMesh()
204 /********************************************************************************
205 ********************************************************************************
206 ******************************** PROPERTY METHODS **************************
207 ********************************************************************************
208 ********************************************************************************/
210 bool AnimatableMesh::Supports( Capability capability ) const
215 bool AnimatableMesh::IsSceneObjectRemovable() const
217 return false; // The scene object is permanently "on stage" whilst this object is alive
220 unsigned int AnimatableMesh::GetDefaultPropertyCount() const
222 return mPropertyCount;
225 void AnimatableMesh::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
227 indices.reserve( mPropertyCount );
229 for ( int i = 0; i < mPropertyCount; ++i )
231 indices.push_back( i );
235 const std::string& AnimatableMesh::GetDefaultPropertyName( Property::Index index ) const
237 if ( ( index >= 0 ) && ( index < mPropertyCount ) )
239 return DEFAULT_PROPERTY_NAMES[index % VERTEX_PROPERTY_COUNT];
243 // Index out-of-range... return empty string.
244 static const std::string INVALID_PROPERTY_NAME;
245 return INVALID_PROPERTY_NAME;
249 Property::Index AnimatableMesh::GetDefaultPropertyIndex(const std::string& name) const
251 Property::Index index = Property::INVALID_INDEX;
253 // TODO: Property names should be modified to append the vertex index
258 bool AnimatableMesh::IsDefaultPropertyWritable(Property::Index index) const
263 bool AnimatableMesh::IsDefaultPropertyAnimatable(Property::Index index) const
268 Property::Type AnimatableMesh::GetDefaultPropertyType(Property::Index index) const
270 if ( ( index >= 0 ) && ( index < mPropertyCount ) )
272 return DEFAULT_PROPERTY_TYPES[index % VERTEX_PROPERTY_COUNT ];
276 // Index out-of-bounds
277 return Property::NONE;
281 void AnimatableMesh::SetDefaultProperty( Property::Index index, const Property::Value& property )
283 DALI_ASSERT_ALWAYS( ( index >= 0 ) && ( index < mPropertyCount ) );
285 int vertexProperty = index % VERTEX_PROPERTY_COUNT;
286 int vertexIndex = index / VERTEX_PROPERTY_COUNT;
287 switch ( vertexProperty )
289 case Dali::AnimatableVertex::POSITION:
291 SetPosition( vertexIndex, property.Get<Vector3>() );
294 case Dali::AnimatableVertex::COLOR:
296 SetColor( vertexIndex, property.Get<Vector4>() );
299 case Dali::AnimatableVertex::TEXTURE_COORDS:
301 SetTextureCoords( vertexIndex, property.Get<Vector2>() );
306 DALI_ASSERT_ALWAYS(false && "AnimatableMesh property index out of range"); // should not come here
312 void AnimatableMesh::SetCustomProperty( Property::Index /*index*/, const CustomProperty& /*entry*/, const Property::Value& /*value*/ )
314 DALI_ASSERT_ALWAYS( 0 && "AnimatableMesh does not support custom properties");
317 Property::Value AnimatableMesh::GetDefaultProperty(Property::Index index) const
319 Property::Value value;
320 int vertexProperty = index % VERTEX_PROPERTY_COUNT;
321 int vertexIndex = index / VERTEX_PROPERTY_COUNT;
323 switch ( vertexProperty )
325 case Dali::AnimatableVertex::POSITION:
327 value = GetCurrentPosition(vertexIndex);
330 case Dali::AnimatableVertex::COLOR:
332 value = GetCurrentColor(vertexIndex);
335 case Dali::AnimatableVertex::TEXTURE_COORDS:
337 value = GetCurrentTextureCoords(vertexIndex);
342 DALI_ASSERT_ALWAYS(false && "AnimatableMesh property index out of range"); // should not come here
350 void AnimatableMesh::InstallSceneObjectProperty( SceneGraph::PropertyBase& newProperty, const std::string& name, unsigned int index )
352 DALI_ASSERT_ALWAYS( 0 && "AnimatableMesh does not support custom properties" );
355 const SceneGraph::PropertyOwner* AnimatableMesh::GetSceneObject() const
360 const SceneGraph::PropertyBase* AnimatableMesh::GetSceneObjectAnimatableProperty( Property::Index index ) const
362 DALI_ASSERT_ALWAYS( IsPropertyAnimatable(index) && "Property is not animatable" );
364 const SceneGraph::PropertyBase* property( NULL );
366 // This method should only return a property which is part of the scene-graph
367 if( mSceneObject != NULL )
369 int vertexProperty = index % VERTEX_PROPERTY_COUNT;
370 int vertexIndex = index / VERTEX_PROPERTY_COUNT;
372 switch ( vertexProperty )
374 case Dali::AnimatableVertex::POSITION:
375 property = &mSceneObject->mVertices[vertexIndex].position;
377 case Dali::AnimatableVertex::COLOR:
378 property = &mSceneObject->mVertices[vertexIndex].color;
380 case Dali::AnimatableVertex::TEXTURE_COORDS:
381 property = &mSceneObject->mVertices[vertexIndex].textureCoords;
385 DALI_ASSERT_DEBUG( 0 && "Index out of bounds" );
393 const PropertyInputImpl* AnimatableMesh::GetSceneObjectInputProperty( Property::Index index ) const
395 const PropertyInputImpl* property( NULL );
396 if( mSceneObject != NULL )
398 int vertexProperty = index % VERTEX_PROPERTY_COUNT;
399 int vertexIndex = index / VERTEX_PROPERTY_COUNT;
401 switch ( vertexProperty )
403 case Dali::AnimatableVertex::POSITION:
404 property = &mSceneObject->mVertices[vertexIndex].position;
406 case Dali::AnimatableVertex::COLOR:
407 property = &mSceneObject->mVertices[vertexIndex].color;
409 case Dali::AnimatableVertex::TEXTURE_COORDS:
410 property = &mSceneObject->mVertices[vertexIndex].textureCoords;