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/animatable-mesh-impl.h>
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>
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::TextureCoords )
46 DALI_PROPERTY_TABLE_END( DEFAULT_DERIVED_HANDLE_PROPERTY_START_INDEX )
50 AnimatableMesh::AnimatableMesh(
51 SceneGraph::UpdateManager& updateManager,
52 SceneGraph::AnimatableMesh* sceneObject,
54 int numberOfVertices )
55 : mUpdateManager( updateManager ),
56 mSceneObject( sceneObject ),
58 mNumberOfVertices( numberOfVertices ),
59 mPropertyCount( numberOfVertices * DEFAULT_PROPERTY_COUNT )
61 // Transfer animatable ownership to a scene message
62 AddAnimatableMeshMessage( mUpdateManager, *mSceneObject );
65 AnimatableMeshPtr AnimatableMesh::New(
66 unsigned int numVertices,
67 const Dali::AnimatableMesh::Faces& faceIndices )
69 return New( numVertices, faceIndices, Dali::Material::New("dummy material"), true );
72 AnimatableMeshPtr AnimatableMesh::New(
73 unsigned int numVertices,
74 const Dali::AnimatableMesh::Faces& faceIndices,
75 Dali::Material material)
77 return New( numVertices, faceIndices, material, false );
80 AnimatableMeshPtr AnimatableMesh::New(
81 unsigned int numVertices,
82 const Dali::AnimatableMesh::Faces& faceIndices,
83 Dali::Material material,
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();
93 unsigned int faceIndex = *faceIter;
94 DALI_ASSERT_ALWAYS( faceIndex < numVertices && "Face index out of range" );
97 ThreadLocalStorage& tls = ThreadLocalStorage::Get();
98 SceneGraph::UpdateManager& updateManager = tls.GetUpdateManager();
99 ResourceManager& resourceManager = tls.GetResourceManager();
101 Dali::MeshData meshData;
103 // We need a valid mesh data object to create the scene graph mesh
104 Dali::MeshData::VertexContainer vertices( numVertices );
106 meshData.SetData(vertices, faceIndices, bones, material);
107 bool useColor = false;
112 meshData.SetHasColor(useColor);
113 meshData.SetHasNormals(false);
114 meshData.SetHasTextureCoords(true);
116 MeshIPtr mesh( Mesh::New( meshData, false /* not discardable, data is updated in the update thread */, true /* Scaling is required */ ) );
118 // Create the scene object
119 SceneGraph::AnimatableMesh* sceneObject = new SceneGraph::AnimatableMesh( resourceManager, mesh->GetResourceId(), meshData.GetVertices() );
121 // Create the event object
122 AnimatableMeshPtr animatableMeshPtr( new AnimatableMesh( updateManager, sceneObject, mesh, meshData.GetVertexCount() ) );
124 return animatableMeshPtr;
127 AnimatableMesh::~AnimatableMesh()
129 // Guard to allow handle destruction after Core has been destroyed
130 if ( Stage::IsInstalled() )
134 RemoveAnimatableMeshMessage( mUpdateManager, *mSceneObject );
139 unsigned int AnimatableMesh::GetNumberOfVertices() const
141 return mNumberOfVertices;
144 Property::Index AnimatableMesh::GetVertexPropertyIndex(
146 Property::Index property ) const
148 DALI_ASSERT_DEBUG(property < DEFAULT_PROPERTY_COUNT );
149 return ( vertex * DEFAULT_PROPERTY_COUNT ) + property;
152 void AnimatableMesh::SetPosition( unsigned int vertexIndex, const Vector3& position)
154 StagePtr stage = Stage::GetCurrent();
155 BakeVertexPositionMessage( stage->GetUpdateInterface(), *mSceneObject, vertexIndex, position );
158 void AnimatableMesh::SetColor( unsigned int vertexIndex, const Vector4& color)
160 StagePtr stage = Stage::GetCurrent();
161 BakeVertexColorMessage( stage->GetUpdateInterface(), *mSceneObject, vertexIndex, color );
164 void AnimatableMesh::SetTextureCoords( unsigned int vertexIndex, const Vector2& coords)
166 StagePtr stage = Stage::GetCurrent();
167 BakeVertexTextureCoordsMessage( stage->GetUpdateInterface(), *mSceneObject, vertexIndex, coords );
170 const Vector3& AnimatableMesh::GetCurrentPosition( unsigned int vertexIndex) const
172 StagePtr stage = Stage::GetCurrent();
173 return mSceneObject->GetPosition(stage->GetEventBufferIndex(), vertexIndex);
176 const Vector4& AnimatableMesh::GetCurrentColor( unsigned int vertexIndex) const
178 StagePtr stage = Stage::GetCurrent();
179 return mSceneObject->GetColor(stage->GetEventBufferIndex(), vertexIndex);
182 const Vector2& AnimatableMesh::GetCurrentTextureCoords( unsigned int vertexIndex) const
184 StagePtr stage = Stage::GetCurrent();
185 return mSceneObject->GetTextureCoords(stage->GetEventBufferIndex(), vertexIndex);
188 MeshIPtr AnimatableMesh::GetMesh()
193 /********************************************************************************
194 ********************************************************************************
195 ******************************** PROPERTY METHODS **************************
196 ********************************************************************************
197 ********************************************************************************/
199 bool AnimatableMesh::Supports( Capability capability ) const
201 return false; // The scene object is permanently "on stage" whilst this object is alive
204 unsigned int AnimatableMesh::GetDefaultPropertyCount() const
206 return mPropertyCount;
209 void AnimatableMesh::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
211 indices.reserve( mPropertyCount );
213 for ( int i = 0; i < mPropertyCount; ++i )
215 indices.push_back( i );
219 const char* AnimatableMesh::GetDefaultPropertyName( Property::Index index ) const
221 if ( ( index >= 0 ) && ( index < mPropertyCount ) )
223 return DEFAULT_PROPERTY_DETAILS[index % DEFAULT_PROPERTY_COUNT].name;
231 Property::Index AnimatableMesh::GetDefaultPropertyIndex(const std::string& name) const
233 Property::Index index = Property::INVALID_INDEX;
235 // Look for name in default properties
236 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
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
248 bool AnimatableMesh::IsDefaultPropertyWritable(Property::Index index) const
250 return DEFAULT_PROPERTY_DETAILS[ index % DEFAULT_PROPERTY_COUNT ].writable;
253 bool AnimatableMesh::IsDefaultPropertyAnimatable(Property::Index index) const
255 return DEFAULT_PROPERTY_DETAILS[ index % DEFAULT_PROPERTY_COUNT ].animatable;
258 bool AnimatableMesh::IsDefaultPropertyAConstraintInput( Property::Index index ) const
260 return DEFAULT_PROPERTY_DETAILS[ index % DEFAULT_PROPERTY_COUNT ].constraintInput;
263 Property::Type AnimatableMesh::GetDefaultPropertyType(Property::Index index) const
265 if ( ( index >= 0 ) && ( index < mPropertyCount ) )
267 return DEFAULT_PROPERTY_DETAILS[ index % DEFAULT_PROPERTY_COUNT ].type;
270 // Index out-of-bounds
271 return Property::NONE;
274 void AnimatableMesh::SetDefaultProperty( Property::Index index, const Property::Value& property )
276 DALI_ASSERT_ALWAYS( ( index < mPropertyCount ) && "Property index out of bounds" );
278 int vertexProperty = index % DEFAULT_PROPERTY_COUNT;
279 int vertexIndex = index / DEFAULT_PROPERTY_COUNT;
280 switch ( vertexProperty )
282 case Dali::AnimatableVertex::Property::Position:
284 SetPosition( vertexIndex, property.Get<Vector3>() );
287 case Dali::AnimatableVertex::Property::Color:
289 SetColor( vertexIndex, property.Get<Vector4>() );
292 case Dali::AnimatableVertex::Property::TextureCoords:
294 SetTextureCoords( vertexIndex, property.Get<Vector2>() );
305 Property::Value AnimatableMesh::GetDefaultProperty(Property::Index index) const
307 Property::Value value;
308 int vertexProperty = index % DEFAULT_PROPERTY_COUNT;
309 int vertexIndex = index / DEFAULT_PROPERTY_COUNT;
311 switch ( vertexProperty )
313 case Dali::AnimatableVertex::Property::Position:
315 value = GetCurrentPosition(vertexIndex);
318 case Dali::AnimatableVertex::Property::Color:
320 value = GetCurrentColor(vertexIndex);
323 case Dali::AnimatableVertex::Property::TextureCoords:
325 value = GetCurrentTextureCoords(vertexIndex);
338 const SceneGraph::PropertyOwner* AnimatableMesh::GetSceneObject() const
343 const SceneGraph::PropertyBase* AnimatableMesh::GetSceneObjectAnimatableProperty( Property::Index index ) const
345 DALI_ASSERT_ALWAYS( IsPropertyAnimatable(index) && "Property is not animatable" );
347 const SceneGraph::PropertyBase* property( NULL );
349 // This method should only return a property which is part of the scene-graph
350 if( mSceneObject != NULL )
352 int vertexProperty = index % DEFAULT_PROPERTY_COUNT;
353 int vertexIndex = index / DEFAULT_PROPERTY_COUNT;
355 switch ( vertexProperty )
357 case Dali::AnimatableVertex::Property::Position:
358 property = &mSceneObject->mVertices[vertexIndex].position;
360 case Dali::AnimatableVertex::Property::Color:
361 property = &mSceneObject->mVertices[vertexIndex].color;
363 case Dali::AnimatableVertex::Property::TextureCoords:
364 property = &mSceneObject->mVertices[vertexIndex].textureCoords;
372 const PropertyInputImpl* AnimatableMesh::GetSceneObjectInputProperty( Property::Index index ) const
374 const PropertyInputImpl* property( NULL );
375 if( mSceneObject != NULL )
377 int vertexProperty = index % DEFAULT_PROPERTY_COUNT;
378 int vertexIndex = index / DEFAULT_PROPERTY_COUNT;
380 switch ( vertexProperty )
382 case Dali::AnimatableVertex::Property::Position:
383 property = &mSceneObject->mVertices[vertexIndex].position;
385 case Dali::AnimatableVertex::Property::Color:
386 property = &mSceneObject->mVertices[vertexIndex].color;
388 case Dali::AnimatableVertex::Property::TextureCoords:
389 property = &mSceneObject->mVertices[vertexIndex].textureCoords;