### NodeHandler NodeInterface Availability LightWave® 9.0 Component Layout Header lwnodes.h The NodeHandler provides a Node based aproach to most texturing or image based/procedural/gradient modifyers within LightWave®. Handler Activation Function
       XCALL_( int ) MyNode( int version, GlobalFunc *global,
          LWNodeHandler *local, void *serverData );
The `local` argument to a NodeHandler activation function is an LWNodeHandler.
       typedef struct st_LWNodeHandler {
          LWInstanceFuncs *inst;
          LWItemFuncs     *item;
          LWRenderFuncs   *rend;
          void            (*evaluate)(LWInstance, LWNodalAccess*,
                                      NodeOutputID, NodeValue  );
          void            (*customPreview)(LWInstance, int width, int height );
       } LWNodeHandler;
The first three members of this structure are the standard handler functions. In addition to these, Node provides a evaluation and preview function. `evaluate( instance, access, ID, value)` The evaluation function receives the LWNodalAccess structure. ID The output belonging to this node. value Value you need to set with the output functions. `customPreview( instance, width, height )` customPreview is called when the node has `NPT_CUSTOM` preview type set. Node Preview Handeling The Mode of the Preview itself is done using the following:
    typedef enum { NPT_RENDER = 0, NPT_CUSTOM, NPT_OFF } NodePreviewType;
The Following defines how to draw in the preview area.
       typedef struct LWNodeDrawFuncs_t {
          void   (*drawPixel)( NodeID node, int c, int x, int y );
          void   (*drawRGBPixel)( NodeID node, int r, int g, int b, int x, int y );
          void   (*drawLine)( NodeID node, int c, int x, int y, int x2, int y2 );
          void   (*drawBox)( NodeID node, int c, int x, int y, int w, int h );
          void   (*drawRGBBox)( NodeID node, int r, int g, int b, int x, int y, int w, int h );
          int    (*textWidth)( NodeID node, char *s );
          int    (*textHeight)( NodeID node, char *s );
          void   (*drawText)( NodeID node, char *s, int c, int x, int y );
          void   (*blitNode)( NodeID node );
       } LWNodeDrawFuncs;
`drawPixel( nodeid, color, x, y ) drawRGBPixel( nodeid, r, g, b, x, y )` Draw a pixel. The coordinates are relative to the upper-left corner of the node preview area. The color is specified as one of the palette colors defined in lwpanel.h or as levels of red, green and blue between 0 and 255. `drawLine( nodeid, color, x1, y1, x2, y2 )` Draw a line connecting the endpoints. `drawBox( nodeid, color, x, y, w, h ) drawRGBBox( nodeid, r, g, b, x, y, w, h )` Draw a solid rectangle. `tw = textWidth( nodeid, string ) th = textHeight( nodeid, string )` The pixel width and height of the text in the font used by panels. `drawText( nodeid, string, color, x, y )` Render a line of text. `blitNode( nodeid )` Blit the node into the editor area. The node will be the only node drawn on the area, and all the other nodes will remain below this node. Interface Activation Function
       XCALL_( int ) MyInterface( int version, GlobalFunc *global,
          LWInterface *local, void *serverData );
