MinGfx Toolkit  1.0
A minimal library for writing cross-platform (Windows, OSX, linux) graphics programs.
Public Member Functions | List of all members
mingfx::UniCam Class Reference

Detailed Description

This implements a user interface for controlling the camera with the mouse.

It is a special interface inspired by the "Unicam" technique developed by Zeleznik et al.

The key feature is that this interface makes it possible to control camera pan, dolly, and rotation with only a single mouse button. That is quite useful because it leaves the other mouse buttons free for pointing, sketching, or other interaction techniques.

The only downside of this technique is that it can take some time to learn. In order to enjoy it, you will need to read these brief instructions on how to Pan, Dolly, Rotate, and Spin:

Example usage:

// Create a global or member variable in your MyGraphicsApp class:
UniCam unicam_;
void MyGraphicsApp::OnLeftMouseDown(const Point2 &pos) {
Point2 mouse_xy = PixelsToNormalizedDeviceCoords(pos);
float mouse_z = ReadZValueAtPixel(pos);
unicam_.OnButtonDown(mouse_xy, mouse_z);
}
void MyGraphicsApp::OnLeftMouseDrag(const Point2 &pos, const Vector2 &delta) {
Point2 mouse_xy = PixelsToNormalizedDeviceCoords(pos);
unicam_.OnDrag(mouse_xy);
}
void MyGraphicsApp::OnLeftMouseUp(const Point2 &pos) {
Point2 mouse_xy = PixelsToNormalizedDeviceCoords(pos);
unicam_.OnButtonUp(mouse_xy);
}
void MyGraphicsApp::InitOpenGL() {
projMatrix_ = Matrix4::perspective(30, aspect_ratio(), 1, 20);
unicam_.set_view_matrix(Matrix4::lookAt(Point3(2.5,1,2.5), Point3(0,0,0), Vector3(0,1,0)););
}
void MyGraphicsApp::DrawOpenGL() {
// draw your scene using the view matrix from UniCam
Matrix4 proj_matrix = Matrix4::Perspective(60, aspect_ratio(), 0.001, 10);;
Matrix4 view_matrix = uniCam.view_matrix();
Matrix4 model_matrix = Matrix4::RotateY(to_radians(45.0));
quickShapes.DrawCube(model_matrix, view_matirx, proj_matrix, Color(1,1,1));
// tell unicam to draw itself (i.e., the small sphere that marks the center of
// rotation when in rotation mode)
unicam_.Draw(proj_matrix);
}
static Matrix4 Perspective(float fov_y_in_degrees, float aspect_ratio, float near_plane_dist, float far_plane_dist)
Returns a perspective projection matrix equivalent to the one gluPerspective creates.
UniCam()
Creates a UniCam object with an initial view matrix = identity.
Matrix4 view_matrix()
Access the camera view matrix created by the UniCam interactions via this method and use it to draw t...

Definition at line 105 of file unicam.h.

#include <unicam.h>

Public Member Functions

 UniCam ()
 Creates a UniCam object with an initial view matrix = identity. More...
 
 UniCam (const Matrix4 &initialViewMatrix)
 Creates a UniCam object with the supplied initial view matrix. More...
 
virtual ~UniCam ()
 
void OnButtonDown (const Point2 &normalizedMousePos, float mouseZ)
 Attach this to whatever mouse button you wish, for example, call this from within GraphicsApp::OnRightMouseDown(). If your mousePos is reported in pixels, you will need to convert it to normalized device coordinates before passing it on to this routine. The depth buffer value for the pixel under the mouse is also needed. If you are using GraphicsApp, you can access both of these as follows: More...
 
void OnDrag (const Point2 &normalizedMousePos)
 Attach this to the corresponding mouse move event, for example, call this from within GraphicsApp::OnRightMouseDrag(). If your mousePos is reported in pixels, you will need to convert it to normalized device coordinates before passing it on to this routine. Within GraphicsApp, use: More...
 
void OnButtonUp (const Point2 &normalizedMousePos)
 Attach this to the corresponding button up event, for example, call this from within GraphicsApp::OnRightMouseUp(). If your mousePos is reported in pixels, you will need to convert it to normalized device coordinates before passing it on to this routine. Within GraphicsApp, use: More...
 
void AdvanceAnimation (double dt)
 Attach this to a callback that can be used to control animation. Within GraphicsApp::UpdateSimulation(), use: More...
 
void Draw (const Matrix4 &projectionMatrix)
 Finally, attach this to your draw callback routine. Within GraphicsApp::DrawUsingOpenGL(), use: More...
 
Matrix4 view_matrix ()
 Access the camera view matrix created by the UniCam interactions via this method and use it to draw the geometry in your scence. For example, within GraphicsApp::DrawUsingOpenGL(), you might have: More...
 
