i/movie

Home Manual Packages Global Index Keywords Quick Reference |
    /*
       MOVIE.I
       Support functions for making animated sequences.

       $Id$
     */
    /*    Copyright (c) 1995.  The Regents of the University of California.
                        All rights reserved.  */

    func movie (draw_frame, time_limit, min_interframe, bracket_time)

    /* DOCUMENT movie, draw_frame

             or movie, draw_frame, time_limit

             or movie, draw_frame, time_limit, min_interframe

         runs a movie based on the given DRAW_FRAME function.  The movie
         stops after a total elapsed time of TIME_LIMIT seconds, which
         defaults to 60 (one minute), or when the DRAW_FRAME function
         returns zero.

    func draw_frame (i)
         {
           // Input argument i is the frame number.

           // draw_frame should return non-zero if there are more
           // frames in this movie.  A zero return will stop the
           // movie.

           // draw_frame must NOT include any fma command if the

           // making_movie variable is set (movie sets this variable

           // before calling draw_frame)
         }

         If MIN_INTERFRAME is specified, a pauses will be added as
         necessary to slow down the movie.  MIN_INTERFRAME is a time
         in seconds (default 0).

         The keyword bracket_time= (again a time in seconds) can be
         used to adjust the duration of the pauses after the first

         and last frames.  It may also be a two element array [beg, end].

         If the pause at the end is greater than five seconds, you will
         be prompted to explain that hitting <RETURN> will abort the final
         pause.

         If every frame of your movie has the same limits, use the

         limits command to fix the limits before you call movie.

       BUG:  If you hit <RETURN> to start a movie early, it will not

             pause at the end of the movie at all.  You probably should
    	 not use long initial pauses.

       SEE ALSO: movie_stats
     */
    {

      if (is_void(time_limit)) time_limit= 60.0;

      if (is_void(min_interframe)) min_interframe= 0.0;

      if (is_void(bracket_time)) bracket_time= [2.,2.];

      else if (numberof(bracket_time)<2) bracket_time= array(bracket_time,2);

      elapsed= this_frame= array(0.0, 3);

      window, wait=1;  /* make sure window is ready to draw */

      fma;             /* clear out any existing picture */
      animate, 1;
      making_movie= 1;

      i= 0;
      timer, elapsed;
      elapsed0= elapsed;
      more= draw_frame(++i);
      fma;
      timer, elapsed, this_frame;
      wait= bracket_time(1)-this_frame(3);
      waited= waited0= 0.0;
      if (wait>0) {
        if (wait>5)
          write,

            format="Movie starts in %.0f secs, or when you hit <RETURN>\n", wait;
        pause, long(1000.*wait);
        waited0+= wait;
      } else {
        wait= min_interframe-this_frame(3);
        if (wait>0) {
          pause, long(1000.*wait);
          waited+= wait;
        }
      }

      while (more) {
        this_frame()= 0.0;
        more= draw_frame(++i);
        fma;
        timer, elapsed, this_frame;
        if (!more || (elapsed(3)-elapsed0(3))>time_limit) break;
        wait= min_interframe-this_frame(3);
        if (wait>0) {
          pause, long(1000.*wait);
          waited+= wait;
        }
      }

      wait= bracket_time(2)-this_frame(3);
      if (wait>0) {
        if (wait>5) {
          write,

            format="Holding last frame for %.0f secs, or hit <RETURN>\n", wait;
          pause, 100;  /* huh? */
        }
        pause, long(1000.*wait);
        waited0+= wait;
      }
      timer, elapsed;

      animate, 0;

      extern movie_timing;

      movie_timing= grow(elapsed-elapsed0, i, waited, waited0);
    }

    func movie_stats (timing)
    /* DOCUMENT movie_stats

             or movie_stats, timing

         prints statistics from the last movie command, or from the
         command which produced TIMING.  TIMING is the contents of the

         movie_timing external variable after the movie command completes.

       SEE ALSO: movie
     */
    {

      if (is_void(timing)) timing= movie_timing;
      cpu= timing(1)+timing(2);
      wall= timing(3);
      nframes= long(timing(4));
      waited= timing(5)+timing(6);
      wait= timing(5);

      write, format="  Wall(sec)  Wait(sec)  CPU(sec)%s\n", "";

      write, format="  %9.3f  %9.3f  %8.3f   %ld frames\n",
             wall, waited, cpu, nframes;

      write, format="  %9.3f  %9.3f  %8.3f   per frame\n",
             (wall-waited)/nframes, wait/(nframes>1?nframes-1:1), cpu/nframes;
    }