Commit a241b6d8 authored by Robert Menzel's avatar Robert Menzel
Browse files

added HMDCamera as special case of GenericCameras

parent 56c5650b
/***********************************************************************
* Copyright 2011-2013 Computer Graphics Group RWTH Aachen University. *
* All rights reserved. *
* Distributed under the terms of the MIT License (see LICENSE.TXT). *
**********************************************************************/
#pragma once
#include <ACGL/ACGL.hh>
#include <ACGL/Math/Math.hh>
namespace ACGL{
......@@ -9,7 +15,8 @@ namespace Scene{
* @brief Common interface for cameras
*
* This interface only contains getter on purpose.
* All logic that wants to modify a camera should know the actual structure of the camera and therefore use the specific subclass.
* All logic that wants to modify a camera should know the actual structure of the camera and therefore use the
* specific subclass.
*/
class CameraBase
{
......
......@@ -42,7 +42,7 @@
* Other camera models rotate first and translate later (e.g. bundler)! The rotation
* is the same, the translation differs.
*
* TODO: support stereo!
* TODO: support more stereo modes!
*/
namespace ACGL{
......@@ -183,7 +183,7 @@ class GenericCamera : public CameraBase
float getFarClippingPlane() const { return mFarClippingPlane; }
/// Gets size of the viewport
glm::uvec2 getViewportSize() const { return mViewportSize; }
virtual glm::uvec2 getViewportSize() const { return mViewportSize; }
/// Gets width of the viewport
unsigned int getViewportWidth() const { return mViewportSize.x; }
/// Gets height of the viewport
......@@ -244,11 +244,11 @@ class GenericCamera : public CameraBase
//
/// Gets the currently active view matrix (depends on stereo mode and current eye)
glm::mat4 getViewMatrix() const;
virtual glm::mat4 getViewMatrix() const;
/// Gets the currently active view matrix (depends on stereo mode and current eye)
glm::mat4 getInverseViewMatrix() const;
/// Gets the currently active projection matrix (depends on stereo mode and current eye)
glm::mat4 getProjectionMatrix() const;
virtual glm::mat4 getProjectionMatrix() const;
///////////////////////////////////////////////////////////////////////////////////////////
......@@ -307,7 +307,7 @@ class GenericCamera : public CameraBase
* @param _position New position of the camera.
*/
void setPosition( const glm::vec3 &_position ) { mPosition = _position; }
glm::vec3 getPosition() const { return mPosition; }
virtual glm::vec3 getPosition() const { return mPosition; }
/// Moves the camera by a given vector (in eyespace)
void move( const glm::vec3 &_vector );
......
/***********************************************************************
* Copyright 2011-2013 Computer Graphics Group RWTH Aachen University. *
* All rights reserved. *
* Distributed under the terms of the MIT License (see LICENSE.TXT). *
**********************************************************************/
#pragma once
/**
* This camera class extends the GenericCamera to better support a
* HeadMountedDisplay.
*
* The usual GenericCamera API controls the position and orientation
* of the *neck* of the camera while the added API add a head rotation
* and an offset of the neck to the eyes.
* These additional values should be set by the HMD hardware.
*
* The projection matrix can also handle an offset applied from the *left*
* to the projection matrix from the GenericCamera. This is needed for
* some HMDs.
*
*/
#include <ACGL/ACGL.hh>
#include <ACGL/Scene/GenericCamera.hh>
namespace ACGL{
namespace Scene{
class HMDCamera : public GenericCamera
{
public:
HMDCamera();
virtual ~HMDCamera() {}
//! View plus the neck transformation
virtual glm::mat4 getViewMatrix() const;
//! projection of the current eye translated by the projection center offset
virtual glm::mat4 getProjectionMatrix() const;
//! projection offset for the left eye, the right eye will mult the X component with -1
void setProjectionCenterOffset( const glm::vec2 &_projectionCenterOffset );
/*
* o = eye
* x = neck == point of rotation
*
* |---| <- mNeckToEyeHorizontalDistance
*
* /----\
* |o | ---
* | | | <- mNeckToEyeVerticalDistance
* \__ | |
* |x| ---
*/
void setNeckToEyeVerticalDistance( float _f );
void setNeckToEyeHorizontalDistance( float _f );
void setHMDRotation( const glm::mat3 &_rotation );
private:
//! stored as a translation vector
glm::vec2 mProjectionCenterOffset;
//! height of the eyes above the neck, just height difference in meters
float mNeckToEyeVerticalDistance;
//! distance eyes to neck without the height in meters
float mNeckToEyeHorizontalDistance;
//! rotation of the HMD
glm::mat4 mHMDRotation;
};
ACGL_SMARTPOINTER_TYPEDEFS(HMDCamera)
}
}
/***********************************************************************
* Copyright 2011-2013 Computer Graphics Group RWTH Aachen University. *
* All rights reserved. *
* Distributed under the terms of the MIT License (see LICENSE.TXT). *
**********************************************************************/
#include <ACGL/Scene/CameraBase.hh>
namespace ACGL{
......
/***********************************************************************
* Copyright 2011-2013 Computer Graphics Group RWTH Aachen University. *
* All rights reserved. *
* Distributed under the terms of the MIT License (see LICENSE.TXT). *
**********************************************************************/
#include <ACGL/Scene/FixedCamera.hh>
......
/***********************************************************************
* Copyright 2011-2013 Computer Graphics Group RWTH Aachen University. *
* All rights reserved. *
* Distributed under the terms of the MIT License (see LICENSE.TXT). *
**********************************************************************/
#include <ACGL/Scene/HMDCamera.hh>
namespace ACGL{
namespace Scene{
HMDCamera::HMDCamera()
{
setStereoMode( GenericCamera::PARALLEL_SHIFT );
mNeckToEyeVerticalDistance = 0.0f;
mNeckToEyeHorizontalDistance = 0.0f;
mHMDRotation = glm::mat4(1.0f);
}
void HMDCamera::setProjectionCenterOffset( const glm::vec2 &_projectionCenterOffset )
{
mProjectionCenterOffset = _projectionCenterOffset;
}
void HMDCamera::setNeckToEyeVerticalDistance( float _f )
{
mNeckToEyeVerticalDistance = _f;
}
void HMDCamera::setNeckToEyeHorizontalDistance( float _f )
{
mNeckToEyeHorizontalDistance = _f;
}
void HMDCamera::setHMDRotation( const glm::mat3 &_rotation )
{
mHMDRotation = glm::mat4( _rotation );
}
glm::mat4 HMDCamera::getViewMatrix() const
{
glm::mat4 viewMatrix = GenericCamera::getViewMatrix();
glm::vec3 up = -mNeckToEyeVerticalDistance * glm::normalize( getUpDirection() );
glm::vec3 forward = -mNeckToEyeHorizontalDistance * glm::normalize( getForwardDirection() );
glm::mat4 neck = glm::translate( up ) * glm::translate( forward );
return neck * mHMDRotation * viewMatrix;
}
glm::mat4 HMDCamera::getProjectionMatrix() const
{
glm::mat4 projectionOffset;
if (getEye() == GenericCamera::EYE_RIGHT) {
projectionOffset = glm::translate( -mProjectionCenterOffset.x, mProjectionCenterOffset.y, 0.0f );
} else {
projectionOffset = glm::translate( mProjectionCenterOffset.x, mProjectionCenterOffset.y, 0.0f );
}
return projectionOffset * GenericCamera::getProjectionMatrix(); // yes, from the left side!
}
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment