AnimUVHandler ChannelHandler Classes Table of Contents


Availability  LightWave® 9.0
Component  Layout
Header  lwcamera.h

The CameraHandler provides ray starting positions and directions for each pixel being raytraced. In this way any type of camera projection can be created. The projection defined by the plugin may be previewed in Layout, if possible, by supplying an OpenGL-like projection matrix.

A camera handler is attached to a camera. The camera handler works in world coordinates, not camera coordinates. The definition of the projection may involve items in the scene other than the camera to which the handler is attached. The camera handler maps filmplane and lens positions to rays.

A position on the film is given in filmplane coordinates. Filmplane coordinates are given in units of meters. They define a location on the hypothetical plane on which the film frame is placed. The film frame is considered to be at the origin of the filmplane. The filmplane coordinate system has y axis going up the film frame, and the x axis in the same direction as the frame's horizontal direction. Note that filmplane coordinates are unaffected by image resolution, film size, or pixel aspect ratio.

A position on the lens is also given in a normalized range from -1 to 1, with the origin considered to be the centre of the lens. The lens positions define points on a hypothetical lens. This is particularly important for depth of field effects. No assumptions are made about the shape of the lens, except that the user can influence the distribution of the sample points that will be supplied by setting a diaphragm shape. It is up to the camera handler to map the combination of filmplane and lens sample position to a ray. For some cameras there may be no concept of a lens. Those cameras can indicate that they don't support and depth of field rendering and can ignore the lens sample positions.

Note that there were substantial changes to this API between version 1 and version 2. As a result, version 1 can no longer be supported.

Handler Activation Function

   XCALL_( int ) MyCamera( int version, GlobalFunc *global,
      LWCameraHandler *local, void *serverData );
The local argument to a CameraHandler activation function is an LWCameraHandler.
   typedef struct st_LWCameraHandler
      LWInstanceFuncs* inst;
      LWItemFuncs*     item;
      LWRenderFuncs*   rend;
      int          (*preview)  (LWInstance, double lpx, double lpy, LWDMatrix4 projection,
                                const LWCameraAccess* camaccess);
      LWError      (*newFrame) (LWInstance, const LWFrameInfo* frameinfo,
                                const LWCameraAccess* camaccess);
      int          (*evaluate) (LWInstance, double fpx, double fpy, double lpx, double lpy,
                                double fractime, LWCameraRay* ray, const LWCameraAccess* camaccess);
      unsigned int (*flags)    (LWInstance);
   } LWCameraHandler;
The first three members of this structure are the standard handler functions. The context argument to the inst->create function is the LWItemID of the associated object.
result = preview( instance, lpx, lpy, projection, access )
Fills in the given matrix with an OpenGL projection matrix that approximates the camera view, if possible. The (lpx, lpy) coordinates is the sample position on the lens, with values in the range between -1 and 1. This may be non-zero when constructing motion blur previews for example. The projection matrix should project from camera space to the camera's filmplane. The matrix follows the OpenGL matrix conventions. It is expected that the matrix projects to the film size (unlike the standard OpenGL frustum which projects to a normalized coordinate system). The effects of aspect ratio of the film and viewport will be automatically handled by LW. Set the projection matrix to fit the projection to the height of the film with a square aspect ratio. The frame number and time for the preview is as given by the most recent call to newTime(). Returns 1 if the matrix has been filled in, or 0 if the matrix could not be filled in, for example because there is no good projection matrix approximation for the camera.

result = newFrame( instance, frameinfo, access )
This is called whenever a new set of evaluations is started, usually at the start of a frame render, or when constructing the view frustum preview of a selected camera in Layout. This is a good place to do some pre-computation. The frameinfo and camera access structures are explained below. Returns a pointer to an error string of something went wrong, or NULL if all is well.

