AnimationPtr ModelActorFactory::CreateAnimation(
    Actor& rootActor,
    const ModelAnimationMap* animationData,
    AlphaFunction alpha,
    float durationSeconds)
{
    DALI_LOG_TRACE_METHOD(Debug::Filter::gModel);

    AnimationPtr animation(Animation::New(durationSeconds));
    animation->SetDefaultAlphaFunction(alpha);

    for(EntityAnimatorMapIter it = animationData->animators.begin(); it != animationData->animators.end(); ++it)
    {
        const EntityAnimatorMap& entityAnimator(*it);

        // find actor for this animator
        ActorPtr animatedActor = rootActor.FindChildByName(entityAnimator.GetEntityName());
        if (!animatedActor)
        {
            // If we can't find the actor, it may not have been instantiated, may
            // be a sibling or parent of rootActor or may have been removed.
            continue;
        }

        Dali::Actor targetActor(animatedActor.Get());

        Dali::KeyFrames posKFHandle = entityAnimator.GetPositionKeyFrames();
        if(posKFHandle)
        {
            const KeyFrames& positionKeyFrames = GetImplementation(posKFHandle);
            if(positionKeyFrames.GetKeyFramesBase()->GetNumberOfKeyFrames() > 0)
            {
                animation->AnimateBetween(Property(targetActor, Dali::Actor::POSITION),
                                          positionKeyFrames, alpha, durationSeconds);
            }
        }

        Dali::KeyFrames scaleKFHandle = entityAnimator.GetScaleKeyFrames();
        if(scaleKFHandle)
        {
            const KeyFrames& scaleKeyFrames    = GetImplementation(scaleKFHandle);
            if(scaleKeyFrames.GetKeyFramesBase()->GetNumberOfKeyFrames() > 0)
            {
                animation->AnimateBetween(Property(targetActor, Dali::Actor::SCALE),    scaleKeyFrames, alpha, durationSeconds);
            }
        }

        Dali::KeyFrames rotationKFHandle = entityAnimator.GetRotationKeyFrames();
        if(rotationKFHandle)
        {
            const KeyFrames& rotationKeyFrames = GetImplementation(rotationKFHandle);
            if(rotationKeyFrames.GetKeyFramesBase()->GetNumberOfKeyFrames() > 0)
            {
                animation->AnimateBetween(Property(targetActor, Dali::Actor::ROTATION), rotationKeyFrames, alpha, durationSeconds);
            }
        }
    }
    return animation;
}
void ModelActorFactory::BindBonesToMeshActors(ActorPtr rootActor, ActorPtr actorPtr)
{
    MeshActor* meshActor = dynamic_cast<MeshActor*>(actorPtr.Get());
    if(meshActor)
    {
        meshActor->BindBonesToMesh(rootActor);
    }

    // Descend to all child actors, not just mesh actors
    const ActorContainer& children = actorPtr->GetChildren();
    for ( ActorConstIter iter = children.begin(); iter != children.end(); ++iter)
    {
        ActorPtr childActor = const_cast<Actor*>(&GetImplementation(*iter));
        BindBonesToMeshActors(rootActor, childActor);
    }
}
ActorPtr ModelActorFactory::RecurseNew(ModelDataPtr modelData, Dali::Entity entity)
{
    ActorPtr actorPtr;
    if(entity.HasMeshes())
    {
        actorPtr = Internal::MeshActor::New(modelData, entity);
    }
    else
    {
        // Root with no mesh, or bone/joint actor (with no mesh)
        actorPtr = Internal::Actor::New();
        actorPtr->SetName(entity.GetName());
        Matrix transform(entity.GetTransformMatrix());
        Vector3 position;
        Quaternion rotation;
        Vector3 scale;
        transform.GetTransformComponents(position, rotation, scale);
        actorPtr->SetPosition(position);
        actorPtr->SetRotation(rotation);
        actorPtr->SetScale(scale);
    }

    actorPtr->SetParentOrigin(ParentOrigin::CENTER);
    actorPtr->SetAnchorPoint(AnchorPoint::CENTER);

    if (entity.HasChildren())
    {
        for (EntityConstIter iter = entity.GetChildren().begin(); iter != entity.GetChildren().end(); ++iter)
        {
            Dali::Entity childEntity = (*iter);
            ActorPtr child = RecurseNew(modelData, childEntity);
            actorPtr->Add(*child.Get());
        }
    }

    return actorPtr;
}