Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

renderpf.C

Go to the documentation of this file.
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 
Motion Strategy Library


Web page maintained by Steve LaValle
Partial support provided by NSF CAREER Award IRI-970228 (LaValle), Honda Research, and Iowa State University.
Contributors: Anna Atramentov, Peng Cheng, James Kuffner, Steve LaValle, and Libo Yang.