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/actors/model-actor-factory-impl.h>
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>
33 using Internal::MeshIter;
34 using Internal::ActorPtr;
39 ActorPtr ModelActorFactory::BuildActorTree(Dali::Model& model, const std::string& entityName)
44 Internal::ModelDataPtr modelData(GetImplementation(model).GetModelData());
48 Dali::Entity root = modelData->GetRootEntity();
49 if (entityName.empty())
55 entity = root.Find(entityName);
61 actorPtr = RecurseNew(modelData, entity);
65 DALI_LOG_INFO(Debug::Filter::gModel, Debug::General, "Entity %s not found\n", entityName.c_str());
70 Vector4 bounds(entity.GetUpperBounds() - entity.GetLowerBounds());
71 Vector3 initialVolume(bounds.x, bounds.y, bounds.z);
73 actorPtr->SetInitialVolume(initialVolume);
74 actorPtr->SetTransmitGeometryScaling(true);
76 BindBonesToMeshActors(actorPtr, actorPtr);
82 ActorPtr ModelActorFactory::RecurseNew(ModelDataPtr modelData, Dali::Entity entity)
85 if(entity.HasMeshes())
87 actorPtr = Internal::MeshActor::New(modelData, entity);
91 // Root with no mesh, or bone/joint actor (with no mesh)
92 actorPtr = Internal::Actor::New();
93 actorPtr->SetName(entity.GetName());
94 Matrix transform(entity.GetTransformMatrix());
98 transform.GetTransformComponents(position, rotation, scale);
99 actorPtr->SetPosition(position);
100 actorPtr->SetRotation(rotation);
101 actorPtr->SetScale(scale);
104 actorPtr->SetParentOrigin(ParentOrigin::CENTER);
105 actorPtr->SetAnchorPoint(AnchorPoint::CENTER);
107 if (entity.HasChildren())
109 for (EntityConstIter iter = entity.GetChildren().begin(); iter != entity.GetChildren().end(); ++iter)
111 Dali::Entity childEntity = (*iter);
112 ActorPtr child = RecurseNew(modelData, childEntity);
113 actorPtr->Add(*child.Get());
120 void ModelActorFactory::BindBonesToMeshActors(ActorPtr rootActor, ActorPtr actorPtr)
122 MeshActor* meshActor = dynamic_cast<MeshActor*>(actorPtr.Get());
125 meshActor->BindBonesToMesh(rootActor);
128 // Descend to all child actors, not just mesh actors
129 const ActorContainer& children = actorPtr->GetChildren();
130 for ( ActorConstIter iter = children.begin(); iter != children.end(); ++iter)
132 ActorPtr childActor = const_cast<Actor*>(&GetImplementation(*iter));
133 BindBonesToMeshActors(rootActor, childActor);
139 AnimationPtr ModelActorFactory::BuildAnimation(
144 AnimationPtr animation;
145 Internal::ModelDataPtr modelData(model.GetModelData());
149 if (index >= modelData->NumberOfAnimationMaps())
151 DALI_LOG_ERROR("Invalid animation index\n");
155 const ModelAnimationMap* animationData(modelData->GetAnimationMap(index));
156 if( animationData != NULL )
158 animation = CreateAnimation(rootActor, animationData, AlphaFunctions::Linear, animationData->duration);
165 AnimationPtr ModelActorFactory::BuildAnimation(
169 float durationSeconds)
171 AnimationPtr animation;
172 Internal::ModelDataPtr modelData(model.GetModelData());
176 if (index >= modelData->NumberOfAnimationMaps())
178 DALI_LOG_ERROR("Invalid animation index\n");
182 const ModelAnimationMap* animationData(modelData->GetAnimationMap(index));
183 if( animationData != NULL )
185 animation = CreateAnimation(rootActor, animationData, AlphaFunctions::Linear, durationSeconds);
192 AnimationPtr ModelActorFactory::BuildAnimation(
198 AnimationPtr animation;
199 Internal::ModelDataPtr modelData(model.GetModelData());
203 if (index >= modelData->NumberOfAnimationMaps())
205 DALI_LOG_ERROR("Invalid animation index\n");
209 const ModelAnimationMap* animationData(modelData->GetAnimationMap(index));
210 if( animationData != NULL )
212 animation = CreateAnimation(rootActor, animationData, alpha, animationData->duration);
220 AnimationPtr ModelActorFactory::BuildAnimation(
225 float durationSeconds)
227 AnimationPtr animation;
228 Internal::ModelDataPtr modelData(model.GetModelData());
232 if (index >= modelData->NumberOfAnimationMaps())
234 DALI_LOG_ERROR("Invalid animation index\n");
238 const ModelAnimationMap* animationData(modelData->GetAnimationMap(index));
239 if( animationData != NULL )
241 animation = CreateAnimation(rootActor, animationData, alpha, durationSeconds);
251 AnimationPtr ModelActorFactory::CreateAnimation(
253 const ModelAnimationMap* animationData,
255 float durationSeconds)
257 DALI_LOG_TRACE_METHOD(Debug::Filter::gModel);
259 AnimationPtr animation(Animation::New(durationSeconds));
260 animation->SetDefaultAlphaFunction(alpha);
262 for(EntityAnimatorMapIter it = animationData->animators.begin(); it != animationData->animators.end(); ++it)
264 const EntityAnimatorMap& entityAnimator(*it);
266 // find actor for this animator
267 ActorPtr animatedActor = rootActor.FindChildByName(entityAnimator.GetEntityName());
270 // If we can't find the actor, it may not have been instantiated, may
271 // be a sibling or parent of rootActor or may have been removed.
275 Dali::Actor targetActor(animatedActor.Get());
277 Dali::KeyFrames posKFHandle = entityAnimator.GetPositionKeyFrames();
280 const KeyFrames& positionKeyFrames = GetImplementation(posKFHandle);
281 if(positionKeyFrames.GetKeyFramesBase()->GetNumberOfKeyFrames() > 0)
283 animation->AnimateBetween(Property(targetActor, Dali::Actor::POSITION),
284 positionKeyFrames, alpha, durationSeconds);
288 Dali::KeyFrames scaleKFHandle = entityAnimator.GetScaleKeyFrames();
291 const KeyFrames& scaleKeyFrames = GetImplementation(scaleKFHandle);
292 if(scaleKeyFrames.GetKeyFramesBase()->GetNumberOfKeyFrames() > 0)
294 animation->AnimateBetween(Property(targetActor, Dali::Actor::SCALE), scaleKeyFrames, alpha, durationSeconds);
298 Dali::KeyFrames rotationKFHandle = entityAnimator.GetRotationKeyFrames();
301 const KeyFrames& rotationKeyFrames = GetImplementation(rotationKFHandle);
302 if(rotationKeyFrames.GetKeyFramesBase()->GetNumberOfKeyFrames() > 0)
304 animation->AnimateBetween(Property(targetActor, Dali::Actor::ROTATION), rotationKeyFrames, alpha, durationSeconds);
313 } // namespace Internal