src/ui/scenic/lib/input/tests/coordinate_transform_test.cc
// In this test we set up a view, apply a ClipSpaceTransform to it, and then send pointer events to
// confirm that the coordinates received by the session are correctly transformed.
//
// Below are ASCII diagrams showing the scene setup.
// Each character is a point on a surface, the top left point representing (0,0)
// and the bottom right (5,5).
// Note that the notated X,Y coordinate system is the screen coordinate system. The view's
// coordinate system has its origin at corner '1'.
//
// Scene pre-transformation (1,2,3,4 denote the corners of the view):
// Note that the view's coordinate system is the same as the screen coordinate system.
//   X ->
// Y 1 O O O O 2 - - - -
// | O O O O O O - - - -
// v O O O O O O - - - -
//   O O O O O O - - - -
//   O O O O O O - - - -
//   4 O O O O 3 - - - -
//   - - - - - - - - - -
//   - - - - - - - - - -
//   - - - - - - - - - -
//   - - - - - - - - - -
//
// Scene after scale, before offset:
// 1   O   O   O   O   2
//
// O   O   O   O   O   O
//
// O   O   O - O - O - O - - -
//         - - - - - - - - - -
// O   O   O - O - O - O - - -
//         - - - - - - - - - -
// O   O   O - O - O - O - - -
//         - - - - - - - - - -
// 4   O   O - O   O - 3 - - -
//         - - - - - - - - - -
//         - - - - - - - - - -
//         - - - - - - - - - -
//         - - - - - - - - - -
//         - - - - - - - - - -
//
// Scene post-scale, post-offset:
// The X and Y dimensions of the view are now effectively scaled up to 10x10
// (compared to the 9x9 of the screen), with origin at screen space origin.
//   X ->
// Y 1A- O - D - O - O - 2
// | - - - - - - - - - -
// V O - O - O - O - O - O
//   - - - - - - - - - -
//   U - O - M - O - O - O
//   - - - - - - - - - -
//   O - O - O - O - O - O
//   - - - - - - - - - -
//   O - O - O - O - O - O
//   - - - - - - - - - -
//   4   O   O   O   O   3
//
// A - Add event
// D - Down event
// M - Move event
// U - Up event
In this test we set up a view, apply a ClipSpaceTransform to it, and then send pointer events to
confirm that the coordinates received by the session are correctly transformed.

Below are ASCII diagrams showing the scene setup.
Each character is a point on a surface, the top left point representing (0,0)
and the bottom right (5,5).
Note that the notated X,Y coordinate system is the screen coordinate system. The view's
coordinate system has its origin at corner '1'.

Scene pre-transformation (1,2,3,4 denote the corners of the view):
Note that the view's coordinate system is the same as the screen coordinate system.







Scene post-scale, post-offset:
The X and Y dimensions of the view are now effectively scaled up to 10x10
(compared to the 9x9 of the screen), with origin at screen space origin.


