License conversion from Flora to Apache 2.0
[platform/core/uifw/dali-core.git] / dali / internal / event / actors / model-actor-factory-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/actors/model-actor-factory-impl.h>
20
21 // INTERNAL INCLUDES
22 #include <dali/public-api/modeling/entity.h>
23 #include <dali/internal/event/actors/mesh-actor-impl.h>
24 #include <dali/internal/event/modeling/model-impl.h>
25 #include <dali/internal/event/modeling/model-data-impl.h>
26 #include <dali/internal/event/modeling/mesh-impl.h>
27 #include <dali/internal/event/animation/animator-connector.h>
28
29
30 namespace
31 {
32 const float ROTATION_EPSILON = 0.003f;
33 }
34
35 namespace Dali
36 {
37 using Dali::Entity;
38 using Internal::MeshIter;
39 using Internal::ActorPtr;
40
41 namespace Internal
42 {
43
44 ActorPtr ModelActorFactory::BuildActorTree(Dali::Model& model, const std::string& entityName)
45 {
46   Dali::Entity entity;
47   ActorPtr actorPtr;
48
49   Internal::ModelDataPtr modelData(GetImplementation(model).GetModelData());
50
51   if (modelData)
52   {
53     Dali::Entity root = modelData->GetRootEntity();
54     if (entityName.empty())
55     {
56       entity = root;
57     }
58     else
59     {
60       entity = root.Find(entityName);
61     }
62   }
63
64   if(entity)
65   {
66     actorPtr = RecurseNew(modelData, entity);
67   }
68   else
69   {
70     DALI_LOG_INFO(Debug::Filter::gModel, Debug::General, "Entity %s not found\n", entityName.c_str());
71   }
72
73   if(actorPtr)
74   {
75     Vector4 bounds(entity.GetUpperBounds() - entity.GetLowerBounds());
76     Vector3 initialVolume(bounds.x, bounds.y, bounds.z);
77
78     actorPtr->SetInitialVolume(initialVolume);
79     actorPtr->SetTransmitGeometryScaling(true);
80
81     BindBonesToMeshActors(actorPtr, actorPtr);
82   }
83   return actorPtr;
84 }
85
86
87 ActorPtr ModelActorFactory::RecurseNew(ModelDataPtr modelData, Dali::Entity entity)
88 {
89   ActorPtr actorPtr;
90   if(entity.HasMeshes())
91   {
92     actorPtr = Internal::MeshActor::New(modelData, entity);
93   }
94   else
95   {
96     // Root with no mesh, or bone/joint actor (with no mesh)
97     actorPtr = Internal::Actor::New();
98     actorPtr->SetName(entity.GetName());
99     Matrix transform(entity.GetTransformMatrix());
100     Vector3 position;
101     Quaternion rotation;
102     Vector3 scale;
103     transform.GetTransformComponents(position, rotation, scale);
104     actorPtr->SetPosition(position);
105     actorPtr->SetRotation(rotation);
106     actorPtr->SetScale(scale);
107   }
108
109   actorPtr->SetParentOrigin(ParentOrigin::CENTER);
110   actorPtr->SetAnchorPoint(AnchorPoint::CENTER);
111
112   if (entity.HasChildren())
113   {
114     for (EntityConstIter iter = entity.GetChildren().begin(); iter != entity.GetChildren().end(); ++iter)
115     {
116       Dali::Entity childEntity = (*iter);
117       ActorPtr child = RecurseNew(modelData, childEntity);
118       actorPtr->Add(*child.Get());
119     }
120   }
121
122   return actorPtr;
123 }
124
125 void ModelActorFactory::BindBonesToMeshActors(ActorPtr rootActor, ActorPtr actorPtr)
126 {
127   MeshActor* meshActor = dynamic_cast<MeshActor*>(actorPtr.Get());
128   if(meshActor)
129   {
130     meshActor->BindBonesToMesh(rootActor);
131   }
132
133   // Descend to all child actors, not just mesh actors
134   const ActorContainer& children = actorPtr->GetChildren();
135   for ( ActorConstIter iter = children.begin(); iter != children.end(); ++iter)
136   {
137     ActorPtr childActor = const_cast<Actor*>(&GetImplementation(*iter));
138     BindBonesToMeshActors(rootActor, childActor);
139   }
140 }
141
142
143
144 AnimationPtr ModelActorFactory::BuildAnimation(
145   Model& model,
146   Actor& rootActor,
147   size_t index)
148 {
149   AnimationPtr animation;
150   Internal::ModelDataPtr modelData(model.GetModelData());
151
152   if (modelData)
153   {
154     if (index >= modelData->NumberOfAnimationMaps())
155     {
156       DALI_LOG_ERROR("Invalid animation index\n");
157     }
158     else
159     {
160       const ModelAnimationMap* animationData(modelData->GetAnimationMap(index));
161       if( animationData != NULL )
162       {
163         animation = CreateAnimation(rootActor, animationData, AlphaFunctions::Linear, animationData->duration);
164       }
165     }
166   }
167   return animation;
168 }
169
170 AnimationPtr ModelActorFactory::BuildAnimation(
171   Model& model,
172   Actor& rootActor,
173   size_t index,
174   float durationSeconds)
175 {
176   AnimationPtr animation;
177   Internal::ModelDataPtr modelData(model.GetModelData());
178
179   if (modelData)
180   {
181     if (index >= modelData->NumberOfAnimationMaps())
182     {
183       DALI_LOG_ERROR("Invalid animation index\n");
184     }
185     else
186     {
187       const ModelAnimationMap* animationData(modelData->GetAnimationMap(index));
188       if( animationData != NULL )
189       {
190         animation = CreateAnimation(rootActor, animationData, AlphaFunctions::Linear, durationSeconds);
191       }
192     }
193   }
194   return animation;
195 }
196
197 AnimationPtr ModelActorFactory::BuildAnimation(
198   Model& model,
199   Actor& rootActor,
200   size_t index,
201   AlphaFunction alpha)
202 {
203   AnimationPtr animation;
204   Internal::ModelDataPtr modelData(model.GetModelData());
205
206   if (modelData)
207   {
208     if (index >= modelData->NumberOfAnimationMaps())
209     {
210       DALI_LOG_ERROR("Invalid animation index\n");
211     }
212     else
213     {
214       const ModelAnimationMap* animationData(modelData->GetAnimationMap(index));
215       if( animationData != NULL )
216       {
217         animation = CreateAnimation(rootActor, animationData, alpha, animationData->duration);
218       }
219     }
220   }
221   return animation;
222 }
223
224
225 AnimationPtr ModelActorFactory::BuildAnimation(
226   Model& model,
227   Actor& rootActor,
228   size_t index,
229   AlphaFunction alpha,
230   float durationSeconds)
231 {
232   AnimationPtr animation;
233   Internal::ModelDataPtr modelData(model.GetModelData());
234
235   if (modelData)
236   {
237     if (index >= modelData->NumberOfAnimationMaps())
238     {
239       DALI_LOG_ERROR("Invalid animation index\n");
240     }
241     else
242     {
243       const ModelAnimationMap* animationData(modelData->GetAnimationMap(index));
244       if( animationData != NULL )
245       {
246         animation = CreateAnimation(rootActor, animationData, alpha, durationSeconds);
247       }
248     }
249   }
250   return animation;
251 }
252
253
254
255
256 AnimationPtr ModelActorFactory::CreateAnimation(
257   Actor& rootActor,
258   const ModelAnimationMap* animationData,
259   AlphaFunction alpha,
260   float durationSeconds)
261 {
262   DALI_LOG_TRACE_METHOD(Debug::Filter::gModel);
263
264   AnimationPtr animation(Animation::New(durationSeconds));
265   animation->SetDefaultAlphaFunction(alpha);
266
267   for(EntityAnimatorMapIter it = animationData->animators.begin(); it != animationData->animators.end(); ++it)
268   {
269     const EntityAnimatorMap& entityAnimator(*it);
270
271     // find actor for this animator
272     ActorPtr animatedActor = rootActor.FindChildByName(entityAnimator.GetEntityName());
273     if (!animatedActor)
274     {
275       // If we can't find the actor, it may not have been instantiated, may
276       // be a sibling or parent of rootActor or may have been removed.
277       continue;
278     }
279
280     Dali::Actor targetActor(animatedActor.Get());
281
282     Dali::KeyFrames posKFHandle = entityAnimator.GetPositionKeyFrames();
283     if(posKFHandle)
284     {
285       const KeyFrames& positionKeyFrames = GetImplementation(posKFHandle);
286       if(positionKeyFrames.GetKeyFramesBase()->GetNumberOfKeyFrames() > 0)
287       {
288         animation->AnimateBetween(Property(targetActor, Dali::Actor::POSITION),
289                                   positionKeyFrames, alpha, durationSeconds);
290       }
291     }
292
293     Dali::KeyFrames scaleKFHandle = entityAnimator.GetScaleKeyFrames();
294     if(scaleKFHandle)
295     {
296       const KeyFrames& scaleKeyFrames    = GetImplementation(scaleKFHandle);
297       if(scaleKeyFrames.GetKeyFramesBase()->GetNumberOfKeyFrames() > 0)
298       {
299         animation->AnimateBetween(Property(targetActor, Dali::Actor::SCALE),    scaleKeyFrames, alpha, durationSeconds);
300       }
301     }
302
303     Dali::KeyFrames rotationKFHandle = entityAnimator.GetRotationKeyFrames();
304     if(rotationKFHandle)
305     {
306       const KeyFrames& rotationKeyFrames = GetImplementation(rotationKFHandle);
307       if(rotationKeyFrames.GetKeyFramesBase()->GetNumberOfKeyFrames() > 0)
308       {
309         animation->AnimateBetween(Property(targetActor, Dali::Actor::ROTATION), rotationKeyFrames, alpha, durationSeconds);
310       }
311     }
312   }
313   return animation;
314 }
315
316
317
318 } // namespace Internal
319 } // namespace Dali