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>
32 const float ROTATION_EPSILON = 0.003f;
38 using Internal::MeshIter;
39 using Internal::ActorPtr;
44 ActorPtr ModelActorFactory::BuildActorTree(Dali::Model& model, const std::string& entityName)
49 Internal::ModelDataPtr modelData(GetImplementation(model).GetModelData());
53 Dali::Entity root = modelData->GetRootEntity();
54 if (entityName.empty())
60 entity = root.Find(entityName);
66 actorPtr = RecurseNew(modelData, entity);
70 DALI_LOG_INFO(Debug::Filter::gModel, Debug::General, "Entity %s not found\n", entityName.c_str());
75 Vector4 bounds(entity.GetUpperBounds() - entity.GetLowerBounds());
76 Vector3 initialVolume(bounds.x, bounds.y, bounds.z);
78 actorPtr->SetInitialVolume(initialVolume);
79 actorPtr->SetTransmitGeometryScaling(true);
81 BindBonesToMeshActors(actorPtr, actorPtr);
87 ActorPtr ModelActorFactory::RecurseNew(ModelDataPtr modelData, Dali::Entity entity)
90 if(entity.HasMeshes())
92 actorPtr = Internal::MeshActor::New(modelData, entity);
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());
103 transform.GetTransformComponents(position, rotation, scale);
104 actorPtr->SetPosition(position);
105 actorPtr->SetRotation(rotation);
106 actorPtr->SetScale(scale);
109 actorPtr->SetParentOrigin(ParentOrigin::CENTER);
110 actorPtr->SetAnchorPoint(AnchorPoint::CENTER);
112 if (entity.HasChildren())
114 for (EntityConstIter iter = entity.GetChildren().begin(); iter != entity.GetChildren().end(); ++iter)
116 Dali::Entity childEntity = (*iter);
117 ActorPtr child = RecurseNew(modelData, childEntity);
118 actorPtr->Add(*child.Get());
125 void ModelActorFactory::BindBonesToMeshActors(ActorPtr rootActor, ActorPtr actorPtr)
127 MeshActor* meshActor = dynamic_cast<MeshActor*>(actorPtr.Get());
130 meshActor->BindBonesToMesh(rootActor);
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)
137 ActorPtr childActor = const_cast<Actor*>(&GetImplementation(*iter));
138 BindBonesToMeshActors(rootActor, childActor);
144 AnimationPtr ModelActorFactory::BuildAnimation(
149 AnimationPtr animation;
150 Internal::ModelDataPtr modelData(model.GetModelData());
154 if (index >= modelData->NumberOfAnimationMaps())
156 DALI_LOG_ERROR("Invalid animation index\n");
160 const ModelAnimationMap* animationData(modelData->GetAnimationMap(index));
161 if( animationData != NULL )
163 animation = CreateAnimation(rootActor, animationData, AlphaFunctions::Linear, animationData->duration);
170 AnimationPtr ModelActorFactory::BuildAnimation(
174 float durationSeconds)
176 AnimationPtr animation;
177 Internal::ModelDataPtr modelData(model.GetModelData());
181 if (index >= modelData->NumberOfAnimationMaps())
183 DALI_LOG_ERROR("Invalid animation index\n");
187 const ModelAnimationMap* animationData(modelData->GetAnimationMap(index));
188 if( animationData != NULL )
190 animation = CreateAnimation(rootActor, animationData, AlphaFunctions::Linear, durationSeconds);
197 AnimationPtr ModelActorFactory::BuildAnimation(
203 AnimationPtr animation;
204 Internal::ModelDataPtr modelData(model.GetModelData());
208 if (index >= modelData->NumberOfAnimationMaps())
210 DALI_LOG_ERROR("Invalid animation index\n");
214 const ModelAnimationMap* animationData(modelData->GetAnimationMap(index));
215 if( animationData != NULL )
217 animation = CreateAnimation(rootActor, animationData, alpha, animationData->duration);
225 AnimationPtr ModelActorFactory::BuildAnimation(
230 float durationSeconds)
232 AnimationPtr animation;
233 Internal::ModelDataPtr modelData(model.GetModelData());
237 if (index >= modelData->NumberOfAnimationMaps())
239 DALI_LOG_ERROR("Invalid animation index\n");
243 const ModelAnimationMap* animationData(modelData->GetAnimationMap(index));
244 if( animationData != NULL )
246 animation = CreateAnimation(rootActor, animationData, alpha, durationSeconds);
256 AnimationPtr ModelActorFactory::CreateAnimation(
258 const ModelAnimationMap* animationData,
260 float durationSeconds)
262 DALI_LOG_TRACE_METHOD(Debug::Filter::gModel);
264 AnimationPtr animation(Animation::New(durationSeconds));
265 animation->SetDefaultAlphaFunction(alpha);
267 for(EntityAnimatorMapIter it = animationData->animators.begin(); it != animationData->animators.end(); ++it)
269 const EntityAnimatorMap& entityAnimator(*it);
271 // find actor for this animator
272 ActorPtr animatedActor = rootActor.FindChildByName(entityAnimator.GetEntityName());
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.
280 Dali::Actor targetActor(animatedActor.Get());
282 Dali::KeyFrames posKFHandle = entityAnimator.GetPositionKeyFrames();
285 const KeyFrames& positionKeyFrames = GetImplementation(posKFHandle);
286 if(positionKeyFrames.GetKeyFramesBase()->GetNumberOfKeyFrames() > 0)
288 animation->AnimateBetween(Property(targetActor, Dali::Actor::POSITION),
289 positionKeyFrames, alpha, durationSeconds);
293 Dali::KeyFrames scaleKFHandle = entityAnimator.GetScaleKeyFrames();
296 const KeyFrames& scaleKeyFrames = GetImplementation(scaleKFHandle);
297 if(scaleKeyFrames.GetKeyFramesBase()->GetNumberOfKeyFrames() > 0)
299 animation->AnimateBetween(Property(targetActor, Dali::Actor::SCALE), scaleKeyFrames, alpha, durationSeconds);
303 Dali::KeyFrames rotationKFHandle = entityAnimator.GetRotationKeyFrames();
306 const KeyFrames& rotationKeyFrames = GetImplementation(rotationKFHandle);
307 if(rotationKeyFrames.GetKeyFramesBase()->GetNumberOfKeyFrames() > 0)
309 animation->AnimateBetween(Property(targetActor, Dali::Actor::ROTATION), rotationKeyFrames, alpha, durationSeconds);
318 } // namespace Internal