#include "ri.h" #include "lrt.h" #include "film.h" #include "primitives.h" #include "accel.h" #include "camera.h" #include "mbdofcamera.h" #include "color.h" #include "light.h" #include "sampling.h" #include "materials.h" #include "transport.h" #include "scene.h" #include "image.h" #include "texture.h" #include "nurbs.h" #include #ifdef _WIN32 #include #else #include #endif #include using std::string; #include using std::map; #include #define MOTION_LEVELS 2 class ParamSet { public: ParamSet() { } ParamSet(int n, RtToken *tokens, RtPointer *params) { init(n, tokens, params); } void init(int n, RtToken *tokens, RtPointer *params); Float findFloat(const char *, Float def); Point findPoint(const char *, const Point &def); Vector findVector(const char *, const Vector &def); Normal findNormal(const char *, const Normal &def); Spectrum findSpectrum(const char *, const Spectrum &def); string findString(const char *, const string &def); private: vector > floats; vector > points; vector > vectors; vector > normals; vector > spectra; vector > strings; }; struct GfxOptions { GfxOptions(); Float PixelSamples[2]; Float PixelAspectRatio, FrameAspectRatio; int XResolution, YResolution; Float ScreenLeft, ScreenRight, ScreenTop, ScreenBottom; Float CropLeft, CropRight, CropTop, CropBottom; Float ClipHither, ClipYon; Float ShutterStart, ShutterEnd; Float FStop, FocalLength, FocalDistance; RtToken CameraAutoMode; enum { ORTHOGRAPHIC, PERSPECTIVE } ProjectionType; Float fov; Transform WorldToCamera[MOTION_LEVELS]; Float Gain, Gamma; RtFilterFunc filterfunc; Float FilterXWidth, FilterYWidth; string imager; int ColorQuantOne, ColorQuantMin, ColorQuantMax; Float ColorQuantDither; int DepthQuantOne, DepthQuantMin, DepthQuantMax; Float DepthQuantDither; RtToken DisplayType; char *DisplayName; bool displayRGB, displayA, displayZ; bool JitterSamples; char *ImageViewer; RtToken IlluminationIntegrator; int maxRaylevel; Filter *MakeFilter( ) const; Image *MakeImage(Sampler *sampler) const; Camera *GfxOptions::MakeCamera(Film *film) const; Film *GfxOptions::MakeFilm(Image *image) const; Sampler *MakeSampler( Filter *filter ) const; Integrator *MakeIntegrator() const; }; GfxOptions::GfxOptions() { PixelSamples[0] = PixelSamples[1] = 2.; PixelAspectRatio = 1.; FrameAspectRatio = 4. / 3.; XResolution = 640; YResolution = 480; ScreenLeft = -4. / 3.; ScreenBottom = -1; ScreenRight = 4. / 3.; ScreenTop = 1.; CropLeft = CropBottom = 0.; CropRight = CropTop = 1.; ClipHither = 1e-2; ClipYon = RI_INFINITY; ShutterStart = ShutterEnd = 0; FStop = RI_INFINITY; FocalLength = FocalDistance = RI_INFINITY; CameraAutoMode = NULL; ProjectionType = PERSPECTIVE; fov = 90.f; Gain = Gamma = 1.; filterfunc = RiGaussianFilter; FilterXWidth = FilterYWidth = 2.; imager = ""; ColorQuantOne = 255; ColorQuantMin = 0; ColorQuantMax = 255; ColorQuantDither = 0.5; DepthQuantOne = DepthQuantMin = DepthQuantMax = 0; DepthQuantDither = 0.; DisplayType = RI_FILE; DisplayName = "lrt.tiff"; displayRGB = displayA = true; displayZ = false; ImageViewer = NULL; IlluminationIntegrator = LRT_WHITTED; maxRaylevel = 5; JitterSamples=true; } struct GfxState { GfxState(); Spectrum color; ParamSet surfaceParams; string surface; bool CastsShadows; int NumLightSamples; enum { SampleSurface, SampleLight, SampleCombination } Sampling; ParamSet areaLightParams; string areaLight; void AddShape(Shape *shape, ParamSet &geomParams); }; GfxState::GfxState() { color = Spectrum(1.); surface = "matte"; CastsShadows = false; NumLightSamples = 1; } #define STATE_UNINITIALIZED 0 #define STATE_BEGIN 1 #define STATE_WORLD_BEGIN 2 static int currentApiState = STATE_UNINITIALIZED; static const char *missingStateCall[] = { "RiEnd()", "RiBegin()", "RiWorldBegin()" }; #define TOKEN_HASH_SIZE 1024 static list > TokenTable[TOKEN_HASH_SIZE]; #define TOKEN_TYPE_ERROR -1 #define TOKEN_TYPE_UNIFORM (1<<0) #define TOKEN_TYPE_VERTEX (1<<1) #define TOKEN_TYPE_FLOAT (1<<2) #define TOKEN_TYPE_POINT (1<<3) #define TOKEN_TYPE_VECTOR (1<<4) #define TOKEN_TYPE_NORMAL (1<<5) #define TOKEN_TYPE_STRING (1<<6) #define TOKEN_TYPE_COLOR (1<<7) #define TOKEN_TYPE_VOID (1<<8) #define TOKEN_TYPE_HPOINT (1<<9) static int argsCount; static int argsAllocated; static RtToken *argTokens; static RtPointer *argParams; static GfxOptions curGfxOptions; static list transformStack[MOTION_LEVELS]; static list hierarchicalState; static GfxState curGfxState; static list gstates; static int motionLevel = 0; static bool inMotionBlock = false; static Transform curTransform[MOTION_LEVELS]; static vector primitives; static vector lights; #define VERIFY_STATE(s, func) \ if (currentApiState != s) { \ Error("Must have called %s before calling %s(). Ignoring.", \ missingStateCall[s], func); \ return; \ } \ else /* swallow trailing semicolon */ RtToken RI_A, RI_ABORT, RI_AMBIENTLIGHT, RI_AMPLITUDE, RI_AZ, RI_BACKGROUND, RI_BEAMDISTRIBUTION, RI_BICUBIC, RI_BILINEAR, RI_BLACK, RI_BUMPY, RI_CAMERA, RI_CLAMP, RI_COMMENT, RI_CONEANGLE, RI_CONEDELTAANGLE, RI_CONSTANT, RI_CS, RI_DEPTHCUE, RI_DIFFERENCE, RI_DISTANCE, RI_DISTANTLIGHT, RI_FILE, RI_FLATNESS, RI_FOG, RI_FOV, RI_FRAMEBUFFER, RI_FROM, RI_HANDLER, RI_HIDDEN, RI_IDENTIFIER, RI_IGNORE, RI_INSIDE, RI_INTENSITY, RI_INTERSECTION, RI_KA, RI_KD, RI_KR, RI_KS, RI_LH, RI_LIGHTCOLOR, RI_MATTE, RI_MAXDISTANCE, RI_METAL, RI_MINDISTANCE, RI_N, RI_NAME, RI_NONPERIODIC, RI_NP, RI_OBJECT, RI_ORIGIN, RI_ORTHOGRAPHIC, RI_OS, RI_OUTSIDE, RI_P, RI_PAINT, RI_PAINTEDPLASTIC, RI_PERIODIC, RI_PERSPECTIVE, RI_PLASTIC, RI_POINTLIGHT, RI_PRIMITIVE, RI_PRINT, RI_PW, RI_PZ, RI_RASTER, RI_RGB, RI_RGBA, RI_RGBAZ, RI_RGBZ, RI_RH, RI_ROUGHNESS, RI_S, RI_SCREEN, RI_SHADINGGROUP, RI_SHINYMETAL, RI_SMOOTH, RI_SPECULARCOLOR, RI_SPOTLIGHT, RI_ST, RI_STRUCTURE, RI_T, RI_TEXTURENAME, RI_TO, RI_TRIMDEVIATION, RI_UNION, RI_WORLD, RI_Z; RtToken LRT_IMAGEVIEWER; RtToken LRT_RENDER, LRT_DISPLAY; RtToken LRT_INTEGRATOR, LRT_SHADOWS, LRT_COLOR; RtToken LRT_WHITTED, LRT_MONTECARLO, LRT_PATH; RtToken LRT_SURFACE, LRT_COMBINATION, LRT_SAMPLE; RtToken LRT_LIGHT, LRT_RAYCAST, LRT_NSAMPLES; RtToken LRT_VIEWST, LRT_GLASS, LRT_INDEX, LRT_KT; RtToken LRT_CHECKERED, LRT_CHECKCOLOR1, LRT_CHECKCOLOR2, LRT_CHECKFREQUENCY; RtToken LRT_DIFFUSE; RtToken LRT_TYPE, LRT_SHUTTER; RtToken LRT_PINHOLE, LRT_MBDOF; RtToken LRT_IRIS, LRT_STRIPE; RtToken LRT_IRIS_RATE, LRT_STRIPE_WIDTH, LRT_STRIPE_DIRECTION; RtToken LRT_DOWN, LRT_UP, LRT_LEFT, LRT_RIGHT; RtToken LRT_FORMAT, LRT_BUCKETSIZE, LRT_GRIDSIZE, LRT_TEXTUREMEMORY; RtToken LRT_ZTHRESHOLD, LRT_EXTREMEDISPLACEMENT, LRT_EYESPLITS; RtToken LRT_GEOMMEMORY, LRT_BIAS0, LRT_BIAS1, LRT_SHADER, LRT_TEXTURE; RtToken LRT_VFXMASTER, LRT_VFXINSTANCE, LRT_ARCHIVE, LRT_RESOURCE; RtToken LRT_MINSAMPLES, LRT_MAXSAMPLES, LRT_MAX_RAYLEVEL, LRT_BRANCH_RATIO; RtToken LRT_MAX_BRANCH_RATIO, LRT_MINSHADOWBIAS, LRT_STEPS, LRT_MINPATCHSAMPLES; RtToken LRT_VERBOSITY, LRT_INCLUDE, LRT_REFRESH, LRT_FULLCOLOR; RtToken LRT_SETPOINTS, LRT_NAME, LRT_SHADINGGROUP, LRT_BINARY; RtToken LRT_COORDINATESYSTEM, LRT_SPHERE, LRT_SENSE, LRT_AVERAGECOLOR; RtToken LRT_EMISSIONCOLOR, LRT_PATCHSIZE, LRT_ELEMSIZE, LRT_MINSIZE; RtToken LRT_ZONAL, LRT_CASTS_SHADOWS, LRT_PATCH_MAXLEVEL, LRT_PATCH_MINLEVEL; RtToken LRT_PATCH_MULTIPLIER, LRT_TRUEDISPLACEMENT, LRT_CACHE; RtToken LRT_UDIVISIONS, LRT_VDIVISIONS, LRT_ORIGIN; RtToken LRT_MERGE, LRT_COMPRESSION, LRT_RESOLUTION, LRT_RESOLUTIONUNIT; RtToken LRT_JITTER, LRT_PDISC, LRT_FLATNESS, LRT_WIDTH, LRT_CONSTANTWIDTH; RtToken LRT_CAMERA_MODE; RtToken LRT_MANUAL, LRT_SHUTTER_PRIORITY; RtToken LRT_APERTURE_PRIORITY, LRT_PROGRAMMED; u_int hashTokenString(const char *name) { u_int hashValue = 0; while (*name) { hashValue <<= 1; hashValue ^= *name; ++name; } return hashValue % TOKEN_HASH_SIZE; } static int stringToType(const char *strType); static void typeToString(int type, char string[]); static int stringToType(const char *strType) { if (strType == NULL) return TOKEN_TYPE_VOID; int type; const char *strp = strType; while (*strp && isspace(*strp)) ++strp; if (!*strp) return TOKEN_TYPE_ERROR; if (strncmp("uniform", strp, strlen("uniform")) == 0) { type = TOKEN_TYPE_UNIFORM; strp += strlen("uniform"); } else if (strncmp("constant", strp, strlen("constant")) == 0) { type = TOKEN_TYPE_UNIFORM; strp += strlen("constant"); } else if (strncmp("vertex", strp, strlen("vertex")) == 0) { type = TOKEN_TYPE_VERTEX; strp += strlen("vertex"); } else type = TOKEN_TYPE_UNIFORM; while (*strp && isspace(*strp)) ++strp; if (!*strp) return TOKEN_TYPE_ERROR; #define TRY_DECODING_TYPE(name, mask) \ if (strncmp(name, strp, strlen(name)) == 0) { \ type |= mask; strp += strlen(name); \ } // *INDENT-OFF* TRY_DECODING_TYPE("float", TOKEN_TYPE_FLOAT) else TRY_DECODING_TYPE("point", TOKEN_TYPE_POINT) else TRY_DECODING_TYPE("hpoint", TOKEN_TYPE_HPOINT) else TRY_DECODING_TYPE("vector", TOKEN_TYPE_VECTOR) else TRY_DECODING_TYPE("normal", TOKEN_TYPE_NORMAL) else TRY_DECODING_TYPE("string", TOKEN_TYPE_STRING) else TRY_DECODING_TYPE("color", TOKEN_TYPE_COLOR) else { Error("RiDeclare: unable to decode type \"%s\"", strType); return TOKEN_TYPE_ERROR; } // *INDENT-ON* while (*strp && isspace(*strp)) ++strp; if (*strp) Warning("RiDeclare: unknown text at end of declared type \"%s\".", strType); return type; } static void typeToString(int type, char *string) { if (type == TOKEN_TYPE_VOID) { string = strcat(string, "RI_NULL"); return; } if (type & TOKEN_TYPE_UNIFORM) string = strcat(string, "uniform "); else if (type & TOKEN_TYPE_VERTEX) string = strcat(string, "vertex "); else Severe("typeToString: unknown type %d", type); if (type & TOKEN_TYPE_FLOAT) string = strcat(string, "float"); else if (type & TOKEN_TYPE_POINT) string = strcat(string, "point"); else if (type & TOKEN_TYPE_HPOINT) string = strcat(string, "hpoint"); else if (type & TOKEN_TYPE_VECTOR) string = strcat(string, "vector"); else if (type & TOKEN_TYPE_NORMAL) string = strcat(string, "normal"); else if (type & TOKEN_TYPE_STRING) string = strcat(string, "string"); else if (type & TOKEN_TYPE_COLOR) string = strcat(string, "color"); else Severe("typeToString: unknown type %d", type); } static RtToken lookupToken(const char *name) { if (name == NULL) return RI_NULL; u_int offset = hashTokenString(name); list >::iterator iter = TokenTable[offset].begin(); while (iter != TokenTable[offset].end()) { if (strcmp(iter->first, name) == 0) return iter->first; ++iter; } return RI_NULL; } static bool lookupTokenAndType(const char *name, RtToken *token, int *type) { Assert(name != NULL); bool tryInline = false; const char *p = name; while (*p) { if (isspace(*p)) { tryInline = true; break; } ++p; } if (tryInline) { const char *end = &name[strlen(name) - 1]; while (!isspace(*end)) --end; char *buf = (char *)alloca(end - name + 1); strncpy(buf, name, end-name); buf[end-name] = '\0'; *type = stringToType(buf); *token = (char *)end + 1; if (*type != TOKEN_TYPE_ERROR) return true; } u_int offset = hashTokenString(name); list >::iterator iter = TokenTable[offset].begin(); while (iter != TokenTable[offset].end()) { if (strcmp(iter->first, name) == 0) { *token = iter->first; *type = iter->second; return true; } ++iter; } return false; } static void vectorizeParameters(va_list args) { argsCount = 0; const char *name; while ((name = va_arg(args, const char *)) != RI_NULL) { if (argsCount >= argsAllocated) { int newArgs; if (argsAllocated == 0) newArgs = 10; else newArgs = 2 * argsAllocated; argTokens = (RtToken *)realloc(argTokens, newArgs * sizeof(RtToken)); argParams = (RtPointer *)realloc(argParams, newArgs * sizeof(RtPointer)); argsAllocated = newArgs; } argTokens[argsCount] = (RtToken)name; argParams[argsCount] = va_arg(args, RtPointer); if (argParams[argsCount] == RI_NULL) Error("Null parameter value for argument %s?!?", name); else ++argsCount; } } void reportUnusedParameters(const char *funcName, int nArgs, RtToken tokens[], ...) { vector usedParameters; va_list args; va_start(args, tokens); RtToken token; while ((token = va_arg(args, RtToken)) != RI_NULL) usedParameters.push_back(token); va_end(args); for (int i = 0; i < nArgs; ++i) { for (u_int j = 0; j < usedParameters.size(); ++j) if (tokens[i] == usedParameters[j]) goto tokenUsed; for (u_int j = 0; j < usedParameters.size(); ++j) if (strcmp(tokens[i], usedParameters[j]) == 0) goto tokenUsed; Warning("%s(): parameter \"%s\" is unknown and will be ignored.", funcName, argTokens[i]); tokenUsed: ; } } void ParamSet::init(int n, RtToken *tokens, RtPointer *params) { floats.erase(floats.begin(), floats.end()); points.erase(points.begin(), points.end()); vectors.erase(vectors.begin(), vectors.end()); normals.erase(normals.begin(), normals.end()); spectra.erase(spectra.begin(), spectra.end()); strings.erase(strings.begin(), strings.end()); for (int i = 0; i < n; ++i) { RtToken tok; int type; if (lookupTokenAndType(tokens[i], &tok, &type)) { if (type & TOKEN_TYPE_STRING) strings.push_back(make_pair(tok, string(*(char **)params[i]))); else { Float *fp = (float *)params[i]; if (type & TOKEN_TYPE_FLOAT) floats.push_back(make_pair(tok, *fp)); else if (type & TOKEN_TYPE_POINT) points.push_back(make_pair(tok, Point(fp[0], fp[1], fp[2]))); if (type & TOKEN_TYPE_VECTOR) vectors.push_back(make_pair(tok, Vector(fp[0], fp[1], fp[2]))); if (type & TOKEN_TYPE_NORMAL) normals.push_back(make_pair(tok, Normal(fp[0], fp[1], fp[2]))); if (type & TOKEN_TYPE_COLOR) spectra.push_back(make_pair(tok, Spectrum(fp[0], fp[1], fp[2]))); } } else Warning("Type of parameter \"%s\" is unknown", tokens[i]); } } Float ParamSet::findFloat(const char *name, Float def) { for (u_int i = 0; i < floats.size(); ++i) if (floats[i].first == name) return floats[i].second; return def; } Point ParamSet::findPoint(const char *name, const Point &def) { for (u_int i = 0; i < points.size(); ++i) if (points[i].first == name) return points[i].second; return def; } Vector ParamSet::findVector(const char *name, const Vector &def) { for (u_int i = 0; i < vectors.size(); ++i) if (vectors[i].first == name) return vectors[i].second; return def; } Normal ParamSet::findNormal(const char *name, const Normal &def) { for (u_int i = 0; i < normals.size(); ++i) if (normals[i].first == name) return normals[i].second; return def; } Spectrum ParamSet::findSpectrum(const char *name, const Spectrum &def) { for (u_int i = 0; i < spectra.size(); ++i) if (spectra[i].first == name) return spectra[i].second; return def; } string ParamSet::findString(const char *name, const string &def) { for (u_int i = 0; i < strings.size(); ++i) if (strings[i].first == name) return strings[i].second; return def; } Filter *GfxOptions::MakeFilter( ) const { if (filterfunc == RiBoxFilter) return new BoxFilter(); if (filterfunc == RiTriangleFilter) return new TriangleFilter(); if (filterfunc == RiCatmullRomFilter) return new GaussianFilter(); // XXX if (filterfunc == RiGaussianFilter) return new GaussianFilter(); if (filterfunc == RiSincFilter) return new GaussianFilter(); // XXX if (filterfunc == RiMitchellFilter) return new MitchellFilter(); return new GeneralFilter( filterfunc ); } Image *GfxOptions::MakeImage(Sampler *sampler) const { Imager *imager = NULL; return new Image(XResolution, YResolution, CropLeft, CropRight, CropBottom, CropTop, displayRGB, displayA, // displayZ, imager, Gain, Gamma, ColorQuantOne, ColorQuantMin, ColorQuantMax, ColorQuantDither, // DepthQuantOne, // DepthQuantMin, DepthQuantMax, DepthQuantDither, DisplayName, sampler); } Camera *GfxOptions::MakeCamera(Film *film) const { if (ShutterStart != ShutterEnd || FStop < RI_INFINITY) { if (ProjectionType == PERSPECTIVE) return new MbDOFPerspectiveCamera(WorldToCamera, MOTION_LEVELS, //ScreenLeft, ScreenRight, ScreenTop, ScreenBottom, ClipHither, ClipYon, ShutterStart, ShutterEnd, FStop, FocalLength, FocalDistance, CameraAutoMode, fov, film); else Error("Orthographic projections not supported for moving/dof cameras"); return NULL; } if (ProjectionType == PERSPECTIVE) return new PerspectiveCamera(WorldToCamera[0], ClipHither, ClipYon, fov, film); else return new OrthoCamera(WorldToCamera[0], ClipHither, ClipYon, film); } Film *GfxOptions::MakeFilm(Image *image) const { return new ColorFilm(image, ScreenLeft, ScreenRight, ScreenTop, ScreenBottom); } Sampler *GfxOptions::MakeSampler( Filter *filter ) const { return new JitterSampler(XResolution, YResolution, PixelSamples[0], PixelSamples[1], JitterSamples, filter ); } Integrator *GfxOptions::MakeIntegrator() const { if (IlluminationIntegrator == LRT_WHITTED) return new WhittedIntegrator(maxRaylevel); else if (IlluminationIntegrator == LRT_PATH) return new PathIntegrator; else if (IlluminationIntegrator == LRT_MONTECARLO) return new MCIntegrator; else return new WhittedIntegrator(5); } void GfxState::AddShape(Shape *shape, ParamSet &geomParams) { if (!shape) return; AreaLight *area = NULL; if (areaLight == "") { // Fine, do nothing } else if (areaLight == "arealight" || areaLight == "diffuse") { Float intensity = areaLightParams.findFloat("intensity", 1.); Spectrum power = areaLightParams.findSpectrum("lightcolor", Spectrum(1.)); power *= intensity; power = areaLightParams.findSpectrum("Phi", power); area = new AreaLight(CastsShadows, curTransform[0], power, shape); } else Warning("Unknown area light type \"%s\"", areaLight.c_str()); Material *mtl = NULL; if (surface == "matte") { Spectrum Kd = color * geomParams.findFloat("Kd", surfaceParams.findFloat("Kd", 1.)); mtl = new Matte(new ConstantTexture(Kd)); } else if (surface == "glass") { Spectrum Kr = color * geomParams.findFloat("Kr", surfaceParams.findFloat("Kr", 1.)); Spectrum Kt = color * geomParams.findFloat("Kt", surfaceParams.findFloat("Kt", 1.)); Float index = geomParams.findFloat("index", surfaceParams.findFloat("index", 1.)); mtl = new Glass(new ConstantTexture(Kr), new ConstantTexture(Kt), new ConstantTexture(index)); } else if (surface == "plastic" || surface == "spd") { Spectrum Kd = color * geomParams.findFloat("Kd", surfaceParams.findFloat("Kd", 1.)); Spectrum Ks = color * geomParams.findFloat("Ks", surfaceParams.findFloat("Ks", 1.)) * geomParams.findSpectrum("specularcolor", surfaceParams.findSpectrum("specularcolor", 1.)); Float rough = geomParams.findFloat("roughness", surfaceParams.findFloat("roughness", .1)); mtl = new Plastic(new ConstantTexture(Kd), new ConstantTexture(Ks), new ConstantTexture(rough)); } else if (surface == "paintedplastic") { Spectrum Kd = color * geomParams.findFloat("Kd", surfaceParams.findFloat("Kd", 1.)); Spectrum Ks = color * geomParams.findFloat("Ks", surfaceParams.findFloat("Ks", 1.)) * geomParams.findSpectrum("specularcolor", surfaceParams.findSpectrum("specularcolor", 1.)); Float rough = geomParams.findFloat("roughness", surfaceParams.findFloat("roughness", .1)); string tex = geomParams.findString("texturename", surfaceParams.findString("texturename", "")); if (tex != "") { Texture *kd = new ScaleTexture( new ConstantTexture(Kd), new ImageTexture(Transform(), tex)); Texture *ks = new ScaleTexture( new ConstantTexture(Ks), new ImageTexture(Transform(), tex)); mtl = new Plastic(kd, ks, new ConstantTexture(rough)); } else mtl = new Plastic(new ConstantTexture(Kd), new ConstantTexture(Ks), new ConstantTexture(rough)); } else if (surface == "checkered") { Float freq = geomParams.findFloat("checkfrequency", surfaceParams.findFloat("checkfrequency", 1.)); Spectrum c1 = color * geomParams.findSpectrum("color1", surfaceParams.findSpectrum("color1", 1.)); Spectrum c2 = color * geomParams.findSpectrum("color2", surfaceParams.findSpectrum("color2", 1.)); Transform xform = Scale(freq, freq, freq); Texture *tex = new SolidCheckerboard(xform, new ConstantTexture(c1), new ConstantTexture(c2)); mtl = new Matte(tex); } else if (surface == "shinymetal") { Spectrum Ks = color * geomParams.findFloat("Ks", surfaceParams.findFloat("Ks", 1.)); Float rough = geomParams.findFloat("roughness", surfaceParams.findFloat("roughness", .1)); Spectrum Kr = color * geomParams.findFloat("Kr", surfaceParams.findFloat("Kr", 1.)); mtl = new ShinyMetal(new ConstantTexture(Ks), new ConstantTexture(rough), new ConstantTexture(Kr)); } else { Warning("Unknown surface type \"%s\"", surface.c_str()); mtl = new Matte(new ConstantTexture(color)); } GeometricPrimitive *prim = new GeometricPrimitive(shape, mtl, area); primitives.push_back(prim); if (area != NULL) lights.push_back(area); } RtVoid RiWorldEnd() { while (hierarchicalState.size()) { char c = hierarchicalState.back(); if (c == 't') Error("Missing end to RiTransformBegin"); else if (c == 'a') Error("Missing end to RiAttributeBegin"); else Severe("Internal error in gfx state management"); hierarchicalState.pop_back(); } if(curGfxOptions.CameraAutoMode == NULL) curGfxOptions.CameraAutoMode = LRT_MANUAL; Filter *filter = curGfxOptions.MakeFilter(); Sampler *sampler = curGfxOptions.MakeSampler(filter); Image *image = curGfxOptions.MakeImage(sampler); Film *film = curGfxOptions.MakeFilm(image); Camera *camera = curGfxOptions.MakeCamera(film); Integrator *integrator = curGfxOptions.MakeIntegrator(); Scene scene(camera, integrator, image, sampler, primitives, lights); scene.Render(); currentApiState = STATE_BEGIN; for (u_int i = 0; i < primitives.size(); ++i) delete primitives[i]; primitives.erase(primitives.begin(), primitives.end()); for (u_int i = 0; i < lights.size(); ++i) delete lights[i]; lights.erase(lights.begin(), lights.end()); StatsPrint(STATS_DETAILED, stderr); } RtToken RiDeclare(char *name, char *type) { int tokenType = stringToType(type); if (tokenType == TOKEN_TYPE_ERROR) return RI_NULL; u_int hashValue = hashTokenString(name); list >::iterator iter = TokenTable[hashValue].begin(); while (iter != TokenTable[hashValue].end()) { if (strcmp(iter->first, name) == 0) { if (iter->second != tokenType) { char str1[80], str2[80]; typeToString(iter->second, str1); typeToString(tokenType, str2); Warning("RiDeclare: Token '%s' redeclared from %s to %s.", name, str1, str2); } return iter->first; } ++iter; } char *newToken = Strdup(name); TokenTable[hashValue].push_front(make_pair(newToken, tokenType)); return newToken; } RtVoid RiBegin(RtToken tok) { if (currentApiState != STATE_UNINITIALIZED) { Error("RiBegin() has already been called."); return; } if (tok != RI_NULL) Warning("Unknown renderer name %s in RiBegin()", tok); currentApiState = STATE_BEGIN; curGfxOptions = GfxOptions(); for (int i = 0; i < MOTION_LEVELS; ++i) curTransform[i] = Transform(); RI_A = RiDeclare("a", RI_NULL); RI_ABORT = RiDeclare("abort", RI_NULL); RI_AMBIENTLIGHT = RiDeclare("ambientlight", RI_NULL); RI_AMPLITUDE = RiDeclare("amplitude", RI_NULL); RI_AZ = RiDeclare("az", RI_NULL); RI_BACKGROUND = RiDeclare("background", RI_NULL); RI_BEAMDISTRIBUTION = RiDeclare("beamdistribution", RI_NULL); RI_BICUBIC = RiDeclare("bicubic", RI_NULL); RI_BILINEAR = RiDeclare("bilinear", RI_NULL); RI_BLACK = RiDeclare("black", RI_NULL); RI_BUMPY = RiDeclare("bumpy", RI_NULL); RI_CAMERA = RiDeclare("camera", RI_NULL); RI_CLAMP = RiDeclare("clamp", RI_NULL); RI_COMMENT = RiDeclare("comment", RI_NULL); RI_CONEANGLE = RiDeclare("coneangle", "float"); RI_CONEDELTAANGLE = RiDeclare("conedeltaangle", "float"); RI_CONSTANT = RiDeclare("constant", RI_NULL); RI_CS = RiDeclare("Cs", "vertex color"); RI_DEPTHCUE = RiDeclare("depthcue", RI_NULL); RI_DIFFERENCE = RiDeclare("difference", RI_NULL); RI_DISTANCE = RiDeclare("distance", RI_NULL); RI_DISTANTLIGHT = RiDeclare("distantlight", RI_NULL); RI_FILE = RiDeclare("file", RI_NULL); RI_FLATNESS = RiDeclare("flatness", RI_NULL); RI_FOG = RiDeclare("fog", RI_NULL); RI_FOV = RiDeclare("fov", "float"); RI_FRAMEBUFFER = RiDeclare("framebuffer", RI_NULL); RI_FROM = RiDeclare("from", "point"); RI_HANDLER = RiDeclare("handler", RI_NULL); RI_HIDDEN = RiDeclare("hidden", RI_NULL); RI_IDENTIFIER = RiDeclare("identifier", "string"); RI_IGNORE = RiDeclare("ignore", RI_NULL); RI_INSIDE = RiDeclare("inside", RI_NULL); RI_INTENSITY = RiDeclare("intensity", "float"); RI_INTERSECTION = RiDeclare("intersection", RI_NULL); RI_KA = RiDeclare("Ka", "float"); RI_KD = RiDeclare("Kd", "float"); RI_KR = RiDeclare("Kr", "float"); RI_KS = RiDeclare("Ks", "float"); RI_LH = RiDeclare("lh", RI_NULL); RI_LIGHTCOLOR = RiDeclare("lightcolor", "color"); RI_MATTE = RiDeclare("matte", RI_NULL); RI_MAXDISTANCE = RiDeclare("maxdistance", "float"); RI_METAL = RiDeclare("metal", RI_NULL); RI_MINDISTANCE = RiDeclare("mindistance", "float"); RI_N = RiDeclare("N", "vertex normal"); RI_NAME = RiDeclare("name", "string"); RI_NONPERIODIC = RiDeclare("nonperiodic", RI_NULL); RI_NP = RiDeclare("Np", RI_NULL); RI_OBJECT = RiDeclare("object", RI_NULL); RI_ORIGIN = RiDeclare("origin", "point"); RI_ORTHOGRAPHIC = RiDeclare("orthographic", RI_NULL); RI_OS = RiDeclare("Os", "float"); RI_OUTSIDE = RiDeclare("outside", RI_NULL); RI_P = RiDeclare("P", "vertex point"); RI_PAINT = RiDeclare("paint", RI_NULL); RI_PAINTEDPLASTIC = RiDeclare("paintedplastic", RI_NULL); RI_PERIODIC = RiDeclare("periodic", RI_NULL); RI_PERSPECTIVE = RiDeclare("perspective", RI_NULL); RI_PLASTIC = RiDeclare("plastic", RI_NULL); RI_POINTLIGHT = RiDeclare("pointlight", RI_NULL); RI_PRIMITIVE = RiDeclare("primitive", RI_NULL); RI_PRINT = RiDeclare("print", RI_NULL); RI_PW = RiDeclare("Pw", "vertex hpoint"); RI_PZ = RiDeclare("Pz", "vertex float"); RI_RASTER = RiDeclare("raster", RI_NULL); RI_RGB = RiDeclare("rgb", RI_NULL); RI_RGBA = RiDeclare("rgba", RI_NULL); RI_RGBAZ = RiDeclare("rgbaz", RI_NULL); RI_RGBZ = RiDeclare("rgbz", RI_NULL); RI_RH = RiDeclare("rh", RI_NULL); RI_ROUGHNESS = RiDeclare("roughness", "float"); RI_S = RiDeclare("s", "vertex float"); RI_SCREEN = RiDeclare("screen", RI_NULL); RI_SHADINGGROUP = RiDeclare("shadinggroup", RI_NULL); RI_SHINYMETAL = RiDeclare("shinymetal", RI_NULL); RI_SMOOTH = RiDeclare("smooth", RI_NULL); RI_SPECULARCOLOR = RiDeclare("specularcolor", "color"); RI_SPOTLIGHT = RiDeclare("spotlight", RI_NULL); //RI_ST = RiDeclare("st", "vertex float[2]"); // XXX RI_STRUCTURE = RiDeclare("structure", RI_NULL); RI_T = RiDeclare("t", "vertex float"); RI_TEXTURENAME = RiDeclare("texturename", "string"); RI_TO = RiDeclare("to", "point"); RI_TRIMDEVIATION = RiDeclare("trimdeviation", "float"); RI_UNION = RiDeclare("union", RI_NULL); RI_WORLD = RiDeclare("world", RI_NULL); RI_Z = RiDeclare("z", RI_NULL); LRT_RAYCAST = RiDeclare("raycast", RI_NULL); LRT_CHECKCOLOR1 = RiDeclare("checkcolor1", "color"); LRT_CHECKCOLOR2 = RiDeclare("checkcolor2", "color"); LRT_CHECKERED = RiDeclare("checkered", RI_NULL); LRT_CHECKFREQUENCY = RiDeclare("checkfrequency", "float"); LRT_COLOR = RiDeclare("color", RI_NULL); LRT_DISPLAY = RiDeclare("display", RI_NULL); LRT_GLASS = RiDeclare("glass", RI_NULL); LRT_IMAGEVIEWER = RiDeclare("imageviewer", "string"); LRT_INDEX = RiDeclare("index", "float"); LRT_INTEGRATOR = RiDeclare("integrator", "string"); LRT_KT = RiDeclare("Kt", "float"); LRT_LIGHT = RiDeclare("light", RI_NULL); LRT_NSAMPLES = RiDeclare("nsamples", "float"); LRT_RENDER = RiDeclare("render", RI_NULL); LRT_SHADOWS = RiDeclare("shadows", "string"); LRT_VIEWST = RiDeclare("viewst", RI_NULL); LRT_WHITTED = RiDeclare("whitted", RI_NULL); LRT_PATH = RiDeclare("path", RI_NULL); LRT_MONTECARLO = RiDeclare("montecarlo", RI_NULL); LRT_DIFFUSE = RiDeclare("diffuse", RI_NULL); LRT_SURFACE = RiDeclare("surface", RI_NULL); LRT_COMBINATION = RiDeclare("combination", RI_NULL); LRT_SAMPLE = RiDeclare("sample", RI_NULL); LRT_PINHOLE = RiDeclare("pinhole", "string" ); LRT_MBDOF = RiDeclare("mbdof", "string" ); LRT_IRIS = RiDeclare("iris", "string" ); LRT_STRIPE = RiDeclare("stripe", "string" ); LRT_TYPE = RiDeclare("type", "string" ); LRT_SHUTTER = RiDeclare("shutter", "string" ); LRT_IRIS_RATE = RiDeclare("iris_rate", "float" ); LRT_STRIPE_WIDTH = RiDeclare("stripe_width", "float" ); LRT_STRIPE_DIRECTION = RiDeclare("stripe_direction", "string" ); LRT_DOWN = RiDeclare( "down", "string" ); LRT_UP = RiDeclare( "up", "string" ); LRT_LEFT = RiDeclare( "left", "string" ); LRT_RIGHT = RiDeclare( "right", "string" ); LRT_CAMERA_MODE = RiDeclare("mode", "string"); LRT_MANUAL = RiDeclare("manual", "string"); LRT_SHUTTER_PRIORITY = RiDeclare("shutter_priority", "string"); LRT_APERTURE_PRIORITY = RiDeclare("aperture_priority", "string"); LRT_PROGRAMMED = RiDeclare("programmed", "string"); LRT_FORMAT = RiDeclare( "format", "string" ); LRT_BUCKETSIZE = RiDeclare( "bucketsize", /*int*/ "float" /*[2]*/); LRT_GRIDSIZE = RiDeclare( "gridsize", /*int*/ "float" /*[2]*/); LRT_TEXTUREMEMORY = RiDeclare( "texturememory", /*int*/ "float" ); LRT_ZTHRESHOLD = RiDeclare( "zthreshold", "point" ); LRT_EXTREMEDISPLACEMENT = RiDeclare( "extremedisplacement", /*int*/ "float" ); LRT_EYESPLITS = RiDeclare( "eyesplits", /*int*/ "float" ); LRT_GEOMMEMORY = RiDeclare( "geommemory", /*int*/ "float" ); LRT_BIAS0 = RiDeclare( "bias0", "float" ); LRT_BIAS1 = RiDeclare( "bias1", "float" ); LRT_SHADER = RiDeclare( "shader", "string" ); LRT_TEXTURE = RiDeclare( "texture", "string" ); LRT_VFXMASTER = RiDeclare( "vfxmaster", "string" ); LRT_VFXINSTANCE = RiDeclare( "vfxinstance", "string" ); LRT_ARCHIVE = RiDeclare( "archive", "string" ); /* Added for PRMan 3.8 */ LRT_RESOURCE = RiDeclare( "resource", "string" ); /* Missing item added. */ LRT_MINSAMPLES = RiDeclare( "minsamples", /*int*/ "float" ); LRT_MAXSAMPLES = RiDeclare( "maxsamples", /*int*/ "float" ); LRT_MAX_RAYLEVEL = RiDeclare( "max_raylevel", /*int*/ "float" ); LRT_BRANCH_RATIO = RiDeclare( "branch_ratio", /*int*/ "float" ); LRT_MAX_BRANCH_RATIO = RiDeclare( "max_branch_ratio", /*int*/ "float" ); LRT_MINSHADOWBIAS = RiDeclare( "minshadowbias", "float" ); LRT_STEPS = RiDeclare( "steps", /*int*/ "float" ); LRT_MINPATCHSAMPLES = RiDeclare( "minpatchsamples", /*int*/ "float" ); LRT_VERBOSITY = RiDeclare( "verbosity", "string" ); LRT_INCLUDE = RiDeclare( "include", "string" ); LRT_REFRESH = RiDeclare( "refresh", /*int*/ "float" ); /* See [PIXA93b]. */ LRT_FULLCOLOR = RiDeclare( "fullcolor", /*int*/ "float" ); /* See [PIXA93b]. */ LRT_SETPOINTS = RiDeclare( "setpoints", /*int*/ "float"/*[2]*/ ); /* See [PIXA98]. */ LRT_NAME = RiDeclare( "name", "string" ); /* already declared as RI_NULL?? */ /*LRT_SHADINGGROUP = RiDeclare( "shadinggroup", "string" );*/ LRT_BINARY = RiDeclare( "binary", /*int*/ "float" ); LRT_COORDINATESYSTEM = RiDeclare( "coordinatesystem", "string" ); LRT_SPHERE = RiDeclare( "sphere", "float" ); LRT_SENSE = RiDeclare( "sense", "string" ); LRT_AVERAGECOLOR = RiDeclare( "averagecolor", "color" ); LRT_EMISSIONCOLOR = RiDeclare( "emissioncolor", "color" ); LRT_PATCHSIZE = RiDeclare( "patchsize", /*int*/ "float" ); LRT_ELEMSIZE = RiDeclare( "elemsize", /*int*/ "float" ); LRT_MINSIZE = RiDeclare( "minsize", /*int*/ "float" ); LRT_ZONAL = RiDeclare( "zonal", "string" ); LRT_CASTS_SHADOWS = RiDeclare( "casts_shadows", "string" ); LRT_PATCH_MAXLEVEL = RiDeclare( "patch_maxlevel", /*int*/ "float" ); LRT_PATCH_MINLEVEL = RiDeclare( "patch_minlevel", /*int*/ "float" ); /* 2.3.5 */ LRT_PATCH_MULTIPLIER = RiDeclare( "patch_multiplier", /*int*/ "float" ); /* 2.3.6? */ LRT_TRUEDISPLACEMENT = RiDeclare( "truedisplacement", /*int*/ "float" ); /* 2.3.5 */ LRT_CACHE = RiDeclare( "cache", "string" ); LRT_UDIVISIONS = RiDeclare( "udivisions", /*int*/ "float" ); /* See [PIXA93b]. */ LRT_VDIVISIONS = RiDeclare( "vdivisions", /*int*/ "float" ); /* See [PIXA93b]. */ /* already declared??*/ /*LRT_ORIGIN = RiDeclare( "origin", int "float[2]" );*/ LRT_MERGE = RiDeclare( "merge", /*int*/ "float" ); LRT_COMPRESSION = RiDeclare( "compression", "string" ); /* See [PIXA93a]. */ LRT_RESOLUTION = RiDeclare( "resolution", /*int*/ "float" /*[2]*/); /* See [PIXA93a]. */ LRT_RESOLUTIONUNIT = RiDeclare( "resolutionunit", "string" ); /* See [PIXA93a]. */ LRT_JITTER = RiDeclare( "jitter", /*int*/ "float" ); LRT_PDISC = RiDeclare( "pdisc", /*int*/ "float" ); /*LRT_FLATNESS = RiDeclare( "flatness", "float" );*/ /* already declared?*/ LRT_WIDTH = RiDeclare( "width", "vertex float" ); LRT_CONSTANTWIDTH = RiDeclare( "constantwidth", "constant float" ); } RtVoid RiEnd() { currentApiState = STATE_UNINITIALIZED; argsAllocated = 0; if (argTokens) { free(argTokens); argTokens = NULL; } if (argParams) { free(argParams); argParams = NULL; } StatsCleanup(); } RtVoid RiFrameBegin(RtInt num) { } RtVoid RiFrameEnd() { } RtVoid RiPixelSamples(RtFloat x, RtFloat y) { VERIFY_STATE(STATE_BEGIN, "RiPixelSamples"); curGfxOptions.PixelSamples[0] = max((Float)1., x); curGfxOptions.PixelSamples[1] = max((Float)1., y); } RtVoid RiFormat(RtInt x, RtInt y, RtFloat pixelAspect) { VERIFY_STATE(STATE_BEGIN, "RiFormat"); if (x < 0) x = 640; if (y < 0) y = 480; if (pixelAspect < 0) pixelAspect = 1; if (x < 2) { Error("RiFormat: x resolution must be >= 2. Value %d invalid", x); x = 2; } if (y < 2) { Error("RiFormat: y resolution must be >= 2. Value %d invalid", y); y = 2; } curGfxOptions.XResolution = x; curGfxOptions.YResolution = y; curGfxOptions.PixelAspectRatio = pixelAspect; curGfxOptions.FrameAspectRatio = x * pixelAspect / y; if (curGfxOptions.FrameAspectRatio >= 1) { curGfxOptions.ScreenLeft = -curGfxOptions.FrameAspectRatio; curGfxOptions.ScreenRight = curGfxOptions.FrameAspectRatio; curGfxOptions.ScreenBottom = -1; curGfxOptions.ScreenTop = 1; } else { curGfxOptions.ScreenLeft = -1; curGfxOptions.ScreenRight = 1; curGfxOptions.ScreenBottom = -1. / curGfxOptions.FrameAspectRatio; curGfxOptions.ScreenTop = 1. / curGfxOptions.FrameAspectRatio; } } RtVoid RiFrameAspectRatio(RtFloat aspect) { VERIFY_STATE(STATE_BEGIN, "RiFrameAspectRatio"); curGfxOptions.FrameAspectRatio = aspect; } RtVoid RiScreenWindow(RtFloat left, RtFloat right, RtFloat bottom, RtFloat top) { VERIFY_STATE(STATE_BEGIN, "RiScreenWindow"); if (left > right) swap(left, right); if (bottom > top) swap(bottom, top); curGfxOptions.ScreenLeft = left; curGfxOptions.ScreenRight = right; curGfxOptions.ScreenBottom = bottom; curGfxOptions.ScreenTop = top; } RtVoid RiCropWindow(RtFloat left, RtFloat right, RtFloat bottom, RtFloat top) { VERIFY_STATE(STATE_BEGIN, "RiCropWindow"); if (left > right) swap(left, right); if (bottom > top) swap(bottom, top); curGfxOptions.CropLeft = left; curGfxOptions.CropRight = right; curGfxOptions.CropBottom = bottom; curGfxOptions.CropTop = top; } RtVoid RiClipping(RtFloat hither, RtFloat yon) { VERIFY_STATE(STATE_BEGIN, "RiClipping"); if (hither < RI_EPSILON) { Warning("RiClipping: hither value of %f is too low", hither); hither = RI_EPSILON; } if (yon <= hither) { Warning("RiClipping: yon value must be greater than hither"); yon = RI_INFINITY; } curGfxOptions.ClipHither = hither; curGfxOptions.ClipYon = yon; } RtVoid RiShutter(RtFloat time0, RtFloat time1) { VERIFY_STATE(STATE_BEGIN, "RiShutter"); curGfxOptions.ShutterStart = time0; curGfxOptions.ShutterEnd = time1; } RtVoid RiDepthOfField(RtFloat fstop, RtFloat focallen, RtFloat focaldist) { VERIFY_STATE(STATE_BEGIN, "RiDepthOfField"); curGfxOptions.FStop = fstop; curGfxOptions.FocalLength = focallen; curGfxOptions.FocalDistance = focaldist; } RtVoid RiProjection(RtToken name, ...) { va_list args; va_start(args, name); vectorizeParameters(args); RiProjectionV(name, argsCount, argTokens, argParams); va_end(args); } RtVoid RiProjectionV(RtToken name, RtInt nArgs, RtToken tokens[], RtPointer params[]) { VERIFY_STATE(STATE_BEGIN, "RiProjection"); if (name == RI_NULL) { RI_UNIMP(); // XXX curGfxOptions.CameraToScreen = curTransform[0]; curGfxOptions.ProjectionType = GfxOptions::PERSPECTIVE; // guess reportUnusedParameters("RiProjection", nArgs, tokens, RI_NULL); } else if (strcmp(name, RI_ORTHOGRAPHIC) == 0) { curGfxOptions.ProjectionType = GfxOptions::ORTHOGRAPHIC; reportUnusedParameters("RiProjection", nArgs, tokens, RI_NULL); } else if (strcmp(name, RI_PERSPECTIVE) == 0) { ParamSet paramSet(nArgs, tokens, params); curGfxOptions.fov = paramSet.findFloat(RI_FOV, 90.); curGfxOptions.ProjectionType = GfxOptions::PERSPECTIVE; reportUnusedParameters("RiProjection", nArgs, tokens, RI_FOV, RI_NULL); } else Error("Unknown projection %s specified in RiProjection()", name); curTransform[0] = Transform(); } RtVoid RiExposure(RtFloat gain, RtFloat gamma) { curGfxOptions.Gain = gain; curGfxOptions.Gamma = gamma; } RtVoid RiPixelFilter(RtFilterFunc filter, RtFloat xwidth, RtFloat ywidth) { curGfxOptions.filterfunc = filter; curGfxOptions.FilterXWidth = xwidth; curGfxOptions.FilterYWidth = ywidth; } RtFloat RiBoxFilter(RtFloat x, RtFloat y, RtFloat xwidth, RtFloat ywidth) { BoxFilter bf; return bf.Apply(x, y, xwidth, ywidth); } RtFloat RiTriangleFilter(RtFloat x, RtFloat y, RtFloat xwidth, RtFloat ywidth) { static TriangleFilter tf; return tf.Apply(x, y, xwidth, ywidth); } RtFloat RiGaussianFilter(RtFloat x, RtFloat y, RtFloat xwidth, RtFloat ywidth) { static GaussianFilter gf; return gf.Apply(x, y, xwidth, ywidth); } RtFloat RiMitchellFilter(RtFloat x, RtFloat y, RtFloat xwidth, RtFloat ywidth) { static MitchellFilter mf; return mf.Apply(x, y, xwidth, ywidth); } RtFloat RiCatmullRomFilter(RtFloat x, RtFloat y, Float xwidth, RtFloat ywidth) { return RiGaussianFilter(x, y, xwidth, ywidth); } RtFloat RiSincFilter(RtFloat x, RtFloat y, RtFloat xwidth, RtFloat ywidth) { return RiGaussianFilter(x, y, xwidth, ywidth); } RtVoid RiImager(RtToken name, ...) { va_list args; va_start(args, name); vectorizeParameters(args); RiImagerV(name, argsCount, argTokens, argParams); va_end(args); } RtVoid RiImagerV(RtToken name, RtInt n, RtToken tokens[], RtPointer params[]) { VERIFY_STATE(STATE_BEGIN, "RiImager"); curGfxOptions.imager = name; reportUnusedParameters("RiImager", n, tokens, RI_NULL); } RtVoid RiQuantize(RtToken type, RtInt one, RtInt minimum, RtInt maximum, RtFloat ditheramp) { if (strcmp(type, RI_RGBA) == 0) { curGfxOptions.ColorQuantOne = one; curGfxOptions.ColorQuantMin = minimum; curGfxOptions.ColorQuantMax = maximum; curGfxOptions.ColorQuantDither = ditheramp; } else if (strcmp(type, RI_Z) == 0) { curGfxOptions.DepthQuantOne = one; curGfxOptions.DepthQuantMin = minimum; curGfxOptions.DepthQuantMax = maximum; curGfxOptions.DepthQuantDither = ditheramp; } else Error("Unknown type %s passed to RiQuantize()", type); } RtVoid RiDisplay(char *name, RtToken type, RtToken mode, ...) { va_list args; va_start(args, mode); vectorizeParameters(args); RiDisplayV(name, type, mode, argsCount, argTokens, argParams); va_end(args); } RtVoid RiDisplayV(char *name, RtToken type, RtToken mode, int nArgs, RtToken tokens[], RtPointer parameters[]) { if (type != RI_FILE && strcmp(type, RI_FILE) != 0) { Error("Display type %s not supported.", type); return; } RtToken displayMode = lookupToken(mode); if (displayMode == RI_NULL) { Error("Display mode %s unknown.", mode); return; } if (displayMode != RI_RGB && displayMode != RI_RGBA && displayMode != RI_RGBZ && displayMode != RI_RGBAZ && displayMode != RI_A && displayMode != RI_AZ && displayMode != RI_Z) { Error("Display mode %s not supported.", mode); return; } curGfxOptions.DisplayType = type; curGfxOptions.DisplayName = Strdup(name); curGfxOptions.displayRGB = (displayMode == RI_RGB || displayMode == RI_RGBA || displayMode == RI_RGBZ || displayMode == RI_RGBAZ); curGfxOptions.displayA = (displayMode == RI_RGBA || displayMode == RI_RGBAZ || displayMode == RI_A || displayMode == RI_AZ); curGfxOptions.displayZ = (displayMode == RI_RGBZ || displayMode == RI_RGBAZ || displayMode == RI_AZ || displayMode == RI_Z); reportUnusedParameters("RiDisplay", nArgs, tokens, RI_NULL); } RtVoid RiHider(RtToken type, ...) { va_list args; va_start(args, type); vectorizeParameters(args); RiHiderV(type, argsCount, argTokens, argParams); va_end(args); } RtVoid RiHiderV(RtToken type, RtInt nArgs, RtToken tokens[], RtPointer parms[]) { if (!type || !strcmp(type, RI_HIDDEN)) { ParamSet paramSet(nArgs, tokens, parms); curGfxOptions.JitterSamples = paramSet.findFloat("jitter", 1.) != 0.; reportUnusedParameters("RiHider", nArgs, tokens, LRT_JITTER, RI_NULL); } else { if (type == RI_PAINT || strcmp(type, RI_PAINT) == 0) Error("Paint hider not supported by RiHider()"); else Error("Unknown type %s passed to RiHider()", type); reportUnusedParameters("RiHider", nArgs, tokens, RI_NULL); } } RtVoid RiOption(RtToken name, ...) { va_list args; va_start(args, name); vectorizeParameters(args); RiOptionV(name, argsCount, argTokens, argParams); va_end(args); } RtVoid RiOptionV(RtToken name, RtInt n, RtToken tokens[], RtPointer parms[]) { if (name == LRT_DISPLAY || strcmp(name, LRT_DISPLAY) == 0) { for (int i = 0 ; i < n ; i++) { if (tokens[i] == LRT_IMAGEVIEWER || strcmp(tokens[i], LRT_IMAGEVIEWER) == 0) { char **arr = (char **) parms[i]; curGfxOptions.ImageViewer = Strdup(arr[0]); } else Warning("Ignoring unknown option 'display' token %s", tokens[i]); } } else if (name == LRT_RENDER || strcmp(name, LRT_RENDER) == 0) { for (int i = 0; i < n; ++i) { if (strcmp(tokens[i], LRT_INTEGRATOR) == 0) { RtToken param = *((RtToken *)(parms[i])); if (strcmp(param, LRT_COLOR) == 0) curGfxOptions.IlluminationIntegrator = LRT_COLOR; else if (strcmp(param, LRT_RAYCAST) == 0) curGfxOptions.IlluminationIntegrator = LRT_RAYCAST; else if (strcmp(param, LRT_WHITTED) == 0) curGfxOptions.IlluminationIntegrator = LRT_WHITTED; else if (strcmp(param, LRT_PATH) == 0) curGfxOptions.IlluminationIntegrator = LRT_PATH; else if (strcmp(param, LRT_MONTECARLO) == 0) curGfxOptions.IlluminationIntegrator = LRT_MONTECARLO; else Error("Unknown integrator type \'%s\' passed to RiOption", param); } else if (!strcmp(tokens[i], LRT_MAX_RAYLEVEL)) { int rl = *((int *)parms[i]); curGfxOptions.maxRaylevel = Clamp(rl, 1, 100); } else Error("Unknown rendering option \"%s\" passed to RiOption", tokens[i]); } } else if(strcmp(name, RI_CAMERA) == 0) { RtToken token = tokens[0]; if(strcmp(token, LRT_CAMERA_MODE) == 0) { RtToken param = *((RtToken *) (parms[0])); if(strcmp(param, LRT_MANUAL) == 0) { curGfxOptions.CameraAutoMode=LRT_MANUAL; } else if(strcmp(param, LRT_SHUTTER_PRIORITY) == 0) { curGfxOptions.CameraAutoMode=LRT_SHUTTER_PRIORITY; } else if(strcmp(param, LRT_APERTURE_PRIORITY) == 0) { curGfxOptions.CameraAutoMode=LRT_APERTURE_PRIORITY; } else if(strcmp(param, LRT_PROGRAMMED) == 0) { curGfxOptions.CameraAutoMode=LRT_PROGRAMMED; } else Warning("RiOption: unknown camera mode %s", param); } else { Warning("RiOption: unknown camera option %s", token); } } else Warning("RiOption: unknown option class %s", name); } RtVoid RiWorldBegin() { VERIFY_STATE(STATE_BEGIN, "RiWorldBegin"); currentApiState = STATE_WORLD_BEGIN; for (int i = 0; i < MOTION_LEVELS; ++i) { curGfxOptions.WorldToCamera[i] = curTransform[i]; curTransform[i] = Transform(); } curGfxState = GfxState(); } RtVoid RiTransformBegin() { for (int i = 0; i < MOTION_LEVELS; ++i) transformStack[i].push_back(curTransform[i]); hierarchicalState.push_back('t'); } RtVoid RiTransformEnd() { if (!transformStack[0].size() || hierarchicalState.back() != 't') { Error("Unmatched RiTransformEnd encountered. Ignoring it."); return; } for (int i = 0; i < MOTION_LEVELS; ++i) { curTransform[i] = transformStack[i].back(); transformStack[i].pop_back(); } hierarchicalState.pop_back(); } RtVoid RiAttributeBegin() { RiTransformBegin(); VERIFY_STATE(STATE_WORLD_BEGIN, "RiAttributeBegin"); gstates.push_front(curGfxState); hierarchicalState.push_back('a'); } RtVoid RiAttributeEnd() { VERIFY_STATE(STATE_WORLD_BEGIN, "RiAttributeEnd"); if (!gstates.size() || hierarchicalState.back() != 'a') { Error("Unmatched RiAttributeEnd encountered. Ignoring it."); return; } curGfxState = gstates.front(); gstates.pop_front(); hierarchicalState.pop_back(); RiTransformEnd(); } RtVoid RiColor(RtColor Cs) { curGfxState.color = Spectrum(Cs[0], Cs[1], Cs[2]); } RtVoid RiOpacity(RtColor Cs) { RI_UNIMP(); } RtVoid RiSurface(RtToken name, ...) { va_list args; va_start(args, name); vectorizeParameters(args); RiSurfaceV(name, argsCount, argTokens, argParams); va_end(args); } RtVoid RiSurfaceV(RtToken name, RtInt n, RtToken tokens[], RtPointer params[]) { curGfxState.surfaceParams.init(n, tokens, params); curGfxState.surface = name; } RtVoid RiAttribute(RtToken name, ...) { va_list args; va_start(args, name); vectorizeParameters(args); RiAttributeV(name, argsCount, argTokens, argParams); va_end(args); } RtVoid RiAttributeV(RtToken name, RtInt n, RtToken tokens[], RtPointer parms[]) { if (name == LRT_LIGHT || strcmp(name, LRT_LIGHT) == 0) { for (int i = 0; i < n; ++i) { if (strcmp(tokens[i], LRT_SHADOWS) == 0) { const char *param = *((const char **)(parms[i])); if (strcmp(param, "on") == 0) curGfxState.CastsShadows = true; else if (strcmp(param, "off") == 0) curGfxState.CastsShadows = false; else Warning("Unknown on/off value for attribute shadows %s", param); } else if (strcmp(tokens[i], LRT_NSAMPLES) == 0) { Float count = *((RtFloat *)(parms[i])); if (count < 1.) Warning("Ignoring < 1 number of light samples %f", count); else curGfxState.NumLightSamples = int(count); } else Error("Ignoring unknown light attribute %s", tokens[i]); } } else if (name == LRT_RENDER || strcmp(name, LRT_RENDER) == 0) { for (int i = 0; i < n; ++i) { if (tokens[i] == LRT_SAMPLE || strcmp(tokens[i], LRT_SAMPLE) == 0) { const char *param = *((const char **)(parms[i])); if (strcmp(param, LRT_SURFACE) == 0) curGfxState.Sampling = GfxState::SampleSurface; else if (strcmp(param, LRT_LIGHT) == 0) curGfxState.Sampling = GfxState::SampleLight; else if (strcmp(param, LRT_COMBINATION) == 0) curGfxState.Sampling = GfxState::SampleCombination; else Warning("Unknown 'sample' value, '%s' for attribute render", param); } else if(name == RI_CAMERA || strcmp(name, RI_CAMERA) == 0) { } else Error("Ignoring unknown rendering attribute '%s'", tokens[i]); } } else Warning("Ignoring unknown attribute %s", name); } RtVoid RiMotionBegin(RtInt N, ...) { RtFloat times[16]; Assert(N < 16); va_list args; va_start(args, N); for (int i = 0; i < N; ++i) times[i] = va_arg(args, double); RiMotionBeginV(N, times); } RtVoid RiMotionBeginV(RtInt N, RtFloat times[]) { Assert(!inMotionBlock); inMotionBlock = true; motionLevel = 0; if (N > 2) Warning("Only two levels in motion block will be used."); } RtVoid RiMotionEnd() { if (!inMotionBlock) Error("Unmatched MotionEnd statement"); inMotionBlock = false; motionLevel=0; } RtVoid RiIdentity() { int xform = 0; if (inMotionBlock) xform = motionLevel; if (motionLevel > MOTION_LEVELS) { Warning("Only %d motion levels are supported. Ignoring.", motionLevel); return; } curTransform[xform] = Transform(); if (inMotionBlock) ++motionLevel; } RtVoid RiTransform(RtMatrix tr) { int xform = 0; if (inMotionBlock) xform = motionLevel; if (motionLevel > MOTION_LEVELS) { Warning("Only %d motion levels are supported. Ignoring.", motionLevel); return; } curTransform[xform] = Transform(tr[0], tr[4], tr[8], tr[12], tr[1], tr[5], tr[9], tr[13], tr[2], tr[6], tr[10], tr[14], tr[3], tr[7], tr[11], tr[15]); if (inMotionBlock) ++motionLevel; } RtVoid RiConcatTransform(RtMatrix tr) { int xform = 0; if (inMotionBlock) xform = motionLevel; if (motionLevel > MOTION_LEVELS) { Warning("Only %d motion levels are supported. Ignoring.", motionLevel); return; } curTransform[xform] = curTransform[xform] * Transform(tr[0], tr[4], tr[8], tr[12], tr[1], tr[5], tr[9], tr[13], tr[2], tr[6], tr[10], tr[14], tr[3], tr[7], tr[11], tr[15]); if (inMotionBlock) ++motionLevel; } RtVoid RiPerspective(RtFloat fov) { int xform = 0; if (inMotionBlock) xform = motionLevel; if (motionLevel > MOTION_LEVELS) { Warning("Only %d motion levels are supported. Ignoring.", motionLevel); return; } // XXX? curTransform[xform] = curTransform[xform] * Perspective(fov, 1.0, curGfxOptions.ClipHither, curGfxOptions.ClipYon); if (inMotionBlock) ++motionLevel; } RtVoid RiTranslate(RtFloat dx, RtFloat dy, RtFloat dz) { int xform = 0; if (inMotionBlock) xform = motionLevel; if (motionLevel > MOTION_LEVELS) { Warning("Only %d motion levels are supported. Ignoring.", motionLevel); return; } curTransform[xform] = curTransform[0] * Translate(Vector(dx, dy, dz)); if (inMotionBlock) ++motionLevel; } RtVoid RiRotate(RtFloat angle, RtFloat dx, RtFloat dy, RtFloat dz) { int xform = 0; if (inMotionBlock) xform = motionLevel; if (motionLevel > MOTION_LEVELS) { Warning("Only %d motion levels are supported. Ignoring.", motionLevel); return; } curTransform[xform] = curTransform[xform] * Rotate(angle, Vector(dx, dy, dz)); if (inMotionBlock) ++motionLevel; } RtVoid RiScale(RtFloat sx, RtFloat sy, RtFloat sz) { int xform = 0; if (inMotionBlock) xform = motionLevel; if (motionLevel > MOTION_LEVELS) { Warning("Only %d motion levels are supported. Ignoring.", motionLevel); return; } curTransform[xform] = curTransform[xform] * Scale(sx, sy, sz); if (inMotionBlock) ++motionLevel; } RtVoid RiCoordinateSystem(RtToken) { RI_UNIMP( ); } RtVoid RiPolygon(RtInt nverts, ...) { va_list args; va_start(args, nverts); vectorizeParameters(args); RiPolygonV(nverts, argsCount, argTokens, argParams); va_end(args); } RtVoid RiPolygonV(RtInt nverts, RtInt n, RtToken tokens[], RtPointer params[]) { ParamSet geomParams(n, tokens, params); Point *P = NULL; for (int i = 0; i < n; ++i) { if (tokens[i] == RI_P || strcmp(tokens[i], RI_P) == 0) P = (Point *)params[i]; } RtInt *indices = new RtInt[ 3*(nverts-2) ]; for (int i = 0 ; i < nverts-2 ; i++) { indices[3*i] = 0; indices[3*i+1] = i+2; indices[3*i+2] = i+1; } curGfxState.AddShape(new TriangleMesh(curTransform[motionLevel], nverts-2, nverts, indices, P), geomParams); } RtVoid RiPointsPolygons( RtInt npolys, RtInt nvertices[], RtInt vertices[], ...) { va_list args; va_start(args, vertices); vectorizeParameters(args); RiPointsPolygonsV(npolys, nvertices, vertices, argsCount, argTokens, argParams); va_end(args); } RtVoid RiPointsPolygonsV( RtInt npolys, RtInt nvertices[], RtInt vertices[], RtInt n, RtToken tokens[], RtPointer params[]) { Point *P = NULL; for (int i = 0; i < n; ++i) { if (tokens[i] == RI_P || strcmp(tokens[i], RI_P) == 0) P = (Point *)params[i]; } int nVertices = 0; int nIndices = 0; int vIndex = 0; for (int i = 0; i < npolys; ++i) { nIndices += 3*(nvertices[i]-2); for (int j = 0 ; j < nvertices[i] ; j++) { nVertices = max(nVertices, vertices[vIndex] + 1); vIndex++; } } RtInt *indices = new RtInt[ nIndices ]; int whichIndex = 0; vIndex = 0; for (int i = 0; i < npolys; ++i) { int anchorIndex = vIndex; for (int j = 0 ; j < nvertices[i]-2 ; j++) { indices[whichIndex++] = vertices[anchorIndex]; indices[whichIndex++] = vertices[vIndex+1]; indices[whichIndex++] = vertices[vIndex+2]; vIndex++; } vIndex += 2; } ParamSet geomParams(n, tokens, params); curGfxState.AddShape(new TriangleMesh(curTransform[motionLevel], nIndices/3, nVertices, indices, P), geomParams); } RtVoid RiSphere(RtFloat radius, RtFloat zmin, RtFloat zmax, RtFloat thetamax, ...) { va_list args; va_start(args, thetamax); vectorizeParameters(args); RiSphereV(radius, zmin, zmax, thetamax, argsCount, argTokens, argParams); va_end(args); } RtVoid RiSphereV(RtFloat radius, RtFloat zmin, RtFloat zmax, RtFloat thetaMax, RtInt n, RtToken tokens[], RtPointer params[]) { ParamSet geomParams(n, tokens, params); curGfxState.AddShape(new Sphere(curTransform[motionLevel], radius, zmin, zmax, thetaMax), geomParams); } RtVoid RiDisk(RtFloat height, RtFloat radius, RtFloat thetamax, ...) { va_list args; va_start(args, thetamax); vectorizeParameters(args); RiDiskV(height, radius, thetamax, argsCount, argTokens, argParams); va_end(args); } RtVoid RiDiskV(RtFloat height, RtFloat radius, RtFloat thetamax, RtInt n, RtToken tokens[], RtPointer params[]) { ParamSet geomParams(n, tokens, params); curGfxState.AddShape(new Disk(curTransform[motionLevel], height, radius, thetamax), geomParams); } RtVoid RiPatchMesh(RtToken type, RtInt nu, RtToken uwrap, RtInt nv, RtToken vwrap, ...) { va_list args; va_start(args, vwrap); vectorizeParameters(args); RiPatchMeshV(type, nu, uwrap, nv, vwrap, argsCount, argTokens, argParams); va_end(args); } RtVoid RiPatchMeshV(RtToken type, RtInt nu, RtToken uwrap, RtInt nv, RtToken vwrap, RtInt n, RtToken tokens[], RtPointer params[]) { if (!strcmp(type, "bilinear") && n == 1 && !strcmp(uwrap, "nonperiodic") && !strcmp(vwrap, "nonperiodic") && !strcmp(tokens[0], "Pz")) { ParamSet geomParams(n, tokens, params); curGfxState.AddShape(new Heightfield(curTransform[motionLevel], nu, 1, nv, 1, (float *)params[0]), geomParams); } else if (!strcmp(type, "bilinear") && n == 1 && !strcmp(tokens[0], "Pz")) { ParamSet geomParams(n, tokens, params); curGfxState.AddShape(new Heightfield(curTransform[motionLevel], nu, atoi(uwrap), nv, atoi(vwrap), (float *)params[0]), geomParams); } else { RI_UNIMP(); } } RtLightHandle RiLightSource(RtToken name, ...) { va_list args; va_start(args, name); vectorizeParameters(args); RtLightHandle ret = RiLightSourceV(name, argsCount, argTokens, argParams); va_end(args); return ret; } RtLightHandle RiLightSourceV(RtToken name, RtInt nArgs, RtToken tokens[], RtPointer params[]) { Light *lt = NULL; ParamSet paramSet(nArgs, tokens, params); Spectrum Phi = paramSet.findSpectrum("lightcolor", Spectrum(1.)); Float intensity = paramSet.findFloat("intensity", 1.); Phi *= intensity; Phi *= M_PI; Phi = paramSet.findSpectrum("Phi", Phi); if (!strcmp(name, "pointlight")) { Phi *= 4. * M_PI; Point P = paramSet.findPoint("from", Point(0,0,0)); lt = new PointLight(curGfxState.CastsShadows, curTransform[motionLevel], Phi, P); } else if (!strcmp(name, "distantlight")) { Point from = paramSet.findPoint("from", Point(0,0,0)); Point to = paramSet.findPoint("to", Point(0,0,1)); Vector dir = to-from; lt = new InfinitePointLight(curGfxState.CastsShadows, curTransform[motionLevel], Phi, dir); } else if (!strcmp(name, "ambientlight")) lt = new AmbientLight(Phi); if (lt == RI_NULL) Error("RiLightSource: point light type '%s' unknown.", name); else lights.push_back(lt); return lt; } RtLightHandle RiAreaLightSource(RtToken name, ...) { va_list args; va_start(args, name); vectorizeParameters(args); RtLightHandle ret = RiAreaLightSourceV(name, argsCount, argTokens, argParams); va_end(args); return ret; } RtLightHandle RiAreaLightSourceV(RtToken name, RtInt n, RtToken tokens[], RtPointer params[] ) { curGfxState.areaLightParams.init(n, tokens, params); curGfxState.areaLight = name; return NULL; } RtVoid RiIlluminate(RtLightHandle light, RtBoolean on) { RI_UNIMP(); } RtVoid RiPixelVariance(RtFloat) { } RtVoid RiTextureCoordinates(RtFloat s1, RtFloat t1, RtFloat s2, RtFloat t2, RtFloat s3, RtFloat t3, RtFloat s4, RtFloat t4) { RI_UNIMP( ); } RtVoid RiShadingRate(RtFloat r) { } RtVoid RiShadingInterpolation(RtToken type) { } RtVoid RiRelativeDetail(RtFloat relativedetail) { } RtVoid RiMatte(RtBoolean onoff) { RI_UNIMP(); } RtVoid RiBound(RtBound bound) {RI_UNIMP( ); } RtVoid RiDetail(RtBound bound) {RI_UNIMP( ); } extern RtVoid RiDetailRange(RtFloat minvis, RtFloat lowtran, RtFloat uptran, RtFloat maxvis) {RI_UNIMP( ); } RtVoid RiGeometricApproximation(RtToken type, RtFloat value) { } RtVoid RiGeometricRepresentation(RtToken type) { RI_UNIMP(); } RtPoint *RiTransformPoints(RtToken fromspace, RtToken tospace, RtInt npoints, RtPoint *points) { RI_UNIMP(); return (RtPoint *)(NULL); } RtVoid RiSkew(RtFloat, RtFloat, RtFloat, RtFloat, RtFloat, RtFloat, RtFloat) { RI_UNIMP(); } extern RtVoid RiDeformation(RtToken name, ...) {RI_UNIMP( ); } extern RtVoid RiDeformationV(RtToken name, RtInt n, RtToken tokens[], RtPointer parms[]) {RI_UNIMP( ); } extern RtVoid RiDisplacement(RtToken name, ...) {RI_UNIMP( ); } extern RtVoid RiDisplacementV(RtToken name, RtInt n, RtToken tokens[], RtPointer parms[]) {RI_UNIMP( ); } RtVoid RiGeometry(RtToken type, ...) { RI_UNIMP(); } RtVoid RiGeometryV(RtToken type, RtInt n, RtToken tokens[], RtPointer params[]) { RI_UNIMP(); } RtVoid RiMakeTexture(char *pic, char *tex, RtToken swrap, RtToken twrap, RtFilterFunc filterfunc, RtFloat swidth, RtFloat twidth, ...) { RI_UNIMP(); } RtVoid RiMakeTextureV(char *pic, char *tex, RtToken swrap, RtToken twrap, RtFilterFunc filterfunc, RtFloat swidth, RtFloat twidth, RtInt n, RtToken tokens[], RtPointer params[]) { RI_UNIMP(); } RtVoid RiMakeBump(char *pic, char *tex, RtToken swrap, RtToken twrap, RtFilterFunc filterfunc, RtFloat swidth, RtFloat twidth, ...) { RI_UNIMP(); } RtVoid RiMakeBumpV(char *pic, char *tex, RtToken swrap, RtToken twrap, RtFilterFunc filterfunc, RtFloat swidth, RtFloat twidth, RtInt n, RtToken tokens[], RtPointer params[]) { RI_UNIMP(); } RtVoid RiMakeLatLongEnvironment(char *pic, char *tex, RtFilterFunc filterfunc, RtFloat swidth, RtFloat twidth, ...) { RI_UNIMP(); } RtVoid RiMakeLatLongEnvironmentV(char *pic, char *tex, RtFilterFunc filterfunc, RtFloat swidth, RtFloat twidth, RtInt n, RtToken tokens[], RtPointer params[]) { RI_UNIMP(); } RtVoid RiMakeCubeFaceEnvironment(char *px, char *nx, char *py, char *ny, char *pz, char *nz, char *tex, RtFloat fov, RtFilterFunc filterfunc, RtFloat swidth, RtFloat twidth, ...) { RI_UNIMP(); } RtVoid RiMakeCubeFaceEnvironmentV(char *px, char *nx, char *py, char *ny, char *pz, char *nz, char *tex, RtFloat fov, RtFilterFunc filterfunc, RtFloat swidth, RtFloat twidth, RtInt n, RtToken tokens[], RtPointer params[]) { RI_UNIMP(); } RtVoid RiMakeShadow(char *pic, char *tex, ...) { RI_UNIMP(); } RtVoid RiMakeShadowV(char *pic, char *tex, RtInt n, RtToken tokens[], RtPointer params[]) { RI_UNIMP(); } extern RtVoid RiColorSamples(RtInt N, RtFloat *nRGB, RtFloat *RGBn) {RI_UNIMP( ); } RtVoid RiAtmosphere( RtToken name, ... ) {RI_UNIMP( ); } extern RtVoid RiAtmosphereV(RtToken name, RtInt n, RtToken tokens[], RtPointer parms[]) {RI_UNIMP( ); } extern RtVoid RiInterior(RtToken name, ...) {RI_UNIMP( ); } extern RtVoid RiInteriorV(RtToken name, RtInt n, RtToken tokens[], RtPointer parms[]) {RI_UNIMP( ); } extern RtVoid RiExterior(RtToken name, ...) {RI_UNIMP( ); } extern RtVoid RiExteriorV(RtToken name, RtInt n, RtToken tokens[], RtPointer parms[]) {RI_UNIMP( ); } RtVoid RiCone(RtFloat height, RtFloat radius, RtFloat tmax, ...) { va_list args; va_start(args, tmax); vectorizeParameters(args); RiConeV(height, radius, tmax, argsCount, argTokens, argParams); va_end(args); } RtVoid RiConeV(RtFloat height, RtFloat radius, RtFloat tmax, RtInt n, RtToken tokens[], RtPointer params[]) { ParamSet geomParams(n, tokens, params); curGfxState.AddShape(new Cone(curTransform[motionLevel], height, radius, tmax), geomParams); } RtVoid RiCylinder(RtFloat radius, RtFloat zmin, RtFloat zmax, RtFloat tmax, ...) { va_list args; va_start(args, tmax); vectorizeParameters(args); RiCylinderV(radius, zmin, zmax, tmax, argsCount, argTokens, argParams); va_end(args); } RtVoid RiCylinderV(RtFloat radius, RtFloat zmin, RtFloat zmax, RtFloat tmax, RtInt n, RtToken tokens[], RtPointer params[]) { ParamSet geomParams(n, tokens, params); curGfxState.AddShape(new Cylinder(curTransform[motionLevel], radius, zmin, zmax, tmax), geomParams); } RtVoid RiHyperboloid(RtPoint point1, RtPoint point2, RtFloat tmax, ...) { va_list args; va_start(args, tmax); vectorizeParameters(args); RiHyperboloidV(point1, point2, tmax, argsCount, argTokens, argParams); va_end(args); } RtVoid RiHyperboloidV(RtPoint p1, RtPoint p2, RtFloat tmax, RtInt n, RtToken tokens[], RtPointer params[]) { ParamSet geomParams(n, tokens, params); curGfxState.AddShape(new Hyperboloid(curTransform[motionLevel], Point(p1[0], p1[1], p1[2]), Point(p2[0], p2[1], p2[2]), tmax), geomParams); } RtVoid RiParaboloid(RtFloat rmax, RtFloat zmin, RtFloat zmax, RtFloat tmax, ...) { va_list args; va_start(args, tmax); vectorizeParameters(args); RiParaboloidV(rmax, zmin, zmax, tmax, argsCount, argTokens, argParams); va_end(args); } RtVoid RiParaboloidV(RtFloat rmax, RtFloat zmin, RtFloat zmax, RtFloat tmax, RtInt n, RtToken tokens[], RtPointer params[]) { ParamSet geomParams(n, tokens, params); curGfxState.AddShape(new Paraboloid(curTransform[motionLevel], rmax, zmin, zmax, tmax), geomParams); } RtVoid RiTorus(RtFloat majrad, RtFloat minrad, RtFloat phimin, RtFloat phimax, RtFloat tmax, ...) { RI_UNIMP(); } RtVoid RiTorusV(RtFloat majrad, RtFloat minrad, RtFloat phimin, RtFloat phimax, RtFloat tmax, RtInt n, RtToken tokens[], RtPointer params[]) { RI_UNIMP(); } RtVoid RiSolidBegin(RtToken) { RI_UNIMP(); } RtVoid RiSolidEnd() { RI_UNIMP(); } RtVoid RiGeneralPolygon(RtInt nloops, RtInt nverts[], ...) { RI_UNIMP(); } RtVoid RiGeneralPolygonV(RtInt nloops, RtInt nverts[], RtInt n, RtToken tokens[], RtPointer parms[]) { RI_UNIMP(); } RtVoid RiPointsGeneralPolygons(RtInt npolys, RtInt nloops[], RtInt nverts[], RtInt verts[], ...) { RI_UNIMP(); } RtVoid RiPointsGeneralPolygonsV(RtInt npolys, RtInt nloops[], RtInt nverts[], RtInt verts[], RtInt n, RtToken tokens[], RtPointer parms[]) { RI_UNIMP(); } RtObjectHandle RiObjectBegin() { RI_UNIMP(); return RtObjectHandle(NULL); } void RiObjectEnd() { RI_UNIMP(); } RtVoid RiNuPatch(RtInt nu, RtInt uorder, RtFloat *uknot, RtFloat umin, RtFloat umax, RtInt nv, RtInt vorder, RtFloat *vknot, RtFloat vmin, RtFloat vmax, ...) { va_list args; va_start(args, vmax); vectorizeParameters(args); RiNuPatchV(nu, uorder, uknot, umin, umax, nv, vorder, vknot, vmin, vmax, argsCount, argTokens, argParams); va_end(args); } RtVoid RiNuPatchV(RtInt nu, RtInt uorder, RtFloat *uknot, RtFloat umin, RtFloat umax, RtInt nv, RtInt vorder, RtFloat *vknot, RtFloat vmin, RtFloat vmax, RtInt n, RtToken tokens[], RtPointer params[]) { float *P = NULL; bool isHomogeneous = false; for (int i = 0; i < n; ++i) { if (strcmp(tokens[i], RI_P) == 0) { P = (float *)params[i]; isHomogeneous = false; break; } if (strcmp(tokens[i], RI_PW) == 0) { P = (float *)params[i]; isHomogeneous = true; break; } } if (!P) { Error("No control points supplied with NURBS patch."); return; } ParamSet geomParams(n, tokens, params); curGfxState.AddShape(new NURBS(curTransform[motionLevel], nu, uorder, uknot, umin, umax, nv, vorder, vknot, vmin, vmax, P, isHomogeneous), geomParams); } RtVoid RiTrimCurve(RtInt nloops, RtInt *ncurves, RtInt *order, RtFloat *knot, RtFloat *amin, RtFloat *amax, RtInt *n, RtFloat *u, RtFloat *v, RtFloat *w) { RI_UNIMP(); } RtVoid RiBasis(RtBasis ubasis, RtInt ustep, RtBasis vbasis, RtInt vstep) { } RtVoid RiPatch(RtToken type, ...) { va_list args; va_start(args, type); vectorizeParameters(args); RiPatchV(type, argsCount, argTokens, argParams); va_end(args); } RtVoid RiPatchV(RtToken type, RtInt n, RtToken tokens[], RtPointer params[]) { RI_UNIMP(); } RtVoid RiOrientation(RtToken orientation) { RI_UNIMP(); } RtVoid RiReverseOrientation() { RI_UNIMP(); } RtVoid RiSides(RtInt sides) { RI_UNIMP(); }