Point3 eye ()
 Returns the "eye" point (i.e., focal point) of the camera in world space coordinates. More...
 
Vector3 look ()
 Returns the look direction (i.e., -Z axis of the camera matrix) in world space coordinates. More...
 
void set_view_matrix (Matrix4 viewMatrix)
 This is not required, but you may use this if you wish to set an initial view matrix or reset the view matrix. More...
 
void set_default_depth (float d)
 This sets the depth of the center of rotation for the case when the user's click does not intersect any geometry. It defaults to 4 units, but the right value to use depends very much on the current scene. For example, you could set a very good value by calculating the current centroid of your scene and the finding the depth of this point (the distance along the look vector) relative to the camera. More...
 

Constructor & Destructor Documentation

◆ UniCam() [1/2]

mingfx::UniCam::UniCam ( )

Creates a UniCam object with an initial view matrix = identity.

◆ UniCam() [2/2]

mingfx::UniCam::UniCam ( const Matrix4 initialViewMatrix)

Creates a UniCam object with the supplied initial view matrix.

◆ ~UniCam()

virtual mingfx::UniCam::~UniCam ( )
virtual

Member Function Documentation

◆ AdvanceAnimation()

void mingfx::UniCam::AdvanceAnimation ( double  dt)

Attach this to a callback that can be used to control animation. Within GraphicsApp::UpdateSimulation(), use:

uniCam.AdvanceAnimation(dt);

◆ Draw()

void mingfx::UniCam::Draw ( const Matrix4 projectionMatrix)

Finally, attach this to your draw callback routine. Within GraphicsApp::DrawUsingOpenGL(), use:

uniCam.Draw(projMatrix);

◆ eye()

Point3 mingfx::UniCam::eye ( )

Returns the "eye" point (i.e., focal point) of the camera in world space coordinates.

◆ look()

Vector3 mingfx::UniCam::look ( )

Returns the look direction (i.e., -Z axis of the camera matrix) in world space coordinates.

◆ OnButtonDown()

void mingfx::UniCam::OnButtonDown ( const Point2 normalizedMousePos,
float  mouseZ 
)

Attach this to whatever mouse button you wish, for example, call this from within GraphicsApp::OnRightMouseDown(). If your mousePos is reported in pixels, you will need to convert it to normalized device coordinates before passing it on to this routine. The depth buffer value for the pixel under the mouse is also needed. If you are using GraphicsApp, you can access both of these as follows:

Point2 mouse_xy = PixelsToNormalizedDeviceCoords(mouse_in_pixels);
float mouse_z = ReadZValueAtPixel(mouse_in_pixels);
uniCam.OnButtonDown(mouse_xy, mouse_z);

◆ OnButtonUp()

void mingfx::UniCam::OnButtonUp ( const Point2 normalizedMousePos)

Attach this to the corresponding button up event, for example, call this from within GraphicsApp::OnRightMouseUp(). If your mousePos is reported in pixels, you will need to convert it to normalized device coordinates before passing it on to this routine. Within GraphicsApp, use:

Point2 mouse_xy = PixelsToNormalizedDeviceCoords(mouse_in_pixels);
uniCam.OnButtonUp(mouse_xy);

◆ OnDrag()

void mingfx::UniCam::OnDrag ( const Point2 normalizedMousePos)

Attach this to the corresponding mouse move event, for example, call this from within GraphicsApp::OnRightMouseDrag(). If your mousePos is reported in pixels, you will need to convert it to normalized device coordinates before passing it on to this routine. Within GraphicsApp, use:

Point2 mouse_xy = PixelsToNormalizedDeviceCoords(mouse_in_pixels);
uniCam.OnDrag(mouse_xy);

◆ set_default_depth()

void mingfx::UniCam::set_default_depth ( float  d)

This sets the depth of the center of rotation for the case when the user's click does not intersect any geometry. It defaults to 4 units, but the right value to use depends very much on the current scene. For example, you could set a very good value by calculating the current centroid of your scene and the finding the depth of this point (the distance along the look vector) relative to the camera.

◆ set_view_matrix()

void mingfx::UniCam::set_view_matrix ( Matrix4  viewMatrix)

This is not required, but you may use this if you wish to set an initial view matrix or reset the view matrix.

◆ view_matrix()

Matrix4 mingfx::UniCam::view_matrix ( )

Access the camera view matrix created by the UniCam interactions via this method and use it to draw the geometry in your scence. For example, within GraphicsApp::DrawUsingOpenGL(), you might have:

Matrix4 P = Matrix4::Perspective(30, aspect_ratio(), 1, 20);
Matrix4 V = unicam.view_matrix();
Matrix4 M = Matrix4::RotateY(GfxMath::ToRadians(45.0));
quick_shapes.DrawCube(M, V, P, Color(1,1,1));
static float ToRadians(float degrees)

The documentation for this class was generated from the following file: