From 9f90ddba69147b5a74cc7ea40b1b877a0634f36a Mon Sep 17 00:00:00 2001 From: David Steele Date: Thu, 22 Sep 2022 16:10:47 +0100 Subject: [PATCH] Moved event side actor world calculation Transition effects used event side calculation of world transform and color. These are more useful in devel core than internally in toolkit. Change-Id: I1a86cee588e3c7beecf5ba1665b1464c5e54939f Signed-off-by: David Steele --- automated-tests/src/dali/utc-Dali-Actor.cpp | 486 ++++++++++++++++++++++++++++ dali/devel-api/actors/actor-devel.cpp | 11 + dali/devel-api/actors/actor-devel.h | 24 ++ dali/internal/event/actors/actor-coords.cpp | 170 +++++++++- dali/internal/event/actors/actor-coords.h | 26 +- 5 files changed, 714 insertions(+), 3 deletions(-) diff --git a/automated-tests/src/dali/utc-Dali-Actor.cpp b/automated-tests/src/dali/utc-Dali-Actor.cpp index 33fcdd9..33d9536 100644 --- a/automated-tests/src/dali/utc-Dali-Actor.cpp +++ b/automated-tests/src/dali/utc-Dali-Actor.cpp @@ -10630,3 +10630,489 @@ int UtcDaliActorAllowOnlyOwnTouchPropertyN(void) } END_TEST; } + +int UtcDaliActorCalculateWorldTransform01(void) +{ + TestApplication application; + + tet_infoline("Test that actor position inheritance produces right transform matrix"); + + Actor rootActor = Actor::New(); + Actor branchActor = Actor::New(); + Actor leafActor = Actor::New(); + + rootActor[Actor::Property::POSITION] = Vector3(0.0f, 0.0f, 0.0f); + branchActor[Actor::Property::POSITION] = Vector3(100.0f, 100.0f, 0.0f); + leafActor[Actor::Property::POSITION] = Vector3(100.0f, 50.0f, 30.0f); + + rootActor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS); + branchActor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS); + leafActor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS); + + // Set anchor point to the same value as parent origin + rootActor[Actor::Property::PARENT_ORIGIN] = ParentOrigin::TOP_LEFT; + branchActor[Actor::Property::PARENT_ORIGIN] = ParentOrigin::TOP_LEFT; + leafActor[Actor::Property::PARENT_ORIGIN] = ParentOrigin::TOP_LEFT; + + rootActor[Actor::Property::ANCHOR_POINT] = AnchorPoint::TOP_LEFT; + branchActor[Actor::Property::ANCHOR_POINT] = AnchorPoint::TOP_LEFT; + leafActor[Actor::Property::ANCHOR_POINT] = AnchorPoint::TOP_LEFT; + + application.GetScene().Add(rootActor); + rootActor.Add(branchActor); + branchActor.Add(leafActor); + + application.SendNotification(); + application.Render(0); + application.SendNotification(); + application.Render(0); + + Matrix m = DevelActor::GetWorldTransform(leafActor); + + Matrix actualMatrix = leafActor.GetCurrentProperty(Actor::Property::WORLD_MATRIX); + DALI_TEST_EQUALS(m, actualMatrix, 0.001f, TEST_LOCATION); + + Vector3 worldPos; + Vector3 worldScale; + Quaternion worldRotation; + m.GetTransformComponents(worldPos, worldRotation, worldScale); + DALI_TEST_EQUALS(worldPos, Vector3(200.0f, 150.0f, 30.0f), 0.0001f, TEST_LOCATION); + + END_TEST; +} + +int UtcDaliActorCalculateWorldTransform02(void) +{ + TestApplication application; + + tet_infoline("Test that actor position produces right transform matrix"); + + Actor rootActor = Actor::New(); + Actor branchActor = Actor::New(); + Actor leafActor = Actor::New(); + + rootActor[Actor::Property::POSITION] = Vector3(0.0f, 0.0f, 0.0f); + branchActor[Actor::Property::POSITION] = Vector3(100.0f, 100.0f, 0.0f); + leafActor[Actor::Property::POSITION] = Vector3(100.0f, 50.0f, 30.0f); + + rootActor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS); + branchActor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS); + leafActor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS); + + // Set anchor point to the same value as parent origin + rootActor[Actor::Property::ANCHOR_POINT] = AnchorPoint::TOP_LEFT; + branchActor[Actor::Property::ANCHOR_POINT] = AnchorPoint::TOP_LEFT; + leafActor[Actor::Property::ANCHOR_POINT] = AnchorPoint::TOP_LEFT; + + application.GetScene().Add(rootActor); + rootActor.Add(branchActor); + branchActor.Add(leafActor); + + leafActor[Actor::Property::INHERIT_POSITION] = false; + leafActor[Actor::Property::INHERIT_ORIENTATION] = false; + leafActor[Actor::Property::INHERIT_SCALE] = false; + + application.SendNotification(); + application.Render(0); + application.SendNotification(); + application.Render(0); + + Matrix m = DevelActor::GetWorldTransform(leafActor); + + Matrix actualMatrix = leafActor.GetCurrentProperty(Actor::Property::WORLD_MATRIX); + DALI_TEST_EQUALS(m, actualMatrix, 0.001f, TEST_LOCATION); + + END_TEST; +} + +int UtcDaliActorCalculateWorldTransform03(void) +{ + TestApplication application; + + tet_infoline("Test that actor position produces right transform matrix"); + + Actor rootActor = Actor::New(); + Actor branchActor = Actor::New(); + Actor leafActor = Actor::New(); + + rootActor[Actor::Property::POSITION] = Vector3(0.0f, 0.0f, 0.0f); + branchActor[Actor::Property::POSITION] = Vector3(100.0f, 100.0f, 0.0f); + leafActor[Actor::Property::POSITION] = Vector3(100.0f, 50.0f, 30.0f); + + rootActor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS); + branchActor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS); + leafActor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS); + + // Set anchor point to the same value as parent origin + rootActor[Actor::Property::ANCHOR_POINT] = AnchorPoint::TOP_LEFT; + branchActor[Actor::Property::ANCHOR_POINT] = AnchorPoint::TOP_LEFT; + leafActor[Actor::Property::ANCHOR_POINT] = AnchorPoint::TOP_LEFT; + + application.GetScene().Add(rootActor); + rootActor.Add(branchActor); + branchActor.Add(leafActor); + + leafActor[Actor::Property::INHERIT_POSITION] = true; + leafActor[Actor::Property::INHERIT_ORIENTATION] = false; + leafActor[Actor::Property::INHERIT_SCALE] = false; + + application.SendNotification(); + application.Render(0); + application.SendNotification(); + application.Render(0); + + Matrix m = DevelActor::GetWorldTransform(leafActor); + + Matrix actualMatrix = leafActor.GetCurrentProperty(Actor::Property::WORLD_MATRIX); + DALI_TEST_EQUALS(m, actualMatrix, 0.001f, TEST_LOCATION); + + END_TEST; +} + +int UtcDaliActorCalculateWorldTransform04(void) +{ + TestApplication application; + + tet_infoline("Test that actor inheritance scale/orientation produces right transform matrix"); + + Actor rootActor = Actor::New(); + Actor branchActor = Actor::New(); + Actor leafActor = Actor::New(); + + rootActor[Actor::Property::POSITION] = Vector3(100.0f, 0.0f, 0.0f); + rootActor[Actor::Property::SCALE] = Vector3(2.0f, 2.0f, 2.0f); + rootActor[Actor::Property::ORIENTATION] = AngleAxis(Degree(90.0f), Vector3::ZAXIS); + + rootActor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS); + branchActor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS); + leafActor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS); + + // Set anchor point to the same value as parent origin + rootActor[Actor::Property::ANCHOR_POINT] = AnchorPoint::CENTER; + rootActor[Actor::Property::PARENT_ORIGIN] = ParentOrigin::CENTER; + branchActor[Actor::Property::ANCHOR_POINT] = AnchorPoint::TOP_LEFT; + leafActor[Actor::Property::ANCHOR_POINT] = AnchorPoint::TOP_LEFT; + + branchActor[Actor::Property::POSITION] = Vector3(100.0f, 100.0f, 0.0f); + leafActor[Actor::Property::POSITION] = Vector3(100.0f, 50.0f, 30.0f); + + application.GetScene().Add(rootActor); + rootActor.Add(branchActor); + branchActor.Add(leafActor); + + application.SendNotification(); + application.Render(0); + application.SendNotification(); + application.Render(0); + + Matrix m = DevelActor::GetWorldTransform(leafActor); + + Matrix actualMatrix = leafActor.GetCurrentProperty(Actor::Property::WORLD_MATRIX); + DALI_TEST_EQUALS(m, actualMatrix, 0.001f, TEST_LOCATION); + + END_TEST; +} + +int UtcDaliActorCalculateWorldTransform05(void) +{ + TestApplication application; + + tet_infoline("Test that actor inheritance of scale produces right transform matrix"); + + Actor rootActor = Actor::New(); + Actor branchActor = Actor::New(); + Actor leafActor = Actor::New(); + + rootActor[Actor::Property::POSITION] = Vector3(100.0f, 0.0f, 0.0f); + rootActor[Actor::Property::SCALE] = Vector3(2.0f, 2.0f, 2.0f); + rootActor[Actor::Property::ORIENTATION] = AngleAxis(Degree(90.0f), Vector3::ZAXIS); + + rootActor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS); + branchActor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS); + leafActor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS); + + // Set anchor point to the same value as parent origin + rootActor[Actor::Property::ANCHOR_POINT] = AnchorPoint::CENTER; + rootActor[Actor::Property::PARENT_ORIGIN] = ParentOrigin::CENTER; + branchActor[Actor::Property::ANCHOR_POINT] = AnchorPoint::TOP_LEFT; + leafActor[Actor::Property::ANCHOR_POINT] = AnchorPoint::TOP_LEFT; + + branchActor[Actor::Property::POSITION] = Vector3(100.0f, 100.0f, 0.0f); + leafActor[Actor::Property::POSITION] = Vector3(100.0f, 50.0f, 30.0f); + + leafActor[Actor::Property::INHERIT_POSITION] = false; + leafActor[Actor::Property::INHERIT_ORIENTATION] = false; + + application.GetScene().Add(rootActor); + rootActor.Add(branchActor); + branchActor.Add(leafActor); + + application.SendNotification(); + application.Render(0); + application.SendNotification(); + application.Render(0); + + Matrix m = DevelActor::GetWorldTransform(leafActor); + + Matrix actualMatrix = leafActor.GetCurrentProperty(Actor::Property::WORLD_MATRIX); + DALI_TEST_EQUALS(m, actualMatrix, 0.001f, TEST_LOCATION); + + END_TEST; +} + +int UtcDaliActorCalculateWorldTransform06(void) +{ + TestApplication application; + + tet_infoline("Test that actor inheritance of scale produces right transform matrix"); + + Actor rootActor = Actor::New(); + Actor branchActor = Actor::New(); + Actor leafActor = Actor::New(); + + rootActor[Actor::Property::POSITION] = Vector3(100.0f, 0.0f, 0.0f); + rootActor[Actor::Property::SCALE] = Vector3(2.0f, 2.0f, 2.0f); + rootActor[Actor::Property::ORIENTATION] = AngleAxis(Degree(90.0f), Vector3::ZAXIS); + + rootActor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS); + branchActor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS); + leafActor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS); + + // Set anchor point to the same value as parent origin + rootActor[Actor::Property::ANCHOR_POINT] = AnchorPoint::CENTER; + rootActor[Actor::Property::PARENT_ORIGIN] = ParentOrigin::CENTER; + branchActor[Actor::Property::ANCHOR_POINT] = AnchorPoint::TOP_LEFT; + leafActor[Actor::Property::ANCHOR_POINT] = AnchorPoint::TOP_LEFT; + + branchActor[Actor::Property::POSITION] = Vector3(100.0f, 30.0f, -50.0f); + branchActor[Actor::Property::ORIENTATION] = AngleAxis(Degree(45.0f), Vector3::XAXIS); + leafActor[Actor::Property::POSITION] = Vector3(100.0f, 50.0f, 30.0f); + + leafActor[Actor::Property::INHERIT_POSITION] = false; + leafActor[Actor::Property::INHERIT_SCALE] = false; + + application.GetScene().Add(rootActor); + rootActor.Add(branchActor); + branchActor.Add(leafActor); + + application.SendNotification(); + application.Render(0); + application.SendNotification(); + application.Render(0); + + Matrix m = DevelActor::GetWorldTransform(leafActor); + + Matrix actualMatrix = leafActor.GetCurrentProperty(Actor::Property::WORLD_MATRIX); + DALI_TEST_EQUALS(m, actualMatrix, 0.001f, TEST_LOCATION); + + END_TEST; +} + +int UtcDaliActorCalculateWorldTransform07(void) +{ + TestApplication application; + + tet_infoline("Test that actor inheritance of scale produces right transform matrix"); + + Actor rootActor = Actor::New(); + Actor branchActor = Actor::New(); + Actor leafActor = Actor::New(); + + rootActor[Actor::Property::POSITION] = Vector3(100.0f, 0.0f, 0.0f); + rootActor[Actor::Property::SCALE] = Vector3(2.0f, 2.0f, 2.0f); + rootActor[Actor::Property::ORIENTATION] = AngleAxis(Degree(90.0f), Vector3::ZAXIS); + + rootActor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS); + branchActor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS); + leafActor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS); + + // Set anchor point to the same value as parent origin + rootActor[Actor::Property::ANCHOR_POINT] = AnchorPoint::CENTER; + rootActor[Actor::Property::PARENT_ORIGIN] = ParentOrigin::CENTER; + branchActor[Actor::Property::ANCHOR_POINT] = AnchorPoint::TOP_LEFT; + + // This should be ignored. + leafActor[Actor::Property::PARENT_ORIGIN] = ParentOrigin::CENTER; + leafActor[Actor::Property::ANCHOR_POINT] = AnchorPoint::CENTER; + + branchActor[Actor::Property::POSITION] = Vector3(100.0f, 30.0f, -50.0f); + branchActor[Actor::Property::ORIENTATION] = AngleAxis(Degree(45.0f), Vector3::XAXIS); + leafActor[Actor::Property::POSITION] = Vector3(100.0f, 50.0f, 30.0f); + + leafActor[Actor::Property::INHERIT_POSITION] = false; + leafActor[Actor::Property::INHERIT_SCALE] = false; + leafActor[Actor::Property::POSITION_USES_ANCHOR_POINT] = false; + + application.GetScene().Add(rootActor); + rootActor.Add(branchActor); + branchActor.Add(leafActor); + + application.SendNotification(); + application.Render(0); + application.SendNotification(); + application.Render(0); + + Matrix m = DevelActor::GetWorldTransform(leafActor); + + Matrix actualMatrix = leafActor.GetCurrentProperty(Actor::Property::WORLD_MATRIX); + DALI_TEST_EQUALS(m, actualMatrix, 0.001f, TEST_LOCATION); + + END_TEST; +} + +int UtcDaliActorCalculateWorldColor01(void) +{ + TestApplication application; + + tet_infoline("Test that actor inheritance of color produces right final color"); + + Actor rootActor = Actor::New(); + Actor branchActor = Actor::New(); + Actor leafActor = Actor::New(); + + rootActor[Actor::Property::POSITION] = Vector3(100.0f, 0.0f, 0.0f); + rootActor[Actor::Property::SCALE] = Vector3(2.0f, 2.0f, 2.0f); + rootActor[Actor::Property::ORIENTATION] = AngleAxis(Degree(90.0f), Vector3::ZAXIS); + + rootActor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS); + branchActor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS); + leafActor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS); + + rootActor[Actor::Property::COLOR] = Color::WHITE; + branchActor[Actor::Property::COLOR] = Vector4(1.0f, 1.0f, 0.5f, 0.8f); + leafActor[Actor::Property::COLOR] = Vector4(0.1f, 0.5f, 0.5f, 0.8f); + + // Default is to inherit: + leafActor[Actor::Property::COLOR_MODE] = ColorMode::USE_OWN_MULTIPLY_PARENT_ALPHA; + + application.GetScene().Add(rootActor); + rootActor.Add(branchActor); + branchActor.Add(leafActor); + + application.SendNotification(); + application.Render(0); + + Vector4 color = DevelActor::GetWorldColor(leafActor); + + Vector4 actualColor = leafActor.GetCurrentProperty(Actor::Property::WORLD_COLOR); + DALI_TEST_EQUALS(color, actualColor, 0.001f, TEST_LOCATION); + + END_TEST; +} + +int UtcDaliActorCalculateWorldColor02(void) +{ + TestApplication application; + + tet_infoline("Test that actor uses own color"); + + Actor rootActor = Actor::New(); + Actor branchActor = Actor::New(); + Actor leafActor = Actor::New(); + + rootActor[Actor::Property::POSITION] = Vector3(100.0f, 0.0f, 0.0f); + rootActor[Actor::Property::SCALE] = Vector3(2.0f, 2.0f, 2.0f); + rootActor[Actor::Property::ORIENTATION] = AngleAxis(Degree(90.0f), Vector3::ZAXIS); + + rootActor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS); + branchActor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS); + leafActor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS); + + rootActor[Actor::Property::COLOR] = Color::WHITE; + branchActor[Actor::Property::COLOR] = Vector4(1.0f, 1.0f, 0.5f, 0.8f); + leafActor[Actor::Property::COLOR] = Vector4(0.1f, 0.5f, 0.5f, 0.8f); + + leafActor[Actor::Property::COLOR_MODE] = ColorMode::USE_OWN_COLOR; + + application.GetScene().Add(rootActor); + rootActor.Add(branchActor); + branchActor.Add(leafActor); + + application.SendNotification(); + application.Render(0); + + Vector4 color = DevelActor::GetWorldColor(leafActor); + + Vector4 actualColor = leafActor.GetCurrentProperty(Actor::Property::WORLD_COLOR); + DALI_TEST_EQUALS(color, actualColor, 0.001f, TEST_LOCATION); + DALI_TEST_EQUALS(color, Vector4(0.1f, 0.5f, 0.5f, 0.8f), 0.001f, TEST_LOCATION); + END_TEST; +} + +int UtcDaliActorCalculateWorldColor03(void) +{ + TestApplication application; + + tet_infoline("Test that actor uses parent color"); + + Actor rootActor = Actor::New(); + Actor branchActor = Actor::New(); + Actor leafActor = Actor::New(); + + rootActor[Actor::Property::POSITION] = Vector3(100.0f, 0.0f, 0.0f); + rootActor[Actor::Property::SCALE] = Vector3(2.0f, 2.0f, 2.0f); + rootActor[Actor::Property::ORIENTATION] = AngleAxis(Degree(90.0f), Vector3::ZAXIS); + + rootActor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS); + branchActor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS); + leafActor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS); + + rootActor[Actor::Property::COLOR] = Color::WHITE * 0.9f; + branchActor[Actor::Property::COLOR] = Vector4(1.0f, 1.0f, 0.5f, 0.8f); + leafActor[Actor::Property::COLOR] = Vector4(0.1f, 0.5f, 0.5f, 0.8f); + + leafActor[Actor::Property::COLOR_MODE] = ColorMode::USE_PARENT_COLOR; + + application.GetScene().Add(rootActor); + rootActor.Add(branchActor); + branchActor.Add(leafActor); + + application.SendNotification(); + application.Render(0); + + Vector4 color = DevelActor::GetWorldColor(leafActor); + + Vector4 actualColor = leafActor.GetCurrentProperty(Actor::Property::WORLD_COLOR); + DALI_TEST_EQUALS(color, actualColor, 0.001f, TEST_LOCATION); + DALI_TEST_EQUALS(color, Vector4(1.0f, 1.0f, 0.5f, 0.72f), 0.001f, TEST_LOCATION); + END_TEST; +} + +int UtcDaliActorCalculateWorldColor04(void) +{ + TestApplication application; + + tet_infoline("Test that actor blends with parent color"); + + Actor rootActor = Actor::New(); + Actor branchActor = Actor::New(); + Actor leafActor = Actor::New(); + + rootActor[Actor::Property::POSITION] = Vector3(100.0f, 0.0f, 0.0f); + rootActor[Actor::Property::SCALE] = Vector3(2.0f, 2.0f, 2.0f); + rootActor[Actor::Property::ORIENTATION] = AngleAxis(Degree(90.0f), Vector3::ZAXIS); + + rootActor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS); + branchActor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS); + leafActor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS); + + rootActor[Actor::Property::COLOR] = Color::WHITE * 0.9f; + branchActor[Actor::Property::COLOR] = Vector4(1.0f, 1.0f, 0.5f, 0.8f); + leafActor[Actor::Property::COLOR] = Vector4(0.1f, 0.5f, 0.5f, 0.8f); + + leafActor[Actor::Property::COLOR_MODE] = ColorMode::USE_OWN_MULTIPLY_PARENT_COLOR; + + application.GetScene().Add(rootActor); + rootActor.Add(branchActor); + branchActor.Add(leafActor); + + application.SendNotification(); + application.Render(0); + + Vector4 color = DevelActor::GetWorldColor(leafActor); + + Vector4 actualColor = leafActor.GetCurrentProperty(Actor::Property::WORLD_COLOR); + DALI_TEST_EQUALS(color, actualColor, 0.001f, TEST_LOCATION); + + END_TEST; +} diff --git a/dali/devel-api/actors/actor-devel.cpp b/dali/devel-api/actors/actor-devel.cpp index 37fa3fb..fc54e89 100644 --- a/dali/devel-api/actors/actor-devel.cpp +++ b/dali/devel-api/actors/actor-devel.cpp @@ -17,6 +17,7 @@ // INTERNAL INCLUDES #include +#include #include namespace Dali @@ -68,6 +69,16 @@ Actor::TouchEventSignalType& HitTestResultSignal(Actor actor) return GetImplementation(actor).HitTestResultSignal(); } +Matrix GetWorldTransform(Actor actor) +{ + return CalculateActorWorldTransform(GetImplementation(actor)); +} + +Vector4 GetWorldColor(Actor actor) +{ + return CalculateActorWorldColor(GetImplementation(actor)); +} + } // namespace DevelActor } // namespace Dali diff --git a/dali/devel-api/actors/actor-devel.h b/dali/devel-api/actors/actor-devel.h index 80b52dc..7b985a0 100644 --- a/dali/devel-api/actors/actor-devel.h +++ b/dali/devel-api/actors/actor-devel.h @@ -389,6 +389,30 @@ DALI_CORE_API void SwitchParent(Actor actor, Actor newParent); */ DALI_CORE_API Actor::TouchEventSignalType& HitTestResultSignal(Actor actor); +/** + * Get the world transform of the actor. + * + * This calculates the world transform from scratch using only event + * side properties - it does not rely on the update thread to have + * already calculated the transform. + * + * @param[in] actor The actor for which to calculate the world transform + * @return The world transform matrix + */ +DALI_CORE_API Matrix GetWorldTransform(Actor actor); + +/** + * Get the world color of the actor. + * + * This calcualtes the world color of the actor from scratch using + * only event side properties. It does not rely on the update thread + * to have already calculated the color. + * + * @param[in] actor The actor to calculate the world color for + * @return the world color + */ +DALI_CORE_API Vector4 GetWorldColor(Actor actor); + } // namespace DevelActor } // namespace Dali diff --git a/dali/internal/event/actors/actor-coords.cpp b/dali/internal/event/actors/actor-coords.cpp index 9d1010e..ce8b7a6 100644 --- a/dali/internal/event/actors/actor-coords.cpp +++ b/dali/internal/event/actors/actor-coords.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -136,7 +136,7 @@ const Vector2 CalculateActorScreenPosition(const Actor& actor, BufferIndex buffe worldPosition -= cameraPosition; Vector3 actorSize = node.GetSize(bufferIndex) * node.GetWorldScale(bufferIndex); - auto sceneSize = scene.GetCurrentSurfaceRect(); // Use the update object's size + auto sceneSize = scene.GetCurrentSurfaceRect(); // Use the update object's size Vector2 halfSceneSize(sceneSize.width * 0.5f, sceneSize.height * 0.5f); // World position origin is center of scene Vector3 halfActorSize(actorSize * 0.5f); Vector3 anchorPointOffSet = halfActorSize - actorSize * actor.GetAnchorPointForPosition(); @@ -155,4 +155,170 @@ Rect<> CalculateActorScreenExtents(const Actor& actor, const Vector2& screenPosi return {position.x, position.y, size.x, size.y}; } +/** + * @brief Computes and center position by using transform properties. + * @param[in] anchorPoint anchorPoint of an actor. + * @param[in] positionUsesAnchorPoint positionUsesAnchorPoint of an actor. + * @param[in] size size of an actor. + * @param[in] scale scale of an actor. + * @param[in] orientation orientation of an actor. + */ +Vector3 CalculateCenterPosition( + const Vector3& anchorPoint, + const bool positionUsesAnchorPoint, + const Vector3& size, + const Vector3& scale, + const Quaternion& orientation) +{ + Vector3 centerPosition; + const Vector3 half(0.5f, 0.5f, 0.5f); + const Vector3 topLeft(0.0f, 0.0f, 0.5f); + // Calculate the center-point by applying the scale and rotation on the anchor point. + centerPosition = (half - anchorPoint) * size * scale; + centerPosition *= orientation; + + // If the position is ignoring the anchor-point, then remove the anchor-point shift from the position. + if(!positionUsesAnchorPoint) + { + centerPosition -= (topLeft - anchorPoint) * size; + } + return centerPosition; +} + +Matrix CalculateActorWorldTransform(const Actor& actor) +{ + enum InheritanceMode + { + DONT_INHERIT_TRANSFORM = 0, + INHERIT_POSITION = 1, + INHERIT_SCALE = 2, + INHERIT_ORIENTATION = 4, + INHERIT_ALL = INHERIT_POSITION | INHERIT_SCALE | INHERIT_ORIENTATION, + }; + + std::vector descentList; + std::vector inheritanceModeList; + Dali::Actor currentActor(const_cast(&actor)); + int inheritance = 0; + do + { + inheritance = (static_cast(currentActor.GetProperty(Dali::Actor::Property::INHERIT_ORIENTATION)) << 2) + + (static_cast(currentActor.GetProperty(Dali::Actor::Property::INHERIT_SCALE)) << 1) + + static_cast(currentActor.GetProperty(Dali::Actor::Property::INHERIT_POSITION)); + inheritanceModeList.push_back(static_cast(inheritance)); + descentList.push_back(currentActor); + currentActor = currentActor.GetParent(); + } while(inheritance != DONT_INHERIT_TRANSFORM && currentActor); + + Matrix worldMatrix; + Vector3 localPosition; + // descentList is leaf first, so traverse from root (end) to leaf (beginning) + for(unsigned int i(descentList.size() - 1); i < descentList.size(); --i) + { + Vector3 anchorPoint = descentList[i].GetProperty(Dali::Actor::Property::ANCHOR_POINT); + Vector3 parentOrigin = descentList[i].GetProperty(Dali::Actor::Property::PARENT_ORIGIN); + bool positionUsesAnchorPoint = descentList[i].GetProperty(Dali::Actor::Property::POSITION_USES_ANCHOR_POINT); + Vector3 size = descentList[i].GetProperty(Dali::Actor::Property::SIZE); + Vector3 actorPosition = descentList[i].GetProperty(Dali::Actor::Property::POSITION); + Quaternion localOrientation = descentList[i].GetProperty(Dali::Actor::Property::ORIENTATION); + Vector3 localScale = descentList[i].GetProperty(Dali::Actor::Property::SCALE); + + Vector3 centerPosition = CalculateCenterPosition(anchorPoint, positionUsesAnchorPoint, size, localScale, localOrientation); + if(inheritanceModeList[i] != DONT_INHERIT_TRANSFORM && descentList[i].GetParent()) + { + Matrix localMatrix; + Vector3 parentSize = descentList[i + 1].GetProperty(Dali::Actor::Property::SIZE); + if(inheritanceModeList[i] == INHERIT_ALL) + { + localPosition = actorPosition + centerPosition + (parentOrigin - Vector3(0.5f, 0.5f, 0.5f)) * parentSize; + localMatrix.SetTransformComponents(localScale, localOrientation, localPosition); + + //Update the world matrix + Matrix tempMatrix; + Matrix::Multiply(tempMatrix, localMatrix, worldMatrix); + worldMatrix = tempMatrix; + } + else + { + Vector3 parentPosition, parentScale; + Quaternion parentOrientation; + worldMatrix.GetTransformComponents(parentPosition, parentOrientation, parentScale); + + if((inheritanceModeList[i] & INHERIT_SCALE) == 0) + { + //Don't inherit scale + localScale /= parentScale; + } + + if((inheritanceModeList[i] & INHERIT_ORIENTATION) == 0) + { + //Don't inherit orientation + parentOrientation.Invert(); + localOrientation = parentOrientation * localOrientation; + } + + if((inheritanceModeList[i] & INHERIT_POSITION) == 0) + { + localMatrix.SetTransformComponents(localScale, localOrientation, Vector3::ZERO); + Matrix tempMatrix; + Matrix::Multiply(tempMatrix, localMatrix, worldMatrix); + worldMatrix = tempMatrix; + worldMatrix.SetTranslation(actorPosition + centerPosition); + } + else + { + localPosition = actorPosition + centerPosition + (parentOrigin - Vector3(0.5f, 0.5f, 0.5f)) * parentSize; + localMatrix.SetTransformComponents(localScale, localOrientation, localPosition); + Matrix tempMatrix; + Matrix::Multiply(tempMatrix, localMatrix, worldMatrix); + worldMatrix = tempMatrix; + } + } + } + else + { + localPosition = actorPosition + centerPosition; + worldMatrix.SetTransformComponents(localScale, localOrientation, localPosition); + } + } + + return worldMatrix; +} + +Vector4 CalculateActorWorldColor(const Actor& actor) +{ + std::vector descentList; + std::vector inheritanceModeList; + Dali::Actor currentActor(const_cast(&actor)); + Dali::ColorMode inheritance = Dali::ColorMode::USE_OWN_MULTIPLY_PARENT_ALPHA; + do + { + inheritance = currentActor.GetProperty(Dali::Actor::Property::COLOR_MODE); + inheritanceModeList.push_back(inheritance); + descentList.push_back(currentActor); + currentActor = currentActor.GetParent(); + } while(inheritance != Dali::ColorMode::USE_OWN_COLOR && currentActor); + + Vector4 worldColor; + for(unsigned int i(descentList.size() - 1); i < descentList.size(); --i) + { + if(inheritanceModeList[i] == USE_OWN_COLOR || i == descentList.size() - 1) + { + worldColor = descentList[i].GetProperty(Dali::Actor::Property::COLOR); + } + else if(inheritanceModeList[i] == USE_OWN_MULTIPLY_PARENT_ALPHA) + { + Vector4 ownColor = descentList[i].GetProperty(Dali::Actor::Property::COLOR); + worldColor = Vector4(ownColor.r, ownColor.g, ownColor.b, ownColor.a * worldColor.a); + } + else if(inheritanceModeList[i] == USE_OWN_MULTIPLY_PARENT_COLOR) + { + Vector4 ownColor = descentList[i].GetProperty(Dali::Actor::Property::COLOR); + worldColor *= ownColor; + } + } + + return worldColor; +} + } // namespace Dali::Internal diff --git a/dali/internal/event/actors/actor-coords.h b/dali/internal/event/actors/actor-coords.h index d6ebd36..1c7d092 100644 --- a/dali/internal/event/actors/actor-coords.h +++ b/dali/internal/event/actors/actor-coords.h @@ -2,7 +2,7 @@ #define DALI_INTERNAL_EVENT_ACTORS_ACTOR_COORDS_H /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -112,6 +112,30 @@ const Vector2 CalculateActorScreenPosition(const Actor& actor, BufferIndex buffe */ Rect<> CalculateActorScreenExtents(const Actor& actor, const Vector2& screenPosition, BufferIndex bufferIndex); +/** + * Get the world transform of the actor. + * + * This calculates the world transform from scratch using only event + * side properties - it does not rely on the update thread to have + * already calculated the transform. + * + * @param[in] actor The actor to calculate the world matrix for + * @return The world transform matrix + */ +Matrix CalculateActorWorldTransform(const Actor& actor); + +/** + * Get the world color of the actor. + * + * This calcualtes the world color of the actor from scratch using + * only event side properties. It does not rely on the update thread + * to have already calculated the color. + * + * @param[in] actor The actor to calculate the world color for + * @return the world color + */ +Vector4 CalculateActorWorldColor(const Actor& actor); + } // namespace Dali::Internal #endif // DALI_INTERNAL_EVENT_ACTORS_ACTOR_COORDS_H -- 2.7.4