This is the standard interface activation for handlers. Node Access The access structure contains functions and fields that will be used for the NodeHandler.
       typedef struct st_LWNodalAccess {
          int                sx, sy;
          LWDVector          oPos, wPos;
          LWDVector          gNorm;
          LWDVector          wNorm;
          LWDVector          wNorm0;
          LWDVector          raySource;
          double             rayLength;
          double             spotSize;
          double             cosine;
          double             bumpHeight;
          double             oXfrm[9], wXfrm[9];
          LWIlluminateFunc   *illuminate;
          LWRayTraceFunc     *rayTrace;
          LWRayCastFunc      *rayCast;
          LWRayShadeFunc     *rayShade;
          LWRayTraceModeFunc *rayTraceMode;
          int                bounces;
          LWItemID           sourceID;
          LWItemID           objID;
          int                polNum;
          LWPntID            verts[4];
          float              weights[4];
          float              vertsWPos[4][3];
          LWPolID            polygon;
          double             incomingEta;
          int                ResourceContextIndex;
          int                flags;
          RandomFloatData    randomData;
          LWRandomFloatFunc  *randomFloat;
          LWIlluminateNormalFunc *illuminateNormal;
          LWIlluminateSampleNormalFunc *illuminateSampleNormal;
          double             subsx, subsy;
          LWDVector          rayDir;
       } LWNodalAccess;
  `sx, sy` The pixel coordinates at which the spot is visible in the rendered image. This is labeled PIXEL in the figure, but note that it won't necessarily be the spot's projection onto the viewplane. When the viewing ray originates on a reflective surface, for example, the pixel coordinates are usually for the source of the ray (the spot's reflection). The pixel coordinate origin (0, 0) is in the upper left corner of the image. `oPos` Spot position in object (Modeler) coordinates (the (X', Y', Z') system in the figure). `wPos` Spot position in world coordinates (X, Y, Z). This is the position after transformation and the effects of bones, displacement and morphing. `gNorm` Geometric normal in world coordinates. This is the raw polygonal normal at the spot, unperturbed by smoothing or bump mapping. `wNorm0` The interpolated normal in world coordinates. This is the same as `gNorm`, but after smoothing. `spotSize` Approximate spot diameter, useful for texture antialiasing. The diameter is only approximate because spots in general aren't circular. On a surface viewed on edge, they're long and thin. `raySource` Origin of the incoming viewing ray in world coordinates. Labeled EYE in the figure, this is often the camera, but it can also, for example, be a point on a reflective surface. `rayLength` The distance the viewing ray traveled in free space to reach this spot (ordinarily the distance between `raySource` and `wPos`). `cosine` The cosine of the angle between the raw surface normal and a ray pointing from the spot back toward the `raySource`. This is the same as the dot product of `gNorm` and the unit vector `(raySource - wPos)/rayLength`. Low values correspond to high angles and therefore glancing views. This is also a measure of how approximate the spot size is. `oXfrm` Object to world transformation matrix. The nine values in this array form a 3 x 3 matrix that describes the rotation and scaling of the object. This is useful primarily for transforming direction vectors (bump gradients, for example) from object to world space.
         LWDVector ovec, wvec;
         wvec[ 0 ] = ovec[ 0 ] * oXfrm[ 0 ]
                   + ovec[ 1 ] * oXfrm[ 1 ]
                   + ovec[ 2 ] * oXfrm[ 2 ];
         wvec[ 1 ] = ovec[ 0 ] * oXfrm[ 3 ]
                   + ovec[ 1 ] * oXfrm[ 4 ]
                   + ovec[ 2 ] * oXfrm[ 5 ];
         wvec[ 2 ] = ovec[ 0 ] * oXfrm[ 6 ]
                   + ovec[ 1 ] * oXfrm[ 7 ]
                   + ovec[ 2 ] * oXfrm[ 8 ];
