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