Classes: AnimLoaderHandler

LightWave

VolumetricHandler AnimSaverHandler Classes Table of Contents

AnimLoaderHandler
AnimLoaderInterface

Availability  LightWave 6.0
Component  Layout, Modeler
Header  lwanimlod.h

An animation loader loads frames from an animation file. An animation file is a file that contains a time sequence of still images, or data that can be interpreted that way. Animation loaders must be prepared to provide random access to the frames in an animation file. They must also be able to distinguish between files they can load and those they can't. LightWave relies on this to choose the proper loader for an animation file.

Handler Activation Function

   XCALL_( int ) MyAnimLoader( long version, GlobalFunc *global,
      LWAnimLoaderHandler *local, void *serverData );

The local argument to an anim loader's activation function is an LWAnimLoaderHandler.

   typedef struct st_LWAnimLoaderHandler {
      LWInstanceFuncs *inst;
      int             (*frameCount) (LWInstance);
      double          (*frameRate)  (LWInstance);
      double          (*aspect)     (LWInstance, int *w, int *h,
                                       double *pixAspect);
      void            (*evaluate)   (LWInstance, double,
                                       LWAnimFrameAccess *);
   } LWAnimLoaderHandler;

The first member of this structure points to the standard instance handler functions. An anim loader also provides functions that return image pixels and other information from the file.

The context argument to the create function is the filename. The create function should open the file and determine whether it's in a format the loader can load. If the format isn't recognized, create should return NULL, without setting the error string. LightWave will understand this to mean that the file should be handled by a different anim loader.

count = frameCount( instance )
Returns the number of frames in the file.

fps = frameRate( instance )
Returns the animation's playback speed, in frames per second.

frame_aspect = aspect( instance, w, h, pixel_aspect )
Fills in the width and height of the frames and the pixel aspect ratio and returns the frame aspect ratio. The aspect ratio of a rectangle describes its shape--whether it's short and broad, tall and thin, or square--and is expressed as width / height. The aspect ratios of each pixel and of the image as a whole are related in the following way.

frame_aspect = w * pixel_aspect / h
pixel_aspect = h * frame_aspect / w

The aspect function therefore asks for redundant information, so to ensure that what you're returning is self-consistent, you should calculate one of the aspects in terms of the other.

evaluate( instance, time, access )
Load an image at the specified running time from the file. At the loader's discretion, the image can be the frame nearest to the time or an interpolation of two or more frames. The access structure, described below, provides the functions the loader uses to pass image data to Layout.

Interface Activation Function

   XCALL_( int ) MyInterface( long version, GlobalFunc *global,
      LWInterface *local, void *serverData );

This is the standard interface activation for handlers. LightWave currently doesn't give the user an interface for animation loaders, although it may in a future version.

Anim Frame Access

The access structure passed to the loader's evaluation function uses the image I/O mechanism to pass image data to Layout.

   typedef struct st_LWAnimFrameAccess {
      void              *priv_data;
      LWImageProtocolID (*begin) (void *, int type);
      void              (*done)  (void *, LWImageProtocolID);
   } LWAnimFrameAccess;
priv_data
An opaque pointer to data used by Layout. Pass this to begin and done.

protocol = begin( priv_data, type )
Call this to tell Layout that you're about to send it image data for a frame. The type argument describes the kind of pixel data you'll send and can be any of the image I/O pixel types. Layout returns an LWImageProtocolID containing the functions used to pass the data.

done( priv_data, protocol )
Call this to tell Layout that you've finished sending the image.

Example

The ancounter sample is a simple animation loader that draws its frames on the fly based on a small amount of information in a text file. The text file is the "animation file" the user selects in order to invoke this loader.

Every animation file passes through every anim loader's create function until one of the loaders claims the file as its own. AnCounter reads the first line of each file and compares it to a phrase that identifies the file as an AnCounter text file. If the phrase isn't present at the start of the file, the create function quietly fails by returning NULL.

   fp = fopen( filename, "r" );
   if ( !fp ) {
      *emsg = "Couldn't open anim file.";
      return NULL;
   }

   fgets( buf, sizeof( buf ), fp );

   if ( strncmp( buf, "Counter AnimLoader File", 23 )) {
      fclose( fp );
      return NULL;
   }

If the phrase is there, create allocates an instance structure and initializes it using the information in the file. The evaluation function later uses this information to make a "counter" image. A string of the form "hh:mm:ss:ff" (hours, minutes, seconds, frames) is made from the time argument, and this is rasterized, using the font information in the text file, and passed to LightWave as the current frame.

   if ( !getTextImage( counter, text )) return;

   ip = access->begin( access->priv_data, LWIMTYP_GREY8 );
   if ( !ip ) return;

   LWIP_SETSIZE( ip, counter->w, counter->h );
   LWIP_SETPARAM( ip, LWIMPAR_ASPECT, 0, 1.0f );

   for ( i = 0; i < counter->h; i++ ) {
      result = LWIP_SENDLINE( ip, i, counter->buf + i * counter->w );
      if ( result != IPSTAT_OK ) break;
   }

   LWIP_DONE( ip, result );
   access->done( access->priv_data, ip );