### CustomObjHandler CustomObjInterface Availability LightWave® 6.0 Component Layout Header lwcustobj.h Layout uses null objects as placeholders for animation data. Nulls can be used as parents to add degrees of freedom to the motion of other objects, or as references for texturing, or as camera targets. Plug-ins can also rely on nulls as a way for users to interactively set parameters. A custom object handler can be associated with a null to customize its appearance in Layout's interface. This is useful for providing visual feedback about, for example, the range or magnitude of an effect controlled by the null. Custom nulls will often be an adjunct to a plug-in of another class that uses nulls for data entry, but they can also be used by themselves for things like guides and rulers. When applied to non-null objects, a custom object plug-in supplements LightWave®'s drawing of the object in the interface. Hypervoxels, for example, uses a custom object handler to draw wireframe bounding spheres around the particles associated with an object. Handler Activation Function
       XCALL_( int ) MyCustomObj( int version, GlobalFunc *global,
          LWCustomObjHandler *local, void *serverData );
The `local` argument to a custom object's activation function is an LWCustomObjHandler.
       typedef struct st_LWCustomObjHandler {
          LWInstanceFuncs *inst;
          LWItemFuncs     *item;
          LWRenderFuncs   *rend;
          void            (*evaluate)(LWInstance, const LWCustomObjAccess *);
          unsigned int    (*flags)   (LWInstance);
       } LWCustomObjHandler;
The first three members of this structure are the standard handler functions. In addition to these, a custom object provides an evaluation function and a flags function. The `context` argument to the `inst->create` function is the LWItemID of the associated object. `evaluate( instance, access )` Draw the object on the interface using the information in the access structure, described below. `f = flags( instance )` Returns bit flags combined using bitwise-or. `LWCOF_SCHEMA_OK` Tells Layout that you support drawing in schematic viewports. `LWCOF_VIEWPORT_INDEX` Tells layout to use the viewport number instead of its type in the LWCustomObjAccess view element `LWCOF_NO_DEPTH_BUFFER` Causes drawing to occur in front of other OpenGL elements, regardless of Z position. `LWCOF_OVERLAY` This is useful for custom object handlers attached to cameras or lights. When used, the internal camera or light drawing will be drawn before the custom one. When not used, the internal drawing of the light or camera is not used at all. 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 custom object's interface by pressing an Options button on the Geometry tab of the Object Properties panel. Custom Object Access The access structure contains drawing functions and fields indicating which of the interface views the object will be drawn in and whether the object is currently selected. Within the limitations of the drawing functions, there aren't any restrictions on what your custom object may look like. But in most cases it will be helpful to users if your object's appearance is consistent in color and style with the rest of Layout's interface.
       typedef struct st_LWCustomObjAccess {
          int   view;
          int   flags;
          void *dispData;
          void (*setColor)    (void *, float rgba[4]);
          void (*setPattern)  (void *, int lpat);
          void (*setTexture)  (void *, int, unsigned char *);
          void (*setUVs)      (void *, double[2], double[2], double[2],
                                 double[2]);
          void (*point)       (void *, double[3], int csys);
          void (*line)        (void *, double[3], double[3], int csys);
          void (*triangle)    (void *, double[3], double[3], double[3],
                                 int csys);
          void (*quad)        (void *, double[3], double[3], double[3],
                                 double[3], int csys);
          void (*circle)      (void *, double[3], double, int csys);
          void (*text)        (void *, double[3], const char *, int just,
                                 int csys);
          LWDVector viewPos, viewDir;
          void (*setCSysItem) (void *, LWItemID item);
          void (*polygon)     (void *, unsigned int numv, double[][3], int csys);
          void (*polyIndexed) (void *, unsigned int numv, unsigned int verts[], double[][3], int csys);
          void (*setDrawMode) (void *, unsigned int mode);
          void (*disk)        (void *, double[3], double, int csys);
          void (*setPart)        (void *, unsigned int part);
       } LWCustomObjAccess;
