00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include <vrj/vrjConfig.h>
00034
00035 #include <string>
00036 #include <gmtl/Math.h>
00037
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
00078 if ( ! Viewport::config(element) )
00079 {
00080 return false;
00081 }
00082
00083 bool result(true);
00084
00085 mType = SURFACE;
00086
00087
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
00102
00103
00104
00105
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
00123
00124
00125
00126
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
00153
00154
00155
00156 mLeftProj = left_proj;
00157 mRightProj = right_proj;
00158
00159
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;
00191
00192
00193 gmtl::Matrix44f cur_head_pos = mUser->getHeadPosProxy()->getData(positionScale);
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206 float interocular_dist = mUser->getInterocularDistance();
00207 interocular_dist *= positionScale;
00208 float eye_offset = interocular_dist/2.0f;
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
00227
00228
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 }