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.
18 #include <dali/internal/event/common/property-index-ranges.h>
19 #include <dali/internal/event/common/stage-impl.h>
20 #include <dali/internal/event/common/thread-local-storage.h>
21 #include <dali/internal/event/modeling/animatable-mesh-impl.h>
22 #include <dali/internal/event/modeling/mesh-impl.h>
23 #include <dali/internal/event/modeling/material-impl.h>
24 #include <dali/internal/update/manager/update-manager.h>
25 #include <dali/internal/update/modeling/scene-graph-animatable-mesh.h>
30 const Property::Index AnimatableVertex::POSITION = 0;
31 const Property::Index AnimatableVertex::COLOR = 1;
32 const Property::Index AnimatableVertex::TEXTURE_COORDS = 2;
40 const PropertyDetails DEFAULT_PROPERTY_DETAILS[] =
42 // Name Type writable animatable constraint-input
43 { "position", Property::VECTOR3, true, true, true }, // POSITION
44 { "vertex-color", Property::VECTOR4, true, true, true }, // COLOR
45 { "texture-coords", Property::VECTOR2, true, true, true }, // TEXTURE_COORDS
48 const int VERTEX_PROPERTY_COUNT = sizeof( DEFAULT_PROPERTY_DETAILS ) / sizeof( DEFAULT_PROPERTY_DETAILS[0] );
52 AnimatableMesh::AnimatableMesh(
53 SceneGraph::UpdateManager& updateManager,
54 SceneGraph::AnimatableMesh* sceneObject,
56 int numberOfVertices )
57 : mUpdateManager( updateManager ),
58 mSceneObject( sceneObject ),
60 mNumberOfVertices( numberOfVertices ),
61 mPropertyCount( numberOfVertices * VERTEX_PROPERTY_COUNT )
63 // Transfer animatable ownership to a scene message
64 AddAnimatableMeshMessage( mUpdateManager, *mSceneObject );
68 AnimatableMeshPtr AnimatableMesh::New(
69 unsigned int numVertices,
70 const Dali::AnimatableMesh::Faces& faceIndices )
72 return New( numVertices, faceIndices, Dali::Material::New("dummy material"), true );
75 AnimatableMeshPtr AnimatableMesh::New(
76 unsigned int numVertices,
77 const Dali::AnimatableMesh::Faces& faceIndices,
78 Dali::Material material)
80 return New( numVertices, faceIndices, material, false );
84 AnimatableMeshPtr AnimatableMesh::New(
85 unsigned int numVertices,
86 const Dali::AnimatableMesh::Faces& faceIndices,
87 Dali::Material material,
90 DALI_ASSERT_ALWAYS( numVertices > 0 && "Mesh has no vertices" );
91 DALI_ASSERT_ALWAYS( ( numVertices * 3 ) < DEFAULT_PROPERTY_MAX_COUNT && "Mesh exceeds maximum supported vertices" );
92 DALI_ASSERT_ALWAYS( faceIndices.size() > 0 && "Mesh has no faces" );
93 for( Dali::AnimatableMesh::FacesConstIter faceIter=faceIndices.begin();
94 faceIter != faceIndices.end();
97 unsigned int faceIndex = *faceIter;
98 DALI_ASSERT_ALWAYS( faceIndex < numVertices && "Face index out of range" );
101 ThreadLocalStorage& tls = ThreadLocalStorage::Get();
102 SceneGraph::UpdateManager& updateManager = tls.GetUpdateManager();
103 ResourceManager& resourceManager = tls.GetResourceManager();
105 Dali::MeshData meshData;
107 // We need a valid mesh data object to create the scene graph mesh
108 Dali::MeshData::VertexContainer vertices( numVertices );
110 meshData.SetData(vertices, faceIndices, bones, material);
111 bool useColor = false;
116 meshData.SetHasColor(useColor);
117 meshData.SetHasNormals(false);
118 meshData.SetHasTextureCoords(true);
120 MeshIPtr mesh( Mesh::New( meshData, false /* not discardable, data is updated in the update thread */, true /* Scaling is required */ ) );
122 // Create the scene object
123 SceneGraph::AnimatableMesh* sceneObject = new SceneGraph::AnimatableMesh( resourceManager, mesh->GetResourceId(), meshData.GetVertices() );
125 // Create the event object
126 AnimatableMeshPtr animatableMeshPtr( new AnimatableMesh( updateManager, sceneObject, mesh, meshData.GetVertexCount() ) );
128 return animatableMeshPtr;
132 AnimatableMesh::~AnimatableMesh()
134 // Guard to allow handle destruction after Core has been destroyed
135 if ( Stage::IsInstalled() )
139 RemoveAnimatableMeshMessage( mUpdateManager, *mSceneObject );
144 unsigned int AnimatableMesh::GetNumberOfVertices() const
146 return mNumberOfVertices;
149 Property::Index AnimatableMesh::GetVertexPropertyIndex(
151 Property::Index property ) const
153 DALI_ASSERT_DEBUG(property < VERTEX_PROPERTY_COUNT );
154 return ( vertex * VERTEX_PROPERTY_COUNT ) + property;
157 void AnimatableMesh::SetPosition( unsigned int vertexIndex, const Vector3& position)
159 StagePtr stage = Stage::GetCurrent();
160 BakeVertexPositionMessage( stage->GetUpdateInterface(), *mSceneObject, vertexIndex, position );
163 void AnimatableMesh::SetColor( unsigned int vertexIndex, const Vector4& color)
165 StagePtr stage = Stage::GetCurrent();
166 BakeVertexColorMessage( stage->GetUpdateInterface(), *mSceneObject, vertexIndex, color );
169 void AnimatableMesh::SetTextureCoords( unsigned int vertexIndex, const Vector2& coords)
171 StagePtr stage = Stage::GetCurrent();
172 BakeVertexTextureCoordsMessage( stage->GetUpdateInterface(), *mSceneObject, vertexIndex, coords );
175 const Vector3& AnimatableMesh::GetCurrentPosition( unsigned int vertexIndex) const
177 StagePtr stage = Stage::GetCurrent();
178 return mSceneObject->GetPosition(stage->GetEventBufferIndex(), vertexIndex);
181 const Vector4& AnimatableMesh::GetCurrentColor( unsigned int vertexIndex) const
183 StagePtr stage = Stage::GetCurrent();
184 return mSceneObject->GetColor(stage->GetEventBufferIndex(), vertexIndex);
187 const Vector2& AnimatableMesh::GetCurrentTextureCoords( unsigned int vertexIndex) const
189 StagePtr stage = Stage::GetCurrent();
190 return mSceneObject->GetTextureCoords(stage->GetEventBufferIndex(), vertexIndex);
193 MeshIPtr AnimatableMesh::GetMesh()
198 /********************************************************************************
199 ********************************************************************************
200 ******************************** PROPERTY METHODS **************************
201 ********************************************************************************
202 ********************************************************************************/
204 bool AnimatableMesh::Supports( Capability capability ) const
206 return false; // The scene object is permanently "on stage" whilst this object is alive
209 unsigned int AnimatableMesh::GetDefaultPropertyCount() const
211 return mPropertyCount;
214 void AnimatableMesh::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
216 indices.reserve( mPropertyCount );
218 for ( int i = 0; i < mPropertyCount; ++i )
220 indices.push_back( i );
224 const char* AnimatableMesh::GetDefaultPropertyName( Property::Index index ) const
226 if ( ( index >= 0 ) && ( index < mPropertyCount ) )
228 return DEFAULT_PROPERTY_DETAILS[index % VERTEX_PROPERTY_COUNT].name;
236 Property::Index AnimatableMesh::GetDefaultPropertyIndex(const std::string& name) const
238 Property::Index index = Property::INVALID_INDEX;
240 // Look for name in default properties
241 for( int i = 0; i < VERTEX_PROPERTY_COUNT; ++i )
243 const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
244 if( 0 == strcmp( name.c_str(), property->name ) ) // dont want to convert rhs to string
253 bool AnimatableMesh::IsDefaultPropertyWritable(Property::Index index) const
255 return DEFAULT_PROPERTY_DETAILS[ index % VERTEX_PROPERTY_COUNT ].writable;
258 bool AnimatableMesh::IsDefaultPropertyAnimatable(Property::Index index) const
260 return DEFAULT_PROPERTY_DETAILS[ index % VERTEX_PROPERTY_COUNT ].animatable;
263 bool AnimatableMesh::IsDefaultPropertyAConstraintInput( Property::Index index ) const
265 return DEFAULT_PROPERTY_DETAILS[ index % VERTEX_PROPERTY_COUNT ].constraintInput;
268 Property::Type AnimatableMesh::GetDefaultPropertyType(Property::Index index) const
270 if ( ( index >= 0 ) && ( index < mPropertyCount ) )
272 return DEFAULT_PROPERTY_DETAILS[ index % VERTEX_PROPERTY_COUNT ].type;
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>() );
307 void AnimatableMesh::SetCustomProperty( Property::Index /*index*/, const CustomProperty& /*entry*/, const Property::Value& /*value*/ )
309 DALI_ASSERT_ALWAYS( 0 && "AnimatableMesh does not support custom properties");
312 Property::Value AnimatableMesh::GetDefaultProperty(Property::Index index) const
314 Property::Value value;
315 int vertexProperty = index % VERTEX_PROPERTY_COUNT;
316 int vertexIndex = index / VERTEX_PROPERTY_COUNT;
318 switch ( vertexProperty )
320 case Dali::AnimatableVertex::POSITION:
322 value = GetCurrentPosition(vertexIndex);
325 case Dali::AnimatableVertex::COLOR:
327 value = GetCurrentColor(vertexIndex);
330 case Dali::AnimatableVertex::TEXTURE_COORDS:
332 value = GetCurrentTextureCoords(vertexIndex);
340 void AnimatableMesh::InstallSceneObjectProperty( SceneGraph::PropertyBase& newProperty, const std::string& name, unsigned int index )
342 DALI_ASSERT_ALWAYS( 0 && "AnimatableMesh does not support custom properties" );
345 const SceneGraph::PropertyOwner* AnimatableMesh::GetSceneObject() const
350 const SceneGraph::PropertyBase* AnimatableMesh::GetSceneObjectAnimatableProperty( Property::Index index ) const
352 DALI_ASSERT_ALWAYS( IsPropertyAnimatable(index) && "Property is not animatable" );
354 const SceneGraph::PropertyBase* property( NULL );
356 // This method should only return a property which is part of the scene-graph
357 if( mSceneObject != NULL )
359 int vertexProperty = index % VERTEX_PROPERTY_COUNT;
360 int vertexIndex = index / VERTEX_PROPERTY_COUNT;
362 switch ( vertexProperty )
364 case Dali::AnimatableVertex::POSITION:
365 property = &mSceneObject->mVertices[vertexIndex].position;
367 case Dali::AnimatableVertex::COLOR:
368 property = &mSceneObject->mVertices[vertexIndex].color;
370 case Dali::AnimatableVertex::TEXTURE_COORDS:
371 property = &mSceneObject->mVertices[vertexIndex].textureCoords;
379 const PropertyInputImpl* AnimatableMesh::GetSceneObjectInputProperty( Property::Index index ) const
381 const PropertyInputImpl* property( NULL );
382 if( mSceneObject != NULL )
384 int vertexProperty = index % VERTEX_PROPERTY_COUNT;
385 int vertexIndex = index / VERTEX_PROPERTY_COUNT;
387 switch ( vertexProperty )
389 case Dali::AnimatableVertex::POSITION:
390 property = &mSceneObject->mVertices[vertexIndex].position;
392 case Dali::AnimatableVertex::COLOR:
393 property = &mSceneObject->mVertices[vertexIndex].color;
395 case Dali::AnimatableVertex::TEXTURE_COORDS:
396 property = &mSceneObject->mVertices[vertexIndex].textureCoords;