Removed AffectedByLighting APIs from MeshActor
[platform/core/uifw/dali-core.git] / dali / internal / event / actor-attachments / mesh-attachment-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/actor-attachments/mesh-attachment-impl.h>
20
21 // INTERNAL INCLUDES
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>
27
28 using Dali::Internal::MeshIPtr;
29 using Dali::Internal::MaterialIPtr;
30
31 namespace Dali
32 {
33
34 namespace Internal
35 {
36
37 MeshAttachmentPtr MeshAttachment::New( Stage& stage, const SceneGraph::Node& parentNode )
38 {
39   MeshAttachmentPtr attachment( new MeshAttachment( stage ) );
40
41   // Transfer object ownership of scene-object to message
42   SceneGraph::MeshAttachment* sceneObject = SceneGraph::MeshAttachment::New();
43   AttachToNodeMessage( stage.GetUpdateManager(), parentNode, sceneObject );
44
45   // Keep raw pointer for message passing
46   attachment->mSceneObject = sceneObject;
47
48   return attachment;
49 }
50
51 MeshAttachment::MeshAttachment( Stage& stage )
52 : RenderableAttachment( stage ),
53   mSceneObject( NULL )
54 {
55 }
56
57 MeshAttachment::~MeshAttachment()
58 {
59   // Belt and braces - should already have been disconnected from stage
60   if ( Stage::IsInstalled() &&
61        OnStage() )
62   {
63     DisconnectMaterial();
64   }
65 }
66
67 void MeshAttachment::SetMesh( const MeshIPtr        meshPtr,
68                               ResourceId            meshId,
69                               const BoneContainer&  bones,
70                               const MaterialIPtr    material )
71 {
72   mMesh.mMesh = meshPtr;
73   mMesh.mCustomMaterial = 0;
74
75   std::size_t boneCount = bones.size();
76
77   if ( boneCount > 0 )
78   {
79     // Copy bone names locally in order to perform actor binding later
80
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 )
83     {
84       const Bone& bone = (*iter);
85       mMesh.mBoneNames.push_back( bone.GetName() );
86     }
87   }
88
89   mMesh.mMaterial = material;
90   const SceneGraph::Material* materialSceneObject = material->GetSceneObject();
91
92   // sceneObject is being used in a separate thread; queue a message to set
93   SetMeshMessage( mStage->GetUpdateInterface(), *mSceneObject, meshId, materialSceneObject, boneCount );
94 }
95
96 void MeshAttachment::SetMesh( const ResourceTicketPtr ticket,
97                               const BoneContainer& bones,
98                               const MaterialIPtr material )
99 {
100   SetMesh( 0, ticket->GetId(), bones, material );
101 }
102
103 void MeshAttachment::SetMaterial( MaterialIPtr material )
104 {
105   const SceneGraph::Material* materialSceneObject = NULL;
106
107   if ( material )
108   {
109     // We have a new material.
110     if ( OnStage() )
111     {
112       DisconnectMaterial();
113
114       // connect the new material
115       material->Connect();
116     }
117
118     mMesh.mCustomMaterial = material;
119
120     materialSceneObject = material->GetSceneObject();
121     DALI_ASSERT_DEBUG( materialSceneObject != NULL );
122   }
123   else
124   {
125     // We are unsetting the current material, and reverting to the original material
126     if ( mMesh.mCustomMaterial )
127     {
128       if ( OnStage() )
129       {
130         mMesh.mCustomMaterial->Disconnect();
131       }
132       mMesh.mCustomMaterial = NULL;
133     }
134
135     // connect original material
136     DALI_ASSERT_DEBUG( mMesh.mMaterial );
137
138     if ( OnStage() )
139     {
140       mMesh.mMaterial->Connect();
141     }
142     materialSceneObject = mMesh.mMaterial->GetSceneObject();
143   }
144
145   if ( OnStage() )
146   {
147     // sceneObject is being used in a separate thread; queue a message to set
148     SetMaterialMessage( mStage->GetUpdateInterface(), *mSceneObject, materialSceneObject );
149   }
150 }
151
152 Internal::MaterialIPtr MeshAttachment::GetMaterial( ) const
153 {
154   Internal::MaterialIPtr material;
155
156   if ( mMesh.mCustomMaterial )
157   {
158     material = mMesh.mCustomMaterial;
159   }
160   else if ( mMesh.mMaterial )
161   {
162     material = mMesh.mMaterial;
163   }
164   return material;
165 }
166
167
168 void MeshAttachment::DisconnectMaterial()
169 {
170   if ( mMesh.mCustomMaterial )
171   {
172     mMesh.mCustomMaterial->Disconnect();
173   }
174   else if ( mMesh.mMaterial )
175   {
176     mMesh.mMaterial->Disconnect();
177   }
178 }
179
180 void MeshAttachment::BindBonesToMesh( Internal::ActorPtr rootActor )
181 {
182   size_t boneIdx = 0;
183   size_t boneCount = mMesh.mBoneNames.size();
184
185   if ( boneCount > 0 )
186   {
187     for ( BoneNamesIter boneIter=mMesh.mBoneNames.begin(); boneIter != mMesh.mBoneNames.end(); ++boneIter )
188     {
189       ActorPtr boneActor = rootActor->FindChildByName( *boneIter );
190       if ( boneActor )
191       {
192         ConnectBoneActor( boneActor, boneIdx, boneCount );
193         boneIdx++;
194       }
195     }
196   }
197 }
198
199 void MeshAttachment::ConnectBoneActor( Internal::ActorPtr boneActor,
200                                        size_t             boneIdx,
201                                        size_t             boneCount )
202 {
203   Connector* connector = new Connector( boneActor, boneIdx, *this );
204   mConnectors.PushBack( connector );
205   connector->ConnectNode();
206 }
207
208 void MeshAttachment::OnStageConnection2()
209 {
210   // Ensure current materials are staged
211   const SceneGraph::MeshAttachment& sceneObject = *mSceneObject;
212
213   const SceneGraph::Material* materialSceneObject = NULL;
214   if ( mMesh.mCustomMaterial )
215   {
216     mMesh.mCustomMaterial->Connect();
217     materialSceneObject = mMesh.mCustomMaterial->GetSceneObject();
218   }
219   else if ( mMesh.mMaterial )
220   {
221     mMesh.mMaterial->Connect();
222     materialSceneObject = mMesh.mMaterial->GetSceneObject();
223   }
224   DALI_ASSERT_DEBUG( materialSceneObject );
225
226   // And that the scene object has a connection to each material
227   SetMaterialMessage( mStage->GetUpdateInterface(), sceneObject, materialSceneObject );
228
229   // Ensure all staged bones are reconnected
230   for(ConnectorList::Iterator iter=mConnectors.Begin(); iter != mConnectors.End(); ++iter)
231   {
232     Connector* connector = (*iter);
233     connector->ConnectNode();
234   }
235 }
236
237 void MeshAttachment::OnStageDisconnection2()
238 {
239   DisconnectMaterial();
240 }
241
242 const SceneGraph::RenderableAttachment& MeshAttachment::GetSceneObject() const
243 {
244   DALI_ASSERT_DEBUG( mSceneObject != NULL );
245   return *mSceneObject;
246 }
247
248 void MeshAttachment::SetBoneNode( SceneGraph::Node* node, size_t boneIdx )
249 {
250   size_t boneCount = mMesh.mBoneNames.size();
251
252   SetBoneNodeMessage( mStage->GetUpdateInterface(), *mSceneObject, node, boneIdx, boneCount );
253 }
254
255 // Helper class for connecting Nodes to the scene-graph MeshAttachment
256 MeshAttachment::Connector::Connector(
257   Internal::ActorPtr boneActor,
258   size_t             boneIdx,
259   MeshAttachment&    meshAttachment)
260 : mMeshAttachment(meshAttachment),
261   mActor(boneActor.Get()),
262   mBoneIdx(boneIdx)
263 {
264   if( mActor )
265   {
266     mActor->AddObserver( *this );
267     ConnectNode();
268   }
269 }
270
271 MeshAttachment::Connector::~Connector()
272 {
273   if( mActor)
274   {
275     mActor->RemoveObserver( *this );
276   }
277 }
278
279 void MeshAttachment::Connector::SceneObjectAdded( Object& object )
280 {
281   ConnectNode();
282 }
283
284 void MeshAttachment::Connector::SceneObjectRemoved( Object& object )
285 {
286   ConnectNode();
287 }
288
289 void MeshAttachment::Connector::ObjectDestroyed( Object& object )
290 {
291   mActor = NULL;
292
293   ConnectNode();
294 }
295
296 void MeshAttachment::Connector::ConnectNode()
297 {
298   SceneGraph::Node* theNode( NULL );
299
300   if( mActor != NULL )
301   {
302     const SceneGraph::PropertyOwner* object = mActor->GetSceneObject();
303     if ( NULL != object )
304     {
305       const SceneGraph::Node* aNode = dynamic_cast< const SceneGraph::Node* >( object );
306       if( aNode != NULL )
307       {
308         theNode = const_cast< SceneGraph::Node* >( aNode );
309       }
310     }
311   }
312
313   mMeshAttachment.SetBoneNode( theNode, mBoneIdx );
314 }
315
316
317 } // namespace Internal
318
319 } // namespace Dali