cuikplay.c
Go to the documentation of this file.
1 #include "cuikplay.h"
2 
3 #include "world.h"
4 #include "box_list.h"
5 #include "error.h"
6 #include "samples.h"
7 
8 #include "cuikplay_interface.h"
9 #include "cuikplay_support.h"
10 
11 #include <gtk/gtk.h>
12 
13 #include <string.h>
14 #include <unistd.h>
15 #include <sys/time.h>
16 
17 
61 #define RECORD 0
62 
63 
90 int main(int argc, char **arg)
91 {
92 
93  if (argc>2)
94  {
95  Tworld world;
96  Tparameters parameters;
97  Tfilename fsols;
98  Tfilename fparam;
99  Tfilename fworld;
100 
101  Tlist sol_box_list;
102  Titerator it;
103  boolean dynamic;
104  unsigned int ns,nvs;
105  double **path;
106  unsigned int da;
107  double **actions;
108  double *times; /* Time increments */
109  double *atimes; /* Accumulated time */
110  Tbox boxPoint,*currentBox;
111  unsigned int *frameID;
112 
113  Tplot3d pt;
114 
115  TCuikPlayControl status;
116  double frameDelay,axesLength,t,delay;
117 
118  GtkWidget *window,*slider;
119  #if (RECORD)
120  char *snapshotFile;
121  unsigned int l;
122 
123  fprintf(stderr,">> RECORD MODE ON\n");
124  #endif
125 
126  CreateFileName(NULL,arg[1],NULL,PARAM_EXT,&fparam);
127  InitParametersFromFile(GetFileFullName(&fparam),&parameters);
128 
129  CreateFileName(NULL,arg[1],NULL,WORLD_EXT,&fworld);
130  InitWorldFromFile(&parameters,TRUE,TRUE,arg[1],&world);
131  #if (RECORD)
132  l=strlen(GetFileName(&fworld));
133  NEW(snapshotFile,l+100,char);
134  #endif
135 
136  CreateFileName(NULL,arg[2],NULL,SOL_EXT,&fsols);
137  if (LoadTrajectory(&fsols,&nvs,&ns,&path,&da,&actions,&times))
138  {
139  unsigned int i;
140 
141  if (argc>4)
142  frameDelay=atof(arg[4]);
143  else
144  frameDelay=0.05;
145 
146  SparsifyTrajectory(frameDelay,&frameID,&ns,path,actions,times);
147 
148  dynamic=TRUE;
149  currentBox=&boxPoint;
150  NEW(atimes,ns,double);
151  atimes[0]=0.0;
152  for(i=1;i<ns;i++)
153  atimes[i]=atimes[i-1]+times[i];
154  }
155  else
156  {
157  DeleteFileName(&fsols);
158  CreateFileName(NULL,arg[2],NULL,SOL_EXT,&fsols);
159  if (!ReadListOfBoxes(GetFileFullName(&fsols),&sol_box_list))
160  Error("Solution file can not be opened");
161 
162  if (argc>4)
163  frameDelay=atof(arg[4]);
164  else
165  frameDelay=DEFAULT_TIME_DELAY;
166 
167  dynamic=FALSE;
168  }
169 
170  if (argc>3)
171  axesLength=atof(arg[3]);
172  else
173  axesLength=0;
174 
175  InitPlot3d(NULL,FALSE,argc,arg,&pt);
176 
177  Start3dBlock(&pt);
178  PlotWorld(&parameters,&pt,axesLength,&world);
179 
180  if (dynamic)
181  InitBoxFromPoint(nvs,path[0],currentBox);
182  else
183  {
184  InitIterator(&it,&sol_box_list);
185  First(&it);
186  currentBox=(Tbox *)GetCurrent(&it);
187  }
188 
189  MoveWorld(&parameters,&pt,currentBox,&world);
190 
191  if (dynamic)
192  DeleteBox(currentBox);
193  Close3dBlock(&pt);
194  LookPlot3d(&pt);
195 
196  if (dynamic)
197  status.maxFrame=ns;
198  else
199  status.maxFrame=ListSize(&sol_box_list);
200  if (status.maxFrame==0)
201  Error("Empty list of solutions");
202 
203  status.end=FALSE;
204  status.mode=PAUSED;
205  status.currentFrame=0;
206  status.nextFrame=0;
207  if (dynamic)
208  status.delay=times;
209  else
210  status.delay=NULL;
211  status.defaultDelay=frameDelay;
212 
213  gtk_disable_setlocale();
214  gtk_init(&argc,&arg);
215 
216  window=create_window_cuikplay((gpointer)(&status),status.maxFrame);
217  slider=lookup_widget(window,"hscale1");
218  gtk_widget_show(window);
219 
220  #if (_DEBUG>1)
221  fprintf(stderr,">> Max frame %u \n",status.maxFrame);
222  #endif
223  while(!status.end)
224  {
225  if (status.mode==PLAYING)
226  {
227  /* when we reach the end -> pause */
228  if (status.currentFrame<(status.maxFrame-1))
229  {
230  /* Not yet at the end: wait until it is time to display next configuration */
231  GET_TIME(t);
232 
233  /* if it is time to move to the next frame */
234  if (t>=status.nextTime)
235  {
236  /* Move the slider to currentFrame+1 and this will trigger and
237  even that actually sets nextFrame to currentFrame+1 and
238  actually displays the frame */
239  double v;
240 
241  #if (_DEBUG>1)
242  fprintf(stderr,">> Moving to next frame %f vs %f\n",t,status.nextTime);
243  #endif
244 
245  v=(double)(status.currentFrame+1);
246 
247  /* Change the slider */
248  #if (_DEBUG>1)
249  fprintf(stderr,">> Moving Slider from %g to %g \n",
250  gtk_range_get_value(GTK_RANGE(slider)),v);
251  #endif
252 
253  gtk_range_set_value(GTK_RANGE(slider),v);
254  }
255  }
256  else
257  status.mode=PAUSED; /*PAUSE*/
258  }
259 
260  /* check for gtk events */
261  gtk_main_iteration_do(FALSE);
262 
263  /* if we have to display a new configuration (even it not playing) */
264  if (status.currentFrame!=status.nextFrame)
265  {
266  if (status.nextFrame<status.maxFrame)
267  {
268  /* not yet at the end */
269  GET_TIME(t);
270 
271  /* Display the solution */
272  if (dynamic)
273  {
274  fprintf(stderr,">> Displaying: %u (t:%f)\n",frameID[status.nextFrame+1],atimes[status.nextFrame]);
275  InitBoxFromPoint(nvs,path[status.nextFrame],currentBox);
276  }
277  else
278  {
279  fprintf(stderr,">> Displaying: %u\n",status.nextFrame+1);
280  MoveTo(status.nextFrame,&it);
281  currentBox=(Tbox *)GetCurrent(&it);
282  }
283  MoveWorld(&parameters,&pt,currentBox,&world);
284 
285  if (dynamic)
286  DeleteBox(currentBox);
287 
288  /* if necessary take a snapshot */
289  #if (RECORD)
290  sprintf(snapshotFile,"/tmp/%s_%04u",GetFileName(&fworld),
291  status.nextFrame+1);
292  Take3dSnapshot(snapshotFile,&pt);
293  #endif
294 
295  /* if playing and still not at the end of the sequence */
296  if ((status.mode==PLAYING)&&(status.nextFrame<status.maxFrame-1))
297  {
298  /* compute the time to display next frame */
299  if (status.delay!=NULL)
300  delay=status.delay[status.nextFrame+1];
301  else
302  delay=status.defaultDelay;
303  GET_TIME(t);
304  /* this frame shouls have been displayed at 'status.nextTime'
305  but it has been acually shown at time 't'. This difference
306  is typically constant and due to qt and geomview delays.
307  We can somehow take into account such delay and schedule
308  next frame accordingly (assuming that this uncontrolled
309  delay for next frame will be the same as the ones for
310  current frame) */
311  delay-=(t-status.nextTime);
312  if (delay<0.001) delay=0.001;
313  status.nextTime=t+delay;
314  #if (_DEBUG>1)
315  fprintf(stderr,">> Next frame (%u) has to be displayed at %f (%f+%f)\n",status.nextFrame+1,status.nextTime,t,delay);
316  #endif
317  }
318 
319  /* We already displayed the nextFrame. It now becomes the current frame */
320  status.currentFrame=status.nextFrame;
321  }
322  else
323  {
324  /* if we reached the end -> pause */
325  status.currentFrame=status.nextFrame=status.maxFrame;
326  status.mode=PAUSED; /*PAUSE*/
327  }
328  }
329  }
330 
331  ClosePlot3d(TRUE,&pt);
332 
333  if (dynamic)
334  {
335  DeleteTrajectory(ns,path,actions,times);
336  free(atimes);
337  }
338  else
339  DeleteListOfBoxes(&sol_box_list);
340 
341 
342  DeleteFileName(&fsols);
343  DeleteFileName(&fworld);
344  DeleteFileName(&fparam);
345  #if (RECORD)
346  free(snapshotFile);
347  #endif
348 
349  DeleteWorld(&world);
350  DeleteParameters(&parameters);
351  }
352  else
353  {
354  fprintf(stdout," Wrong number of parameters.\n");
355  fprintf(stdout," Use:\n");
356  fprintf(stdout," cuikplay <world>.world <solutions>.sol [<axes> <delay>]\n");
357  fprintf(stdout," Where:\n");
358  fprintf(stdout," <world>: File describing the problem\n");
359  fprintf(stdout," <solutions>: Is the path of solutions to be animated\n");
360  fprintf(stdout," <axes>: Optional. Length for the axes for each link.\n");
361  fprintf(stdout," The default value is 0, i.e., not to display them.\n");
362  fprintf(stdout," <delay>: Optional. Delay (in seconds) between frames.\n");
363  fprintf(stdout," The default delay is 0.1 seconds.\n");
364  fprintf(stdout," File extensions are not required\n");
365  }
366 
367  return(EXIT_SUCCESS);
368 }