1c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This file is part of Eigen, a lightweight C++ template library 2c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// for linear algebra. 3c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// 4c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> 5c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// 6c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This Source Code Form is subject to the terms of the Mozilla 7c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Public License v. 2.0. If a copy of the MPL was not distributed 8c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 9c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 10c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#include "camera.h" 11c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 12c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#include "gpuhelper.h" 13c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#include <GL/glu.h> 14c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 15c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#include "Eigen/LU" 16c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathusing namespace Eigen; 17c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 18c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan KamathCamera::Camera() 19c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath : mViewIsUptodate(false), mProjIsUptodate(false) 20c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 21c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mViewMatrix.setIdentity(); 22c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 23c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mFovY = M_PI/3.; 24c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mNearDist = 1.; 25c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mFarDist = 50000.; 26c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 27c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mVpX = 0; 28c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mVpY = 0; 29c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 30c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath setPosition(Vector3f::Constant(100.)); 31c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath setTarget(Vector3f::Zero()); 32c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 33c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 34c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan KamathCamera& Camera::operator=(const Camera& other) 35c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 36c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mViewIsUptodate = false; 37c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mProjIsUptodate = false; 38c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 39c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mVpX = other.mVpX; 40c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mVpY = other.mVpY; 41c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mVpWidth = other.mVpWidth; 42c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mVpHeight = other.mVpHeight; 43c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 44c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mTarget = other.mTarget; 45c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mFovY = other.mFovY; 46c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mNearDist = other.mNearDist; 47c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mFarDist = other.mFarDist; 48c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 49c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mViewMatrix = other.mViewMatrix; 50c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mProjectionMatrix = other.mProjectionMatrix; 51c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 52c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return *this; 53c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 54c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 55c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan KamathCamera::Camera(const Camera& other) 56c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 57c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath *this = other; 58c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 59c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 60c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan KamathCamera::~Camera() 61c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 62c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 63c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 64c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 65c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathvoid Camera::setViewport(uint offsetx, uint offsety, uint width, uint height) 66c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 67c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mVpX = offsetx; 68c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mVpY = offsety; 69c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mVpWidth = width; 70c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mVpHeight = height; 71c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 72c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mProjIsUptodate = false; 73c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 74c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 75c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathvoid Camera::setViewport(uint width, uint height) 76c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 77c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mVpWidth = width; 78c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mVpHeight = height; 79c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 80c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mProjIsUptodate = false; 81c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 82c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 83c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathvoid Camera::setFovY(float value) 84c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 85c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mFovY = value; 86c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mProjIsUptodate = false; 87c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 88c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 89c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan KamathVector3f Camera::direction(void) const 90c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 91c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return - (orientation() * Vector3f::UnitZ()); 92c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 93c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan KamathVector3f Camera::up(void) const 94c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 95c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return orientation() * Vector3f::UnitY(); 96c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 97c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan KamathVector3f Camera::right(void) const 98c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 99c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return orientation() * Vector3f::UnitX(); 100c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 101c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 102c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathvoid Camera::setDirection(const Vector3f& newDirection) 103c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 104c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // TODO implement it computing the rotation between newDirection and current dir ? 105c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Vector3f up = this->up(); 106c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 107c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Matrix3f camAxes; 108c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 109c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath camAxes.col(2) = (-newDirection).normalized(); 110c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath camAxes.col(0) = up.cross( camAxes.col(2) ).normalized(); 111c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath camAxes.col(1) = camAxes.col(2).cross( camAxes.col(0) ).normalized(); 112c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath setOrientation(Quaternionf(camAxes)); 113c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 114c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mViewIsUptodate = false; 115c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 116c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 117c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathvoid Camera::setTarget(const Vector3f& target) 118c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 119c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mTarget = target; 120c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if (!mTarget.isApprox(position())) 121c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 122c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Vector3f newDirection = mTarget - position(); 123c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath setDirection(newDirection.normalized()); 124c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 125c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 126c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 127c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathvoid Camera::setPosition(const Vector3f& p) 128c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 129c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mFrame.position = p; 130c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mViewIsUptodate = false; 131c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 132c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 133c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathvoid Camera::setOrientation(const Quaternionf& q) 134c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 135c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mFrame.orientation = q; 136c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mViewIsUptodate = false; 137c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 138c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 139c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathvoid Camera::setFrame(const Frame& f) 140c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 141c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mFrame = f; 142c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mViewIsUptodate = false; 143c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 144c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 145c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathvoid Camera::rotateAroundTarget(const Quaternionf& q) 146c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 147c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Matrix4f mrot, mt, mtm; 148c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 149c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // update the transform matrix 150c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath updateViewMatrix(); 151c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Vector3f t = mViewMatrix * mTarget; 152c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 153c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mViewMatrix = Translation3f(t) 154c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * q 155c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * Translation3f(-t) 156c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * mViewMatrix; 157c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 158c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Quaternionf qa(mViewMatrix.linear()); 159c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath qa = qa.conjugate(); 160c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath setOrientation(qa); 161c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath setPosition(- (qa * mViewMatrix.translation()) ); 162c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 163c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mViewIsUptodate = true; 164c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 165c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 166c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathvoid Camera::localRotate(const Quaternionf& q) 167c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 168c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath float dist = (position() - mTarget).norm(); 169c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath setOrientation(orientation() * q); 170c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mTarget = position() + dist * direction(); 171c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mViewIsUptodate = false; 172c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 173c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 174c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathvoid Camera::zoom(float d) 175c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 176c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath float dist = (position() - mTarget).norm(); 177c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if(dist > d) 178c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 179c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath setPosition(position() + direction() * d); 180c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mViewIsUptodate = false; 181c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 182c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 183c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 184c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathvoid Camera::localTranslate(const Vector3f& t) 185c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 186c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Vector3f trans = orientation() * t; 187c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath setPosition( position() + trans ); 188c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath setTarget( mTarget + trans ); 189c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 190c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mViewIsUptodate = false; 191c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 192c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 193c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathvoid Camera::updateViewMatrix(void) const 194c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 195c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if(!mViewIsUptodate) 196c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 197c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Quaternionf q = orientation().conjugate(); 198c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mViewMatrix.linear() = q.toRotationMatrix(); 199c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mViewMatrix.translation() = - (mViewMatrix.linear() * position()); 200c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 201c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mViewIsUptodate = true; 202c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 203c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 204c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 205c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathconst Affine3f& Camera::viewMatrix(void) const 206c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 207c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath updateViewMatrix(); 208c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return mViewMatrix; 209c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 210c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 211c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathvoid Camera::updateProjectionMatrix(void) const 212c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 213c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if(!mProjIsUptodate) 214c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 215c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mProjectionMatrix.setIdentity(); 216c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath float aspect = float(mVpWidth)/float(mVpHeight); 217c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath float theta = mFovY*0.5; 218c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath float range = mFarDist - mNearDist; 219c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath float invtan = 1./tan(theta); 220c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 221c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mProjectionMatrix(0,0) = invtan / aspect; 222c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mProjectionMatrix(1,1) = invtan; 223c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mProjectionMatrix(2,2) = -(mNearDist + mFarDist) / range; 224c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mProjectionMatrix(3,2) = -1; 225c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mProjectionMatrix(2,3) = -2 * mNearDist * mFarDist / range; 226c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mProjectionMatrix(3,3) = 0; 227c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 228c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mProjIsUptodate = true; 229c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 230c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 231c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 232c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathconst Matrix4f& Camera::projectionMatrix(void) const 233c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 234c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath updateProjectionMatrix(); 235c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return mProjectionMatrix; 236c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 237c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 238c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathvoid Camera::activateGL(void) 239c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 240c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath glViewport(vpX(), vpY(), vpWidth(), vpHeight()); 241c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath gpu.loadMatrix(projectionMatrix(),GL_PROJECTION); 242c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath gpu.loadMatrix(viewMatrix().matrix(),GL_MODELVIEW); 243c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 244c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 245c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 246c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan KamathVector3f Camera::unProject(const Vector2f& uv, float depth) const 247c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 248c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Matrix4f inv = mViewMatrix.inverse().matrix(); 249c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return unProject(uv, depth, inv); 250c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 251c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 252c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan KamathVector3f Camera::unProject(const Vector2f& uv, float depth, const Matrix4f& invModelview) const 253c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 254c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath updateViewMatrix(); 255c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath updateProjectionMatrix(); 256c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 257c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Vector3f a(2.*uv.x()/float(mVpWidth)-1., 2.*uv.y()/float(mVpHeight)-1., 1.); 258c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath a.x() *= depth/mProjectionMatrix(0,0); 259c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath a.y() *= depth/mProjectionMatrix(1,1); 260c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath a.z() = -depth; 261c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // FIXME /\/| 262c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Vector4f b = invModelview * Vector4f(a.x(), a.y(), a.z(), 1.); 263c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return Vector3f(b.x(), b.y(), b.z()); 264c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 265