In this test we set up a view apply a ClipSpaceTransform to it and then send pointer events to confirm that the coordinates received by the session are correctly transformed . Below are ASCII diagrams showing the scene setup . Each character is a point on a surface the top left point representing ( 0 0 ) and the bottom right ( 5 5 ) . Note that the notated X Y coordinate system is the screen coordinate system . The view ' s coordinate system has its origin at corner ' 1 ' . Scene pre - transformation ( 1 2 3 4 denote the corners of the view ) : Note that the view ' s coordinate system is the same as the screen coordinate system . Scene post - scale post - offset : The X and Y dimensions of the view are now effectively scaled up to 10x10 ( compared to the 9x9 of the screen ) with origin at screen space origin .
TEST_F(CoordinateTransformTest, ClipSpaceTransformed) {
  auto [view_token, view_holder_token] = scenic::ViewTokenPair::New();
  auto [root_session, root_resources] = CreateScene();
  {
    scenic::Session* const session = root_session.session();
    scenic::Scene* const scene = &root_resources.scene;
    scenic::ViewHolder view_holder(session, std::move(view_holder_token), "view_holder");
    view_holder.SetViewProperties(k5x5x1);
    scene->AddChild(view_holder);
    root_resources.camera.SetClipSpaceTransform( 1,  1,  2);
    RequestToPresent(session);
  }
  SessionWrapper client = CreateClient("view", std::move(view_token));
  {
    scenic::Session* session = root_session.session();
    PointerCommandGenerator pointer(root_resources.compositor.id(),  1,
                                     1, PointerEventType::TOUCH);
    session->Enqueue(pointer.Add(0.5, 0.5));
    session->Enqueue(pointer.Down(4.5, 0.5));
    session->Enqueue(pointer.Move(4.5, 4.5));
    session->Enqueue(pointer.Up(0.5, 4.5));
  }
  RunLoopUntilIdle();
  {  
    const std::vector<InputEvent>& events = client.events();
    EXPECT_EQ(events.size(), 5u);
    EXPECT_TRUE(events[0].is_pointer());
    EXPECT_TRUE(PointerMatches(events[0].pointer(), 1u, PointerEventPhase::ADD, 0.25, 0.25));
    EXPECT_TRUE(events[2].is_pointer());
    EXPECT_TRUE(PointerMatches(events[2].pointer(), 1u, PointerEventPhase::DOWN, 2.25, 0.25));
    EXPECT_TRUE(events[3].is_pointer());
    EXPECT_TRUE(PointerMatches(events[3].pointer(), 1u, PointerEventPhase::MOVE, 2.25, 2.25));
    EXPECT_TRUE(events[4].is_pointer());
    EXPECT_TRUE(PointerMatches(events[4].pointer(), 1u, PointerEventPhase::UP, 0.25, 2.25));
  }
}
TEST_F ( CoordinateTransformTest , ClipSpaceTransformed ) { auto [ view_token , view_holder_token ] = scenic :: ViewTokenPair :: New ( ) ; auto [ root_session , root_resources ] = CreateScene ( ) ; { scenic :: Session * const session = root_session . session ( ) ; scenic :: Scene * const scene = & root_resources . scene ; scenic :: ViewHolder view_holder ( session , std :: move ( view_holder_token ) , " " ) ; view_holder . SetViewProperties ( k5x5x1 ) ; scene -> AddChild ( view_holder ) ; root_resources . camera . SetClipSpaceTransform ( 1 , 1 , 2 ) ; RequestToPresent ( session ) ; } SessionWrapper client = CreateClient ( " " , std :: move ( view_token ) ) ; { scenic :: Session * session = root_session . session ( ) ; PointerCommandGenerator pointer ( root_resources . compositor . id ( ) , 1 , 1 , PointerEventType :: TOUCH ) ; session -> Enqueue ( pointer . Add ( 0.5 , 0.5 ) ) ; session -> Enqueue ( pointer . Down ( 4.5 , 0.5 ) ) ; session -> Enqueue ( pointer . Move ( 4.5 , 4.5 ) ) ; session -> Enqueue ( pointer . Up ( 0.5 , 4.5 ) ) ; } RunLoopUntilIdle ( ) ; { const std :: vector < InputEvent > & events = client . events ( ) ; EXPECT_EQ ( events . size ( ) , 5u ) ; EXPECT_TRUE ( events [ 0 ] . is_pointer ( ) ) ; EXPECT_TRUE ( PointerMatches ( events [ 0 ] . pointer ( ) , 1u , PointerEventPhase :: ADD , 0.25 , 0.25 ) ) ; EXPECT_TRUE ( events [ 2 ] . is_pointer ( ) ) ; EXPECT_TRUE ( PointerMatches ( events [ 2 ] . pointer ( ) , 1u , PointerEventPhase :: DOWN , 2.25 , 0.25 ) ) ; EXPECT_TRUE ( events [ 3 ] . is_pointer ( ) ) ; EXPECT_TRUE ( PointerMatches ( events [ 3 ] . pointer ( ) , 1u , PointerEventPhase :: MOVE , 2.25 , 2.25 ) ) ; EXPECT_TRUE ( events [ 4 ] . is_pointer ( ) ) ; EXPECT_TRUE ( PointerMatches ( events [ 4 ] . pointer ( ) , 1u , PointerEventPhase :: UP , 0.25 , 2.25 ) ) ; } }
In this test we set up a view, apply a ClipSpaceTransform to it, and then send pointer events to
confirm that the coordinates received by the session are correctly transformed.
In this test we set up a view apply a ClipSpaceTransform to it and then send pointer events to confirm that the coordinates received by the session are correctly transformed .
// Set the clip space transform on the camera. // The transform scales everything by 2 around the center of the screen (4.5, 4.5) and then // applies offsets in Vulkan normalized device coordinates to bring the origin back // to where it was originally. (Parameters are in Vulkan Normalized Device Coordinates.) /*x offset*/ /*y offset*/ /*scale*/ // Client vends a View to the global scene. // Scene is now set up, send in the input. One event for where each corner of the view was // pre-transformation. Injected events are in the screen coordinate space. /*device id*/ /*pointer id*/ // Received events should be in the coordinate space of the view. // Expect received coordinates to be half of the injected coordinates, since the view is now // effectively twice as big on screen.