[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

8.4.2 The DynamicLoad Procedural Primitive

This example shows how to write a procedural primitive in the form of a DSO. It is special in that it calls itself a number of times to create a Menger's Sponge. It can be invoked in a RIB as such: Procedural "DynamicLoad" ["sponge" "3"] [-1 1 -1 1 -1 1] The single parameter it takes is the maximal recursion depth. It also makes use of the detailsize parameter of the subdivision routine to avoid outputting too much detail. Note that 3Delight will attempt to find sponge.so (or sponge.dll on Windows) and then sponge in the procedural search path. This allows you not to specify the extension.

 
 
#include <stdlib.h>

#include "ri.h"

#if defined(_WIN32)
#define DLLEXPORT __declspec(dllexport)
#else
#define DLLEXPORT
#endif

#ifdef __cplusplus
extern "C" {
#endif

/* Declarations */
RtPointer DLLEXPORT ConvertParameters(RtString paramstr);
RtVoid DLLEXPORT Subdivide(RtPointer data, float detail);
RtVoid DLLEXPORT Free(RtPointer data);

RtPointer DLLEXPORT ConvertParameters(RtString paramstr)
{
    int* depth = (int*) malloc(sizeof(int));
    *depth = 3;                /* decent default value */
    sscanf(paramstr, "%d", depth);
    return depth;
}

RtVoid DLLEXPORT Subdivide(RtPointer blinddata, RtFloat detailsize)
{
    int depth = *(int*) blinddata;
    
    /* Simple usage of detailsize to avoid drawing too much detail */
    if (depth <= 0 || detailsize <= 5.0f)
    {
        /* Draw a cube */
        RtInt nverts[] = {4, 4, 4, 4, 4, 4};
        RtInt verts[] = {
            3, 7, 6, 2,        /* top face    */
            5, 1, 0, 4,        /* bottom face */
            7, 3, 1, 5,        /* back face   */
            3, 2, 0, 1,        /* left face   */
            6, 7, 5, 4,        /* right face  */
            2, 6, 4, 0};       /* front face  */

        RtFloat points[] = {
            -1, -1, -1,      -1, -1, 1,
            -1, 1, -1,       -1, 1, 1,
            1, -1, -1,       1, -1, 1,
            1, 1, -1,        1, 1, 1};
        RiPointsPolygons(
            (RtInt)6, nverts, verts, RI_P, (RtPointer)points, RI_NULL);
    } else {
        /* Recursive call, reduce depth and scale the object by 1/3 */
        RtBound bound = {-1, 1, -1, 1, -1, 1};
        int* newDepth;
        unsigned x,y,z;
        RiScale(1.0/3.0, 1.0/3.0, 1.0/3.0);

        for (x = 0; x < 3; ++x)
            for (y = 0; y < 3; ++y)
                for (z = 0; z < 3; ++z)
                    if (x % 2 + y % 2 + z % 2 < 2)
                    {
                        RiTransformBegin();
                        RiTranslate(
                            x * 2.0 - 2.0,
                            y * 2.0 - 2.0,
                            z * 2.0 - 2.0);
                        newDepth = (int*) malloc(sizeof(int));
                        *newDepth = depth - 1;
                        /* We could make the recursive call using
                           RiProcDynamicLoad but that would be more complex and
                           slightly less efficient */
                        RiProcedural(newDepth, bound, Subdivide, Free);
                        RiTransformEnd();
                    }
    }
}

RtVoid DLLEXPORT Free(RtPointer blinddata)
{
    free(blinddata);
}

#ifdef __cplusplus
}
#endif

This example can be compiled with the following commands:

Linux
gcc -o sponge.so -O3 -I$DELIGHT/include/ -shared sponge.c
Mac OS X
mkdir -p sponge.so/Contents/MacOS ; gcc -o sponge.so/Contents/MacOS/sponge -O3 -I$DELIGHT/include/ -L$DELIGHT/lib/ -arch "ppc" -bundle sponge.c -l3delight
IRIX
CC -o sponge.so -O3 -n32 -TARG:isa=mips4 -TARG:processor=r10k -I$DELIGHT/include/ -shared sponge.c
Windows
CL /Ox /LD /I%DELIGHT%\include\ sponge.c %DELIGHT%\lib\3Delight.lib

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

This document was generated by Aghiles Kheffache on July, 31 2003 using texi2html
3Delight 1.0.0. Copyright 2000-2003 The 3Delight Team. All Rights Reserved.