`wXfrm` World to object transformation matrix (the inverse of `oXfrm`). `objID` The object being shaded. It's possible for a single shader instance to be shared between multiple objects, so this may be different for each call to the shader's evaluation function. For sample sphere rendering the ID will refer to an object not in the current scene. `polNum` An index identifying the polygon that contains the spot. It may represent other sub-object information in non-mesh objects. See also the `polygon` field. `bounces` The number of times the viewing ray has branched, or bounced, before reaching this spot. This value can be used to limit recursion, particularly the shader's own calls to the raytracing functions. `sourceID` The item ID of the source of the viewing ray. `verts` The four vertices surrounding the spot, useful for interpolating vertex-based surface data. `weights` The weights assigned to the four neighboring vertices. `vertsWPos` The world coordinate position of the neighboring vertices. `incomingEta` Incoming refraction index. `ResourceContextIndex` Current CPU thread running. `flags` Bit fields describing the nature of the call. The `LWRT_SHADOW` bit tells you when the evaluation function is being called during shadow computations, which you might want to treat differently from "regular" shader evaluation. `randomFloat` The function generates a random number on [>0, <1] interval. `subsx, subsy` The pixel coordinates at which the spot is visible in the rendered image with sub-pixel precision. `rayDir` The incoming ray direction. Rendering Functions `lit = illuminate( lightID, position, direction, color ) len = rayTrace( position, direction, color ) len = rayCast( position, direction ) len = rayShade( position, direction, shaderAccess ) len = rayTraceMode( position, direction, color, eta, rtmode ) lit = illuminateSample( lightID, position, direction, sampler, data ) lit = illuminateNormal( lightID, position, direction, normal, color ) lit = illuminateSampleNormal( lightID, position, direction, normal, sampler, data )` See the raytracing functions page for a description of these. Input Event Types Defines Input events on Nodes.
    typedef enum LWNodalEvent_t {
    	NIE_CONNECT = 0,          // When an output is connected to this input.
    	NIE_DISCONNECT,           // When the output was disconnected from this input.
    	NIE_INPUTNODEDESTROY      // When the node connected to this input was destroyed.
    } LWNodalEvent;
    typedef int NodeInputEvent( void *userData, NodeInputID, LWNodalEvent, ConnectionType );
Receives the user data, the input the function belongs to, the LWNodalEvent, and the type of the output connected to the input this function was called for, if the event was NIE_CONNECT, otherwise ConnectionType is 0. In addition there are various types to define input and output type with the following:
    typedef enum {
        NOT_COLOR = 1,
        NOT_SCALAR,
        NOT_VECTOR,
        NOT_INTEGER
    } ConnectionType;
Color type An array of 3 doubles. Scalar type A single double value. Vector type An array of 3 doubles. Integer type A single integer value. Node Input Functions
       typedef struct    LWNodeInputFuncs_t {
          NodeInputID    (*create)( NodeID, ConnectionType, const char*, NodeInputEvent* );
          void           (*destroy)( NodeID, NodeInputID );
          int            (*evaluate)( NodeInputID, LWNodalAccess*, void* value );
          int            (*check)( NodeInputID );
          NodeInputID    (*first)( NodeID );
          NodeInputID    (*next)( NodeInputID );
          NodeInputID    (*previous)( NodeInputID );
          int            (*numInputs)( NodeID );
          NodeInputID    (*byIndex)( NodeID, int );
          int            (*getIndex)( NodeID, NodeInputID );
          void           (*disconnect)( NodeID, NodeInputID );
          NodeID         (*node)( NodeInputID );
       } LWNodeInputFuncs;
`create( NodeID, ConnectionTyp , name, NodeInputEvent )` Create a new input for the node. `destroy( NodeID, NodeInputID )` Destroy an input from the node. `evaluate( NodeInputID, access, value )` Evaluate an input. The value will be filled with a value received from the node evaluated, according to the type of the input evaluated. The value must point to a variable of the corresponding type of the input. For example, If the input type is NOT_SCALAR, the value should be the address of a double variable. `check( NodeInputID )` Check if this input is connected to. `first( NodeID )` Get the first input from a node. `next( NodeInputID )` Get the next input. `previous( NodeInputID )` Get the previous input. `numInputs( NodeID )` Get the number of inputs for this node. `byIndex( NodeID , index )` Get an input by it's index number. The index number of the first input is 1. `getIndex( NodeID , NodeInputID )` Get the index number of the input. If the input doesn't belong to this node, returns 0. The index number of the first input is 1. `disconnect( NodeID , NodeInputID )` Disconnect an output from this input. `node( NodeInputID )` Returns the node this input belongs to. Node Output Functions
       typedef struct    LWNodeOutputFuncs_t {
          NodeInputID    (*create)( NodeID, ConnectionType, const char* );
          void           (*destroy)( NodeID, NodeOutputID );
          void           (*setValue)( NodeValue, void* );
          void           (*getValue)( NodeValue );
          ConnectionType (*getType)( NodeValue );
          NodeInputID    (*first)( NodeID );
          NodeInputID    (*next)( NodeOutputID );
          NodeInputID    (*previous)( NodeOutputID );
          int            (*numInputs)( NodeID );
          NodeInputID    (*byIndex)( NodeID, int );
          int            (*getIndex)( NodeID, NodeOutputID );
          NodeID         (*node)( NodeOutputID );
       } LWNodeOutputFuncs;
