131 lines
7.0 KiB
C++
131 lines
7.0 KiB
C++
/**************************************************************************************/
|
|
/* */
|
|
/* Visualization Library */
|
|
/* http://visualizationlibrary.org */
|
|
/* */
|
|
/* Copyright (c) 2005-2020, Michele Bosi */
|
|
/* All rights reserved. */
|
|
/* */
|
|
/* Redistribution and use in source and binary forms, with or without modification, */
|
|
/* are permitted provided that the following conditions are met: */
|
|
/* */
|
|
/* - Redistributions of source code must retain the above copyright notice, this */
|
|
/* list of conditions and the following disclaimer. */
|
|
/* */
|
|
/* - Redistributions in binary form must reproduce the above copyright notice, this */
|
|
/* list of conditions and the following disclaimer in the documentation and/or */
|
|
/* other materials provided with the distribution. */
|
|
/* */
|
|
/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND */
|
|
/* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */
|
|
/* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */
|
|
/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR */
|
|
/* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */
|
|
/* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */
|
|
/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */
|
|
/* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
|
|
/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
|
|
/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
|
|
/* */
|
|
/**************************************************************************************/
|
|
|
|
#ifndef StereoCamera_INCLUDE_ONCE
|
|
#define StereoCamera_INCLUDE_ONCE
|
|
|
|
#include <vlGraphics/Camera.hpp>
|
|
|
|
namespace vl
|
|
{
|
|
/** Utility class to setup a pair of left/right cameras for stereo rendering.
|
|
\par Usage
|
|
- Assign the mono camera representing the point of view of your observer using the setMonoCamera() method.
|
|
- Assign the left and right cameras representing the left and right eyes with the setLeftCamera()/setRightCamera() methods.
|
|
- Set the desired convergence and eye separation using setConvergence() and setEyeSeparation().
|
|
- Call updateLeftRightCameras() whenever the mono camera or viewport changes.
|
|
|
|
\sa App_Stereo.cpp for a basic example of how to setup stereo rendering using anaglyphs. */
|
|
class StereoCamera: public Object
|
|
{
|
|
VL_INSTRUMENT_CLASS(vl::StereoCamera, Object)
|
|
|
|
public:
|
|
StereoCamera()
|
|
{
|
|
mConvergence = 20;
|
|
mEyeSeparation = 1;
|
|
}
|
|
|
|
/** Distance of the convergence plane from the camera.
|
|
The points laying on the convergence plane look the same from both the left and right camera. */
|
|
void setConvergence( float convergence ) { mConvergence = convergence; }
|
|
/** Distance of the convergence plane from the camera.
|
|
The points laying on the convergence plane look the same from both the left and right camera. */
|
|
float convergence() const { return mConvergence; }
|
|
|
|
/** The distance between the center of the two eyes. */
|
|
void setEyeSeparation( float eye_separation ) { mEyeSeparation = eye_separation; }
|
|
/** The distance between the center of the two eyes. */
|
|
float eyeSeparation() const { return mEyeSeparation; }
|
|
|
|
/** The Camera used to drive the left and right cameras.
|
|
The mono camera viewport will be automatically used by the left and right cameras as well. */
|
|
void setMonoCamera(Camera* camera) { mMonoCamera = camera; }
|
|
/** The Camera used to drive the left and right cameras.
|
|
The mono camera viewport will be automatically used by the left and right cameras as well. */
|
|
Camera* monoCamera() { return mMonoCamera.get(); }
|
|
/** The Camera used to drive the left and right cameras.
|
|
The mono camera viewport will be automatically used by the left and right cameras as well. */
|
|
const Camera* monoCamera() const { return mMonoCamera.get(); }
|
|
|
|
/** The Camera representing the left eye. */
|
|
void setLeftCamera(Camera* camera) { mLeftCamera = camera; }
|
|
/** The Camera representing the left eye. */
|
|
Camera* leftCamera() { return mLeftCamera.get(); }
|
|
/** The Camera representing the left eye. */
|
|
const Camera* leftCamera() const { return mLeftCamera.get(); }
|
|
|
|
/** The Camera representing the right eye. */
|
|
void setRightCamera(Camera* camera) { mRightCamera = camera; }
|
|
/** The Camera representing the right eye. */
|
|
Camera* rigthCamera() { return mRightCamera.get(); }
|
|
/** The Camera representing the right eye. */
|
|
const Camera* rightCamera() const { return mRightCamera.get(); }
|
|
|
|
/** Updates the left and right cameras based on the mono camera view matrix and viewport. */
|
|
void updateLeftRightCameras()
|
|
{
|
|
mLeftCamera->setViewport( mMonoCamera->viewport() );
|
|
mRightCamera->setViewport( mMonoCamera->viewport() );
|
|
|
|
float aspect_ratio = (float)mMonoCamera->viewport()->width()/mMonoCamera->viewport()->height();
|
|
float near_clip = mMonoCamera->nearPlane();
|
|
float far_clip = mMonoCamera->farPlane();
|
|
float radians = mMonoCamera->fov()/2*fDEG_TO_RAD;
|
|
float wd2 = near_clip * tan(radians);
|
|
float ndfl = near_clip / mConvergence;
|
|
float top, bottom, left, right;
|
|
top = wd2;
|
|
bottom = - wd2;
|
|
|
|
left = - aspect_ratio * wd2 - mEyeSeparation/2 * ndfl;
|
|
right = aspect_ratio * wd2 - mEyeSeparation/2 * ndfl;
|
|
mLeftCamera->setProjectionFrustum(left, right, bottom, top, near_clip, far_clip);
|
|
mLeftCamera->setViewMatrix( mat4::getTranslation(-mEyeSeparation/2, 0, 0)*mMonoCamera->viewMatrix() );
|
|
|
|
left = - aspect_ratio * wd2 + mEyeSeparation/2 * ndfl;
|
|
right = aspect_ratio * wd2 + mEyeSeparation/2 * ndfl;
|
|
mRightCamera->setProjectionFrustum(left, right, bottom, top, near_clip, far_clip);
|
|
mRightCamera->setViewMatrix( mat4::getTranslation(+mEyeSeparation/2, 0, 0)*mMonoCamera->viewMatrix() );
|
|
}
|
|
|
|
private:
|
|
ref<Camera> mMonoCamera;
|
|
ref<Camera> mLeftCamera;
|
|
ref<Camera> mRightCamera;
|
|
float mConvergence;
|
|
float mEyeSeparation;
|
|
};
|
|
}
|
|
|
|
#endif
|