2.9.16
Coherent GT
A modern user interface library for games
Sample - Input in 3D

This tutorial demonstrates forwarding keyboard and mouse input to a Coherent::UIGT: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 GT 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 Input In 3D 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/bin directory.

Prerequisites

  1. This sample assumes you're already familiar with input forwarding to a Coherent::UIGT:View and extends HelloGT 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 hit-point.
  2. Transforming that hit-point into pixel coordinates.

Sample walk-through

There are a few changes, compared to HelloGT.

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 GT integration. This unrelated code includes creation of a cube object and an appropriate shader, turning on the Z-Buffer and ray-casting for intersection checking. Event processing and methods relevant to the integration are still in the sample's main file.

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 GT 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 ray-cast (see Application::IsCursorOnObject) and fill an IntersectionInfo structure with the hit results. The hit results, among other things, contain the texture coordinates of the hit point, 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: you only have to adjust the UV coordinates reported by the IntersectionInfo structure by these two steps - first, you have to inverse the v-coordinate of m_IntersectionInfo as shown below. This is needed because the UV coordinates of the IntersectionInfo structure and those of the view use respectively left- and right-handed coordinate systems. Then, the second step is to multiply the texture coordinates by the view's dimensions, because Coherent GT expects screen coordinates (i.e. a specific pixel).

// Adjust coords and inverse the v coordinate
float u = m_IntersectionInfo.U;
float v = 1 - m_IntersectionInfo.V;
eventCopy.X = int(m_IntersectionInfo.U * VIEW_WIDTH);
eventCopy.Y = int(m_IntersectionInfo.V * VIEW_HEIGHT);
m_Views[m_CurrentView]->MouseEvent(eventCopy);

If you're interested in the intersection code, check Application::IsCursorOnObject 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.