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