SurfaceViewport.cpp

Go to the documentation of this file.
00001 /*************** <auto-copyright.pl BEGIN do not edit this line> **************
00002  *
00003  * VR Juggler is (C) Copyright 1998-2005 by Iowa State University
00004  *
00005  * Original Authors:
00006  *   Allen Bierbaum, Christopher Just,
00007  *   Patrick Hartling, Kevin Meinert,
00008  *   Carolina Cruz-Neira, Albert Baker
00009  *
00010  * This library is free software; you can redistribute it and/or
00011  * modify it under the terms of the GNU Library General Public
00012  * License as published by the Free Software Foundation; either
00013  * version 2 of the License, or (at your option) any later version.
00014  *
00015  * This library is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018  * Library General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU Library General Public
00021  * License along with this library; if not, write to the
00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00023  * Boston, MA 02111-1307, USA.
00024  *
00025  * -----------------------------------------------------------------
00026  * File:          $RCSfile$
00027  * Date modified: $Date: 2006-12-18 18:00:29 -0600 (Mon, 18 Dec 2006) $
00028  * Version:       $Revision: 19704 $
00029  * -----------------------------------------------------------------
00030  *
00031  *************** <auto-copyright.pl END do not edit this line> ***************/
00032 
00033 #include <vrj/vrjConfig.h>
00034 
00035 #include <string>
00036 #include <gmtl/Math.h>
00037 //#include <vrj/Math/Coord.h>
00038 #include <gmtl/Vec.h>
00039 #include <jccl/Config/ConfigElement.h>
00040 #include <vrj/Kernel/User.h>
00041 
00042 #include <gadget/Type/Position/PositionUnitConversion.h>
00043 
00044 #include <gmtl/Matrix.h>
00045 #include <gmtl/MatrixOps.h>
00046 #include <gmtl/Generate.h>
00047 #include <gmtl/Xforms.h>
00048 
00049 #include <vrj/Display/SurfaceProjection.h>
00050 #include <vrj/Display/TrackedSurfaceProjection.h>
00051 #include <vrj/Display/DisplayExceptions.h>
00052 #include <vrj/Display/SurfaceViewport.h>
00053 
00054 namespace vrj
00055 {
00056 
00057 SurfaceViewport::~SurfaceViewport()
00058 {
00059    if ( NULL != mLeftProj )
00060    {
00061       delete mLeftProj;
00062       mLeftProj = NULL;
00063    }
00064 
00065    if ( NULL != mRightProj )
00066    {
00067       delete mRightProj;
00068       mRightProj = NULL;
00069    }
00070 }
00071 
00072 bool SurfaceViewport::config(jccl::ConfigElementPtr element)
00073 {
00074    vprASSERT(element.get() != NULL);
00075    vprASSERT(element->getID() == "surface_viewport");
00076 
00077    // Call base class config
00078    if ( ! Viewport::config(element) )
00079    {
00080       return false;
00081    }
00082 
00083    bool result(true);
00084 
00085    mType = SURFACE;
00086 
00087    // Read in the corners
00088    mLLCorner.set(element->getProperty<float>("lower_left_corner", 0),
00089                  element->getProperty<float>("lower_left_corner", 1),
00090                  element->getProperty<float>("lower_left_corner", 2));
00091    mLRCorner.set(element->getProperty<float>("lower_right_corner", 0),
00092                  element->getProperty<float>("lower_right_corner", 1),
00093                  element->getProperty<float>("lower_right_corner", 2));
00094    mURCorner.set(element->getProperty<float>("upper_right_corner", 0),
00095                  element->getProperty<float>("upper_right_corner", 1),
00096                  element->getProperty<float>("upper_right_corner", 2));
00097    mULCorner.set(element->getProperty<float>("upper_left_corner", 0),
00098                  element->getProperty<float>("upper_left_corner", 1),
00099                  element->getProperty<float>("upper_left_corner", 2));
00100 
00101    // Calculate the rotation and the pts
00102 //   calculateSurfaceRotation();
00103 //   calculateCornersInBaseFrame();
00104 
00105    // Get info about being tracked
00106    mTracked = element->getProperty<bool>("tracked");
00107    if(mTracked)
00108    {
00109       mTrackerProxyName = element->getProperty<std::string>("tracker_proxy");
00110    }
00111 
00112    if ( NULL != mLeftProj )
00113    {
00114       delete mLeftProj;
00115    }
00116 
00117    if ( NULL != mRightProj )
00118    {
00119       delete mRightProj;
00120    }
00121 
00122    // Create Projection objects
00123    // NOTE: The -'s are because we are measuring distance to
00124    //  the left(bottom) which is opposite the normal axis direction
00125    //vjMatrix rot_inv;
00126    //rot_inv.invert(mSurfaceRotation);
00127    SurfaceProjection* left_proj(NULL);
00128    SurfaceProjection* right_proj(NULL);
00129 
00130    if(!mTracked)
00131    {
00132       left_proj = new SurfaceProjection(mLLCorner, mLRCorner, mURCorner,
00133                                         mULCorner);
00134       right_proj = new SurfaceProjection(mLLCorner, mLRCorner, mURCorner,
00135                                          mULCorner);
00136    }
00137    else
00138    {
00139       left_proj = new TrackedSurfaceProjection(mLLCorner, mLRCorner,
00140                                                mURCorner, mULCorner,
00141                                                mTrackerProxyName);
00142       right_proj = new TrackedSurfaceProjection(mLLCorner, mLRCorner,
00143                                                 mURCorner, mULCorner,
00144                                                 mTrackerProxyName);
00145    }
00146 
00147    try
00148    {
00149       left_proj->validateCorners();
00150       right_proj->validateCorners();
00151 
00152       // NOTE: Even if the corner validation above failed, we still proceed with
00153       // setting up mLeftProj and mRightProj. This is because other code is not
00154       // written to handle the case of a viewport having no projections. This
00155       // could definitely be improved.
00156       mLeftProj  = left_proj;
00157       mRightProj = right_proj;
00158 
00159       // Configure the projections
00160       mLeftProj->config(element);
00161       mLeftProj->setEye(Projection::LEFT);
00162       mLeftProj->setViewport(this);
00163 
00164       mRightProj->config(element);
00165       mRightProj->setEye(Projection::RIGHT);
00166       mRightProj->setViewport(this);
00167    }
00168    catch (InvalidSurfaceException& ex)
00169    {
00170       vprDEBUG(vrjDBG_DISP_MGR, vprDBG_CRITICAL_LVL)
00171          << clrOutBOLD(clrRED, "ERROR")
00172          << ": The surface defined by the viewport named\n" << vprDEBUG_FLUSH;
00173       vprDEBUG_NEXT(vrjDBG_DISP_MGR, vprDBG_CRITICAL_LVL)
00174          << "       '" << element->getName() << "' is invalid!\n"
00175          << vprDEBUG_FLUSH;
00176       vprDEBUG_NEXT(vrjDBG_DISP_MGR, vprDBG_CRITICAL_LVL)
00177          << ex.what() << std::endl << vprDEBUG_FLUSH;
00178 
00179       delete left_proj;
00180       delete right_proj;
00181 
00182       result = false;
00183    }
00184 
00185    return result;
00186 }
00187 
00188 void SurfaceViewport::updateProjections(const float positionScale)
00189 {
00190    gmtl::Matrix44f left_eye_pos, right_eye_pos;     // NOTE: Eye coord system is -z forward, x-right, y-up
00191 
00192    // -- Calculate Eye Positions -- //
00193    gmtl::Matrix44f cur_head_pos = mUser->getHeadPosProxy()->getData(positionScale);
00194    /*
00195    Coord  head_coord(cur_head_pos);       // Create a user readable version
00196 
00197    vprDEBUG(vprDBG_ALL, vprDBG_HVERB_LVL)
00198       << "vjDisplay::updateProjections: Getting head position" << std::endl
00199       << vprDEBUG_FLUSH;
00200    vprDEBUG(vprDBG_ALL, vprDBG_HVERB_LVL) << "\tHeadPos:" << head_coord.pos << "\tHeadOr:"
00201                         << head_coord.orient << std::endl << vprDEBUG_FLUSH;
00202                         */
00203 
00204    // Compute location of left and right eyes
00205    //float interocularDist = 2.75f/12.0f;
00206    float interocular_dist = mUser->getInterocularDistance();
00207    interocular_dist *= positionScale;              // Scale eye separation
00208    float eye_offset = interocular_dist/2.0f;      // Distance to move eye
00209 
00210    left_eye_pos = cur_head_pos * gmtl::makeTrans<gmtl::Matrix44f>(gmtl::Vec3f( -eye_offset, 0, 0));
00211    right_eye_pos = cur_head_pos * gmtl::makeTrans<gmtl::Matrix44f>(gmtl::Vec3f(eye_offset, 0, 0));
00212 
00213    mLeftProj->calcViewMatrix(left_eye_pos, positionScale);
00214    mRightProj->calcViewMatrix(right_eye_pos, positionScale);
00215 }
00216 
00217 std::ostream& SurfaceViewport::outStream(std::ostream& out,
00218                                          const unsigned int indentLevel)
00219 {
00220    Viewport::outStream(out, indentLevel);
00221    out << std::endl;
00222 
00223    const std::string indent_text(indentLevel, ' ');
00224 
00225    /*
00226    out << "LL: " << mLLCorner << ", LR: " << mLRCorner
00227        << ", UR: " << mURCorner << ", UL:" << mULCorner << std::endl;
00228    out << "surfRot: \n" << mSurfaceRotation << std::endl;
00229    */
00230    if ( mView == vrj::Viewport::LEFT_EYE || mView == vrj::Viewport::STEREO )
00231    {
00232       out << indent_text << "Left projection:\n";
00233       mLeftProj->outStream(out, indentLevel + 2);
00234       out << std::endl;
00235    }
00236    if ( mView == vrj::Viewport::RIGHT_EYE || mView == vrj::Viewport::STEREO )
00237    {
00238       out << indent_text << "Right projection:\n";
00239       mRightProj->outStream(out, indentLevel + 2);
00240       out << std::endl;
00241    }
00242 
00243    return out;
00244 }
00245 
00246 }

Generated on Thu Jan 4 10:56:52 2007 for VR Juggler by  doxygen 1.5.1