Coherent UI  2.5.3
A modern user interface library for games
 All Classes Namespaces Functions Variables Enumerations Enumerator Pages
Sample - Input in 3D

This tutorial demonstrates forwarding keyboard and mouse input to a Coherent::UI:View when the view is placed on an object in the game world.

You can move in the world using W/A/S/D, look around using the mouse and lock/unlock the mouse by pressing Alt. Input forwarding works only when the mouse is unlocked.

Note
Supplied code, unrelated to Coherent UI integration, is not representative for a well-designed, high-performance solution. It's written for simplicity and its purpose is to demonstrate integration in an existing game framework.

Building the sample

The sample solution is already configured and you only have to compile and run it.

It uses a sample mini game framework that provides very basic functionality.

The output will be in the Coherent/Samples/UI/bin directory.

Prerequisites

  1. This sample assumes you're already familiar with input forwarding to a Coherent::UI:View and extends Sample - Input in 2D mostly by game-specific code for getting a 3D point in the world below the cursor and converting it to texture space.

Key points

  1. Getting the object below the cursor and the location of the hitpoint.
  2. Transforming that hitpoint into pixel coordinates.

Sample walkthrough

There are a few changes, compared to Sample - Input in 2D.

Here we start using the Camera and GameObject classes. The Application class now has its own header and implementation file (Application.cpp), which includes game code that is unrelated to Coherent UI integration. This unrelated code includes creation of a cube objecta and an appropriate shader, turning on the Z-Buffer and raycasting for intersection checking. Event processing and methods relevant to the integration are still in the sample's main file.

Moving on, the ViewEventListener::OnViewCreated method is changed a bit:

virtual void OnViewCreated(Coherent::UI::View* view)
{
m_View = view;
m_TextureFromHost = m_Renderer->CreateTexture(VIEW_WIDTH, VIEW_HEIGHT, true, m_UseSharedMemory, true, IRenderer::TFMT_ARGB8);
m_View->SetFocus();
}

This new code is almost the same as the PlatformViewListener base implementation, except that here the texture created is no longer the same size as the window, plus the full mip chain of the texture is created. The mip chain is helpful since this time we're drawing a texture onto a 3D object and it reduces minification and magnification texture artifacts.

The final important change is in the mouse input events processing. When we want to pass the mouse coordinates to a view, mapped on a 3D object, we can't just forward the mouse position, because Coherent UI cannot infer the position on the 3D object - we have to convert it in the game.

In this sample, we do this conversion the most straight-forward way possible. Every frame, we check whether the mouse is over the single game object in the world using a raycast (see Application::IsCursorOnObject) and fill an IntersectionInfo structure with the hit results. The hit results, among other things, contain the texture coordinates of the hitpoint, that is a point in the [0,1]x[0,1] range. That point tells us exactly what is the position of the mouse over the view. Application::ShouldForwardEventToView now checks this structure and returns true only if there is a valid hit. When forwarding the mouse input event, the conversion to texture space using the intersection info is simple:

Coherent::UI::MouseEventData eventCopy = event;
// Adjust coords
eventCopy.X = int(m_IntersectionInfo.U * VIEW_WIDTH);
eventCopy.Y = int(m_IntersectionInfo.V * VIEW_HEIGHT);
m_ViewListener->GetView()->MouseEvent(eventCopy);

We have to multiply the texture coordinates by the view's dimensions, because Coherent UI expects screen coordinates (i.e. a specific pixel).

If you're interested in the intersection code, check Application::IsCursonOnObject for converting the mouse screen position to a world space ray and GameObject::Intersects for the actual ray-object intersection and calculation of texture coordinates of the hit point.