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

render.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 "render.h"
00023 #include "defs.h"
00024 
00025 // Include the VCR buttons
00026 #include "pixmaps/ff.xpm"
00027 #include "pixmaps/pause.xpm"
00028 #include "pixmaps/play.xpm"
00029 #include "pixmaps/rw.xpm"
00030 #include "pixmaps/stop.xpm"
00031 #include "pixmaps/prev.xpm"
00032 #include "pixmaps/next.xpm"
00033 
00034 // Include the msl icon
00035 #include "pixmaps/msl.xpm"
00036 
00037 
00038 #include <LEDA/REDEFINE_NAMES.h>
00039 
00041 //
00042 // Render Class
00043 //
00045 
00046 Render::Render() {
00047   Render("");
00048 }
00049 
00050 
00051 Render::Render(string filepath)
00052 {
00053   FilePath = filepath;
00054 }
00055 
00056 
00057 Render::Render(Scene *s, string filepath)
00058 {
00059   SetScene(s);
00060 
00061   FilePath = filepath;
00062   ControlFreak = false;
00063 }
00064 
00065 
00066 // This sets up the file names for the environment and movable bodies
00067 void Render::Init()
00068 {
00069   int i;
00070 
00071   Reset();
00072 
00073   FrameTime = 0.1; // This is default; each renderer should determine this
00074   AnimationStartPause = 0.0; // should be in seconds
00075   AnimationEndPause = 0.0;
00076   RenderCtlWindowOn = false;
00077 
00078   // Colors for objects (add more if you like, but increase RENDERCOLORS)
00079   //RGBRed[0] = .467; RGBGreen[0] = 0.53; RGBBlue[0] = 0.6; // Light Slate Gray
00080   RGBRed[0] = 1.0; RGBGreen[0] = 0.0; RGBBlue[0] = 1.0; // Magenta
00081   RGBRed[1] = 0.8; RGBGreen[1] = 0.0; RGBBlue[1] = 0.0; // Red
00082   RGBRed[2] = 0.0; RGBGreen[2] = 0.7; RGBBlue[2] = 0.0; // Green
00083   RGBRed[3] = 0.7; RGBGreen[3] = 0.7; RGBBlue[3] = 0.0; // Yellow
00084   RGBRed[4] = 0.0; RGBGreen[4] = 0.7; RGBBlue[4] = 0.7; // Lightblue
00085   RGBRed[5] = 1.0; RGBGreen[5] = 0.0; RGBBlue[5] = 1.0; // Magenta
00086   RGBRed[6] = 0.0; RGBGreen[6] = 0.0; RGBBlue[6] = 0.7; // Blue
00087   RGBRed[7] = 1.0; RGBGreen[7] = 0.65; RGBBlue[7] = 0.0; // Orange
00088   RGBRed[8] = 1.0; RGBGreen[8] = 0.078; RGBBlue[8] = 0.576; // DeepPink
00089   RGBRed[9] = 1.0; RGBGreen[9] = 0.51; RGBBlue[9] = 0.278; // Sienna1
00090 
00091   // Load environment
00092   if (is_file(FilePath+"EnvList")) {
00093     file_istream fin1(FilePath + "EnvList");
00094     fin1 >> EnvList;
00095   }
00096   else {
00097     EnvList.clear(); // Make sure empty
00098     if (is_file(FilePath+"Obst"))
00099       EnvList.push("Obst"); // Use the robot from Geom
00100   }
00101   
00102   // Load bodies
00103   if (is_file(FilePath+"BodyList")) {
00104     file_istream fin(FilePath + "BodyList");
00105     fin >> BodyList;
00106   }
00107   else {
00108     BodyList.clear(); // Make sure empty
00109     if (is_file(FilePath+"Robot")) {
00110       BodyList.push("Robot"); // Use the robot from Geom
00111     }
00112     else { // Multiple robots 
00113       for (i = 0; i < S->NumBodies; i++) {
00114         if (is_file(string("%sRobot%d",FilePath,i))) {
00115           BodyList.push_back(string("Robot%d",i)); // Use the robot from World
00116         }
00117       }
00118     }
00119   }
00120 }
00121 
00122 
00123 
00124 void Render::SetScene(Scene *s) 
00125 {
00126   S = s; // S is the Scene for Render
00127 }
00128 
00129 
00130 void Render::MakeAnimationFrames(const list<vector> &xlist, double deltat) 
00131 {
00132   double t;
00133   int i;
00134 
00135   StateList = xlist;
00136   TimeList.clear();
00137   
00138   t = 0.0;
00139   for (i = 0; i < xlist.length(); i++) {
00140     TimeList.push_back(t);
00141     t += deltat;
00142   }
00143   
00144   SetFrameList();
00145 }
00146 
00147 
00148 void Render::MakeAnimationFrames(const list<vector> &xlist,
00149                                  const list<double> &timelist) 
00150 {
00151   StateList = xlist;
00152   TimeList = timelist;
00153   SetFrameList();
00154 }
00155 
00156 
00157 
00158 void Render::SetFrameList()
00159 {
00160   double ltime; // Lower time
00161   double utime; // Upper time
00162   double ctime; // Current time
00163   double lasttime;
00164   double lambda;
00165   vector sc; // scene configuration
00166   vector lx,ux; // lower and upper states
00167   int i;
00168   list_item li,tli,stli,tstli;
00169 
00170   //cout << "Running SetFrameList\n";
00171   //cout << "StateList: " << StateList << "\n";
00172   //cout << "TimeList: " << TimeList << "\n";
00173 
00174   FrameList.clear();
00175   NumFrames = 0;
00176 
00177   if (TimeList.length() < 2) {
00178     if (TimeList.length() == 1) {
00179       FrameList.push(S->StateToSceneConfiguration(StateList.head()));
00180       NumFrames = 1;
00181     }
00182     return;
00183   }
00184 
00185   // Make the starting pause
00186   for (i = 0; i < (int) (AnimationStartPause/FrameTime); i++) {
00187     FrameList.push_back(S->StateToSceneConfiguration(StateList.head()));
00188     NumFrames++;
00189   }
00190 
00191   li = TimeList.succ(TimeList.first());
00192   stli = StateList.succ(StateList.first());
00193   utime = TimeList.inf(li);  // Time index of second element
00194   ux = StateList.inf(stli);
00195   ltime = TimeList.head();
00196   lx = StateList.head();
00197   ctime = ltime;
00198   lasttime = TimeList.tail();
00199   while (ctime <= lasttime) {
00200     while ((utime < ctime)&&  // Make sure the ctime is within upper and lower
00201            (TimeList.succ(li))) {
00202       li = TimeList.succ(li);
00203       stli = StateList.succ(stli);
00204       utime = TimeList.inf(li);
00205       ux = StateList.inf(stli);
00206     }
00207     tli = TimeList.pred(li);
00208     ltime = TimeList.inf(tli);
00209     tstli = StateList.pred(stli);
00210     lx = StateList.inf(tstli);
00211     while (ltime > ctime) { // This can happen sometimes (I think)!
00212       tli = TimeList.pred(tli);
00213       tstli = StateList.pred(tstli);
00214       ltime = TimeList.inf(tli);
00215       lx = StateList.inf(tstli);
00216     }
00217 
00218     lambda = (ctime - ltime)/(utime - ltime);
00219     //cout << "lambda: " << lambda << "\n";
00220 
00221     // Interoplate based on states lx and ux
00222     sc = S->InterpolatedSceneConfiguration(lx,ux,lambda);
00223     FrameList.push_back(sc);
00224     NumFrames++;
00225     ctime += FrameTime;
00226   }
00227   
00228   // Add in the last frame, if necessary
00229   if (FrameList.tail() != (S->StateToSceneConfiguration(StateList.tail())))
00230     FrameList.push_back(S->StateToSceneConfiguration(StateList.tail()));
00231 
00232   // Make the ending pause
00233   for (i = 0; i < (int) (AnimationEndPause/FrameTime); i++) {
00234     FrameList.push_back(S->StateToSceneConfiguration(StateList.tail())); 
00235     NumFrames++;
00236   }
00237 
00238   //vector x;
00239   //cout << "StateList:\n";
00240   //forall(x,StateList)
00241   //  cout << x << "\n";
00242   //cout << "TimeList: " << TimeList << "\n";
00243   //cout << "\n\nFrameList:\n";
00244   //forall(x,FrameList)
00245   //  cout << x << "\n";
00246   //cout << "NumFrames: " << NumFrames << "\n";
00247 }
00248 
00249 
00250 
00251 void Render::SetCurrentAnimationFrame() {
00252   vector c(S->SceneConfigurationDim);
00253   int num,skip;
00254 
00255   // How long has the frame been stuck?
00256   FrameStuckTime = used_time() - LastFrameTime;
00257 
00258   skip = (int) (AnimationTimeScale * FrameStuckTime / FrameTime);
00259 
00260   if (skip > 0) {
00261     AnimationFrameIndex += skip;
00262     used_time(LastFrameTime);
00263   }
00264     
00265   num = FrameList.length();
00266   if (AnimationFrameIndex > num - 1) {
00267     AnimationFrameIndex = 0;
00268     used_time(LastFrameTime);
00269   }
00270 
00271   if (AnimationFrameIndex < 0) {
00272     AnimationFrameIndex = 0;
00273     used_time(LastFrameTime);
00274   }
00275 
00276   if (num > 0) {
00277     c = FrameList.contents(FrameList.get_item(AnimationFrameIndex));
00278   }
00279 
00280   CurrentAnimationFrame = c;
00281 }
00282 
00283 
00284 
00285 void Render::ButtonHandle(int b) 
00286 {
00287   //cout << "Button " << b << "\n";
00288 
00289   switch (b) {
00290 
00291   case 70: // Play
00292     if (!AnimationActive) {
00293       used_time(LastFrameTime);
00294       AnimationActive = true;
00295     }
00296     break;
00297   case 71: // Stop
00298       AnimationActive = false;
00299       AnimationFrameIndex = 0;
00300       LastFrameTime = 0.0;;
00301       used_time(LastFrameTime);
00302     break;
00303   case 72: // Pause
00304     if (AnimationActive) {
00305       AnimationActive = false;
00306     }
00307     else {
00308       AnimationActive = true;
00309       used_time(LastFrameTime);
00310     }
00311     cout << "Frame: " << AnimationFrameIndex << "   Time stamp: " 
00312          << AnimationFrameIndex*FrameTime << "s\n";
00313     break;
00314   case 73: // Deccelerate animation
00315     AnimationTimeScale /= 1.41421356237; // Two presses doubles the speed
00316     break;
00317   case 74: // Accelerate animation
00318     AnimationTimeScale *= 1.41421356237; // Two presses doubles the speed
00319     break;
00320   case 75:
00321     Reset();
00322     break;
00323   case 76: // Prev frame
00324     AnimationActive = false;
00325     if (AnimationFrameIndex > 0)
00326       AnimationFrameIndex--;
00327     else
00328       AnimationFrameIndex = FrameList.length() - 1;
00329     CurrentAnimationFrame = FrameList.contents(FrameList.get_item(AnimationFrameIndex));
00330     ShowCurrentAnimationFrame();
00331     cout << "Frame: " << AnimationFrameIndex << "   Time stamp: " 
00332          << AnimationFrameIndex*FrameTime << "s\n";
00333    break;
00334   case 77: // Next frame
00335     AnimationActive = false;
00336     if (AnimationFrameIndex < FrameList.length() - 1)
00337       AnimationFrameIndex++;
00338     else
00339       AnimationFrameIndex = 0;
00340     CurrentAnimationFrame = FrameList.contents(FrameList.get_item(AnimationFrameIndex));
00341     ShowCurrentAnimationFrame();
00342     cout << "Frame: " << AnimationFrameIndex << "   Time stamp: " 
00343          << AnimationFrameIndex*FrameTime << "s\n";
00344     break;
00345   default: cout << "Function not implemented\n";
00346     break;
00347   }
00348 }
00349 
00350 
00351 void Render::MainLoop(Gui *g) {
00352 
00353   g->Finished = false;
00354 
00355   while (!g->Finished) {
00356     g->HandleEvents();
00357     HandleEvents();
00358   }
00359 
00360 }
00361 
00362 
00363 
00364 void Render::Reset() {
00365   AnimationActive = false;
00366   AnimationFrameIndex = 0;
00367   if (FrameList.length() > 0)
00368     CurrentAnimationFrame = FrameList.contents(FrameList.get_item(0));
00369   else
00370     CurrentAnimationFrame = vector(S->SceneConfigurationDim);
00371   AnimationTimeScale = 1.0;
00372   LastFrameTime = 0.0;
00373   used_time(LastFrameTime);
00374   AttachedCameraOn = false;
00375   BoundingBoxOn = false;
00376   MultipleViewsOn = false;
00377   ShowPathOn = false;
00378   AmbientLight = 0.2;
00379 }
00380 
00381 
00382 
00383 void Render::ToggleRenderCtlWindow() 
00384 {
00385   char *play,*stop,*pause,*rw,*ff,*prev,*next;
00386   RenderCtlWindowOn = !RenderCtlWindowOn;
00387   if (RenderCtlWindowOn) {
00388     RenderCtlWindow = new window(200,155,"MSL: Render Control Window");
00389     RenderCtlWindow->set_icon_pixrect(RenderCtlWindow->create_pixrect(msl_xpm));
00390     RenderCtlWindow->double_item("AnimationTimeScale",AnimationTimeScale);
00391     RenderCtlWindow->double_item("AmbientLight",AmbientLight);
00392     RenderCtlWindow->bool_item("BoundingBox",BoundingBoxOn);
00393     RenderCtlWindow->bool_item("MultipleViews",MultipleViewsOn);
00394     RenderCtlWindow->bool_item("AttachedCamera",AttachedCameraOn);
00395     RenderCtlWindow->bool_item("ShowPath",ShowPathOn);
00396     
00397     // Make the animation buttons
00398     play = RenderCtlWindow->create_pixrect(play_xpm);
00399     stop = RenderCtlWindow->create_pixrect(stop_xpm);
00400     pause = RenderCtlWindow->create_pixrect(pause_xpm);
00401     rw = RenderCtlWindow->create_pixrect(rw_xpm);
00402     ff = RenderCtlWindow->create_pixrect(ff_xpm);
00403     prev = RenderCtlWindow->create_pixrect(prev_xpm);
00404     next = RenderCtlWindow->create_pixrect(next_xpm);
00405     RenderCtlWindow->buttons_per_line(7);
00406     RenderCtlWindow->button(stop,stop,"",71);
00407     RenderCtlWindow->button(prev,prev,"",76);
00408     RenderCtlWindow->button(pause,pause,"",72);
00409     RenderCtlWindow->button(next,next,"",77);
00410     RenderCtlWindow->button(rw,rw,"",73);
00411     RenderCtlWindow->button(play,play,"",70);
00412     RenderCtlWindow->button(ff,ff,"",74);
00413 
00414     RenderCtlWindow->button("Reset",75);
00415 
00416     RenderCtlWindow->display();
00417   }
00418   else {
00419     RenderCtlWindow->close();
00420   }
00421 }
00422 
00423 
00424 
00425 #include <LEDA/UNDEFINE_NAMES.h>
00426 
00427 
00428 
00429 
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.