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 <gmtl/Matrix.h>
00036 #include <gmtl/Generate.h>
00037 #include <gmtl/MatrixOps.h>
00038 #include <gmtl/Vec.h>
00039 #include <gmtl/VecOps.h>
00040 #include <gmtl/Xforms.h>
00041 #include <gmtl/Output.h>
00042
00043 #include <vrj/Kernel/User.h>
00044
00045 #include <vrj/Draw/OGL/GlDrawManager.h>
00046
00047 #include <vrj/Display/DisplayManager.h>
00048 #include <vrj/Display/Projection.h>
00049 #include <vrj/Display/Viewport.h>
00050 #include <vrj/Display/SimViewport.h>
00051 #include <vrj/Display/SurfaceViewport.h>
00052
00053 #include <vrj/Draw/OGL/GlSimInterfaceFactory.h>
00054 #include <vrj/Draw/OGL/GlBasicSimulator.h>
00055
00056 #include <boost/concept_check.hpp>
00057
00058
00059 namespace vrj
00060 {
00061
00062 VRJ_REGISTER_GL_SIM_INTERFACE_CREATOR(GlBasicSimulator);
00063
00064 GlBasicSimulator::GlBasicSimulator() : mQuadObj(NULL)
00065 {
00066
00067 setDrawWandFunctor(new GlDrawRightAngleWandFunctor());
00068 }
00069
00070
00071
00072
00073
00074
00075 bool GlBasicSimulator::config(jccl::ConfigElementPtr element)
00076 {
00077 vprASSERT(element.get() != NULL);
00078 vprASSERT(element->getID() == std::string("default_simulator"));
00079
00080 std::string camera_proxy_str = element->getProperty<std::string>("camera_pos");
00081 std::string wand_proxy_str = element->getProperty<std::string>("wand_pos");
00082
00083 mCamera.init(camera_proxy_str);
00084 mWand.init(wand_proxy_str);
00085
00086 if(!mCamera.isConnected())
00087 {
00088 vprDEBUG(vprDBG_ERROR, vprDBG_CRITICAL_LVL)
00089 << clrOutNORM(clrRED,"ERROR:")
00090 << "GlBasicSimulator:: Fatal Error: Camera not found named: "
00091 << camera_proxy_str.c_str() << vprDEBUG_FLUSH;
00092 vprASSERT(false);
00093 }
00094
00095
00096 mDrawProjections = element->getProperty<bool>("draw_projections");
00097 mSurfaceColor[0] = element->getProperty<float>("surface_color", 0);
00098 mSurfaceColor[1] = element->getProperty<float>("surface_color", 1);
00099 mSurfaceColor[2] = element->getProperty<float>("surface_color", 2);
00100
00101 return true;
00102 }
00103
00108 void GlBasicSimulator::draw(const float scaleFactor)
00109 {
00110 drawSimulator(scaleFactor);
00111 }
00112
00113
00117 void GlBasicSimulator::setEventWindow(gadget::EventWindowInterface ewInterface)
00118 {
00119 boost::ignore_unused_variable_warning(ewInterface);
00120 }
00121
00122
00123 void GlBasicSimulator::updateProjectionData(const float positionScale,
00124 Projection* leftProj, Projection* rightProj)
00125 {
00126 updateInternalData(positionScale);
00127
00128 gmtl::Matrix44f camera_pos = getCameraPos();
00129 gmtl::Vec3f camera_trans = gmtl::makeTrans<gmtl::Vec3f>(camera_pos);
00130
00131
00132
00133 gmtl::Matrix44f left_eye_pos, right_eye_pos;
00134
00135
00136 vprDEBUG(vprDBG_ALL, vprDBG_HEX_LVL)
00137 << "vjDisplay::updateProjections: Getting cam position" << std::endl
00138 << vprDEBUG_FLUSH;
00139 vprDEBUG(vprDBG_ALL, vprDBG_HEX_LVL) << "CamPos:" << camera_trans << std::endl << vprDEBUG_FLUSH;
00140
00141
00142 float interocular_dist = mSimViewport->getUser()->getInterocularDistance();
00143 interocular_dist *= positionScale;
00144 float eye_offset = interocular_dist / 2.0f;
00145
00146 left_eye_pos = camera_pos * gmtl::makeTrans<gmtl::Matrix44f>( gmtl::Vec3f(-eye_offset, 0.0f, 0.0f) );
00147 right_eye_pos = camera_pos * gmtl::makeTrans<gmtl::Matrix44f>( gmtl::Vec3f(eye_offset, 0.0f, 0.0f) );
00148
00149 leftProj->calcViewMatrix(left_eye_pos, positionScale);
00150 rightProj->calcViewMatrix(right_eye_pos, positionScale);
00151 }
00152
00154 void GlBasicSimulator::updateInternalData(float positionScale)
00155 {
00156 mHeadPos = mSimViewport->getUser()->getHeadPosProxy()->getData(positionScale);
00157 mWandPos = mWand->getData(positionScale);
00158
00159 mCameraPos = mCamera->getData(positionScale);
00160 gmtl::invert(mCameraPos);
00161 }
00162
00163
00164
00165
00166 void GlBasicSimulator::drawObjects()
00167 {
00168 glPushAttrib( GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_LIGHTING_BIT );
00169 {
00170 glDisable(GL_LIGHTING);
00171 glDisable(GL_BLEND);
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186 }
00187 glPopAttrib();
00188 }
00189
00190
00198 void GlBasicSimulator::drawProjections(bool drawFrustum, gmtl::Vec3f surfColor, const float scaleFactor)
00199 {
00200 const float ALPHA_VALUE(0.25f);
00201
00202 DisplayManager* display_man = vrj::GlDrawManager::instance()->getDisplayManager();
00203 display_man->updateProjections(scaleFactor);
00204
00205 std::vector<Display*> disps = display_man->getAllDisplays();
00206
00207 gmtl::Vec3f apex, ur, lr, ul, ll;
00208 Projection* proj; proj = NULL;
00209
00210 for (unsigned int i=0;i<disps.size();i++)
00211 {
00212 for (unsigned int v=0;v<disps[i]->getNumViewports();v++)
00213 {
00214 Viewport* view_port = disps[i]->getViewport(v);
00215
00216 if (view_port->isSurface())
00217 {
00218 for(unsigned proj_num=0;proj_num<2;++proj_num)
00219 {
00220
00221 SurfaceViewport* surf_vp = dynamic_cast<SurfaceViewport*>(view_port);
00222 vprASSERT(surf_vp != NULL);
00223 proj = NULL;
00224 if(0 == proj_num)
00225 proj = surf_vp->getLeftProj();
00226 else
00227 proj = surf_vp->getRightProj();
00228
00229
00230
00231 int red_on = (i & 0x1); int green_on = ((i >> 1) & 0x1); int blue_on = ((i >> 2) & 0x1);
00232
00233 float red(0.0f), green(0.0f), blue(0.0f);
00234 if (red_on > 0) red = 1.0f;
00235 if (green_on > 0) green = 1.0f;
00236 if (blue_on > 0) blue = 1.0f;
00237
00238 if ((!red_on) && (!blue_on) && (!green_on))
00239 red = blue = green = 0.75f;
00240
00241 gmtl::Vec3f surf_color;
00242 gmtl::Vec3f apex_color;
00243 if (drawFrustum)
00244 {
00245 surf_color = gmtl::Vec3f(red,blue,green);
00246 }
00247 else
00248 {
00249 surf_color = surfColor;
00250 }
00251 apex_color = surf_color;
00252 if(1 == proj_num)
00253 {
00254 apex_color = gmtl::Vec3f(1.0f, 1.0f, 1.0f) - apex_color;
00255 }
00256
00257
00258
00259 const float ll_scale(0.10f);
00260 const float ul_scale(0.55f);
00261 const float ur_scale(1.0f);
00262 gmtl::Vec4f ll_clr(ll_scale*surf_color[0],ll_scale*surf_color[1],ll_scale*surf_color[2],ALPHA_VALUE);
00263 gmtl::Vec4f ul_clr(ul_scale*surf_color[0],ul_scale*surf_color[1],ul_scale*surf_color[2],ALPHA_VALUE);
00264 gmtl::Vec4f lr_clr(ul_scale*surf_color[0],ul_scale*surf_color[1],ul_scale*surf_color[2],ALPHA_VALUE);
00265 gmtl::Vec4f ur_clr(ur_scale*surf_color[0],ur_scale*surf_color[1],ur_scale*surf_color[2],ALPHA_VALUE);
00266
00267
00268 proj->getFrustumApexAndCorners(apex, ur, lr, ul, ll);
00269 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_STATE_LVL) << "apex: " << apex
00270 << std::endl << vprDEBUG_FLUSH;
00271
00272 glColor4fv(&(apex_color[0]));
00273 glPushMatrix();
00274 if (drawFrustum)
00275 {
00276 drawLine(apex, ur); drawLine(apex, lr); drawLine(apex, ul); drawLine(apex, ll);
00277 }
00278
00279 glColor4fv(&(ur_clr[0]));
00280
00281 drawLine(ur, lr); drawLine(lr, ll); drawLine(ll, ul); drawLine(ul, ur);
00282
00283
00284 glEnable(GL_BLEND);
00285 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00286 glBegin(GL_TRIANGLES);
00287 glColor4fv(ll_clr.mData); glVertex3fv(ll.mData);
00288 glColor4fv(lr_clr.mData); glVertex3fv(lr.mData);
00289 glColor4fv(ur_clr.mData); glVertex3fv(ur.mData);
00290
00291 glColor4fv(ur_clr.mData); glVertex3fv(ur.mData);
00292 glColor4fv(ul_clr.mData); glVertex3fv(ul.mData);
00293 glColor4fv(ll_clr.mData); glVertex3fv(ll.mData);
00294 glEnd();
00295 glDisable(GL_BLEND);
00296 glPopMatrix();
00297 }
00298 }
00299 }
00300 }
00301 }
00302
00307 void GlBasicSimulator::drawSimulator(const float scaleFactor)
00308 {
00309
00310
00311
00312 const float head_height(0.254f*scaleFactor);
00313 const float head_width_scale(0.7f);
00314 const float head_depth_scale(0.8f);
00315
00316
00317 const float interocular( mSimViewport->getUser()->getInterocularDistance()*scaleFactor);
00318 const float eye_radius(0.0254f*0.5f*scaleFactor);
00319
00320 glPushAttrib( GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_LIGHTING_BIT);
00321 {
00322
00323 GLboolean lighting_on, light0_on;
00324 glGetBooleanv(GL_LIGHTING, &lighting_on);
00325 glGetBooleanv(GL_LIGHT0, &light0_on);
00326
00327 bool use_lighting_in_sim = (lighting_on == GL_TRUE);
00328
00329
00330
00331
00332
00333 float mat_ambient[] = {0.1f, 0.1f, 0.1f, 1.0f};
00334 float mat_shininess[] = {50.0f};
00335 float mat_diffuse[] = {.7f, .7f, .7f, 1.0f};
00336 float mat_specular[] = {1.0f, 1.0f, 1.0f, 1.0f};
00337
00338 glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
00339 glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
00340 glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
00341 glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
00342
00343 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
00344 glEnable(GL_COLOR_MATERIAL);
00345
00346 glDisable(GL_TEXTURE_2D);
00347 glDisable(GL_TEXTURE_1D);
00348
00349
00351
00352 glDisable(GL_LIGHTING);
00353
00354 glPushMatrix();
00355 gmtl::Vec3f x_axis(scaleFactor,0.0f,0.0f); gmtl::Vec3f y_axis(0.0f, scaleFactor, 0.0f);
00356 gmtl::Vec3f z_axis(0.0f, 0.0f, scaleFactor); gmtl::Vec3f origin(0.0f, 0.0f, 0.0f);
00357 glBegin(GL_LINES);
00358 glColor3f(1.0f, 0.0f, 0.0f); glVertex3fv(origin.mData); glVertex3fv(x_axis.mData);
00359 glColor3f(0.0f, 1.0f, 0.0f); glVertex3fv(origin.mData); glVertex3fv(y_axis.mData);
00360 glColor3f(0.0f, 0.0f, 1.0f); glVertex3fv(origin.mData); glVertex3fv(z_axis.mData);
00361 glEnd();
00362 glPopMatrix();
00363
00364
00365 if(use_lighting_in_sim)
00366 {
00367 glEnable(GL_LIGHTING);
00368 glEnable(GL_NORMALIZE);
00369 }
00370
00371 glPushMatrix();
00372 glMultMatrixf(getHeadPos().mData);
00373
00374 glPushMatrix();
00375
00376
00377
00378 gmtl::Vec3f forehead_offset(0.0f, head_height*0.17f, -(head_depth_scale*head_height)*0.45f);
00379 glTranslatef(-forehead_offset[0], -forehead_offset[1], -forehead_offset[2]);
00380 glScalef(head_width_scale, 1.0f, head_depth_scale);
00381
00382
00383 glColor4f(0.5f, 0.75f, 0.90f, 0.67f);
00384 drawSphere(head_height/2.0f, 10, 10);
00385
00386 glPopMatrix();
00387
00388
00389 glPushMatrix();
00390 glColor3f(0.8f, 0.4f, 0.2f);
00391
00392 glPushMatrix();
00393 glTranslatef((interocular/2.0f), 0.0f, 0.0f);
00394 drawSphere(eye_radius, 5, 5);
00395 glPopMatrix();
00396 glPushMatrix();
00397 glTranslatef(-(interocular/2.0f), 0.0f, 0.0f);
00398 drawSphere(eye_radius, 5, 5);
00399 glPopMatrix();
00400 glPopMatrix();
00401 glPopMatrix();
00402
00403
00404 glPushMatrix();
00405 glMultMatrixf(getWandPos().mData);
00406 glScalef(scaleFactor,scaleFactor,scaleFactor);
00407 glEnable(GL_NORMALIZE);
00408 mDrawWandFunctor->draw();
00409 glPopMatrix();
00410
00411
00412 if(use_lighting_in_sim)
00413 glDisable(GL_LIGHTING);
00414
00415 glPushMatrix();
00416 drawProjections(shouldDrawProjections(), getSurfaceColor(), scaleFactor);
00417 glPopMatrix();
00418 }
00419 glPopAttrib();
00420 }
00421
00422
00423 void GlBasicSimulator::initQuadObj()
00424 {
00425 if (mQuadObj == NULL)
00426 mQuadObj = gluNewQuadric();
00427 }
00428
00429 void GlBasicSimulator::drawLine(gmtl::Vec3f& start, gmtl::Vec3f& end)
00430 {
00431 glBegin(GL_LINES);
00432 glVertex3fv(start.mData);
00433 glVertex3fv(end.mData);
00434 glEnd();
00435 }
00436
00437 void GlBasicSimulator::drawSphere(float radius, int slices, int stacks)
00438 {
00439 initQuadObj();
00440 gluQuadricDrawStyle(mQuadObj, (GLenum) GLU_FILL);
00441 gluQuadricNormals(mQuadObj, (GLenum) GLU_SMOOTH);
00442 gluSphere(mQuadObj, radius, slices, stacks);
00443 }
00444
00445
00446 void GlBasicSimulator::drawCone(float base, float height, int slices, int stacks)
00447 {
00448 initQuadObj();
00449 gluQuadricDrawStyle(mQuadObj, (GLenum) GLU_FILL);
00450 gluQuadricNormals(mQuadObj, (GLenum) GLU_SMOOTH);
00451 gluCylinder(mQuadObj, base, 0.0, height, slices, stacks);
00452 }
00453
00454
00455
00456 void GlBasicSimulator::drawBox(float size, GLenum type)
00457 {
00458 static GLfloat n[6][3] =
00459 {
00460 {-1.0, 0.0, 0.0},
00461 {0.0, 1.0, 0.0},
00462 {1.0, 0.0, 0.0},
00463 {0.0, -1.0, 0.0},
00464 {0.0, 0.0, 1.0},
00465 {0.0, 0.0, -1.0}
00466 };
00467
00468 static GLint faces[6][4] =
00469 {
00470 {0, 1, 2, 3},
00471 {3, 2, 6, 7},
00472 {7, 6, 5, 4},
00473 {4, 5, 1, 0},
00474 {5, 6, 2, 1},
00475 {7, 4, 0, 3}
00476 };
00477 GLfloat v[8][3];
00478 GLint i;
00479
00480 v[0][0] = v[1][0] = v[2][0] = v[3][0] = -size / 2;
00481 v[4][0] = v[5][0] = v[6][0] = v[7][0] = size / 2;
00482 v[0][1] = v[1][1] = v[4][1] = v[5][1] = -size / 2;
00483 v[2][1] = v[3][1] = v[6][1] = v[7][1] = size / 2;
00484 v[0][2] = v[3][2] = v[4][2] = v[7][2] = -size / 2;
00485 v[1][2] = v[2][2] = v[5][2] = v[6][2] = size / 2;
00486
00487 for (i = 5; i >= 0; i--) {
00488 glBegin(type);
00489 glNormal3fv(&n[i][0]);
00490 glVertex3fv(&v[faces[i][0]][0]);
00491 glVertex3fv(&v[faces[i][1]][0]);
00492 glVertex3fv(&v[faces[i][2]][0]);
00493 glVertex3fv(&v[faces[i][3]][0]);
00494 glEnd();
00495 }
00496 }
00497
00498
00499 void GlBasicSimulator::drawWireCube(float size)
00500 {
00501 drawBox(size, GL_LINE_LOOP);
00502 }
00503
00504 void GlBasicSimulator::drawSolidCube(float size)
00505 {
00506 drawBox(size, GL_QUADS);
00507 }
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649 }
00650