2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 // Licensed under the Flora License, Version 1.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://floralicense.org/license/
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/actors/model-actor-factory-impl.h>
21 #include <dali/public-api/modeling/entity.h>
22 #include <dali/internal/event/actors/mesh-actor-impl.h>
23 #include <dali/internal/event/modeling/model-impl.h>
24 #include <dali/internal/event/modeling/model-data-impl.h>
25 #include <dali/internal/event/modeling/mesh-impl.h>
26 #include <dali/internal/event/animation/animator-connector.h>
31 const float ROTATION_EPSILON = 0.003f;
37 using Internal::MeshIter;
38 using Internal::ActorPtr;
43 ActorPtr ModelActorFactory::BuildActorTree(Dali::Model& model, const std::string& entityName)
48 Internal::ModelDataPtr modelData(GetImplementation(model).GetModelData());
52 Dali::Entity root = modelData->GetRootEntity();
53 if (entityName.empty())
59 entity = root.Find(entityName);
65 actorPtr = RecurseNew(modelData, entity);
69 DALI_LOG_INFO(Debug::Filter::gModel, Debug::General, "Entity %s not found\n", entityName.c_str());
74 Vector4 bounds(entity.GetUpperBounds() - entity.GetLowerBounds());
75 Vector3 initialVolume(bounds.x, bounds.y, bounds.z);
77 actorPtr->SetInitialVolume(initialVolume);
78 actorPtr->SetTransmitGeometryScaling(true);
80 BindBonesToMeshActors(actorPtr, actorPtr);
86 ActorPtr ModelActorFactory::RecurseNew(ModelDataPtr modelData, Dali::Entity entity)
89 if(entity.HasMeshes())
91 actorPtr = Internal::MeshActor::New(modelData, entity);
95 // Root with no mesh, or bone/joint actor (with no mesh)
96 actorPtr = Internal::Actor::New();
97 actorPtr->SetName(entity.GetName());
98 Matrix transform(entity.GetTransformMatrix());
102 transform.GetTransformComponents(position, rotation, scale);
103 actorPtr->SetPosition(position);
104 actorPtr->SetRotation(rotation);
105 actorPtr->SetScale(scale);
108 actorPtr->SetParentOrigin(ParentOrigin::CENTER);
109 actorPtr->SetAnchorPoint(AnchorPoint::CENTER);
111 if (entity.HasChildren())
113 for (EntityConstIter iter = entity.GetChildren().begin(); iter != entity.GetChildren().end(); ++iter)
115 Dali::Entity childEntity = (*iter);
116 ActorPtr child = RecurseNew(modelData, childEntity);
117 actorPtr->Add(*child.Get());
124 void ModelActorFactory::BindBonesToMeshActors(ActorPtr rootActor, ActorPtr actorPtr)
126 MeshActor* meshActor = dynamic_cast<MeshActor*>(actorPtr.Get());
129 meshActor->BindBonesToMesh(rootActor);
132 // Descend to all child actors, not just mesh actors
133 const ActorContainer& children = actorPtr->GetChildren();
134 for ( ActorConstIter iter = children.begin(); iter != children.end(); ++iter)
136 ActorPtr childActor = const_cast<Actor*>(&GetImplementation(*iter));
137 BindBonesToMeshActors(rootActor, childActor);
143 AnimationPtr ModelActorFactory::BuildAnimation(
148 AnimationPtr animation;
149 Internal::ModelDataPtr modelData(model.GetModelData());
153 if (index >= modelData->NumberOfAnimationMaps())
155 DALI_LOG_ERROR("Invalid animation index\n");
159 const ModelAnimationMap* animationData(modelData->GetAnimationMap(index));
160 if( animationData != NULL )
162 animation = CreateAnimation(rootActor, animationData, AlphaFunctions::Linear, animationData->duration);
169 AnimationPtr ModelActorFactory::BuildAnimation(
173 float durationSeconds)
175 AnimationPtr animation;
176 Internal::ModelDataPtr modelData(model.GetModelData());
180 if (index >= modelData->NumberOfAnimationMaps())
182 DALI_LOG_ERROR("Invalid animation index\n");
186 const ModelAnimationMap* animationData(modelData->GetAnimationMap(index));
187 if( animationData != NULL )
189 animation = CreateAnimation(rootActor, animationData, AlphaFunctions::Linear, durationSeconds);
196 AnimationPtr ModelActorFactory::BuildAnimation(
202 AnimationPtr animation;
203 Internal::ModelDataPtr modelData(model.GetModelData());
207 if (index >= modelData->NumberOfAnimationMaps())
209 DALI_LOG_ERROR("Invalid animation index\n");
213 const ModelAnimationMap* animationData(modelData->GetAnimationMap(index));
214 if( animationData != NULL )
216 animation = CreateAnimation(rootActor, animationData, alpha, animationData->duration);
224 AnimationPtr ModelActorFactory::BuildAnimation(
229 float durationSeconds)
231 AnimationPtr animation;
232 Internal::ModelDataPtr modelData(model.GetModelData());
236 if (index >= modelData->NumberOfAnimationMaps())
238 DALI_LOG_ERROR("Invalid animation index\n");
242 const ModelAnimationMap* animationData(modelData->GetAnimationMap(index));
243 if( animationData != NULL )
245 animation = CreateAnimation(rootActor, animationData, alpha, durationSeconds);
255 AnimationPtr ModelActorFactory::CreateAnimation(
257 const ModelAnimationMap* animationData,
259 float durationSeconds)
261 DALI_LOG_TRACE_METHOD(Debug::Filter::gModel);
263 AnimationPtr animation(Animation::New(durationSeconds));
264 animation->SetDefaultAlphaFunction(alpha);
266 for(EntityAnimatorMapIter it = animationData->animators.begin(); it != animationData->animators.end(); ++it)
268 const EntityAnimatorMap& entityAnimator(*it);
270 // find actor for this animator
271 ActorPtr animatedActor = rootActor.FindChildByName(entityAnimator.GetEntityName());
274 // If we can't find the actor, it may not have been instantiated, may
275 // be a sibling or parent of rootActor or may have been removed.
279 Dali::Actor targetActor(animatedActor.Get());
281 Dali::KeyFrames posKFHandle = entityAnimator.GetPositionKeyFrames();
284 const KeyFrames& positionKeyFrames = GetImplementation(posKFHandle);
285 if(positionKeyFrames.GetKeyFramesBase()->GetNumberOfKeyFrames() > 0)
287 animation->AnimateBetween(Property(targetActor, Dali::Actor::POSITION),
288 positionKeyFrames, alpha, durationSeconds);
292 Dali::KeyFrames scaleKFHandle = entityAnimator.GetScaleKeyFrames();
295 const KeyFrames& scaleKeyFrames = GetImplementation(scaleKFHandle);
296 if(scaleKeyFrames.GetKeyFramesBase()->GetNumberOfKeyFrames() > 0)
298 animation->AnimateBetween(Property(targetActor, Dali::Actor::SCALE), scaleKeyFrames, alpha, durationSeconds);
302 Dali::KeyFrames rotationKFHandle = entityAnimator.GetRotationKeyFrames();
305 const KeyFrames& rotationKeyFrames = GetImplementation(rotationKFHandle);
306 if(rotationKeyFrames.GetKeyFramesBase()->GetNumberOfKeyFrames() > 0)
308 animation->AnimateBetween(Property(targetActor, Dali::Actor::ROTATION), rotationKeyFrames, alpha, durationSeconds);
317 } // namespace Internal