`create( NodeID, ConnectionType , name )` Create a new output for the node. `destroy( NodeID, NodeOutputID )` Destroy an output from the node. `setValue( NodeValue, value )` Set the value for the output being evaluated. Call from the node evaluation function when rendering. Value should be the size of the corresponding output type. For example, if the output type is NOT_COLOR, the value should be an array of 3 doubles. `getValue( NodeValue )` Get the pointer to the value cast to the input functions evaluate call. `getType( NodeValue )` Get the type of the connection the value is coming from. `first( NodeID )` Get the first output from a node. `next( NodeOutputID )` Get the next output. `previous( NodeOutputID )` Get the previous output. `numInputs( NodeID )` Get the number of outputs for this node. `byIndex( NodeID , int )` Get an output by it's index number. The index number of the first output is 1. `getIndex( NodeID , NodeOutputID )` Get the index number of the output. If the output doesn't belong to this node, returns 0. The index number of the first output is 1. `node( NodeOutputID )` Returns the node this output belongs to. Node Functions
       typedef struct    LWNodeFuncs_t {
          const char     (*nodeName)( NodeID );
          const char     (*serverUserName)( NodeID );
          LWChanGroupID  (*chanGrp)( NodeID );
          void           (*setNodeColor)( NodeID, int[3] );
          void           (*setNodeColor3)( NodeID, int r, int g, int b );
          void           (*setNodePreviewType)( NodeID, NodePreviewType );
          void           (*UpdateNodePreview)( NodeID );
      } LWNodeFuncs;
`nodeName( NodeID )` Get the name for the node in the editor. Will be the name of the node, with it's index number added to it. Ie. "Texture (1)", etc. `serverUserName( NodeID )` Get the server name for this node. `chanGrp( NodeID )` Get the channel group for this node. `setNodeColor( NodeID, int )` Set the color for this node as an array of 3 integers. `setNodeColor3( NodeID, r, g, b )` Set the color for this node. using separated R, G and B values. `setNodePreviewType( NodeID, NodePreviewType )` Set the preview type for this node. `UpdateNodePreview( NodeID )` Do an immediate interface update for this node. Draws the preview, only for this node. Blending Modes
       typedef enum {
          Blend_Normal,
          Blend_Additive,
          Blend_Subtractive,
          Blend_Multiply,
          Blend_Screen,
          Blend_Darken,
          Blend_Lighten,
          Blend_Difference,
          Blend_Negative,
          Blend_ColorDodge,
          Blend_ColorBurn,
          Blend_Red,
          Blend_Green,
          Blend_Blue
      } BlendingMode;
Node Utility Functions
       typedef struct LWNodeUtilityFuncs_t {
         void    (*Blend)( LWDVector, LWDVector, LWDVector, double, BlendingMode );
         void    (*NodeAutosize)( NodeID, LWDVector scale, LWDVector position );
      } LWNodeUtilityFuncs;
`Blend( Result, BG , FG , ALPHA , BlendingMode )` Blend two nodes using the blending modes above, input includes foreground, background and alpha. `NodeAutosize( NodeID, LWDVector scale, LWDVector position )` Scale and position vectors will be filled with the automatic values. Example The Specular Node sample demonstrates how to create a specular shading model node.