result = evaluate( instance, fpx, fpy, lpx, lpy, fractime, ray, access )
Given a position (fpx, fpy) on the camera filmplane, a position (lpx, lpy) on the lens, and a fractional time into the frame, compute a starting position and direction for the ray to be cast. The filmplane coordinates may fall outside of the film frame. There is no defined order to the filmplane and lens positions with which the evaluation function is called. The supplied time value is a fraction between 0 and 1 that ranges over the time duration of the frame (which can be retrieved from the frameinfo structure supplied to newFrame()). 0 means the start time of the frame, while 1 means the time at the end of the duration of the frame (which may be different than that implied by the current frames per second setting, as it includes the effects of fields and motion blur length). There is no defined ordering to the time values that will be given. It is recommended that the camera handler pre-computes any animation of settings in newFrame() and uses the fractime parameter to interpolate. LightWave can do a default interpolation on the returned ray, which consists of transforming the ray coordinates according to the change in position and orientation of the camera at the fractional time compared with the start of the frame. If this is sufficient, the camera handler should compute the ray position and direction as it would be at the start of the frame, ignoring the fractional time, and return a result of LWCAMTYPEEVAL_DO_DEF_INTERP (see below). The evaluation function must also be thread-safe, for example using the multithreading utilities if needed. The evaluation fills in the ray structure if the camera can cast a ray for the given coordinates and time. The return value is one of:
No ray can be cast.
A ray can be cast.
A ray can be cast, but let LightWave do a defauly time interpolation.

flags = flags( instance )
Returns bit flags combined using bitwise-or. Currently defined flags are:
The camera support depth of field rendering.
Interface Activation Function
   XCALL_( int ) MyInterface( int version, GlobalFunc *global,
      LWInterface *local, void *serverData );

This is the standard interface activation for handlers. Users open a Camera interface by pressing an Properties button on the Camera Properties panel.

To help implement the user interface, the standard zoom factor controller is available as an XPanel control of type "zoomfactor-env", which uses a vparm as its underlying data type. This control is available from LightWave® 9.3 onwards. The vparm must have been created in the channel group of the camera. The control will handle getting and setting the camera zoom settings. The vparm does not have to be saved or loaded by the camera plugin.

Frame Info

The newFrame() function is supplied with some basic information about the frame that is about to be evaluated. More detailed information may be obtained through the camera info global.

   typedef struct st_LWFrameInfo {
      LWFrame frame;
      LWTime start;
      LWTime duration;
      double framesPerSecond;
      unsigned int motionSteps;
} LWFrameInfo;
The frame number of the frame to be evaluated.
The start time of the frame to be evaluated.
The duration of the frame to be evaluated. Together with the start time this defines the range of time values over which the fractime parameter passed to the evaluation function is normalized. Finer-grained information can be obtained through caminfo->frameTiming()
The current FPS setting. This is the time from the start of one frame to the start of the next frame. Note that this is often different that the duration of the frame due to field rendering and motion blur length.
The suggested number of time steps to use for constructing animation interpolation. To compute the positions, orientations, and other parameters for items at any time within the frame duration, LightWave pre-computes the animations at regular intervals along the frame's duration, and then interpolates during during rendering to determine the parameters at any arbitrary time within the frame duration. The number of intervals used is given by motionSteps. Camera handlers can use this as a guide to determine how many intervals to split the frame duration up in to pre-compute the animation of its settings. Note that this value may be 0.

Camera Access

The access structure information that may be useful for computing the camera.

   typedef struct st_LWCameraAccess {
      LWItemID cameraID;
      LWDVector worldPos;
      LWDVector toWorld[3];
      LWDVector toCamera[3];
      double filmSize[2];
   } LWCameraAccess;
The ItemID of the camera that the CameraHandler plugin is be applied to.
The position of the camera item in world coordinates.
Right, Up and Forward directions of the camera in world coordinates.
Inverse of toWorld[3] .
The width and height of a film frame, given in meters.

Ray structure

The evaluation function fills in a ray structure describing the ray to be cast.

   typedef struct st_LWCameraRay {
      LWDVector rayPos;
      LWDVector rayDir;
      LWDVector filmNorm;
      LWDVector filter[3];
   } LWCameraRay;
The starting position of the ray, in world coordinates.
The ray direction, in world coordinates.
The normal to the film plane for the ray. This is used to compute the depth buffer value for any point along the ray. The depth buffer value is computed by projecting the point (relative to the start position of the ray) onto the film normal for that ray. The length of the resulting vector is taken to be the depth value. For example, for a perspective camera the film normal is the camera's Z axis. For a spherical projection camera it may be more proper to set the film normal equal to the ray direction, so that the depth value is equal to distance along the ray.
A camera lens may affect the color, for example darkening towards the edges causing vignetting. The camera handler can set a color filter for each of the red, green, and blue channels. A filter is applied to a channel by doing a dot-product of the filter with the raytraced RGB color. Note that this is not meant to replace the functionality of pixel filters or image filters. The camera filter is used to apply shading effects which are inherent to the camera, not the film or scene.