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/actor-attachments/mesh-attachment-impl.h>
22 #include <dali/public-api/common/dali-common.h>
23 #include <dali/internal/update/node-attachments/scene-graph-mesh-attachment.h>
24 #include <dali/internal/update/modeling/scene-graph-material.h>
25 #include <dali/internal/event/common/stage-impl.h>
26 #include <dali/internal/update/nodes/node.h>
28 using Dali::Internal::MeshIPtr;
29 using Dali::Internal::MaterialIPtr;
37 MeshAttachmentPtr MeshAttachment::New( Stage& stage, const SceneGraph::Node& parentNode )
39 MeshAttachmentPtr attachment( new MeshAttachment( stage ) );
41 // Transfer object ownership of scene-object to message
42 SceneGraph::MeshAttachment* sceneObject = SceneGraph::MeshAttachment::New();
43 AttachToNodeMessage( stage.GetUpdateManager(), parentNode, sceneObject );
45 // Keep raw pointer for message passing
46 attachment->mSceneObject = sceneObject;
51 MeshAttachment::MeshAttachment( Stage& stage )
52 : RenderableAttachment( stage ),
57 MeshAttachment::~MeshAttachment()
59 // Belt and braces - should already have been disconnected from stage
60 if ( Stage::IsInstalled() &&
67 void MeshAttachment::SetMesh( const MeshIPtr meshPtr,
69 const BoneContainer& bones,
70 const MaterialIPtr material )
72 mMesh.mMesh = meshPtr;
73 mMesh.mCustomMaterial = 0;
75 std::size_t boneCount = bones.size();
79 // Copy bone names locally in order to perform actor binding later
81 // Must keep names in same order (vertices reference into bone matrix array by index)
82 for ( BoneContainer::const_iterator iter = bones.begin(); iter != bones.end(); ++iter )
84 const Bone& bone = (*iter);
85 mMesh.mBoneNames.push_back( bone.GetName() );
89 mMesh.mMaterial = material;
90 const SceneGraph::Material* materialSceneObject = material->GetSceneObject();
92 // sceneObject is being used in a separate thread; queue a message to set
93 SetMeshMessage( mStage->GetUpdateInterface(), *mSceneObject, meshId, materialSceneObject, boneCount );
96 void MeshAttachment::SetMesh( const ResourceTicketPtr ticket,
97 const BoneContainer& bones,
98 const MaterialIPtr material )
100 SetMesh( 0, ticket->GetId(), bones, material );
103 void MeshAttachment::SetMaterial( MaterialIPtr material )
105 const SceneGraph::Material* materialSceneObject = NULL;
109 // We have a new material.
112 DisconnectMaterial();
114 // connect the new material
118 mMesh.mCustomMaterial = material;
120 materialSceneObject = material->GetSceneObject();
121 DALI_ASSERT_DEBUG( materialSceneObject != NULL );
125 // We are unsetting the current material, and reverting to the original material
126 if ( mMesh.mCustomMaterial )
130 mMesh.mCustomMaterial->Disconnect();
132 mMesh.mCustomMaterial = NULL;
135 // connect original material
136 DALI_ASSERT_DEBUG( mMesh.mMaterial );
140 mMesh.mMaterial->Connect();
142 materialSceneObject = mMesh.mMaterial->GetSceneObject();
147 // sceneObject is being used in a separate thread; queue a message to set
148 SetMaterialMessage( mStage->GetUpdateInterface(), *mSceneObject, materialSceneObject );
152 Internal::MaterialIPtr MeshAttachment::GetMaterial( ) const
154 Internal::MaterialIPtr material;
156 if ( mMesh.mCustomMaterial )
158 material = mMesh.mCustomMaterial;
160 else if ( mMesh.mMaterial )
162 material = mMesh.mMaterial;
168 void MeshAttachment::DisconnectMaterial()
170 if ( mMesh.mCustomMaterial )
172 mMesh.mCustomMaterial->Disconnect();
174 else if ( mMesh.mMaterial )
176 mMesh.mMaterial->Disconnect();
180 void MeshAttachment::BindBonesToMesh( Internal::ActorPtr rootActor )
183 size_t boneCount = mMesh.mBoneNames.size();
187 for ( BoneNamesIter boneIter=mMesh.mBoneNames.begin(); boneIter != mMesh.mBoneNames.end(); ++boneIter )
189 ActorPtr boneActor = rootActor->FindChildByName( *boneIter );
192 ConnectBoneActor( boneActor, boneIdx, boneCount );
199 void MeshAttachment::ConnectBoneActor( Internal::ActorPtr boneActor,
203 Connector* connector = new Connector( boneActor, boneIdx, *this );
204 mConnectors.PushBack( connector );
205 connector->ConnectNode();
208 void MeshAttachment::OnStageConnection2()
210 // Ensure current materials are staged
211 const SceneGraph::MeshAttachment& sceneObject = *mSceneObject;
213 const SceneGraph::Material* materialSceneObject = NULL;
214 if ( mMesh.mCustomMaterial )
216 mMesh.mCustomMaterial->Connect();
217 materialSceneObject = mMesh.mCustomMaterial->GetSceneObject();
219 else if ( mMesh.mMaterial )
221 mMesh.mMaterial->Connect();
222 materialSceneObject = mMesh.mMaterial->GetSceneObject();
224 DALI_ASSERT_DEBUG( materialSceneObject );
226 // And that the scene object has a connection to each material
227 SetMaterialMessage( mStage->GetUpdateInterface(), sceneObject, materialSceneObject );
229 // Ensure all staged bones are reconnected
230 for(ConnectorList::Iterator iter=mConnectors.Begin(); iter != mConnectors.End(); ++iter)
232 Connector* connector = (*iter);
233 connector->ConnectNode();
237 void MeshAttachment::OnStageDisconnection2()
239 DisconnectMaterial();
242 const SceneGraph::RenderableAttachment& MeshAttachment::GetSceneObject() const
244 DALI_ASSERT_DEBUG( mSceneObject != NULL );
245 return *mSceneObject;
248 void MeshAttachment::SetBoneNode( SceneGraph::Node* node, size_t boneIdx )
250 size_t boneCount = mMesh.mBoneNames.size();
252 SetBoneNodeMessage( mStage->GetUpdateInterface(), *mSceneObject, node, boneIdx, boneCount );
255 // Helper class for connecting Nodes to the scene-graph MeshAttachment
256 MeshAttachment::Connector::Connector(
257 Internal::ActorPtr boneActor,
259 MeshAttachment& meshAttachment)
260 : mMeshAttachment(meshAttachment),
261 mActor(boneActor.Get()),
266 mActor->AddObserver( *this );
271 MeshAttachment::Connector::~Connector()
275 mActor->RemoveObserver( *this );
279 void MeshAttachment::Connector::SceneObjectAdded( Object& object )
284 void MeshAttachment::Connector::SceneObjectRemoved( Object& object )
289 void MeshAttachment::Connector::ObjectDestroyed( Object& object )
296 void MeshAttachment::Connector::ConnectNode()
298 SceneGraph::Node* theNode( NULL );
302 const SceneGraph::PropertyOwner* object = mActor->GetSceneObject();
303 if ( NULL != object )
305 const SceneGraph::Node* aNode = dynamic_cast< const SceneGraph::Node* >( object );
308 theNode = const_cast< SceneGraph::Node* >( aNode );
313 mMeshAttachment.SetBoneNode( theNode, mBoneIdx );
317 } // namespace Internal