Getting a List of Objects

You can specify that a shader parameter is a list of objects. For example, the sib_lightning shader permits the user to draw lightning between a set of selected objects.

In the PropertySet section of the SPDL file, use the type reference in the SPDL file:

   ...
   Parameter "objects" input #OBJECT LIST
   {
       title = "objects";
       guid = "{92832F80-119A-11D5-AE9A-00A0C96E63E1}";
       type = reference;

In the Defaults section of the SPDL file, specify that the UIType widget to use is the ReferenceWidget. The “mode” flag signals the ReferenceWidget whether to allow multiple objects to be specified as (“multi”), or as only one (“single”).

Defaults
{
   ...
   startpoint
   {
       Name = "Objects";
       Description = "Objects to work with";
       UIType = "ReferenceWidget.ReferenceWidget.1"
       {
          # Filter for objects only
          filter = "{6B579D20-3DC5-11D0-9449-00AA006D3165}";
          # Allow the user to specify several objects
          mode  = "multi";
       }
   }
   ...
}

Whether the widget is set to multi or single mode, the shader will receive an array of miTags. With mental ray, array parameters require three separate variables in the parameter block:

typedef struct {
   ...
   miInteger i_objects;
   miInteger n_objects;
   miTag     objects[1];
   ...
} my_shader_params;

mental ray uses this three parameter mechanism to permit an increase in performance during distributed rendering.

• The first parameter i_objects is an initial offset into the array of objects. Note that i_objects will always access data outside of the bounds of the array objects.

• The second parameter, n_objects, is the number of objects in the array.

• The third parameter, objects, is the base address from which to access the data from.

Given a parameter block my_shader_params *in_pParams, the elements can be accessed as follows:

miBoolean my_shader( miColor *out, miState *state, my_shader_params *paras )
{
/* Retrieve a pointer to the array at the offset
* where it starts. If an array only contains one item,
* this offset is usually zero and is able to use the
* allocated space in the struct. If the array contains
* more items, the offset points to a memory location
* beyond the struct where the actual array elements
* are located.
*/
miTag *objects = ¶s->objects[ paras->i_objects ]; 

for (k = 0; k < paras->n_objects; k++)
{
/* For a reference parameter, the tags are not texturable
* and hence we do not need to perform an mi_eval on them
*/
miTag objtag = miNULLTAG;
miUint objlabel = 0;

/* Get the primitive object (miObject, miLight etc.) from 
* the miInstance referred to by the tag in the object list.
*/
if(!mi_query(miQ_INST_ITEM, NULL, objects[ k ], &objtag))
continue;

/* No primitive? Check the next one then */
if (objtag != miNULLTAG)
continue;

/* Get the label id of the primitive */
if( !mi_query(miQ_OBJ_LABEL, NULL, objtag, &objlabel ) )
continue;

/* Do something with referenced object's label */
mi_debug("Label is %d", objlabel);
}
return( miTRUE );
}


Autodesk Softimage v7.5