END_TEST;
}
+
+int UtcDaliRenderTaskWorldToViewport(void)
+{
+ TestApplication application( static_cast<size_t>(400), static_cast<size_t>(400) ); // square surface
+
+ RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
+
+ Actor actor = Actor::New();
+ actor.SetSize(100.0f, 100.0f);
+ actor.SetPosition( Vector3(0.0, 0.0, 0.0) );
+
+ actor.SetParentOrigin( Vector3(0.5, 0.5, 0.5) );
+ actor.SetAnchorPoint( Vector3(0.5, 0.5, 0.5) );
+
+ Stage::GetCurrent().Add(actor);
+
+ application.Render();
+ application.SendNotification();
+ application.Render();
+ application.SendNotification();
+
+ RenderTask task = taskList.GetTask( 0u );
+
+ CameraActor camera = task.GetCameraActor();
+
+ Vector2 screenSize = task.GetCurrentViewportSize();
+
+ float screenX = 0.0;
+ float screenY = 0.0;
+
+ bool ok = task.WorldToViewport(actor.GetCurrentWorldPosition(), screenX, screenY);
+ DALI_TEST_CHECK(ok == true);
+
+ DALI_TEST_EQUALS(screenX, screenSize.x/2, Math::MACHINE_EPSILON_10000, TEST_LOCATION);
+ DALI_TEST_EQUALS(screenY, screenSize.y/2, Math::MACHINE_EPSILON_10000, TEST_LOCATION);
+
+ Actor actor2 = Actor::New();
+ float actor2Size = 100.f;
+ actor2.SetSize( actor2Size, actor2Size );
+ actor2.SetPosition( Vector3(0.0, 0.0, 0.0) );
+ actor2.SetParentOrigin( Vector3(0.5, 0.5, 0.0) );
+ actor2.SetAnchorPoint( Vector3(0.5, 0.5, 0.0) );
+ Stage::GetCurrent().Add( actor2 );
+ actor2.Add(actor);
+ actor.SetParentOrigin( Vector3(0,0,0) );
+
+ application.Render();
+ application.SendNotification();
+ application.Render();
+ application.SendNotification();
+
+ ok = task.WorldToViewport(actor.GetCurrentWorldPosition(), screenX, screenY);
+ DALI_TEST_CHECK(ok == true);
+
+ DALI_TEST_EQUALS(screenX, screenSize.x/2 - actor2Size/2, Math::MACHINE_EPSILON_10000, TEST_LOCATION);
+ DALI_TEST_EQUALS(screenY, screenSize.y/2 - actor2Size/2, Math::MACHINE_EPSILON_10000, TEST_LOCATION);
+
+ END_TEST;
+}
+
+
+int UtcDaliRenderTaskViewportToLocal(void)
+{
+ TestApplication application;
+ Actor actor = Actor::New();
+ actor.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+ actor.SetSize(100.0f, 100.0f);
+ actor.SetPosition(10.0f, 10.0f);
+ Stage::GetCurrent().Add(actor);
+
+ RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
+ RenderTask task = taskList.GetTask( 0u );
+
+ // flush the queue and render once
+ application.SendNotification();
+ application.Render();
+
+ float localX;
+ float localY;
+
+ float rtLocalX;
+ float rtLocalY;
+
+ float screenX = 50.0f;
+ float screenY = 50.0f;
+
+ DALI_TEST_CHECK( actor.ScreenToLocal(localX, localY, screenX, screenY) );
+
+ DALI_TEST_CHECK( task.ViewportToLocal(actor, screenX, screenY, rtLocalX, rtLocalY ) );
+
+ DALI_TEST_EQUALS(localX, rtLocalX, 0.01f, TEST_LOCATION);
+ DALI_TEST_EQUALS(localY, rtLocalY, 0.01f, TEST_LOCATION);
+
+ END_TEST;
+
+}
return false;
}
-bool Actor::ScreenToLocal( RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const
+bool Actor::ScreenToLocal( const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const
{
bool retval = false;
// only valid when on-stage
* @copydoc Dali::Actor::GetMaximumSize
*/
float GetMaximumSize( Dimension::Type dimension ) const;
-
+
/**
* @copydoc Dali::Actor::AddRenderer()
*/
* @param[in] screenY The screen Y-coordinate.
* @return True if the conversion succeeded.
*/
- bool ScreenToLocal( RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const;
+ bool ScreenToLocal( const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const;
/**
* Converts from the actor's coordinate system to screen coordinates.
#include <dali/public-api/math/rect.h>
#include <dali/public-api/math/matrix.h>
#include <dali/public-api/math/vector4.h>
+#include <dali/public-api/math/vector2.h>
+#include <dali/public-api/math/viewport.h>
#include <dali/integration-api/debug.h>
+#include <dali/public-api/math/math-utils.h>
namespace Dali
{
return true;
}
+bool ProjectFull( const Vector4& position,
+ const Matrix& modelView,
+ const Matrix& projection,
+ float viewportX,
+ float viewportY,
+ float viewportWidth,
+ float viewportHeight,
+ Vector4& windowPos )
+{
+ bool ok = false;
+
+ Matrix Mvp( false ); // Don't initialize.
+ Matrix::Multiply( Mvp, modelView, projection );
+
+ Vector4 p = Mvp * position;
+
+ Vector2 depthRange(0,1);
+
+ if( !EqualsZero( p.w ) )
+ {
+ float div = 1.0 / p.w;
+
+ windowPos = Vector4( (1 + p.x * div) * viewportWidth / 2 + viewportX,
+ (1 - p.y * div) * viewportHeight / 2 + viewportY,
+ (p.z * div) * (depthRange.y - depthRange.x) + depthRange.x,
+ div);
+ ok = true;
+ }
+
+ return ok;
+}
+
+
} // namespace Internal
} // namespace Dali
{
struct Vector4;
+struct Vector2;
+
class Matrix;
namespace Internal
float viewportHeight,
Dali::Vector4& objectPos);
+bool ProjectFull( const Vector4& position,
+ const Matrix& modelView,
+ const Matrix& projection,
+ float viewportX,
+ float viewportY,
+ float viewportWidth,
+ float viewportHeight,
+ Vector4& windowPos );
+
} // namespace Internal
} // namespace Dali
}
SetDefaultSurfaceRectMessage( mUpdateManager, Rect<int>( 0, 0, width, height ) );
+
+ // if single render task to screen then set its viewport parameters
+ if( 1 == mRenderTaskList->GetTaskCount() )
+ {
+ Dali::RenderTask mDefaultRenderTask = mRenderTaskList->GetTask(0);
+
+ if(!mDefaultRenderTask.GetTargetFrameBuffer())
+ {
+ mDefaultRenderTask.SetViewport( Viewport(0, 0, width, height) );
+ }
+ }
+
}
Vector2 Stage::GetSize() const
#include <dali/internal/event/actors/camera-actor-impl.h>
#include <dali/internal/event/common/property-helper.h>
#include <dali/internal/event/common/stage-impl.h>
+#include <dali/internal/event/common/projection.h>
#include <dali/internal/event/images/frame-buffer-image-impl.h>
#include <dali/internal/update/nodes/node.h>
#include <dali/internal/event/render-tasks/render-task-list-impl.h>
return mIsSystemLevel;
}
+bool RenderTask::WorldToViewport(const Vector3 &position, float& viewportX, float& viewportY) const
+{
+ CameraActor* cam = GetCameraActor();
+
+ Vector4 pos(position);
+ pos.w = 1.0;
+
+ Vector4 viewportPosition;
+
+ Viewport viewport;
+ GetViewport( viewport );
+
+ bool ok = ProjectFull(pos,
+ cam->GetViewMatrix(),
+ cam->GetProjectionMatrix(),
+ viewport.x,
+ viewport.y,
+ viewport.width,
+ viewport.height,
+ viewportPosition);
+ if(ok)
+ {
+ viewportX = viewportPosition.x;
+ viewportY = viewportPosition.y;
+ }
+
+ return ok;
+}
+
+bool RenderTask::ViewportToLocal(Actor* actor, float viewportX, float viewportY, float &localX, float &localY) const
+{
+ return actor->ScreenToLocal( *this, localX, localY, viewportX, viewportY );
+}
+
SceneGraph::RenderTask* RenderTask::CreateSceneObject()
{
// This should only be called once, with no existing scene-object
*/
bool IsSystemLevel() const;
+ /**
+ * @copydoc Dali::RenderTask::WorldToViewport()
+ */
+ bool WorldToViewport(const Vector3 &position, float& viewportX, float& viewportY) const;
+
+ /**
+ * @copydoc Dali::RenderTask::ViewportToLocal()
+ */
+ bool ViewportToLocal(Actor* actor, float viewportX, float viewportY, float &localX, float &localY) const;
+
public: // Used by RenderTaskList, which owns the SceneGraph::RenderTasks
/**
return GetImplementation(*this).GetInputEnabled();
}
+bool RenderTask::WorldToViewport(const Vector3 &position, float& viewportX, float& viewportY) const
+{
+ return GetImplementation(*this).WorldToViewport(position, viewportX, viewportY);
+}
+
+bool RenderTask::ViewportToLocal(Actor actor, float viewportX, float viewportY, float &localX, float &localY) const
+{
+ if( actor )
+ {
+ Internal::Actor* actorImpl( &GetImplementation( actor ) );
+ return GetImplementation(*this).ViewportToLocal( actorImpl, viewportX, viewportY, localX, localY );
+ }
+ else
+ {
+ return false;
+ }
+}
+
+
RenderTask::RenderTask( Internal::RenderTask* internal )
: Handle(internal)
{
*/
unsigned int GetRefreshRate() const;
+ /*
+ * @brief Get viewport coordinates for given world position
+ *
+ * @since DALi 1.1.13
+ *
+ * @param[in] position The world position.
+ * @param[out] viewportX The viewport x position.
+ * @param[out] viewportY The viewport y position.
+ * @return true if the position has a screen coordinate
+ */
+ bool WorldToViewport(const Vector3 &position, float& viewportX, float& viewportY) const;
+
+ /*
+ * @brief Get actor local coordinates for given viewport coordinates
+ *
+ * @since DALi 1.1.13
+ *
+ * @param[in] actor The actor describing local coordinate system.
+ * @param[in] viewportX The viewport x position.
+ * @param[in] viewportY The viewport y position.
+ * @param[out] localX The local x position.
+ * @param[out] localY The local y position.
+ * @return true if the screen position has a local coordinate
+ */
+ bool ViewportToLocal(Actor actor, float viewportX, float viewportY, float &localX, float &localY) const;
+
public: // Signals
/**