`view` The view the object will be drawn in. Possible values are: `LWVIEW_ZY` `LWVIEW_XZ` `LWVIEW_XY` `LWVIEW_PERSP` `LWVIEW_LIGHT` `LWVIEW_CAMERA` `LWVIEW_SCHEMA` These refer to the orthographic, perspective, light, camera and schematic views available to the user in the Layout interface. `flags` Contains bitfields with information about the context of the render request. `LWCOFL_SELECTED` The object is selected, and should be rendered in a selected state. `LWCOFL_PICKING` The custom object is being evaluated to determine if it is part of a picking selection. The drawing functions do no actual drawing to the viewports. Instead they are used only to define the shape of the object. `dispData` An opaque pointer to private data used by Layout. Pass this as the first argument to the drawing functions. `setColor( dispData, rgba )` Set the current drawing color, including the alpha level. Calling this is optional. By default, all drawing is done in the color set by the user in the Scene panel when the custom object isn't selected, and in yellow when the object is selected. Color settings don't persist between calls to the evaluation function, nor do they change the settings in the Scene panel. `setPattern( dispData, linepat )` Set the current line pattern. The pattern codes are: `LWLPAT_SOLID` `LWLPAT_DOT` `LWLPAT_DASH` `LWLPAT_LONGDOT` As with `setColor`, calling `setPattern` is optional. By default, all drawing is done with solid lines. Line pattern settings don't persist between evaluations. `setTexture( dispData, size, imagebytes )` Set the current image for texture mapping. This image is mapped onto quads drawn by the `quad` function. The `size` is the width (and height) of the image in pixels and must be a power of 2. The pixel data is an OpenGL image in `GL_RGBA` format and `GL_UNSIGNED_BYTE` data type. Each pixel is represented by a set of four contiguous bytes containing red, green, blue and alpha values ranging from 0 to 255. `setUVs( dispData, uv0, uv1, uv2, uv3 )` Set the UVs for texture mapping. This sets the position of the texture image on each polygon drawn by the `quad` function until the next call to `setUVs`. `point( dispData, xyz, coord_sys )` Draw a point at the specified position. The point will be drawn in the color set by the most recent `setColor` call, or in the default color if no color was set. The coordinate system argument identifies the coordinates in which the position is expressed and may be one of the following: `LWCSYS_WORLD` "Absolute" coordinates, unaffected by the position, rotation and scale of the underlying null object. `LWCSYS_OBJECT` "Relative" coordinates. Layout will transform the point. `LWCSYS_ICON` A special coordinate system that works like `LWCSYS_OBJECT` but scales with the grid size. Layout's camera and light images are examples of the use of this coordinate system. `LWCSYS_VIEWPORT` Viewport pixel coordinates, with the origin at the top-left of the viewport. The x and y values are in pixels. The z value ranges from 0 for a point on the near plane, to 1 for a point on the far plane. Note that drawing exactly on the near or far plane may cause artifacts caused by unreliable clipping due to floating point imprecision. `line( dispData, end1, end2, coord_sys )` Draw a line between the specified endpoints using the current color and line pattern. `triangle( dispData, v1, v2, v3, coord_sys )` Draw a solid triangle with the specified vertices using the current color. `quad( dispData, v1, v2, v3, v4, coord_sys )` Draw a solid quadrangle with the specified vertices using the current color or texture. `circle( dispData, center, radius, coord_sys )` Draw a circle of the given radius around the specified center point using the current color and line pattern. `text( dispData, pos, textline, justify, coord_sys )` Draw a single line of text using the current color and line pattern. The `justify` argument determines whether the text will be drawn to the left or right of the position, or centered on it: `LWJUST_LEFT` `LWJUST_CENTER` `LWJUST_RIGHT` `setCSysItem( dispData, itemid ) (LW9.3+)` Sets the item used for relative coordinate systems, namely `LWCSYS_OBJECT` and `LWCSYS_ICON`. This overrides the default, if any. `polygon( dispData, numv, vertices, coord_sys ) (LW9.5)` Draw a polygon using the given vertices. The array of vertices must contain at least `numv` points. `polyIndexed( dispData, numv, indices, vertices, coord_sys ) (LW9.5)` Draw a polygon where the vertices are given as indices into an array of vertices. The array of indices must contain at least `numv` indices. The array of vertices must contain at least all the points in the indices array. Not all vertices have to be used. `setDrawMode( dispData, mode ) (LW9.5)` Sets the current drawing mode. The mode is defined by combining the following flags with bitwise-or: `LWDRAWMODE_CULLFACE` Does not draw backfacing shapes. `LWDRAWMODE_OUTLINE` Draws using outlines instead of fill. `LWDRAWMODE_DEPTHTEST` Enables depthbuffer testing. `LWDRAWMODE_DEPTHWRITE` Enables writing to the depthbuffer. The default mode is `LWDRAWMODE_DEPTHTEST + LWDRAWMODE_DEPTHWRITE`. `disk( dispData, center, radius, coord_sys ) (LW9.5)` Draw a disk (filled circle) of the given radius around the specified center point using the current color. `setPart( dispData, part ) (LW9.6)` Associate a part number with the following drawing. The parts can be numbered from 1 to 32 inclusive. A part number of 0 implies no particular part number association. This is currently only useful for implementing gizmos. History In LightWave® 7.0, `LWCUSTOMOBJ_VERSION` was incremented to 5 because of significant changes to the LWCustomObjAccess structure. The previous version of the structure looked like this.
      typedef struct st_LWCustomObjAccess_V4 {
          int   view;
          int   flags;
          void *dispData;
          void (*setColor)   (void *, float rgb[3]);
          void (*setPattern) (void *, int lpat);
          void (*point)      (void *, double[3], int csys);
          void (*line)       (void *, double[3], double[3], int csys);
          void (*triangle)   (void *, double[3], double[3], double[3],
                                int csys);
          void (*circle)     (void *, double[3], double, int csys);
          void (*text)       (void *, double[3], const char *, int csys);
       } LWCustomObjAccess_V4;
The `setTexture`, `setUVs` and `quad` functions are missing, and the `text` function lacks the justification argument. Example The barn sample draws a simple barn or house shape. It's easy to tell which way this shape is pointing, which makes it useful for quickly testing programming assumptions about the effects of animation parameters on the orientation of objects.