00001 //---------------------------------------------------------------------- 00002 // The Motion Strategy Library (MSL) 00003 //---------------------------------------------------------------------- 00004 // 00005 // Copyright (c) 1998-2000 Iowa State University and Steve LaValle. 00006 // All Rights Reserved. 00007 // 00008 // Permission to use, copy, and distribute this software and its 00009 // documentation is hereby granted free of charge, provided that 00010 // (1) it is not a component of a commercial product, and 00011 // (2) this notice appears in all copies of the software and 00012 // related documentation. 00013 // 00014 // Iowa State University and the author make no representations 00015 // about the suitability or fitness of this software for any purpose. 00016 // It is provided "as is" without express or implied warranty. 00017 //---------------------------------------------------------------------- 00018 00019 #include <math.h> 00020 #include <stdlib.h> 00021 00022 #include "renderpf.h" 00023 #include "defs.h" 00024 00025 #include <LEDA/REDEFINE_NAMES.h> 00026 #undef set // This leda class conflicts with Performer 00027 00028 #define CONTROLPANEL_CENTER_X -0.22 00029 #define CONTROLPANEL_CENTER_Z -0.37 00030 #define CONTROLPANEL_WIDTH 0.2 00031 #define CONTROLPANEL_HEIGHT 0.1 00032 #define CONTROLPANEL_BAR_WIDTH 0.18 00033 #define CONTROLPANEL_BAR_HEIGHT 0.005 00034 #define CONTROLPAD_WIDTH 0.01 00035 #define CONTROLPAD_HEIGHT 0.02 00036 00037 // Range of speeds: 2^-ANIMATING_SPEED_FACTOR to 2^ANIMATING_SPEED_FACTOR 00038 #define ANIMATING_SPEED_FACTOR 10 00039 00040 00042 // 00043 // RenderPerformer Class 00044 // 00046 00047 SharedData* RenderPerformer::Shared; 00048 00049 RenderPerformer::RenderPerformer(): Render() 00050 { 00051 00052 } 00053 00054 00055 RenderPerformer::RenderPerformer(string filepath=""): Render(filepath) 00056 { 00057 00058 } 00059 00060 00061 RenderPerformer::RenderPerformer(Scene *s, 00062 string filepath): Render(s,filepath) 00063 { 00064 00065 } 00066 00067 00068 00069 void RenderPerformer::LoadEnvironment(pfGroup *env){ 00070 string object; 00071 pfNode *root; 00072 00073 forall(object, EnvList){ 00074 // Append to Performer search path 00075 if (!strstr(object,".")) { 00076 root = LoadNativeModel(object, 0); 00077 } 00078 else{ 00079 pfFilePath(FilePath); 00080 00081 cout << "Loading " << object << "\n"; 00082 root = pfdLoadFile(object); 00083 if (root == NULL) 00084 { 00085 pfExit(); 00086 exit(-1); 00087 } 00088 } 00089 env->addChild(root); 00090 } 00091 00092 // Draw bounding box 00093 } 00094 00095 00096 00097 void RenderPerformer::LoadBodies(pfGroup *bodies){ 00098 string object; 00099 pfNode *root; 00100 int i; 00101 00102 i = 0; 00103 forall(object, BodyList) { 00104 if (!strstr(object,".")) { 00105 root = LoadNativeModel(object, i+1); 00106 } 00107 else { 00108 // Append to Performer search path 00109 pfFilePath(FilePath); 00110 00111 cout << "Loading " << object << "\n"; 00112 root = pfdLoadFile(object); 00113 if (root == NULL) 00114 { 00115 pfExit(); 00116 exit(-1); 00117 } 00118 } 00119 pfDCS *piece = new pfDCS; 00120 piece->addChild(root); 00121 bodies->addChild(piece); 00122 00123 i++; 00124 } 00125 } 00126 00127 00128 00129 pfNode* RenderPerformer::LoadNativeModel(string file, int colorindex) 00130 { 00131 pfGeode *root = new pfGeode; 00132 pfGeoSet *gset = new pfGeoSet; 00133 list<Triangle> trlist; 00134 list<polygon> plist; 00135 int i, num; 00136 Triangle t; 00137 double d1[3],d2[3], n[3]; 00138 00139 file_istream fin(FilePath + file); 00140 if (S->GeomDim == 2) { 00141 fin >> plist; 00142 trlist = PolygonsToTriangles(plist,5.0); // Defined in 3Dtriangle.C 00143 } 00144 else 00145 fin >> trlist; 00146 fin.close(); 00147 00148 num = trlist.length(); 00149 //cout << "number of triangles: " << num << endl; 00150 pfVec3 *tri = new pfVec3[3*num]; 00151 pfVec3 *norm = new pfVec3[num]; 00152 pfVec4 *color = new pfVec4[1]; 00153 00154 for (i=0; i<num; i++) { 00155 t = trlist.contents(trlist.get_item(i)); 00156 tri[3*i].set((float)t.p1.xcoord(), (float)t.p1.ycoord(), (float)t.p1.zcoord()); 00157 tri[3*i+1].set((float)t.p2.xcoord(), (float)t.p2.ycoord(), (float)t.p2.zcoord()); 00158 tri[3*i+2].set((float)t.p3.xcoord(), (float)t.p3.ycoord(), (float)t.p3.zcoord()); 00159 00160 d1[0] = t.p2.xcoord() - t.p1.xcoord(); 00161 d1[1] = t.p2.ycoord() - t.p1.ycoord(); 00162 d1[2] = t.p2.zcoord() - t.p1.zcoord(); 00163 d2[0] = t.p3.xcoord() - t.p1.xcoord(); 00164 d2[1] = t.p3.ycoord() - t.p1.ycoord(); 00165 d2[2] = t.p3.zcoord() - t.p1.zcoord(); 00166 NormCrossProduct(d1, d2, n); 00167 norm[i].set(n[0], n[1], n[2]); 00168 } 00169 color[0].set( RGBRed[colorindex % RENDERCOLORS], 00170 RGBGreen[colorindex % RENDERCOLORS], 00171 RGBBlue[colorindex % RENDERCOLORS], 0.0f ); 00172 00173 gset->setAttr(PFGS_COORD3, PFGS_PER_VERTEX, tri, NULL); 00174 gset->setAttr(PFGS_NORMAL3, PFGS_PER_PRIM, norm, NULL); 00175 gset->setAttr(PFGS_COLOR4, PFGS_OVERALL, color, NULL); 00176 gset->setPrimType(PFGS_TRIS); 00177 gset->setNumPrims(num); 00178 00179 //Specify Geometry State 00180 pfGeoState *gstate = new pfGeoState; 00181 gstate->setMode(PFSTATE_ENLIGHTING, PF_ON); 00182 gstate->setMode(PFSTATE_CULLFACE, PF_OFF); 00183 //gstate->setMode(PFSTATE_SHADEMODEL, PFSM_GOURAUD); 00184 00185 // Using material 00186 pfMaterial *mat = new pfMaterial; 00187 mat->setColor(PFMTL_AMBIENT, 0.0f, 0.0f, 0.0f); 00188 mat->setColor(PFMTL_SPECULAR, 0.5f, 0.5f, 0.5f); 00189 mat->setShininess(10.0f); 00190 mat->setColorMode(PFMTL_BOTH, PFMTL_CMODE_AD); 00191 //mat->apply(); 00192 00193 gstate->setAttr(PFSTATE_FRONTMTL, mat); 00194 gset->setGState(gstate); 00195 00196 //gset->setDrawMode(PFGS_FLATSHADE, PF_ON); 00197 00198 root->addGSet(gset); 00199 00200 return root; 00201 } 00202 00203 00204 void RenderPerformer::MakeBoundingBox(pfGeode *bound){ 00205 pfGeoSet *gset = new pfGeoSet; 00206 pfVec3 *ver = new pfVec3[24]; 00207 pfVec3 *norm = new pfVec3[12]; 00208 pfVec4 *color = new pfVec4[1]; 00209 00210 ver[0].set(S->LowerWorld[0], S->LowerWorld[1], S->LowerWorld[2]); 00211 ver[1].set(S->UpperWorld[0], S->LowerWorld[1], S->LowerWorld[2]); 00212 norm[0].set(0.0,1.0,0.0); 00213 00214 ver[2].set(S->LowerWorld[0], S->LowerWorld[1], S->LowerWorld[2]); 00215 ver[3].set(S->LowerWorld[0], S->UpperWorld[1], S->LowerWorld[2]); 00216 norm[1].set(0.0,1.0,0.0); 00217 00218 ver[4].set(S->LowerWorld[0], S->LowerWorld[1], S->LowerWorld[2]); 00219 ver[5].set(S->LowerWorld[0], S->LowerWorld[1], S->UpperWorld[2]); 00220 norm[2].set(0.0,1.0,0.0); 00221 00222 ver[6].set(S->UpperWorld[0], S->LowerWorld[1], S->LowerWorld[2]); 00223 ver[7].set(S->UpperWorld[0], S->UpperWorld[1], S->LowerWorld[2]); 00224 norm[3].set(0.0,1.0,0.0); 00225 00226 ver[8].set(S->UpperWorld[0], S->LowerWorld[1], S->LowerWorld[2]); 00227 ver[9].set(S->UpperWorld[0], S->LowerWorld[1], S->UpperWorld[2]); 00228 norm[4].set(0.0,1.0,0.0); 00229 00230 ver[10].set(S->LowerWorld[0], S->UpperWorld[1], S->LowerWorld[2]); 00231 ver[11].set(S->UpperWorld[0], S->UpperWorld[1], S->LowerWorld[2]); 00232 norm[5].set(0.0,1.0,0.0); 00233 00234 ver[12].set(S->LowerWorld[0], S->UpperWorld[1], S->LowerWorld[2]); 00235 ver[13].set(S->LowerWorld[0], S->UpperWorld[1], S->UpperWorld[2]); 00236 norm[6].set(0.0,1.0,0.0); 00237 00238 ver[14].set(S->LowerWorld[0], S->LowerWorld[1], S->UpperWorld[2]); 00239 ver[15].set(S->UpperWorld[0], S->LowerWorld[1], S->UpperWorld[2]); 00240 norm[7].set(0.0,1.0,0.0); 00241 00242 ver[16].set(S->LowerWorld[0], S->LowerWorld[1], S->UpperWorld[2]); 00243 ver[17].set(S->LowerWorld[0], S->UpperWorld[1], S->UpperWorld[2]); 00244 norm[8].set(0.0,1.0,0.0); 00245 00246 ver[18].set(S->UpperWorld[0], S->UpperWorld[1], S->UpperWorld[2]); 00247 ver[19].set(S->LowerWorld[0], S->UpperWorld[1], S->UpperWorld[2]); 00248 norm[9].set(0.0,1.0,0.0); 00249 00250 ver[20].set(S->UpperWorld[0], S->UpperWorld[1], S->UpperWorld[2]); 00251 ver[21].set(S->UpperWorld[0], S->LowerWorld[1], S->UpperWorld[2]); 00252 norm[10].set(0.0,1.0,0.0); 00253 00254 ver[22].set(S->UpperWorld[0], S->UpperWorld[1], S->UpperWorld[2]); 00255 ver[23].set(S->UpperWorld[0], S->UpperWorld[1], S->LowerWorld[2]); 00256 norm[11].set(0.0,1.0,0.0); 00257 00258 color[0].set( 1, 0, 0, 0.0f ); 00259 00260 gset->setAttr(PFGS_COORD3, PFGS_PER_VERTEX, ver, NULL); 00261 gset->setAttr(PFGS_NORMAL3, PFGS_PER_PRIM, norm, NULL); 00262 gset->setAttr(PFGS_COLOR4, PFGS_OVERALL, color, NULL); 00263 gset->setPrimType(PFGS_LINES); 00264 gset->setNumPrims(12); 00265 00266 //Specify Geometry State 00267 pfGeoState *gstate = new pfGeoState; 00268 gstate->setMode(PFSTATE_ENLIGHTING, PF_ON); 00269 gstate->setMode(PFSTATE_CULLFACE, PF_OFF); 00270 //gstate->setMode(PFSTATE_SHADEMODEL, PFSM_GOURAUD); 00271 00272 // Using material 00273 pfMaterial *mat = new pfMaterial; 00274 mat->setColor(PFMTL_AMBIENT, 0.0f, 0.0f, 0.0f); 00275 mat->setColor(PFMTL_SPECULAR, 0.5f, 0.5f, 0.5f); 00276 mat->setShininess(10.0f); 00277 mat->setColorMode(PFMTL_BOTH, PFMTL_CMODE_AD); 00278 gstate->setAttr(PFSTATE_FRONTMTL, mat); 00279 00280 gset->setGState(gstate); 00281 00282 bound->addGSet(gset); 00283 } 00284 00285 00286 00287 void RenderPerformer::MakeControlPanel(pfGroup *con, pfDCS *pad){ 00288 pfGeode *geopad = new pfGeode; 00289 pfGeode *geo = new pfGeode; 00290 pfGeoSet *gset_frame = new pfGeoSet; 00291 pfGeoSet *gset_pad = new pfGeoSet; 00292 00293 //Specify Geometry State 00294 pfGeoState *gstate = new pfGeoState; 00295 gstate->setMode(PFSTATE_TRANSPARENCY, PFTR_ON); 00296 gstate->setMode(PFSTATE_ENLIGHTING, PF_ON); 00297 gstate->setMode(PFSTATE_CULLFACE, PF_OFF); 00298 00299 // Using material 00300 pfMaterial *mat = new pfMaterial; 00301 mat->setColor(PFMTL_AMBIENT, 0.0f, 0.0f, 0.0f); 00302 mat->setColor(PFMTL_SPECULAR, 0.5f, 0.5f, 0.5f); 00303 mat->setShininess(10.0f); 00304 mat->setColorMode(PFMTL_BOTH, PFMTL_CMODE_AD); 00305 gstate->setAttr(PFSTATE_FRONTMTL, mat); 00306 00307 pfVec3 *tri = new pfVec3[4]; 00308 pfVec3 *norm = new pfVec3[1]; 00309 pfVec4 *color = new pfVec4[1]; 00310 00311 tri[0].set(-CONTROLPANEL_BAR_WIDTH + CONTROLPANEL_CENTER_X, -299.0, 00312 -CONTROLPANEL_BAR_HEIGHT + CONTROLPANEL_CENTER_Z); 00313 tri[1].set(-CONTROLPANEL_BAR_WIDTH + CONTROLPANEL_CENTER_X, -299.0, 00314 CONTROLPANEL_BAR_HEIGHT + CONTROLPANEL_CENTER_Z); 00315 tri[2].set(CONTROLPANEL_BAR_WIDTH + CONTROLPANEL_CENTER_X, -299.0, 00316 CONTROLPANEL_BAR_HEIGHT + CONTROLPANEL_CENTER_Z); 00317 tri[3].set(CONTROLPANEL_BAR_WIDTH + CONTROLPANEL_CENTER_X, -299.0, 00318 -CONTROLPANEL_BAR_HEIGHT + CONTROLPANEL_CENTER_Z); 00319 norm[0].set(0.0, -1.0, 0.0); 00320 color[0].set(0.5, 0.5, 1.0, 0.5f ); 00321 00322 gset_frame->setAttr(PFGS_COORD3, PFGS_PER_VERTEX, tri, NULL); 00323 gset_frame->setAttr(PFGS_NORMAL3, PFGS_PER_PRIM, norm, NULL); 00324 gset_frame->setAttr(PFGS_COLOR4, PFGS_PER_PRIM, color, NULL); 00325 gset_frame->setPrimType(PFGS_QUADS); 00326 gset_frame->setNumPrims(1); 00327 gset_frame->setGState(gstate); 00328 geo->addGSet(gset_frame); 00329 00330 con->addChild(geo); 00331 00332 // Draw Control Pad 00333 pfVec3 *tri1 = new pfVec3[4]; 00334 pfVec3 *norm1 = new pfVec3[1]; 00335 pfVec4 *color1 = new pfVec4[1]; 00336 00337 tri1[0].set(-CONTROLPAD_WIDTH + CONTROLPANEL_CENTER_X, -299.0, 00338 -CONTROLPAD_HEIGHT + CONTROLPANEL_CENTER_Z); 00339 tri1[1].set(-CONTROLPAD_WIDTH + CONTROLPANEL_CENTER_X, -299.0, 00340 CONTROLPAD_HEIGHT + CONTROLPANEL_CENTER_Z); 00341 tri1[2].set(CONTROLPAD_WIDTH + CONTROLPANEL_CENTER_X, -299.0, 00342 CONTROLPAD_HEIGHT + CONTROLPANEL_CENTER_Z); 00343 tri1[3].set(CONTROLPAD_WIDTH + CONTROLPANEL_CENTER_X, -299.0, 00344 -CONTROLPAD_HEIGHT + CONTROLPANEL_CENTER_Z); 00345 norm1[0].set(0.0, -1.0, 0.0); 00346 color1[0].set(0.0, 0.0, 1.0, 0.5); 00347 00348 gset_pad->setAttr(PFGS_COORD3, PFGS_PER_VERTEX, tri1, NULL); 00349 gset_pad->setAttr(PFGS_NORMAL3, PFGS_PER_PRIM, norm1, NULL); 00350 gset_pad->setAttr(PFGS_COLOR4, PFGS_PER_PRIM, color1, NULL); 00351 gset_pad->setPrimType(PFGS_QUADS); 00352 gset_pad->setNumPrims(1); 00353 gset_pad->setGState(gstate); 00354 geopad->addGSet(gset_pad); 00355 00356 pad->addChild(geopad); 00357 } 00358 00359 00360 00361 00362 00363 void RenderPerformer::NormCrossProduct(double v1[3], double v2[3], 00364 double out[3]) { 00365 out[0] = v1[1]*v2[2] - v1[2]*v2[1]; 00366 out[1] = v1[2]*v2[0] - v1[0]*v2[2]; 00367 out[2] = v1[0]*v2[1] - v1[1]*v2[0]; 00368 00369 GLfloat d = sqrt(out[0]*out[0] + out[1]*out[1] + out[2]*out[2]); 00370 00371 out[0] /= d; 00372 out[1] /= d; 00373 out[2] /= d; 00374 } 00375 00376 00377 00378 void RenderPerformer::GetCurrentMousePos(double &x, double &y){ 00379 pfuGetMouse(Shared->Mouse); 00380 pfuMapMouseToChan(Shared->Mouse, Shared->Chan); // no matter mouse in chan or not return a value 00381 x = (double)Shared->Mouse->xchan; 00382 y = (double)Shared->Mouse->ychan; 00383 00384 switch(Shared->Mouse->click){ 00385 case 1: // click right 00386 Shared->HoldRightMouse = true; 00387 break; 00388 case 2: // click middle 00389 Shared->HoldMiddleMouse = true; 00390 break; 00391 case 4: // click left 00392 Shared->HoldLeftMouse = true; 00393 break; 00394 default: // none 00395 break; 00396 } 00397 00398 switch(Shared->Mouse->release){ 00399 case 5: // release right and left 00400 Shared->HoldRightMouse = false; 00401 Shared->HoldLeftMouse = false; 00402 break; 00403 case 7: // release middle; 00404 Shared->HoldMiddleMouse = false; 00405 break; 00406 default: // none 00407 break; 00408 } 00409 } 00410 00411 00412 void RenderPerformer::ShowCurrentAnimationFrame() { 00413 int i,j; 00414 vector conf(6),oldframe; 00415 pfMatrix orientation, rot, delta_rot; 00416 00417 if (AnimationActive) 00418 SetCurrentAnimationFrame(); 00419 00420 // Show the bodies in their proper places 00421 for (i = 0; i < S->NumBodies; i++) { 00422 // for each robot, first read its own configuration from FrameList 00423 for (j = 0; j < 6; j++) 00424 conf[j] = CurrentAnimationFrame[6*i+j]; 00425 00426 // update coordinate system 00427 orientation.makeIdent(); 00428 rot.makeIdent(); 00429 // rotate x 00430 delta_rot.makeRot(conf[3]*180.0/PI, 1.0, 0.0, 0.0); 00431 rot.postMult(delta_rot); 00432 // rotate y 00433 delta_rot.makeRot(conf[4]*180.0/PI, 0.0, 1.0, 0.0); 00434 rot.postMult(delta_rot); 00435 // rotate Z 00436 delta_rot.makeRot(conf[5]*180.0/PI, 0.0, 0.0, 1.0); 00437 rot.postMult(delta_rot); 00438 00439 // Translate 00440 orientation.postTrans(rot, conf[0], conf[1], conf[2]); 00441 00442 pfDCS *child_robot = pfGetChild(Shared->BodiesDCS, i); 00443 child_robot->setMat(orientation); 00444 } 00445 } 00446 00447 00448 void RenderPerformer::Init() { 00449 Render::Init(); 00450 00451 // Initialize Performer 00452 pfInit(); 00453 00454 // Use default multiprocessing mode based on number of processors. 00455 pfMultiprocess( PFMP_DEFAULT ); 00456 00457 // allocate shared before fork()'ing parallel processes 00458 Shared = (SharedData*)pfMalloc(sizeof(SharedData), pfGetSharedArena()); 00459 00460 // Set Performer Search Path 00461 pfFilePath(FilePath); 00462 00463 // Load all loader DSO's before pfConfig() forks 00464 string object; 00465 forall(object, EnvList) { 00466 if( strstr(object,".") ) 00467 pfdInitConverter(object); 00468 } 00469 00470 forall(object, BodyList) { 00471 if( strstr(object,".") ) 00472 pfdInitConverter(object); 00473 } 00474 00475 // initiate multi-processing mode set in pfMultiprocess call 00476 // FORKs for Performer processes, CULL and DRAW, etc. happen here. 00477 pfConfig(); 00478 00479 // Initiate performer utility library 00480 pfuInit(); 00481 00482 // Create Mouse and InputEvents 00483 Shared->Mouse = new pfuMouse; 00484 Shared->InputEvents = new pfuEventStream; 00485 00486 // Create a new pfScene 00487 pfScene *PerfScene = new pfScene; 00488 00489 // Load Environment and attach it to scene 00490 Shared->ShowCase = new pfSwitch; 00491 Shared->ControlPanel = new pfGroup; 00492 Shared->ControlPad = new pfDCS; 00493 Shared->WorldDCS = new pfDCS; 00494 Shared->WorkEnv = new pfSwitch; 00495 Shared->Env = new pfGroup; 00496 Shared->BodiesDCS = new pfDCS; 00497 Shared->BoundingBox = new pfGeode; 00498 00499 LoadEnvironment(Shared->Env); 00500 LoadBodies(Shared->BodiesDCS); 00501 00502 MakeBoundingBox(Shared->BoundingBox); 00503 MakeControlPanel(Shared->ControlPanel, Shared->ControlPad); 00504 00505 Shared->ControlPanel->addChild(Shared->ControlPad); 00506 Shared->WorkEnv->addChild(Shared->Env); 00507 Shared->WorkEnv->addChild(Shared->BoundingBox); 00508 Shared->WorldDCS->addChild(Shared->WorkEnv); 00509 Shared->WorldDCS->addChild(Shared->BodiesDCS); 00510 Shared->ShowCase->addChild(Shared->WorldDCS); 00511 Shared->ShowCase->addChild(Shared->ControlPanel); 00512 PerfScene->addChild(Shared->ShowCase); 00513 00514 // Create a pfLightSource 00515 pfLightSource *sun = new pfLightSource; 00516 sun->setPos(-100.0, -100.0, 100.0, 1.0); 00517 PerfScene->addChild(sun); 00518 pfLightSource *sun2 = new pfLightSource; 00519 sun2->setPos(0.0, 0.0, 0.0, 0.0); 00520 00521 // Uncomment the next line to make things brighter 00522 //sun2->setAmbient(1.0, 1.0, 1.0); 00523 00524 PerfScene->addChild(sun2); 00525 00526 // Configure and open GL window 00527 pfPipe *Pipe = pfGetPipe(0); 00528 Shared->PW = new pfPipeWindow(Pipe); 00529 Shared->PW->setWinType(PFPWIN_TYPE_X); 00530 Shared->PW->setName("MSL Render: IRIS Performer Window"); 00531 Shared->PW->setOriginSize(0,0,500,500); 00532 Shared->PW->open(); 00533 00534 // Create and configure a pfChannel. 00535 pfChannel *chan = new pfChannel(Pipe); 00536 chan->setScene(PerfScene); 00537 chan->setFOV(45.0f, 45.0f); 00538 chan->setNearFar(1.0f, 1000.0f); 00539 chan->setTravFunc(PFTRAV_DRAW, DrawChannel); 00540 chan->setViewport(0.0, 1.0, 0, 1.0); 00541 chan->setShare(PFCHAN_FOV | PFCHAN_NEARFAR 00542 | PFCHAN_EARTHSKY 00543 | PFCHAN_STRESS 00544 | PFCHAN_LOD | PFCHAN_SWAPBUFFERS 00545 | PFCHAN_SWAPBUFFERS_HW); 00546 00547 Shared->Chan = chan; 00548 // Set Chan view point 00549 // Unfortunately, this viewing transformation has to be fixed, 00550 // otherwise the control panel will disappear because of the 00551 // way it was designed. 00552 pfCoord view; 00553 view.hpr.set(0.0, 0.0, 0.0); // z,x,y 00554 view.xyz.set(0.0, -300.0, 0.0); 00555 Shared->Chan->setView(view.xyz, view.hpr); 00556 00557 pfEarthSky *esky = new pfEarthSky(); 00558 esky->setMode(PFES_BUFFER_CLEAR, PFES_SKY_GRND); 00559 esky->setAttr(PFES_GRND_HT, -1000.0f); 00560 esky->setColor(PFES_GRND_FAR, 0.3f, 0.1f, 0.0f, 1.0f); 00561 esky->setColor(PFES_GRND_NEAR, 0.5f, 0.3f, 0.1f, 1.0f); 00562 chan->setESky(esky); 00563 00564 // Initilize the slave channel 00565 /*pfChannel *chaneye = new pfChannel(Pipe); 00566 pfScene *eyescene = new pfScene; 00567 pfMatrix m; 00568 m.makeIdent(); 00569 pfSCS *eyeworld = new pfSCS(m); 00570 00571 eyeworld->addChild(Shared->EnvDCS); 00572 eyeworld->addChild(Shared->BodiesDCS); 00573 eyescene->addChild(eyeworld); 00574 00575 chaneye->setScene(eyescene); 00576 chan->attach(chaneye); 00577 chaneye->setViewport(0.0, 1.0/4.0, 3.0/4.0, 1.0); 00578 Shared->ChanEye = chaneye; 00579 PW->removeChan(ChanEye); // remove chanslaver as default 00580 */ 00581 00582 // Initilize input device 00583 pfuInitInput(Shared->PW,PFUINPUT_X); 00584 00585 // Get frame rate and set it to FrameTime 00586 FrameTime = (double) 0.1; // (1.0/pfGetFrameRate()); 00587 //cout << "FrameTime: " << FrameTime << endl; 00588 00589 Shared->HoldRightMouse = false; 00590 Shared->HoldLeftMouse = false; 00591 Shared->HoldMiddleMouse = false; 00592 //Shared->ReleaseRightMouse = false; 00593 //Shared->ReleaseLeftMouse = false; 00594 //Shared->ReleaseMiddleMouse = false; 00595 00596 // Here is where we have to make the initial values correspond 00597 // to what the viewing parameters from Scene dictate. 00598 Shared->TranX = 0.0; 00599 Shared->TranY = 0.0; 00600 Shared->TranZ = 0.0; 00601 Shared->RotX = 0.0; 00602 Shared->RotY = 0.0; 00603 Shared->RotZ = 0.0; 00604 00605 //Set boundbox 00606 BoundingBoxOn = false; 00607 00608 // By default, don't use attached camera 00609 AttachedCameraOn = false; 00610 00611 // Set control pannel initial pos 00612 Shared->ControlPanelOn = true; 00613 Shared->FocusOnControlPad = false; 00614 Shared->PadX = 0.0; 00615 Shared->ControlPad->setTrans(Shared->PadX, 0.0, 0.0); 00616 00617 // Make Eye initial matrix 00618 pfMatrix delta_rot; 00619 Shared->EyeMat.makeIdent(); 00620 // rotate along Z 90 degrees 00621 delta_rot.makeRot(-90.0, 0.0, 0.0, 1.0); 00622 Shared->EyeMat.postMult(delta_rot); 00623 // Translate to designed position 00624 delta_rot.makeTrans(10, 10, 0); 00625 Shared->EyeMat.postMult(delta_rot); 00626 00627 // Get courrent mouse position 00628 GetCurrentMousePos(Shared->MouseXOld, Shared->MouseYOld); 00629 } 00630 00631 00632 00633 void RenderPerformer::Terminate(){ 00634 // Terminate parallel processes and exit 00635 pfuExitInput(); 00636 pfExit(); 00637 } 00638 00639 00640 00641 void RenderPerformer::HandleKeyInput(){ 00642 int inkey; 00643 00644 pfuGetEvents(Shared->InputEvents); 00645 00646 if (Shared->InputEvents->numKeys > 0) { 00647 inkey = Shared->InputEvents->keyQ[0]; 00648 pfuResetEventStream(Shared->InputEvents); 00649 //cout << inkey << endl; 00650 00651 switch(inkey){ 00652 case 'b' : 00653 BoundingBoxOn = !BoundingBoxOn; // Toggle 00654 break; 00655 case 'c' : 00656 Shared->ControlPanelOn = !Shared->ControlPanelOn; // Toggle 00657 break; 00658 case 'v' : 00659 AttachedCameraOn = !AttachedCameraOn; // Toggle 00660 break; 00661 } 00662 } 00663 } 00664 00665 00666 00667 void RenderPerformer::GetControlPadSize(double &padwidth_l, 00668 double &padwidth_r, 00669 double &padheight_b, 00670 double &padheight_top){ 00671 00672 padwidth_l = (CONTROLPANEL_CENTER_X + 00673 Shared->PadX - CONTROLPAD_WIDTH)/tan(22.5*PI/180.0); 00674 padwidth_r = (CONTROLPANEL_CENTER_X + 00675 Shared->PadX + CONTROLPAD_WIDTH)/tan(22.5*PI/180.0); 00676 padheight_b = (CONTROLPANEL_CENTER_Z - 00677 CONTROLPAD_HEIGHT)/tan(22.5*PI/180.0); 00678 padheight_top = (CONTROLPANEL_CENTER_Z + 00679 CONTROLPAD_HEIGHT)/tan(22.5*PI/180.0); 00680 00681 } 00682 00683 00684 00685 void RenderPerformer::HandleMouseEvents() { 00686 double mousex_new, mousey_new, theta; 00687 pfMatrix transform, dtransform; 00688 double padw_l, padw_r, padh_b, padh_top; 00689 vector vp,vd; 00690 double vo; 00691 int j,k; 00692 vector c,conf(6); 00693 00694 // Get control pad size 00695 GetControlPadSize(padw_l, padw_r, padh_b, padh_top); 00696 00697 // Get current mouse position 00698 GetCurrentMousePos(mousex_new, mousey_new); 00699 00700 // If mouse is inside the pad and ControlPanelOn is true 00701 // deal with control pannel 00702 if( Shared->MouseXOld >= padw_l 00703 && Shared->MouseXOld <= padw_r 00704 && Shared->MouseYOld >= padh_b 00705 && Shared->MouseYOld <= padh_top 00706 && Shared->HoldLeftMouse 00707 && Shared->ControlPanelOn ){ 00708 Shared->FocusOnControlPad = true; 00709 } 00710 if(!Shared->HoldLeftMouse) 00711 Shared->FocusOnControlPad = false;; 00712 00713 if(Shared->FocusOnControlPad){ 00714 Shared->PadX = Shared->PadX + 0.3*(mousex_new - Shared->MouseXOld); 00715 if(Shared->PadX >= CONTROLPANEL_BAR_WIDTH) 00716 Shared->PadX = CONTROLPANEL_BAR_WIDTH; 00717 else 00718 if(Shared->PadX <= -CONTROLPANEL_BAR_WIDTH) 00719 Shared->PadX = -CONTROLPANEL_BAR_WIDTH; 00720 00721 // Range of speeds: 2^-ANIMATING_SPEED_FACTOR to 2^ANIMATING_SPEED_FACTOR 00722 AnimationTimeScale = pow(2.0,ANIMATING_SPEED_FACTOR * 00723 Shared->PadX/CONTROLPANEL_BAR_WIDTH); 00724 00725 Shared->ControlPad->setTrans(Shared->PadX, 0.0, 0.0); 00726 } 00727 00728 // else set global orientation 00729 if( !Shared->FocusOnControlPad && Shared->HoldRightMouse ) { 00730 if(fabs(Shared->MouseXOld - mousex_new) > 0.00001) 00731 Shared->RotY += 40*(mousex_new - Shared->MouseXOld); 00732 if(fabs(Shared->MouseYOld - mousey_new) > 0.00001) { 00733 Shared->TranY += 60*(mousey_new - Shared->MouseYOld); 00734 } 00735 } 00736 00737 if( !Shared->FocusOnControlPad && Shared->HoldLeftMouse ){ 00738 if(fabs(Shared->MouseXOld - mousex_new) > 0.00001) 00739 Shared->RotZ -= 40*(Shared->MouseXOld - mousex_new); 00740 if(fabs(Shared->MouseYOld - mousey_new) > 0.00001) 00741 Shared->RotX += 40*(Shared->MouseYOld - mousey_new); 00742 } 00743 00744 if( !Shared->FocusOnControlPad && Shared->HoldMiddleMouse ){ 00745 if(fabs(Shared->MouseXOld - mousex_new) > 0.00001) 00746 Shared->TranX += 60*(mousex_new - Shared->MouseXOld); 00747 if(fabs(Shared->MouseYOld - mousey_new) > 0.00001) 00748 Shared->TranZ += 60*(mousey_new - Shared->MouseYOld); 00749 } 00750 00751 00752 // Compute the global transformation matrix 00753 00754 // Start with identity 00755 transform.makeIdent(); 00756 00757 // Determine where to take the viewing transformations from 00758 if (AttachedCameraOn) { 00759 k = AnimationFrameIndex; 00760 c = FrameList.inf(FrameList.get_item(k)); 00761 for (j = 0; j < 6; j++) 00762 conf[j] = c[ 6 * S->AttachedCameraBody + j]; 00763 00764 vp = S->AttachedCameraPosition; 00765 vd = S->AttachedCameraDirection; 00766 vo = 0.0; // THIS NEEDS TO BE COMPUTED FROM AttachedCameraZenith 00767 00768 // Transform the camera according to the attached body 00769 dtransform.makeTrans(-conf[0], -conf[1], -conf[2]); 00770 transform.postMult(dtransform); 00771 00772 dtransform.makeRot(-conf[5]*180.0/PI, 0.0, 0.0, 1.0); 00773 transform.postMult(dtransform); 00774 00775 dtransform.makeRot(-conf[4]*180.0/PI, 0.0, 1.0, 0.0); 00776 transform.postMult(dtransform); 00777 00778 dtransform.makeRot(-conf[3]*180.0/PI, 1.0, 0.0, 0.0); 00779 transform.postMult(dtransform); 00780 } 00781 else { 00782 vp = S->GlobalCameraPosition; 00783 vd = S->GlobalCameraDirection; 00784 vo = 0.0; // THIS NEEDS TO BE COMPUTED FROM GlobalCameraZenith 00785 } 00786 00787 // Set up the viewing direction 00788 dtransform.makeTrans(-vp[0], -vp[1], -vp[2]); 00789 transform.postMult(dtransform); 00790 00791 dtransform.makeRot(-vo*180.0/PI, vd[0], vd[1], vd[2]); 00792 transform.postMult(dtransform); 00793 00794 theta = -asin(sqrt(sqr(vd[0]) + sqr(vd[2]))); 00795 dtransform.makeRot(theta*180.0/PI, vd[2], 0.0, -vd[0]); 00796 transform.postMult(dtransform); 00797 00798 // Handle the translation generated by the user 00799 dtransform.makeTrans(Shared->TranX, Shared->TranY, Shared->TranZ); 00800 transform.postMult(dtransform); 00801 00802 // Undo the forced channel viewpoint 00803 dtransform.makeTrans(0.0, -300.0, 0.0); 00804 transform.postMult(dtransform); 00805 00806 // Handle the rotation generated by the user 00807 dtransform.makeRot(Shared->RotZ, 0.0, 0.0, 1.0); 00808 transform.postMult(dtransform); 00809 dtransform.makeRot(Shared->RotY, 0.0, 1.0, 0.0); 00810 transform.postMult(dtransform); 00811 dtransform.makeRot(Shared->RotX, 1.0, 0.0, 0.0); 00812 transform.postMult(dtransform); 00813 00814 // Set the transformation 00815 Shared->WorldDCS->setMat(transform); 00816 00817 //Update old mouse position 00818 Shared->MouseXOld = mousex_new; 00819 Shared->MouseYOld = mousey_new; 00820 } 00821 00822 00823 00824 void RenderPerformer::HandleEvents() { 00825 // Handle events from render control window 00826 Render::HandleEvents(); 00827 00828 // Go to sleep until next frame time. 00829 pfSync(); 00830 00831 //Collect key input events 00832 HandleKeyInput(); 00833 00834 // handle Mouse events 00835 HandleMouseEvents(); 00836 00837 // setup body animating 00838 if (AnimationActive) { 00839 ShowCurrentAnimationFrame(); 00840 } 00841 00842 // Always display world 00843 Shared->WorkEnv->setVal(Shared->WorkEnv->searchChild(Shared->Env)); 00844 Shared->ShowCase->setVal(Shared->ShowCase->searchChild(Shared->WorldDCS)); 00845 00846 // Show Bounding Box 00847 if (BoundingBoxOn){ 00848 Shared->WorkEnv->setVal(PFSWITCH_ON); 00849 } 00850 00851 // Show Control Panel 00852 if(Shared->ControlPanelOn){ 00853 Shared->ShowCase->setVal(PFSWITCH_ON); 00854 } 00855 00856 // Initiate cull/draw for this frame. 00857 pfFrame(); 00858 } 00859 00860 00861 00862 // Draw process callback 00863 void RenderPerformer::DrawChannel(pfChannel *chan, void *) { 00864 chan->clear(); 00865 pfDraw(); 00866 } 00867 00868 00869 00870 #include <LEDA/UNDEFINE_NAMES.h> 00871 00872 00873 00874 00875 00876 00877 00878 00879 00880