#include #include #include #include #include #include "ri.h" #include "types.h" #include "matrix.h" #include "stack.h" #include "graph_state.h" #include "object.h" #include "vars.h" #include "engine.h" #include "linklist.h" #include "ribgen.h" // Globals engine_t engine = {0}; graph_state_t *pG; scene_t *pW; scene_t *pL; RtToken RI_FRAMEBUFFER = "framebuffer"; RtToken RI_FILE = "file"; RtToken RI_RGB = "rgb"; RtToken RI_RGBA = "rgba"; RtToken RI_RGBZ = "rgbz"; RtToken RI_RGBAZ = "rgbaz"; RtToken RI_A = "a"; RtToken RI_Z = "z"; RtToken RI_AZ = "az"; RtToken RI_PERSPECTIVE = "perspective"; RtToken RI_ORTHOGRAPHIC = "orthographic"; RtToken RI_FOV = "fov"; RtToken RI_BILINEAR = "bilinear"; RtToken RI_BICUBIC = "bicubic"; RtToken RI_LINEAR = "linear"; RtToken RI_CUBIC = "cubic"; RtToken RI_PERIODIC = "periodic"; RtToken RI_NONPERIODIC = "nonperiodic"; RtBasis RiBezierBasis = { {-1, 3, -3, 1}, {3, -6, 3, 0}, {-3, 3, 0, 0}, {1, 0, 0, 0}}; RtBasis RiBSplineBasis = {{-(RtFloat)1/6, (RtFloat)3/6, -(RtFloat)3/6, (RtFloat)1/6} ,{(RtFloat)3/6, -(RtFloat)6/6, (RtFloat)3/6, 0}, {-(RtFloat)3/6, 0, (RtFloat)3/6, 0}, {(RtFloat)1/6, (RtFloat)4/6, (RtFloat)1/6, 0}}; RtBasis RiCatmullRomBasis = { {-(RtFloat)1/2, (RtFloat)3/2, -(RtFloat)3/2, (RtFloat)1/2}, {(RtFloat)2/2, -(RtFloat)5/2, (RtFloat)4/2, -(RtFloat)1/2}, {-(RtFloat)1/2, 0, (RtFloat)1/2, 0}, {0, (RtFloat)2/2, 0, 0}}; RtBasis RiHermiteBasis = { {2, 1, -2, 1}, {-3, -2, 3, -1}, {0, 1, 0, 0}, {1, 0, 0, 0}}; RtBasis RiPowerBasis = { {1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}; // -------------------------------------------------------------- // RenderMan interface // -------------------------------------------------------------- /* Basic control flow, scoping, stacks */ RtVoid RiBegin (RtToken name) { if (Engine_context_get(&engine, ENGINE_CONTEXT_LEVEL_MAIN) != ENGINE_CONTEXT_INVALID) { fprintf(stderr, "RiBegin() cannot be nested!\n"); return; } Engine_init(&engine, name); pG = &engine.gs; pW = &engine.geometry; pL = &engine.lights; GS_init(pG); // Init scene pW->pObjs = NULL; pL->pObjs = NULL; // Set camera as current coordinate system GS_xform_set(pG, camera_space); Engine_context_set(&engine, ENGINE_CONTEXT_MAIN, ENGINE_CONTEXT_LEVEL_MAIN); } // -------------------------------------------------------------- RtVoid RiEnd (void) { if (Engine_context_get(&engine, ENGINE_CONTEXT_LEVEL_MAIN) == ENGINE_CONTEXT_INVALID) { fprintf(stderr, "RiBegin() not declared previously!\n"); return; } Engine_DeleteScene(&engine); GS_free(pG); Engine_free(&engine); } // -------------------------------------------------------------- RtVoid RiFrameBegin (RtInt number) { uint32_t i; if (Engine_context_get(&engine, ENGINE_CONTEXT_LEVEL_MAIN) == ENGINE_CONTEXT_INVALID) { fprintf(stderr, "RiBegin() not declared previously!\n"); return; } if (Engine_context_get(&engine, ENGINE_CONTEXT_LEVEL_MAIN) == ENGINE_CONTEXT_FRAME) { fprintf(stderr, "RiFrameBegin() cannot be nested!\n"); return; } if (Engine_context_get(&engine, ENGINE_CONTEXT_LEVEL_MAIN) == ENGINE_CONTEXT_WORLD) { fprintf(stderr, "RiFrameBegin() is invalid within world block!\n"); return; } pG->frame = number; // Initialize coordinate systems for (i=0; i < NUM_COORD_SYSTEMS; i++) { IdentityMatrix(&pG->pXform->space[i]); } Engine_context_push(&engine); Engine_context_set(&engine, ENGINE_CONTEXT_FRAME, ENGINE_CONTEXT_LEVEL_MAIN); Ribgen_FrameBegin(&engine, number); } // -------------------------------------------------------------- RtVoid RiFrameEnd (void) { if (Engine_context_get(&engine, ENGINE_CONTEXT_LEVEL_MAIN) < ENGINE_CONTEXT_FRAME) { fprintf(stderr, "RiFrameBegin() not declared previously!\n"); return; } Engine_DeleteScene(&engine); Engine_context_pop(&engine); Ribgen_FrameEnd(&engine); } // -------------------------------------------------------------- RtVoid RiWorldBegin (void) { if (Engine_context_get(&engine, ENGINE_CONTEXT_LEVEL_MAIN) == ENGINE_CONTEXT_INVALID) { fprintf(stderr, "RiBegin() not declared previously!\n"); return; } if (Engine_context_get(&engine, ENGINE_CONTEXT_LEVEL_MAIN) == ENGINE_CONTEXT_WORLD) { fprintf(stderr, "RiWorldBegin() cannot be nested!\n"); return; } // Set world as current coordinate system GS_xform_set(pG, world_space); Engine_context_push(&engine); Engine_context_set(&engine, ENGINE_CONTEXT_WORLD, ENGINE_CONTEXT_LEVEL_MAIN); GS_opt_push(pG); GS_attr_push(pG); GS_xform_push(pG); Ribgen_WorldBegin(&engine); } // -------------------------------------------------------------- RtVoid RiWorldEnd (void) { if (Engine_context_get(&engine, ENGINE_CONTEXT_LEVEL_MAIN) < ENGINE_CONTEXT_WORLD) { fprintf(stderr, "RiWorldBegin() not declared previously!\n"); return; } // Set camera as current coordinate system GS_xform_set(pG, camera_space); Engine_Render(&engine); Engine_SceneInfo(&engine); Engine_DeleteScene(&engine); Engine_context_pop(&engine); GS_opt_pop(pG); GS_attr_pop(pG); GS_xform_pop(pG); Ribgen_WorldEnd(&engine); } // -------------------------------------------------------------- RtVoid RiAttributeBegin (void) { if (Engine_context_get(&engine, ENGINE_CONTEXT_LEVEL_MAIN) == ENGINE_CONTEXT_INVALID) { fprintf(stderr, "RiBegin() not declared previously!\n"); return; } GS_attr_push(pG); GS_xform_push(pG); Engine_context_push(&engine); Engine_context_set(&engine, ENGINE_CONTEXT_ATTRIBUTE, ENGINE_CONTEXT_LEVEL_SUB); Ribgen_AttributeBegin(&engine); } // -------------------------------------------------------------- RtVoid RiAttributeEnd (void) { if (Engine_context_get(&engine, ENGINE_CONTEXT_LEVEL_MAIN) == ENGINE_CONTEXT_INVALID) { fprintf(stderr, "RiWorldBegin() not declared previously!\n"); return; } if (Engine_context_get(&engine, ENGINE_CONTEXT_LEVEL_SUB) != ENGINE_CONTEXT_ATTRIBUTE) { fprintf(stderr, "RiAttributeBegin() not declared previously!\n"); return; } GS_attr_pop(pG); GS_xform_pop(pG); Engine_context_pop(&engine); Ribgen_AttributeEnd(&engine); } // -------------------------------------------------------------- RtVoid RiTransformBegin (void) { if (Engine_context_get(&engine, ENGINE_CONTEXT_LEVEL_MAIN) == ENGINE_CONTEXT_INVALID) { fprintf(stderr, "RiBegin() not declared previously!\n"); return; } GS_xform_push(pG); Engine_context_push(&engine); Engine_context_set(&engine, ENGINE_CONTEXT_TRANSFORM, ENGINE_CONTEXT_LEVEL_SUB); Ribgen_TransformBegin(&engine); } // -------------------------------------------------------------- RtVoid RiTransformEnd (void) { if (Engine_context_get(&engine, ENGINE_CONTEXT_LEVEL_MAIN) == ENGINE_CONTEXT_INVALID) { fprintf(stderr, "RiWorldBegin() not declared previously!\n"); return; } if (Engine_context_get(&engine, ENGINE_CONTEXT_LEVEL_SUB) != ENGINE_CONTEXT_TRANSFORM) { fprintf(stderr, "RiTransformBegin() not declared previously!\n"); return; } GS_xform_pop(pG); Engine_context_pop(&engine); Ribgen_TransformEnd(&engine); } // -------------------------------------------------------------- RtToken RiDeclare (char *name, char *declaration) { uint32_t i, len; RtToken pVar; char *pClass; char *pType; len = strlen(declaration); pClass = jmalloc(len); memset(pClass, 0, len); pType = jmalloc(len); memset(pType, 0, len); i=0; while(*declaration != ' ') pClass[i++] = *declaration++; declaration++; i=0; while(*declaration) pType[i++] = *declaration++; pVar = (RtToken)VarListDeclare(&engine.varList, name, pClass, pType); jfree(pClass); jfree(pType); return pVar; } // -------------------------------------------------------------- /* Transformations */ RtVoid RiConcatTransform (RtMatrix transform) { RtMatrix T; GS_xform_push(pG); memcpy(T, *pG->pXform_curr, sizeof(RtMatrix)); MultiplyMatrices(T, transform, pG->pXform_curr); Ribgen_ConcatTransform(&engine, transform); } // -------------------------------------------------------------- RtVoid RiCoordinateSystem (RtToken space) { } // -------------------------------------------------------------- RtVoid RiCoordSysTransform (RtToken space) { } // -------------------------------------------------------------- RtVoid RiIdentity (void) { GS_xform_push(pG); IdentityMatrix(pG->pXform_curr); Ribgen_Identity(&engine); } // -------------------------------------------------------------- RtVoid RiPerspective (RtFloat fov) { pG->pOpt->projection.fov = fov; Ribgen_Perspective(&engine, fov); } // -------------------------------------------------------------- RtVoid RiRotate (RtFloat angle, RtFloat dx, RtFloat dy, RtFloat dz) { RtFloat v[3]; RtMatrix R, T; RtFloat c, s, n, x, y, z; RtFloat a; GS_xform_push(pG); v[0] = dx; v[1] = dy; v[2] = dz; n = Norm(v, 3); x = v[0]/n; y = v[1]/n; z = v[2]/n; a = (RtFloat)(PI*angle/180.0); c = (RtFloat)(1.0 - cos(a)); s = (RtFloat)-sin(a); IdentityMatrix(&R); R[0][0] = 1 + c*(x*x-1); R[0][1] = z*s + c*x*y; R[0][2] = -y*s + c*x*z; R[1][0] = -z*s + c*x*y; R[1][1] = 1 + c*(y*y-1); R[1][2] = x*s + c*y*z; R[2][0] = y*s + c*x*z; R[2][1] = -x*s + c*y*z; R[2][2] = 1 + c*(z*z-1); memcpy(T, *pG->pXform_curr, sizeof(RtMatrix)); MultiplyMatrices(T, R, pG->pXform_curr); Ribgen_Rotate(&engine, angle, dx, dy, dz); } // -------------------------------------------------------------- RtVoid RiScale (RtFloat dx, RtFloat dy, RtFloat dz) { RtMatrix R, T; GS_xform_push(pG); IdentityMatrix(&R); R[0][0] = dx; R[1][1] = dy; R[2][2] = dz; memcpy(T, *pG->pXform_curr, sizeof(RtMatrix)); MultiplyMatrices(T, R, pG->pXform_curr); Ribgen_Scale(&engine, dx, dy, dz); } // -------------------------------------------------------------- RtVoid RiSkew (RtFloat angle, RtFloat dx1, RtFloat dy1, RtFloat dz1, RtFloat dx2, RtFloat dy2, RtFloat dz2) { } // -------------------------------------------------------------- RtVoid RiTransform (RtMatrix transform) { uint32_t i, j; GS_xform_push(pG); for (i=0; i < 4; i++) for (j=0; j < 4; j++) *pG->pXform_curr[i][j] = transform[i][j]; Ribgen_Transform(&engine, transform); } // -------------------------------------------------------------- RtVoid RiTranslate (RtFloat dx, RtFloat dy, RtFloat dz) { RtMatrix R, T; GS_xform_push(pG); IdentityMatrix(&R); R[0][3] = dx; R[1][3] = dy; R[2][3] = dz; memcpy(T, *pG->pXform_curr, sizeof(RtMatrix)); MultiplyMatrices(T, R, pG->pXform_curr); Ribgen_Translate(&engine, dx, dy, dz); } // -------------------------------------------------------------- RtPoint *RiTransformPoints (RtToken fromspace, RtToken tospace, RtInt npoints, RtPoint *points) { return RI_NULL; } // -------------------------------------------------------------- /* Options */ RtVoid RiCropWindow (RtFloat xmin, RtFloat xmax, RtFloat ymin, RtFloat ymax) { GS_opt_push(pG); pG->pOpt->crop[0] = xmin; pG->pOpt->crop[1] = xmax; pG->pOpt->crop[2] = ymin; pG->pOpt->crop[3] = ymax; Ribgen_CropWindow(&engine, xmin, xmax, ymin, ymax); } // -------------------------------------------------------------- RtVoid RiDisplay (char *name, RtToken type, RtToken mode, ...) { RtToken token; RtPointer arg; va_list args; va_start(args, mode); GS_opt_push(pG); pG->pOpt->display.name = name; pG->pOpt->display.type = type; pG->pOpt->display.mode = mode; while((token = va_arg(args, RtToken)) != RI_NULL) { arg = va_arg(args, RtPointer); } va_start(args, mode); Ribgen_Display(&engine, name, type, mode, args); va_end(args); } // -------------------------------------------------------------- RtVoid RiFormat (RtInt xres, RtInt yres, RtFloat aspect) { GS_opt_push(pG); pG->pOpt->format.xres = xres; pG->pOpt->format.yres = yres; if (aspect > 0) pG->pOpt->format.ar_p = (RtFloat)aspect; pG->pOpt->format.ar_f = pG->pOpt->format.ar_p*xres/yres; Ribgen_Format(&engine, xres, yres, aspect); } // -------------------------------------------------------------- RtVoid RiFrameAspectRatio (RtFloat aspect) { GS_opt_push(pG); pG->pOpt->format.ar_f = aspect; Ribgen_FrameAspectRatio(&engine, aspect); } // -------------------------------------------------------------- RtVoid RiProjection (char *name, ...) { RtToken token; RtPointer arg; va_list args; va_start(args, name); GS_opt_push(pG); pG->pOpt->projection.type = name; while((token = va_arg(args, RtToken)) != RI_NULL) { if (token == RI_FOV) { arg = va_arg(args, RtPointer); pG->pOpt->projection.fov = *((RtFloat*)arg); } } va_start(args, name); Ribgen_Projection(&engine, name, args); va_end(args); } // -------------------------------------------------------------- RtVoid RiScreenWindow (RtFloat left, RtFloat right, RtFloat bot, RtFloat top) { GS_opt_push(pG); pG->pOpt->screen[0] = left; pG->pOpt->screen[1] = right; pG->pOpt->screen[2] = bot; pG->pOpt->screen[3] = top; Ribgen_ScreenWindow(&engine, left, right, bot, top); } // -------------------------------------------------------------- RtVoid RiClipping (RtFloat hither, RtFloat yon) { pG->pOpt->clipping[0] = hither; pG->pOpt->clipping[1] = yon; Ribgen_Clipping(&engine, hither, yon); } // -------------------------------------------------------------- /* Attributes */ RtVoid RiColor (RtColor Cs) { GS_attr_push(pG); pG->pAttr->cs[0] = Cs[0]; pG->pAttr->cs[1] = Cs[1]; pG->pAttr->cs[2] = Cs[2]; Ribgen_Color(&engine, Cs); } // -------------------------------------------------------------- RtVoid RiShadingRate (RtFloat size) { GS_attr_push(pG); pG->pAttr->shadingrate = size; Ribgen_ShadingRate(&engine, size); } // -------------------------------------------------------------- RtVoid RiIlluminate (RtLightHandle light, RtBoolean onoff) { light_t *pLight; pLight = (light_t*)light; pLight->onoff = onoff; Ribgen_Illuminate(&engine, pLight->id, onoff); } // -------------------------------------------------------------- RtVoid RiSides (RtInt nsides) { pG->pAttr->nsides = nsides; Ribgen_Sides(&engine, nsides); } // -------------------------------------------------------------- /* Geometric Primitives (and a couple gprim-specific attributes) */ RtVoid RiPointsPolygons (RtInt npolys, RtInt *nverts, RtInt *verts, ...) { uint32_t j, v, n, k; object_t *pObj; RtToken token; RtPoint *pPoint, *pVert; ri_var_t *pVar; va_list args; va_start(args, verts); if (Engine_context_get(&engine, ENGINE_CONTEXT_LEVEL_MAIN) < ENGINE_CONTEXT_WORLD) { fprintf(stderr, "RiPolygon(): Invalid context!\n"); return; } pObj = (object_t*)jmalloc(npolys*sizeof(object_t)); for (n=0; n < (uint32_t)npolys; n++) { Polygon_init(&pObj[n], ++pW->stat.num_polygons, nverts[n]); } while((token = va_arg(args, RtToken)) != RI_NULL) { if (token == RI_P) { pPoint = (RtPoint*)va_arg(args, RtPointer); v = 0; for (n=0; n < (uint32_t)npolys; n++) { pVar = VarListFindByName(&engine.varList, token); if (!pVar) { fprintf(stderr, "RiPointsPolygons(): Variable \"%s\" not found!\n", token); return; } pVar = VarListAdd(&pObj[n].vars, pVar); pVert = (RtPoint*)VarSet(pVar, NULL, nverts[n]); for (j=0; j < (uint32_t)nverts[n]; j++) { k = verts[v++]; pVert[j][0] = pPoint[k][0]; pVert[j][1] = pPoint[k][1]; pVert[j][2] = pPoint[k][2]; } } } }; for (n=0; n < (uint32_t)npolys; n++) { Object_set_xform(&pObj[n], pG->pXform_curr); Object_set_attr(&pObj[n], pG->pAttr); Scene_Add(pW, &pObj[n]); } jfree(pObj); va_start(args, verts); Ribgen_PointsPolygons(&engine, npolys, nverts, verts, args); va_end(args); } // -------------------------------------------------------------- RtVoid RiPolygon (RtInt nvertices, ...) { object_t obj = {0}; RtToken token; RtPointer arg; ri_var_t *pVar; va_list args; va_start(args, nvertices); if (Engine_context_get(&engine, ENGINE_CONTEXT_LEVEL_MAIN) < ENGINE_CONTEXT_WORLD) { fprintf(stderr, "RiPolygon(): Invalid context!\n"); return; } Polygon_init(&obj, ++pW->stat.num_polygons, nvertices); while((token = va_arg(args, RtToken)) != RI_NULL) { arg = va_arg(args, RtPointer); pVar = VarListFindByName(&engine.varList, token); if (!pVar) { fprintf(stderr, "RiPolygon(): Variable \"%s\" not found!\n", token); return; } pVar = VarListAdd(&obj.vars, pVar); VarSet(pVar, arg, nvertices); }; Object_set_xform(&obj, pG->pXform_curr); Object_set_attr(&obj, pG->pAttr); Scene_Add(pW, &obj); va_start(args, nvertices); Ribgen_Polygon(&engine, &obj, args); va_end(args); } // -------------------------------------------------------------- RtVoid RiBasis (RtBasis ubasis, RtInt ustep, RtBasis vbasis, RtInt vstep) { if (Engine_context_get(&engine, ENGINE_CONTEXT_LEVEL_MAIN) < ENGINE_CONTEXT_WORLD) { fprintf(stderr, "RiBasis(): Invalid context!\n"); return; } GS_attr_push(pG); pG->pAttr->ubasis = (RtPointer)ubasis; pG->pAttr->vbasis = (RtPointer)vbasis; pG->pAttr->ustep = ustep; pG->pAttr->vstep = vstep; Ribgen_Basis(&engine, ubasis, ustep, vbasis, vstep); } RtVoid RiCurves (RtToken degree, RtInt ncurves, RtInt nverts[], RtToken wrap, ...) { uint32_t n; object_t *pObj; RtToken token; RtPointer arg; ri_var_t *pVar, *pKnownVar; va_list args; va_start(args, wrap); if (Engine_context_get(&engine, ENGINE_CONTEXT_LEVEL_MAIN) < ENGINE_CONTEXT_WORLD) { fprintf(stderr, "RiCurves(): Invalid context!\n"); return; } pObj = (object_t*)jmalloc(ncurves*sizeof(object_t)); for (n=0; n < ncurves; n++) { Curve_init(&pObj[n], ++pW->stat.num_curves, degree, nverts[n], wrap); } while((token = va_arg(args, RtToken)) != RI_NULL) { arg = va_arg(args, RtPointer); pKnownVar = VarListFindByName(&engine.varList, token); if (!pKnownVar) { fprintf(stderr, "RiCurves(): Variable \"%s\" not found!\n", token); return; } for (n=0; n < ncurves; n++) { pVar = VarListAdd(&pObj[n].vars, pKnownVar); VarSet(pVar, arg, nverts[n]); } }; for (n=0; n < ncurves; n++) { Object_set_xform(&pObj[n], pG->pXform_curr); Object_set_attr(&pObj[n], pG->pAttr); Scene_Add(pW, &pObj[n]); } va_start(args, wrap); Ribgen_Curves(&engine, pObj, degree, ncurves, nverts, wrap, args); va_end(args); jfree(pObj); } // -------------------------------------------------------------- RtVoid RiPatch (RtToken type, ...) { RtInt npoints; object_t obj; RtToken token; RtPointer arg; ri_var_t *pVar; va_list args; va_start(args, type); if (Engine_context_get(&engine, ENGINE_CONTEXT_LEVEL_MAIN) < ENGINE_CONTEXT_WORLD) { fprintf(stderr, "RiPatch(): Invalid context!\n"); return; } Patch_init(&obj, ++pW->stat.num_patches, type); npoints = 4; if (type == RI_BICUBIC) npoints = 16; while((token = va_arg(args, RtToken)) != RI_NULL) { arg = va_arg(args, RtPointer); pVar = VarListFindByName(&engine.varList, token); if (!pVar) { fprintf(stderr, "RiPatch(): Variable \"%s\" not found!\n", token); return; } pVar = VarListAdd(&obj.vars, pVar); VarSet(pVar, arg, npoints); }; Object_set_xform(&obj, pG->pXform_curr); Object_set_attr(&obj, pG->pAttr); Scene_Add(pW, &obj); va_start(args, type); Ribgen_Patch(&engine, &obj, type, args); va_end(args); } // -------------------------------------------------------------- RtVoid RiPatchMesh (RtToken type, RtInt nu, RtToken uwrap, RtInt nv, RtToken vwrap, ...) { object_t obj; RtToken token; RtPointer arg; ri_var_t *pVar; va_list args; va_start(args, vwrap); if (Engine_context_get(&engine, ENGINE_CONTEXT_LEVEL_MAIN) < ENGINE_CONTEXT_WORLD) { fprintf(stderr, "RiPatchMesh(): Invalid context!\n"); return; } Patchmesh_init(&obj, ++pW->stat.num_patchmeshes, type, nu, uwrap, nv, vwrap, NULL); while((token = va_arg(args, RtToken)) != RI_NULL) { arg = va_arg(args, RtPointer); pVar = VarListFindByName(&engine.varList, token); if (!pVar) { fprintf(stderr, "RiPatch(): Variable \"%s\" not found!\n", token); return; } pVar = VarListAdd(&obj.vars, pVar); VarSet(pVar, arg, nu*nv); }; Object_set_xform(&obj, pG->pXform_curr); Object_set_attr(&obj, pG->pAttr); Scene_Add(pW, &obj); va_start(args, vwrap); Ribgen_Patchmesh(&engine, &obj, type, nu, uwrap, nv, vwrap, args); va_end(args); } // -------------------------------------------------------------- RtVoid RiSphere (RtFloat radius, RtFloat zmin, RtFloat zmax, RtFloat thetamax, ...) { object_t obj = {0}; RtToken token; RtPointer arg; ri_var_t *pVar; va_list args; va_start(args, thetamax); if (Engine_context_get(&engine, ENGINE_CONTEXT_LEVEL_MAIN) < ENGINE_CONTEXT_WORLD) { fprintf(stderr, "RiSphere(): Invalid context!\n"); return; } Sphere_init(&obj, ++pW->stat.num_spheres, radius, zmin, zmax, thetamax); while((token = va_arg(args, RtToken)) != RI_NULL) { arg = va_arg(args, RtPointer); pVar = VarListFindByName(&engine.varList, token); if (!pVar) { fprintf(stderr, "RiSphere(): Variable \"%s\" not found!\n", token); return; } pVar = VarListAdd(&obj.vars, pVar); VarSet(pVar, arg, 1); }; Object_set_xform(&obj, pG->pXform_curr); Object_set_attr(&obj, pG->pAttr); Scene_Add(pW, &obj); va_start(args, thetamax); Ribgen_Sphere(&engine, &obj, radius, zmin, zmax, thetamax, args); va_end(args); } /* Shaders */ RtLightHandle RiLightSource (char *name, ...) { light_t *pLight ; object_t obj = {0}; RtToken token; RtPointer arg; ri_var_t *pVar; va_list args; va_start(args, name); Light_init(&obj, ++pL->stat.num_lights); while((token = va_arg(args, RtToken)) != RI_NULL) { arg = va_arg(args, RtPointer); pVar = VarListFindByName(&engine.varList, token); if (!pVar) { fprintf(stderr, "RiLightSource(): Variable \"%s\" not found!\n", token); return NULL; } pVar = VarListAdd(&obj.vars, pVar); VarSet(pVar, arg, 1); } Object_set_xform(&obj, pG->pXform_curr); Object_set_attr(&obj, pG->pAttr); Scene_Add(pL, &obj); pLight = (light_t*)obj.pObjData; va_start(args, name); Ribgen_LightSource(&engine, &obj, name, pLight->id, args); va_end(args); return (RtLightHandle)pLight; } RtVoid RiSurface (char *name, ...) { RtToken token; RtPointer arg; ri_var_t *pVar; va_list args; va_start(args, name); while((token = va_arg(args, RtToken)) != RI_NULL) { arg = va_arg(args, RtPointer); pVar = VarListFindByName(&engine.varList, token); if (!pVar) { fprintf(stderr, "RiSurface(): Variable \"%s\" not found!\n", token); return; } // pVar = VarListAdd(&obj.vars, pVar); // VarSet(pVar, arg, 1); } va_start(args, name); Ribgen_Surface(&engine, name, args); va_end(args); } RtVoid RiDisplacement (char *name, ...) { RtToken token; RtPointer arg; ri_var_t *pVar; va_list args; va_start(args, name); while((token = va_arg(args, RtToken)) != RI_NULL) { arg = va_arg(args, RtPointer); pVar = VarListFindByName(&engine.varList, token); if (!pVar) { fprintf(stderr, "RiSurface(): Variable \"%s\" not found!\n", token); return; } // pVar = VarListAdd(&obj.vars, pVar); // VarSet(pVar, arg, 1); } va_start(args, name); Ribgen_Displacement(&engine, name, args); va_end(args); }