~ubuntu-branches/ubuntu/maverick/blender/maverick

« back to all changes in this revision

Viewing changes to extern/qdune/ribparse/ri.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Khashayar Naderehvandi, Khashayar Naderehvandi, Alessio Treglia
  • Date: 2009-01-22 16:53:59 UTC
  • mfrom: (14.1.1 experimental)
  • Revision ID: james.westby@ubuntu.com-20090122165359-v0996tn7fbit64ni
Tags: 2.48a+dfsg-1ubuntu1
[ Khashayar Naderehvandi ]
* Merge from debian experimental (LP: #320045), Ubuntu remaining changes:
  - Add patch correcting header file locations.
  - Add libvorbis-dev and libgsm1-dev to Build-Depends.
  - Use avcodec_decode_audio2() in source/blender/src/hddaudio.c

[ Alessio Treglia ]
* Add missing previous changelog entries.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
//------------------------------------------------------------------------------
2
 
// RI API
3
 
//------------------------------------------------------------------------------
4
 
 
5
 
#include "ri.h"
6
 
#include <cmath>
7
 
#include <cstdlib>
8
 
 
9
 
#include "State.h"
10
 
#include "Quadrics.h"
11
 
#include "Patches.h"
12
 
#include "CCSubdivision.h"
13
 
#include "Polygons.h"
14
 
#include "Curves.h"
15
 
#include "Nurbs.h"
16
 
#include "Points.h"
17
 
#include "ribInterface.h"
18
 
// for ReadArchive handling...
19
 
#include "RIB_parser.h"
20
 
 
21
 
#include "slshader.h"
22
 
#include "Mathutil.h"
23
 
#include <cstdarg>
24
 
#include <cassert>
25
 
 
26
 
#ifdef WIN32
27
 
#define WIN32_LEAN_AND_MEAN
28
 
#include <windows.h>
29
 
#endif
30
 
 
31
 
#ifdef _MSC_VER
32
 
#define snprintf _snprintf
33
 
#endif
34
 
 
35
 
// for error/warning debug output, just use C funcs
36
 
#include <cstdio>
37
 
#define ERROUT stderr
38
 
 
39
 
using namespace QDRender;
40
 
 
41
 
// Token definitions
42
 
RtToken RI_FRAMEBUFFER          =       "framebuffer";
43
 
RtToken RI_FILE                 =       "file";
44
 
RtToken RI_RGB                  =       "rgb";
45
 
RtToken RI_RGBA                 =       "rgba";
46
 
RtToken RI_RGBZ                 =       "rgbz";
47
 
RtToken RI_RGBAZ                =       "rgbaz";
48
 
RtToken RI_A                    =       "a";
49
 
RtToken RI_Z                    =       "z";
50
 
RtToken RI_AZ                   =       "az";
51
 
RtToken RI_PERSPECTIVE          =       "perspective";
52
 
RtToken RI_ORTHOGRAPHIC         =       "orthographic";
53
 
RtToken RI_HIDDEN               =       "hidden";
54
 
RtToken RI_PAINT                =       "paint";
55
 
RtToken RI_CONSTANT             =       "constant";
56
 
RtToken RI_SMOOTH               =       "smooth";
57
 
RtToken RI_FLATNESS             =       "flatness";
58
 
RtToken RI_FOV                  =       "fov";
59
 
RtToken RI_AMBIENTLIGHT         =       "ambientlight";
60
 
RtToken RI_POINTLIGHT           =       "pointlight";
61
 
RtToken RI_DISTANTLIGHT         =       "distantlight";
62
 
RtToken RI_SPOTLIGHT            =       "spotlight";
63
 
RtToken RI_INTENSITY            =       "intensity";
64
 
RtToken RI_LIGHTCOLOR           =       "lightcolor";
65
 
RtToken RI_FROM                 =       "from";
66
 
RtToken RI_TO                   =       "to";
67
 
RtToken RI_CONEANGLE            =       "coneangle";
68
 
RtToken RI_CONEDELTAANGLE       =       "conedeltaangle";
69
 
RtToken RI_BEAMDISTRIBUTION     =       "beamdistribution";
70
 
RtToken RI_MATTE                =       "matte";
71
 
RtToken RI_METAL                =       "metal";
72
 
RtToken RI_SHINYMETAL           =       "shinymetal";
73
 
RtToken RI_PLASTIC              =       "plastic";
74
 
RtToken RI_PAINTEDPLASTIC       =       "paintedplastic";
75
 
RtToken RI_KA                   =       "Ka";
76
 
RtToken RI_KD                   =       "Kd";
77
 
RtToken RI_KS                   =       "Ks";
78
 
RtToken RI_ROUGHNESS            =       "roughness";
79
 
RtToken RI_KR                   =       "Kr";
80
 
RtToken RI_TEXTURENAME          =       "texturename";
81
 
RtToken RI_SPECULARCOLOR        =       "specularcolor";
82
 
RtToken RI_DEPTHCUE             =       "depthcue";
83
 
RtToken RI_FOG                  =       "fog";
84
 
RtToken RI_BUMPY                =       "bumpy";
85
 
RtToken RI_MINDISTANCE          =       "mindistance";
86
 
RtToken RI_MAXDISTANCE          =       "maxdistance";
87
 
RtToken RI_BACKGROUND           =       "background";
88
 
RtToken RI_DISTANCE             =       "distance";
89
 
RtToken RI_AMPLITUDE            =       "amplitude";
90
 
RtToken RI_RASTER               =       "raster";
91
 
RtToken RI_SCREEN               =       "screen";
92
 
RtToken RI_CAMERA               =       "camera";
93
 
RtToken RI_WORLD                =       "world";
94
 
RtToken RI_OBJECT               =       "object";
95
 
RtToken RI_INSIDE               =       "inside";
96
 
RtToken RI_OUTSIDE              =       "outside";
97
 
RtToken RI_LH                   =       "lh";
98
 
RtToken RI_RH                   =       "rh";
99
 
RtToken RI_P                    =       "P";
100
 
RtToken RI_PZ                   =       "Pz";
101
 
RtToken RI_PW                   =       "Pw";
102
 
RtToken RI_N                    =       "N";
103
 
RtToken RI_NP                   =       "Np";
104
 
RtToken RI_CS                   =       "Cs";
105
 
RtToken RI_OS                   =       "Os";
106
 
RtToken RI_S                    =       "s";
107
 
RtToken RI_T                    =       "t";
108
 
RtToken RI_ST                   =       "st";
109
 
RtToken RI_BILINEAR             =       "bilinear";
110
 
RtToken RI_BICUBIC              =       "bicubic";
111
 
RtToken RI_LINEAR               =       "linear";
112
 
RtToken RI_CUBIC                =       "cubic";
113
 
RtToken RI_PRIMITIVE            =       "primitive";
114
 
RtToken RI_INTERSECTION         =       "intersection";
115
 
RtToken RI_UNION                =       "union";
116
 
RtToken RI_DIFFERENCE           =       "difference";
117
 
RtToken RI_PERIODIC             =       "periodic";
118
 
RtToken RI_NONPERIODIC          =       "nonperiodic";
119
 
RtToken RI_CLAMP                =       "clamp";
120
 
RtToken RI_BLACK                =       "black";
121
 
RtToken RI_IGNORE               =       "ignore";
122
 
RtToken RI_PRINT                =       "print";
123
 
RtToken RI_ABORT                =       "abort";
124
 
RtToken RI_HANDLER              =       "handler";
125
 
RtToken RI_COMMENT              =       "comment";
126
 
RtToken RI_STRUCTURE            =       "structure";
127
 
RtToken RI_VERBATIM             =       "verbatim";
128
 
RtToken RI_IDENTIFIER           =       "identifier";
129
 
RtToken RI_NAME                 =       "name";
130
 
RtToken RI_SHADINGGROUP         =       "shadinggroup";
131
 
RtToken RI_WIDTH                =       "width";
132
 
RtToken RI_CONSTANTWIDTH        =       "constantwidth";
133
 
// extra's
134
 
RtToken RI_JITTER               =       "jitter";
135
 
RtToken RI_ZFILE                =       "zfile";
136
 
RtToken RI_SPHERE               =       "sphere";
137
 
RtToken RI_RAYTRACE             =       "raytrace";
138
 
RtToken RI_HYBRID               =       "hybrid";
139
 
RtToken RI_BUCKETSIZE           =       "bucketsize";
140
 
RtToken RI_TEXTUREMEMORY        =       "texturememory";
141
 
RtToken RI_GRIDSIZE             =       "gridsize";
142
 
RtToken RI_BINARY               =       "binary";
143
 
RtToken RI_EYESPLITS            =       "eyesplits";
144
 
 
145
 
//------------------------------------------------------------------------------
146
 
// Basis Matrices
147
 
 
148
 
RtBasis RiBezierBasis   =       {{-1,  3, -3, 1},
149
 
                                 { 3, -6,  3, 0},
150
 
                                 {-3,  3,  0, 0},
151
 
                                 { 1,  0,  0, 0}};
152
 
 
153
 
RtBasis RiBSplineBasis    = {{(RtFloat)-1/6, 0.5, -0.5, (RtFloat)1/6},
154
 
                             {0.5, -1, 0.5, 0},
155
 
                             {-0.5, 0, 0.5, 0},
156
 
                             {(RtFloat)1/6, (RtFloat)4/6, (RtFloat)1/6, 0}};
157
 
 
158
 
RtBasis RiCatmullRomBasis = {{-0.5,  1.5, -1.5,  0.5},
159
 
                             {   1, -2.5,    2, -0.5},
160
 
                             {-0.5,    0,  0.5,    0},
161
 
                             {   0,    1,    0,    0}};
162
 
 
163
 
RtBasis RiHermiteBasis    = {{ 2,  1, -2,  1},
164
 
                             {-3, -2,  3, -1},
165
 
                             { 0,  1,  0,  0},
166
 
                             { 1,  0,  0,  0}};
167
 
 
168
 
RtBasis RiPowerBasis      = {{1, 0, 0, 0},
169
 
                             {0, 1, 0, 0},
170
 
                             {0, 0, 1, 0},
171
 
                             {0, 0, 0, 1}};
172
 
 
173
 
//------------------------------------------------------------------------------
174
 
// helper functions for building parameter lists from var args
175
 
 
176
 
static RtToken* _tokens = NULL;
177
 
static RtPointer* _parms = NULL;
178
 
 
179
 
static void getArgs(va_list args, unsigned int n)
180
 
{
181
 
        for (unsigned int i=0; i<n; i++) {
182
 
                _tokens[i] = va_arg(args, const char*);
183
 
                _parms[i] = va_arg(args, void*);
184
 
        }
185
 
}
186
 
 
187
 
static int cntArgs(va_list args)
188
 
{
189
 
        const char* t;
190
 
        void* p;
191
 
        int n = 0;
192
 
        t = va_arg(args, const char*);
193
 
        while (t!=NULL) {
194
 
                n++;
195
 
                p = va_arg(args, void*);
196
 
                // p should never be NULL, this would indicate an error in the parameter list
197
 
                assert(p != NULL);
198
 
                t = va_arg(args, const char*);
199
 
        }
200
 
        return n;
201
 
}
202
 
 
203
 
// note: on linux got crashes here,
204
 
// obviously have to restart the list after first pass in CountArgs()
205
 
// why it doesn't happen on win32 I do not know...
206
 
#define BUILD_TOKENPARAM_LIST(start_arg)\
207
 
        va_list args;\
208
 
        va_start(args, start_arg);\
209
 
        unsigned int n = cntArgs(args);\
210
 
        va_end(args);\
211
 
        if (n!=0) {\
212
 
                delete[] _tokens;\
213
 
                delete[] _parms;\
214
 
                _tokens = new RtToken[n];\
215
 
                _parms = new RtPointer[n];\
216
 
                va_start(args, start_arg);\
217
 
                getArgs(args, n);\
218
 
                va_end(args);\
219
 
        }\
220
 
 
221
 
//------------------------------------------------------------------------------
222
 
// helper functions to test for presence of 'P' array in parameter list (or Pz/Pw)
223
 
// P only
224
 
bool haveP(const char* funcname, RtInt n, RtToken tokens[], RtPointer parms[])
225
 
{
226
 
        for (int i=0; i<n; ++i)
227
 
                if (!strcmp(tokens[i], RI_P)) return true;
228
 
        fprintf(ERROUT, "[ERROR]: %s() -> required 'P' array is missing\n", funcname);
229
 
        return false;
230
 
}
231
 
 
232
 
// P or Pz
233
 
bool haveP_Pz(const char* funcname, RtInt n, RtToken tokens[], RtPointer parms[])
234
 
{
235
 
        for (int i=0; i<n; ++i)
236
 
                if ((!strcmp(tokens[i], RI_P)) || (!strcmp(tokens[i], RI_PZ))) return true;
237
 
        fprintf(ERROUT, "[ERROR]: %s() -> required 'P' or 'Pz' array is missing\n", funcname);
238
 
        return false;
239
 
}
240
 
 
241
 
// P or Pw
242
 
bool haveP_Pw(const char* funcname, RtInt n, RtToken tokens[], RtPointer parms[])
243
 
{
244
 
        for (int i=0; i<n; ++i)
245
 
                if ((!strcmp(tokens[i], RI_P)) || (!strcmp(tokens[i], RI_PW))) return true;
246
 
        fprintf(ERROUT, "[ERROR]: %s() -> required 'P' or 'Pw' array is missing\n", funcname);
247
 
        return false;
248
 
}
249
 
 
250
 
// any of P/Pz/Pw
251
 
bool haveP_any(const char* funcname, RtInt n, RtToken tokens[], RtPointer parms[])
252
 
{
253
 
        for (int i=0; i<n; ++i)
254
 
                if ((!strcmp(tokens[i], RI_P)) || (!strcmp(tokens[i], RI_PZ)) || (!strcmp(tokens[i], RI_PW))) return true;
255
 
        fprintf(ERROUT, "[ERROR]: %s() -> required 'P', 'Pz' or 'Pw' array is missing\n", funcname);
256
 
        return false;
257
 
}
258
 
 
259
 
//------------------------------------------------------------------------------
260
 
// motion block error checking
261
 
 
262
 
static int motion_pos = -1;
263
 
enum mbCmdType {MB_NONE,
264
 
// transforms
265
 
MB_TRANSFORM, MB_CONCATTRANSFORM, MB_PERSPECTIVE, MB_TRANSLATE, MB_ROTATE, MB_SCALE, MB_SKEW,
266
 
MB_PROJECTION, MB_DISPLACEMENT, MB_DEFORMATION,
267
 
// geometry
268
 
MB_BOUND, MB_DETAIL, MB_POLYGON, MB_GENERALPOLYGON, MB_POINTSPOLYGONS, MB_POINTSGENERALPOLYGONS, MB_PATCH,
269
 
MB_PATCHMESH, MB_NUPATCH, MB_SPHERE, MB_CONE, MB_CYLINDER, MB_HYPERBOLOID, MB_PARABOLOID, MB_DISK, MB_TORUS, MB_POINTS, MB_CURVES,
270
 
MB_SUBDIVISIONMESH, MB_BLOBBY,
271
 
// not in list of valid commands, but this must be valid too
272
 
MB_READARCHIVE,
273
 
// shading
274
 
MB_COLOR, MB_OPACITY, MB_LIGHTSOURCE, MB_AREALIGHTSOURCE, MB_SURFACE, MB_INTERIOR, MB_EXTERIOR, MB_ATMOSPHERE
275
 
};
276
 
static mbCmdType prev_motion_cmd = MB_NONE;
277
 
// commands in readarchive include files are not tested yet.
278
 
// for now temporary solution is to only check commands in main file
279
 
static bool in_readarchive = false;
280
 
 
281
 
static bool mbCheck(bool valid=false, mbCmdType cur_cmd=MB_NONE)
282
 
{
283
 
        if (cur_cmd == MB_READARCHIVE)
284
 
                in_readarchive = true;
285
 
        else if (in_readarchive)        // skip if reading archive files, see comment above
286
 
                return true;
287
 
        if (!valid) {
288
 
                if (motion_pos >= 0) {
289
 
                        fprintf(ERROUT, "[ERROR]: illegal command inside motion block\n");
290
 
                        State::Instance()->cancelMotion();
291
 
                        return false;
292
 
                }
293
 
                return true;
294
 
        }
295
 
        if ((motion_pos >= 1) && (prev_motion_cmd != cur_cmd)) {
296
 
                fprintf(ERROUT, "[ERROR]: command inside current motion block is different from previous\n");
297
 
                State::Instance()->cancelMotion();
298
 
                return false;
299
 
        }
300
 
        if (motion_pos >= 0) {
301
 
                motion_pos++;
302
 
                prev_motion_cmd = cur_cmd;
303
 
        }
304
 
        return true;
305
 
}
306
 
 
307
 
//------------------------------------------------------------------------------
308
 
// Pixel Filters
309
 
 
310
 
RtFloat RiGaussianFilter(RtFloat x, RtFloat y, RtFloat xwidth, RtFloat ywidth)
311
 
{
312
 
        x *= (RtFloat)2 / xwidth;
313
 
        y *= (RtFloat)2 / ywidth;
314
 
        return expf((RtFloat)-2 * (x*x + y*y));
315
 
}
316
 
 
317
 
RtFloat RiBoxFilter(RtFloat x, RtFloat y, RtFloat xwidth, RtFloat ywidth)
318
 
{
319
 
        return (RtFloat)1;
320
 
}
321
 
 
322
 
RtFloat RiTriangleFilter(RtFloat x, RtFloat y, RtFloat xwidth, RtFloat ywidth)
323
 
{
324
 
        RtFloat hfx = xwidth * (RtFloat)0.5;
325
 
        RtFloat hfy = ywidth * (RtFloat)0.5;
326
 
        RtFloat ax = fabs(x), ay = fabs(y);
327
 
        return MIN2((hfx-ax)/hfx, (hfy-ay)/hfy);
328
 
}
329
 
 
330
 
RtFloat RiCatmullRomFilter(RtFloat x, RtFloat y, RtFloat xwidth, RtFloat ywidth)
331
 
{
332
 
        RtFloat r2 = (x*x + y*y);
333
 
        RtFloat r = sqrt(r2);
334
 
        return (r>=(RtFloat)2) ? (RtFloat)0 :
335
 
                                (r<(RtFloat)1) ? ((RtFloat)3*r*r2 - (RtFloat)5*r2 + (RtFloat)2) :
336
 
                                (-r*r2 + (RtFloat)5*r2 - (RtFloat)8*r + (RtFloat)4);
337
 
}
338
 
 
339
 
RtFloat RiSincFilter(RtFloat x, RtFloat y,
340
 
                                                                                RtFloat xwidth, RtFloat ywidth)
341
 
{
342
 
        RtFloat s,t;
343
 
        x *= (RtFloat)M_PI;
344
 
        y *= (RtFloat)M_PI;
345
 
        if ((x>-RI_EPSILON) && (x<RI_EPSILON))
346
 
                s = (RtFloat)1;
347
 
        else
348
 
                s = sinf(x)/x;
349
 
        if ((y>-RI_EPSILON) && (y<RI_EPSILON))
350
 
                t = (RtFloat)1;
351
 
        else
352
 
                t = sinf(y)/y;
353
 
        return s*t;
354
 
}
355
 
 
356
 
//------------------------------------------------------------------------------
357
 
// separable versions of all of the above (though not necessarly exactly the same...)
358
 
RtFloat RiSepGaussianFilter(RtFloat v, RtFloat width)
359
 
{
360
 
        v *= (RtFloat)2 / width;
361
 
        return (RtFloat)expf((RtFloat)-2*v*v);
362
 
}
363
 
 
364
 
RtFloat RiSepBoxFilter(RtFloat v, RtFloat width)
365
 
{
366
 
        return (RtFloat)1;
367
 
}
368
 
 
369
 
RtFloat RiSepTriangleFilter(RtFloat v, RtFloat width)
370
 
{
371
 
        RtFloat hf = width * (RtFloat)0.5;
372
 
        return (hf - ABS(v)) / hf;
373
 
}
374
 
 
375
 
RtFloat RiSepCatmullRomFilter(RtFloat v, RtFloat width)
376
 
{
377
 
        if (v < (RtFloat)-2) return (RtFloat)0;
378
 
        if (v < (RtFloat)-1) return (RtFloat)0.5*((RtFloat)4 +   v*((RtFloat) 8 + v*((RtFloat) 5 + v)));
379
 
        if (v < (RtFloat) 0) return (RtFloat)0.5*((RtFloat)2 + v*v*((RtFloat)-5 + v* (RtFloat)-3));
380
 
        if (v < (RtFloat) 1) return (RtFloat)0.5*((RtFloat)2 + v*v*((RtFloat)-5 + v* (RtFloat) 3));
381
 
        if (v < (RtFloat) 2) return (RtFloat)0.5*((RtFloat)4 +   v*((RtFloat)-8 + v*((RtFloat) 5 - v)));
382
 
        return (RtFloat)0;
383
 
}
384
 
 
385
 
RtFloat RiSepSincFilter(RtFloat v, RtFloat width)
386
 
{
387
 
        v *= (RtFloat)M_PI;
388
 
        if ((v > -RI_EPSILON) && (v < RI_EPSILON)) return (RtFloat)1;
389
 
        return (sinf(v) / v);
390
 
}
391
 
 
392
 
//------------------------------------------------------------------------------
393
 
 
394
 
RtToken RiDeclare(const char* name, const char* declaration)
395
 
{
396
 
        if (!mbCheck()) return NULL;
397
 
        decParam_t dp = {0, 0, 0};
398
 
        if (!parseDeclaration(declaration, &dp, NULL)) {
399
 
                fprintf(ERROUT, "[ERROR]: RiDeclare() -> parameter declaration error\n");
400
 
                return NULL;
401
 
        }
402
 
        State::Instance()->addDeclared(name, dp);
403
 
        return name;
404
 
}
405
 
 
406
 
// Graphics State
407
 
RtVoid RiBegin(RtToken name)
408
 
{
409
 
        //if (name) newfile?;
410
 
        State::Instance()->begin(name);
411
 
}
412
 
 
413
 
RtVoid RiEnd()
414
 
{
415
 
        // free last token/parm array allocs
416
 
        if (_tokens) delete[] _tokens;
417
 
        if (_parms) delete[] _parms;
418
 
        // state end
419
 
        State::Instance()->end();
420
 
}
421
 
 
422
 
RtContextHandle RiGetContext()
423
 
{
424
 
        return NULL;
425
 
}
426
 
 
427
 
RtVoid RiContext(RtContextHandle)
428
 
{
429
 
}
430
 
 
431
 
RtVoid RiFrameBegin(RtInt frame)
432
 
{
433
 
        if (!mbCheck()) return;
434
 
        State::Instance()->frameBegin(frame);
435
 
}
436
 
 
437
 
RtVoid RiFrameEnd()
438
 
{
439
 
        if (!mbCheck()) return;
440
 
        State::Instance()->frameEnd();
441
 
}
442
 
 
443
 
RtVoid RiWorldBegin()
444
 
{
445
 
        if (!mbCheck()) return;
446
 
        State::Instance()->worldBegin();
447
 
}
448
 
 
449
 
RtVoid RiWorldEnd()
450
 
{
451
 
        if (!mbCheck()) return;
452
 
        State::Instance()->worldEnd();
453
 
}
454
 
 
455
 
// Camera Options
456
 
RtVoid RiFormat(RtInt xres, RtInt yres, RtFloat aspect)
457
 
{
458
 
        if (!mbCheck()) return;
459
 
        Options& options = State::Instance()->topOptions();
460
 
        // if negative: use defaults
461
 
        if (xres>=0) options.xRes = xres;
462
 
        if (yres>=0) options.yRes = yres;
463
 
        if (aspect>=0) options.pixelAspectRatio = aspect;
464
 
        // also affects other related options
465
 
        options.frameAspectRatio = options.pixelAspectRatio * (xres / (float)yres);
466
 
        if (xres >= yres) {
467
 
                options.left = -options.frameAspectRatio;
468
 
                options.right = options.frameAspectRatio;
469
 
                options.bottom = -1.f;
470
 
                options.top = 1.f;
471
 
        }
472
 
        else {
473
 
                options.left = -1.f;
474
 
                options.right = 1.f;
475
 
                options.bottom = -1.f/options.frameAspectRatio;
476
 
                options.top = 1.f/options.frameAspectRatio;
477
 
        }
478
 
}
479
 
 
480
 
RtVoid RiFrameAspectRatio(RtFloat aspect)
481
 
{
482
 
        if (!mbCheck()) return;
483
 
        Options& options = State::Instance()->topOptions();
484
 
        options.frameAspectRatio = aspect;
485
 
        State::Instance()->resetFrameAspect = true;
486
 
}
487
 
 
488
 
RtVoid RiScreenWindow(RtFloat left, RtFloat right, RtFloat bot, RtFloat top)
489
 
{
490
 
        if (!mbCheck()) return;
491
 
        Options& options = State::Instance()->topOptions();
492
 
        options.left = left;
493
 
        options.right = right;
494
 
        options.bottom = bot;
495
 
        options.top = top;
496
 
        State::Instance()->resetScrWin = true;
497
 
}
498
 
 
499
 
RtVoid RiCropWindow(RtFloat xmin, RtFloat xmax, RtFloat ymin, RtFloat ymax)
500
 
{
501
 
        if (!mbCheck()) return;
502
 
        Options& options = State::Instance()->topOptions();
503
 
        options.xMin = xmin;
504
 
        options.xMax = xmax;
505
 
        options.yMin = ymin;
506
 
        options.yMax = ymax;
507
 
}
508
 
 
509
 
RtVoid RiProjection(RtToken name, ...)
510
 
{
511
 
        BUILD_TOKENPARAM_LIST(name)
512
 
        RiProjectionV(name, n, _tokens, _parms);
513
 
}
514
 
 
515
 
RtVoid RiProjectionV(RtToken name, RtInt n, RtToken tokens[], RtPointer parms[])
516
 
{
517
 
        if (!mbCheck(true, MB_PROJECTION)) return;
518
 
        Options& options = State::Instance()->topOptions();
519
 
        if (!strcmp(name, RI_PERSPECTIVE)) {
520
 
                options.projection = Options::PROJ_PERSPECTIVE;
521
 
                // optional param 'fov'
522
 
                for (int i=0; i<n; i++) {
523
 
                        if (!strcmp(tokens[i], RI_FOV)) {
524
 
                                options.fov = *((RtFloat*)parms[i]);
525
 
                                // nothing else yet
526
 
                                break;
527
 
                        }
528
 
                }
529
 
        }
530
 
        else if (!strcmp(name, RI_ORTHOGRAPHIC))
531
 
                options.projection = Options::PROJ_ORTHOGRAPHIC;
532
 
        else
533
 
                fprintf(ERROUT, "[WARNING]: RiProjection() -> unknown projection type '%s'\n", name);
534
 
}
535
 
 
536
 
RtVoid RiClipping(RtFloat hither, RtFloat yon)
537
 
{
538
 
        if (!mbCheck()) return;
539
 
        Options& options = State::Instance()->topOptions();
540
 
        options.nearClip = hither;
541
 
        options.farClip = yon;
542
 
}
543
 
 
544
 
RtVoid RiClippingPlane(RtFloat x, RtFloat y, RtFloat z, RtFloat nx, RtFloat ny, RtFloat nz)
545
 
{
546
 
        if (!mbCheck()) return;
547
 
        // not yet...
548
 
        fprintf(ERROUT, "'ClippingPlane' not implemented (yet)\n");
549
 
}
550
 
 
551
 
RtVoid RiDepthOfField(RtFloat fstop, RtFloat focallength, RtFloat focaldistance)
552
 
{
553
 
        if (!mbCheck()) return;
554
 
        Options& options = State::Instance()->topOptions();
555
 
        options.fStop = fstop;
556
 
        options.focalLength = focallength;
557
 
        options.focalDistance = focaldistance;
558
 
}
559
 
 
560
 
RtVoid RiShutter(RtFloat min, RtFloat max)
561
 
{
562
 
        if (!mbCheck()) return;
563
 
        Options& options = State::Instance()->topOptions();
564
 
        options.closeShutter = min;
565
 
        options.closeShutter = max;
566
 
}
567
 
 
568
 
// Display Options
569
 
RtVoid RiPixelVariance(RtFloat variation)
570
 
{
571
 
        if (!mbCheck()) return;
572
 
        Options& options = State::Instance()->topOptions();
573
 
        options.pixelVariance = variation;
574
 
}
575
 
 
576
 
RtVoid RiPixelSamples(RtFloat xsamples, RtFloat ysamples)
577
 
{
578
 
        if (!mbCheck()) return;
579
 
        Options& options = State::Instance()->topOptions();
580
 
        options.xSamples = xsamples;
581
 
        options.ySamples = ysamples;
582
 
}
583
 
 
584
 
RtVoid RiPixelFilter(RtFilterFunc filterfunc, RtFloat xwidth, RtFloat ywidth)
585
 
{
586
 
        if (!mbCheck()) return;
587
 
        Options& options = State::Instance()->topOptions();
588
 
        options.pixelFilter = filterfunc;
589
 
        options.xWidth = xwidth;
590
 
        options.yWidth = ywidth;
591
 
}
592
 
 
593
 
RtVoid RiExposure(RtFloat gain, RtFloat gamma)
594
 
{
595
 
        if (!mbCheck()) return;
596
 
        Options& options = State::Instance()->topOptions();
597
 
        options.gain = gain;
598
 
        options.gamma = gamma;
599
 
}
600
 
 
601
 
RtVoid RiImager(RtToken name, ...)
602
 
{
603
 
        BUILD_TOKENPARAM_LIST(name)
604
 
        RiImagerV(name, n, _tokens, _parms);
605
 
}
606
 
 
607
 
RtVoid RiImagerV(RtToken name, RtInt n, RtToken tokens[], RtPointer parms[])
608
 
{
609
 
        if (!mbCheck()) return;
610
 
        // TODO
611
 
        fprintf(ERROUT, "'Imager' not implemented (yet)\n");
612
 
}
613
 
 
614
 
RtVoid RiQuantize(RtToken type, RtInt one, RtInt min, RtInt max, RtFloat ampl)
615
 
{
616
 
        if (!mbCheck()) return;
617
 
        Options& options = State::Instance()->topOptions();
618
 
        if (!strcmp(type, RI_RGBA)) {
619
 
                options.cqOne = one;
620
 
                options.cqMin = min;
621
 
                options.cqMax = max;
622
 
                options.cqDitherAmplitude = ampl;
623
 
        }
624
 
        else if (!strcmp(type, RI_Z)) {
625
 
                options.zqOne = one;
626
 
                options.zqMin = min;
627
 
                options.zqMax = max;
628
 
                options.zqDitherAmplitude = ampl;
629
 
        }
630
 
        else
631
 
        fprintf(ERROUT, "Unknown quantizer: '%s'\n", type);
632
 
}
633
 
 
634
 
RtVoid RiDisplay(const char* name, RtToken type, RtToken mode, ...)
635
 
{
636
 
        BUILD_TOKENPARAM_LIST(mode)
637
 
        RiDisplayV(name, type, mode, n, _tokens, _parms);
638
 
}
639
 
 
640
 
RtVoid RiDisplayV(const char* name, RtToken type, RtToken mode,
641
 
                                                                        RtInt n, RtToken tokens[], RtPointer parms[])
642
 
{
643
 
        if (!mbCheck()) return;
644
 
        Options& options = State::Instance()->topOptions();
645
 
        // name
646
 
        strncpy(options.displayName, name, 80);
647
 
        // type
648
 
        if (!strcmp(type, RI_FRAMEBUFFER))
649
 
                options.displayType = Options::DT_FRAMEBUFFER;
650
 
        else if (!strcmp(type, RI_FILE))
651
 
                options.displayType = Options::DT_FILE;
652
 
        else if (!strcmp(type, RI_ZFILE))
653
 
                options.displayType = Options::DT_ZFILE;
654
 
        else
655
 
                fprintf(ERROUT, "Display type unknown: '%s'\n", type);
656
 
        // mode
657
 
        if (!strcmp(mode, RI_RGB))
658
 
                options.displayMode = Options::DM_RGB;
659
 
        else if (!strcmp(mode, RI_RGBA))
660
 
                options.displayMode = Options::DM_RGBA;
661
 
        else if (!strcmp(mode, RI_RGBZ))
662
 
                options.displayMode = Options::DM_RGBZ;
663
 
        else if (!strcmp(mode, RI_RGBAZ))
664
 
                options.displayMode = Options::DM_RGBAZ;
665
 
        else if (!strcmp(mode, RI_A))
666
 
                options.displayMode = Options::DM_A;
667
 
        else if (!strcmp(mode, RI_Z))
668
 
                options.displayMode = Options::DM_Z;
669
 
        else if (!strcmp(mode, RI_AZ))
670
 
                options.displayMode = Options::DM_AZ;
671
 
        else
672
 
                fprintf(ERROUT, "[WARNING]: Display mode unknown: '%s'\n", mode);
673
 
        // no other parameters used yet
674
 
}
675
 
 
676
 
// Additional Options
677
 
RtVoid RiHider(RtToken type, ...)
678
 
{
679
 
        BUILD_TOKENPARAM_LIST(type)
680
 
        RiHiderV(type, n, _tokens, _parms);
681
 
}
682
 
 
683
 
RtVoid RiHiderV(RtToken type, RtInt n, RtToken tokens[], RtPointer parms[])
684
 
{
685
 
        if (!mbCheck()) return;
686
 
        State* state = State::Instance();
687
 
        state->verifyMode(MODE_BASE, RIE_NOTSTARTED, "RiHiderV()");
688
 
        Options& options = state->topOptions();
689
 
        if (!strcmp(type, RI_HIDDEN))
690
 
                options.hider = Options::HD_HIDDEN;
691
 
        else if (!strcmp(type, RI_RAYTRACE))
692
 
                options.hider = Options::HD_RAYTRACE;
693
 
        else if (!strcmp(type, RI_HYBRID))
694
 
                options.hider = Options::HD_HYBRID;
695
 
        else {
696
 
                fprintf(ERROUT, "[WARNING] -> State::worldBegin(): Unknown hider '%s', will use 'hidden' instead\n", type);
697
 
                options.hider = Options::HD_HIDDEN;
698
 
        }
699
 
        // optional jitter param
700
 
        for (int i=0; i<n; i++) {
701
 
                if (!strcmp(tokens[i], RI_JITTER)) {
702
 
                        options.jitter = MAX2(0.f, MIN2(1.f, *((RtFloat*)parms[i])));
703
 
                        break;
704
 
                }
705
 
        }
706
 
}
707
 
 
708
 
RtVoid RiColorSamples(RtInt n, RtFloat nRGB[], RtFloat RGBn[])
709
 
{
710
 
        if (!mbCheck()) return;
711
 
        // TODO (possibly), for now fixed at 3 (RGB)
712
 
        fprintf(ERROUT, "'ColorSamples' not implemented (yet)\n");
713
 
}
714
 
 
715
 
RtVoid RiRelativeDetail(RtFloat relativedetail)
716
 
{
717
 
        if (!mbCheck()) return;
718
 
        Options& options = State::Instance()->topOptions();
719
 
        options.relativeDetail = relativedetail;
720
 
}
721
 
 
722
 
// Implementation-specific Options
723
 
RtVoid RiOption(RtToken name, ...)
724
 
{
725
 
        if (!mbCheck()) return;
726
 
        BUILD_TOKENPARAM_LIST(name)
727
 
        RiOptionV(name, n, _tokens, _parms);
728
 
}
729
 
 
730
 
RtVoid RiOptionV(RtToken name, RtInt n, RtToken tokens[], RtPointer parms[])
731
 
{
732
 
        if (!mbCheck()) return;
733
 
        Options& options = State::Instance()->topOptions();
734
 
        if (!strcmp(name, "hider")) {
735
 
                for (int i=0; i<n; ++i) {
736
 
                        if (!strcmp(tokens[i], RI_JITTER))
737
 
                                options.jitter = MAX2(0.f, MIN2(1.f, *((RtFloat*)parms[i])));
738
 
                        else
739
 
                                fprintf(ERROUT, "Unknown hider option '%s'\n", tokens[i]);
740
 
                }
741
 
        }
742
 
        else if (!strcmp(name, "limits")) {
743
 
                for (int i=0; i<n; ++i) {
744
 
                        if (!strcmp(tokens[i], RI_BUCKETSIZE))
745
 
                                options.bucketsize = ABS(*((RtInt*)parms[i]));
746
 
                        else if (!strcmp(tokens[i], RI_TEXTUREMEMORY))
747
 
                                options.texturememory = ABS(*((RtInt*)parms[i]))*1024;
748
 
                        else if (!strcmp(tokens[i], RI_GRIDSIZE))
749
 
                                options.gridsize = ABS(*((RtInt*)parms[i]));
750
 
                        else if (!strcmp(tokens[i], RI_EYESPLITS))
751
 
                                options.eyesplits = ABS(*((RtInt*)parms[i]));
752
 
                        else
753
 
                                fprintf(ERROUT, "Unknown limits option '%s'\n", tokens[i]);
754
 
                }
755
 
        }
756
 
        else
757
 
                fprintf(ERROUT, "Unknown option '%s'\n", name);
758
 
}
759
 
 
760
 
//------------------------------------------------------------------------------
761
 
// helper function to get declared parameter values for shaders
762
 
bool getShaderParams(SlShaderInstance* SI, RtInt n, RtToken tokens[], RtPointer parms[])
763
 
{
764
 
        // get declared params
765
 
        for (int i=0; i<n; i++) {
766
 
                // skip special case 'code' if found
767
 
                if (!strcmp(tokens[i], "code")) continue;
768
 
                // get parameter
769
 
                decParam_t dp = {0, 0, 0};
770
 
                char inline_name[256] = {0};
771
 
                const char* varname = tokens[i];
772
 
                if (!State::Instance()->parameterFromName(varname, dp, inline_name)) continue;
773
 
                if (inline_name[0] != 0) varname = inline_name; // was inline declared
774
 
                // get value
775
 
                if (dp.ct_flags & DT_FLOAT)
776
 
                        SI->setParameter(varname, SL_FLOAT, ((dp.ct_flags & SC_VARYING)!=0), dp.arlen, parms[i]);
777
 
                else if (dp.ct_flags & DT_STRING)
778
 
                        SI->setParameter(varname, SL_STRING, ((dp.ct_flags & SC_VARYING)!=0), dp.arlen, parms[i]);
779
 
                else if (dp.ct_flags & DT_FLOAT3MASK) {
780
 
                        // to simplify, point/vector/normal/color all accessed as vector,
781
 
                        // all are float[3] typedefs anyway
782
 
                        RtVector *parm = (RtVector*)parms[i];
783
 
                        RtVector* tv = new RtVector[dp.arlen];
784
 
                        // current space transform
785
 
                        const Transform* xf = SI->xform;
786
 
                        if (dp.ct_flags & DT_POINT) {
787
 
                                for (int j=0; j<dp.arlen; j++) {
788
 
                                        Point3 t = *xf * Point3(parm[j][0], parm[j][1], parm[j][2]);
789
 
                                        tv[j][0] = t.x, tv[j][1] = t.y, tv[j][2] = t.z;
790
 
                                }
791
 
                                SI->setParameter(varname, SL_POINT, ((dp.ct_flags & SC_VARYING)!=0), dp.arlen, tv);
792
 
                        }
793
 
                        else if (dp.ct_flags & DT_VECTOR) {
794
 
                                for (int j=0; j<dp.arlen; j++) {
795
 
                                        Vector t = *xf * Vector(parm[j][0], parm[j][1], parm[j][2]);
796
 
                                        tv[j][0] = t.x, tv[j][1] = t.y, tv[j][2] = t.z;
797
 
                                }
798
 
                                SI->setParameter(varname, SL_VECTOR, ((dp.ct_flags & SC_VARYING)!=0), dp.arlen, tv);
799
 
                        }
800
 
                        else if (dp.ct_flags & DT_NORMAL) {
801
 
                                Transform nxf = *xf;
802
 
                                nxf.transpose();
803
 
                                nxf.invert();
804
 
                                for (int j=0; j<dp.arlen; j++) {
805
 
                                        Vector t = nxf * Vector(parm[j][0], parm[j][1], parm[j][2]);
806
 
                                        tv[j][0] = t.x, tv[j][1] = t.y, tv[j][2] = t.z;
807
 
                                }
808
 
                                SI->setParameter(varname, SL_NORMAL, ((dp.ct_flags & SC_VARYING)!=0), dp.arlen, tv);
809
 
                        }
810
 
                        else if (dp.ct_flags & DT_COLOR) // no xform
811
 
                                SI->setParameter(varname, SL_COLOR, ((dp.ct_flags & SC_VARYING)!=0), dp.arlen, parms[i]);
812
 
                        delete[] tv;
813
 
                }
814
 
                else if (dp.ct_flags & DT_MATRIX)
815
 
                        SI->setParameter(varname, SL_MATRIX, ((dp.ct_flags & SC_VARYING)!=0), dp.arlen, parms[i]);
816
 
                /*
817
 
                // RSL does not have hpoint type, needs conversion to point. TODO
818
 
                else if (ct_flags & DT_HPOINT)
819
 
                        SI->setParameter(varname, SL_HPOINT, ((dp.ct_flags & SC_VARYING)!=0), dp.arlen, parms[i]);
820
 
                // integer type also not supported, should generate error?
821
 
                else if (ct_flags & DT_INT)
822
 
                        SI->setParameter(varname, SL_INTEGER, ((dp.ct_flags & SC_VARYING)!=0), dp.arlen, parms[i]);
823
 
                */
824
 
                else {
825
 
                        fprintf(ERROUT, "[ERROR]: getShaderParams() -> unexpected unknown type '%s'\n", tokens[i]);
826
 
                        return false;
827
 
                }
828
 
        }
829
 
        return true;
830
 
}
831
 
//------------------------------------------------------------------------------
832
 
// Attributes
833
 
RtVoid RiAttributeBegin()
834
 
{
835
 
        State::Instance()->attributeBegin();
836
 
}
837
 
 
838
 
RtVoid RiAttributeEnd()
839
 
{
840
 
        State::Instance()->attributeEnd();
841
 
}
842
 
 
843
 
// Color & Opacity
844
 
RtVoid RiColor(RtColor color)
845
 
{
846
 
        if (!mbCheck(true, MB_COLOR)) return;
847
 
        Attributes& attr = State::Instance()->topAttributes();
848
 
        attr.color[0] = color[0];
849
 
        attr.color[1] = color[1];
850
 
        attr.color[2] = color[2];
851
 
}
852
 
 
853
 
RtVoid RiOpacity(RtColor color)
854
 
{
855
 
        if (!mbCheck(true, MB_OPACITY)) return;
856
 
        Attributes& attr = State::Instance()->topAttributes();
857
 
        attr.opacity[0] = color[0];
858
 
        attr.opacity[1] = color[1];
859
 
        attr.opacity[2] = color[2];
860
 
}
861
 
 
862
 
// Texture Coordinates
863
 
RtVoid RiTextureCoordinates(RtFloat s1, RtFloat t1, RtFloat s2, RtFloat t2,
864
 
                                                                                                                RtFloat s3, RtFloat t3, RtFloat s4, RtFloat t4)
865
 
{
866
 
        if (!mbCheck()) return;
867
 
        Attributes& attr = State::Instance()->topAttributes();
868
 
        attr.texCoords[0] = s1;
869
 
        attr.texCoords[1] = t1;
870
 
        attr.texCoords[2] = s2;
871
 
        attr.texCoords[3] = t2;
872
 
        attr.texCoords[4] = s3;
873
 
        attr.texCoords[5] = t3;
874
 
        attr.texCoords[6] = s4;
875
 
        attr.texCoords[7] = t4;
876
 
}
877
 
 
878
 
// Light Sources
879
 
RtLightHandle RiLightSource(RtToken name, ...)
880
 
{
881
 
        BUILD_TOKENPARAM_LIST(name)
882
 
        return RiLightSourceV(name, n, _tokens, _parms);
883
 
}
884
 
 
885
 
RtLightHandle RiLightSourceV(RtToken name, RtInt n, RtToken tokens[], RtPointer parms[])
886
 
{
887
 
        if (!mbCheck(true, MB_LIGHTSOURCE)) return NULL;
888
 
 
889
 
        State* state = State::Instance();
890
 
 
891
 
        SlShaderInstance* SI;
892
 
        SI = state->loadShader(name, SL_LIGHT); // on success will also add lightshader to current lightsource list
893
 
        if (SI == NULL) return NULL; // load failed
894
 
 
895
 
        // run default initialization code
896
 
        SI->run_initcode();
897
 
        // then set userdefined params, possibly overriding defaults
898
 
        getShaderParams(SI, n, tokens, parms);
899
 
 
900
 
        return SI;
901
 
}
902
 
 
903
 
RtLightHandle RiAreaLightSource(RtToken name, ...)
904
 
{
905
 
        BUILD_TOKENPARAM_LIST(name)
906
 
        RtLightHandle LH = RiAreaLightSourceV(name, n, _tokens, _parms);
907
 
        return LH;
908
 
}
909
 
 
910
 
RtLightHandle RiAreaLightSourceV(RtToken name, RtInt n, RtToken tokens[], RtPointer parms[])
911
 
{
912
 
        if (!mbCheck(true, MB_AREALIGHTSOURCE)) return NULL;
913
 
        // TODO
914
 
        fprintf(ERROUT, "'AreaLightSource' not implemented (yet)\n");
915
 
        return NULL;
916
 
}
917
 
 
918
 
RtVoid RiIlluminate(RtLightHandle light, RtBoolean onoff)
919
 
{
920
 
        if (!mbCheck()) return;
921
 
        State::Instance()->setLight(light, onoff);
922
 
}
923
 
 
924
 
// Surface Shading
925
 
RtVoid RiSurface(RtToken name, ...)
926
 
{
927
 
        BUILD_TOKENPARAM_LIST(name)
928
 
        RiSurfaceV(name, n, _tokens, _parms);
929
 
}
930
 
 
931
 
RtVoid RiSurfaceV(RtToken name, RtInt n, RtToken tokens[], RtPointer parms[])
932
 
{
933
 
        if (!mbCheck(true, MB_SURFACE)) return;
934
 
 
935
 
        State* state = State::Instance();
936
 
 
937
 
        SlShaderInstance* SI;
938
 
        SI = state->loadShader(name, SL_SURFACE);
939
 
        if (SI == NULL) return; // load failed
940
 
 
941
 
        // run default initialization code
942
 
        SI->run_initcode();
943
 
        // then set userdefined params, possibly overriding defaults
944
 
        getShaderParams(SI, n, tokens, parms);
945
 
}
946
 
 
947
 
// Displacement Shading
948
 
RtVoid RiDisplacement(RtToken name, ...)
949
 
{
950
 
        BUILD_TOKENPARAM_LIST(name)
951
 
        RiDisplacementV(name, n, _tokens, _parms);
952
 
}
953
 
 
954
 
RtVoid RiDisplacementV(RtToken name, RtInt n, RtToken tokens[], RtPointer parms[])
955
 
{
956
 
        if (!mbCheck(true, MB_DISPLACEMENT)) return;
957
 
 
958
 
        State* state = State::Instance();
959
 
 
960
 
        SlShaderInstance* SI;
961
 
        SI = state->loadShader(name, SL_DISPLACEMENT);
962
 
        if (SI == NULL) return; // load failed
963
 
 
964
 
        // run default initialization code
965
 
        SI->run_initcode();
966
 
        // then set userdefined params, possibly overriding defaults
967
 
        getShaderParams(SI, n, tokens, parms);
968
 
}
969
 
 
970
 
// Volume Shading
971
 
RtVoid RiAtmosphere(RtToken name, ...)
972
 
{
973
 
        BUILD_TOKENPARAM_LIST(name)
974
 
        RiAtmosphereV(name, n, _tokens, _parms);
975
 
}
976
 
 
977
 
RtVoid RiAtmosphereV(RtToken name,RtInt n, RtToken tokens[], RtPointer parms[])
978
 
{
979
 
        if (!mbCheck(true, MB_ATMOSPHERE)) return;
980
 
 
981
 
        State* state = State::Instance();
982
 
 
983
 
        SlShaderInstance* SI;
984
 
        SI = state->loadShader(name, SL_VOLUME);
985
 
        if (SI == NULL) return; // load failed
986
 
 
987
 
        // run default initialization code
988
 
        SI->run_initcode();
989
 
        // then set userdefined params, possibly overriding defaults
990
 
        getShaderParams(SI, n, tokens, parms);
991
 
}
992
 
 
993
 
RtVoid RiInterior(RtToken name, ...)
994
 
{
995
 
        BUILD_TOKENPARAM_LIST(name)
996
 
        RiInteriorV(name, n, _tokens, _parms);
997
 
}
998
 
 
999
 
RtVoid RiInteriorV(RtToken name, RtInt n, RtToken tokens[], RtPointer parms[])
1000
 
{
1001
 
        if (!mbCheck(true, MB_INTERIOR)) return;
1002
 
        // TODO
1003
 
        fprintf(ERROUT, "'Interior' not implemented (yet)\n");
1004
 
}
1005
 
 
1006
 
RtVoid RiExterior(RtToken name, ...)
1007
 
{
1008
 
        BUILD_TOKENPARAM_LIST(name)
1009
 
        RiExteriorV(name, n, _tokens, _parms);
1010
 
}
1011
 
 
1012
 
RtVoid RiExteriorV(RtToken name, RtInt n, RtToken tokens[], RtPointer parms[])
1013
 
{
1014
 
        if (!mbCheck(true, MB_EXTERIOR)) return;
1015
 
        // TODO
1016
 
        fprintf(ERROUT, "'Exterior' not implemented (yet)\n");
1017
 
}
1018
 
 
1019
 
// ShadingRate
1020
 
RtVoid RiShadingRate(RtFloat size)
1021
 
{
1022
 
        if (!mbCheck()) return;
1023
 
        Attributes& attr = State::Instance()->topAttributes();
1024
 
        // since the diceable test works with edgelengths and not area's,
1025
 
        // set effectiveShadingRate to some approximate edgelength assuming a square area
1026
 
        attr.effectiveShadingRate = sqrtf(size);
1027
 
}
1028
 
 
1029
 
// ShadingInterpolation
1030
 
RtVoid RiShadingInterpolation(RtToken type)
1031
 
{
1032
 
        if (!mbCheck()) return;
1033
 
        Attributes& attr = State::Instance()->topAttributes();
1034
 
        if (!strcmp(type, RI_CONSTANT))
1035
 
                attr.flags &= ~AF_SMOOTH;
1036
 
        else if (!strcmp(type, RI_SMOOTH))
1037
 
                attr.flags |= AF_SMOOTH;
1038
 
        else
1039
 
                fprintf(ERROUT, "[WARNING]: ShadingInterpolation type unknown: '%s'\n", type);
1040
 
}
1041
 
 
1042
 
// Matte Objects
1043
 
RtVoid RiMatte(RtBoolean onoff)
1044
 
{
1045
 
        if (!mbCheck()) return;
1046
 
        Attributes& attr = State::Instance()->topAttributes();
1047
 
        if (onoff == (RtBoolean)RI_TRUE)
1048
 
                attr.flags |= AF_MATTE;
1049
 
        else
1050
 
                attr.flags &= ~AF_MATTE;
1051
 
}
1052
 
 
1053
 
// Bound
1054
 
RtVoid RiBound(RtBound bound)
1055
 
{
1056
 
        if (!mbCheck(true, MB_BOUND)) return;
1057
 
        // currently not used
1058
 
        /*
1059
 
        Attributes& attr = State::Instance()->topAttributes();
1060
 
        attr.bound[0] = bound[0];
1061
 
        attr.bound[1] = bound[1];
1062
 
        attr.bound[2] = bound[2];
1063
 
        attr.bound[3] = bound[3];
1064
 
        attr.bound[4] = bound[4];
1065
 
        attr.bound[5] = bound[5];
1066
 
        */
1067
 
}
1068
 
 
1069
 
// Detail
1070
 
RtVoid RiDetail(RtBound bound)
1071
 
{
1072
 
        if (!mbCheck(true, MB_DETAIL)) return;
1073
 
        // currently not used
1074
 
        /*
1075
 
        Attributes& attr = State::Instance()->topAttributes();
1076
 
        attr.detail[0] = bound[0];
1077
 
        attr.detail[1] = bound[1];
1078
 
        attr.detail[2] = bound[2];
1079
 
        attr.detail[3] = bound[3];
1080
 
        attr.detail[4] = bound[4];
1081
 
        attr.detail[5] = bound[5];
1082
 
        */
1083
 
}
1084
 
 
1085
 
RtVoid RiDetailRange(RtFloat minvis, RtFloat lowtran, RtFloat uptran, RtFloat maxvis)
1086
 
{
1087
 
        // currently not used
1088
 
        /*
1089
 
        Attributes& attr = State::Instance()->topAttributes();
1090
 
        attr.minVisible = minvis;
1091
 
        attr.lowerTransition = lowtran;
1092
 
        attr.upperTransition = uptran;
1093
 
        attr.maxVisible = maxvis;
1094
 
        */
1095
 
}
1096
 
 
1097
 
// Geometric Approximation
1098
 
RtVoid RiGeometricApproximation(RtToken type, RtFloat value)
1099
 
{
1100
 
        if (!mbCheck()) return;
1101
 
        // currently not used
1102
 
        /*
1103
 
        Attributes& attr = State::Instance()->topAttributes();
1104
 
        if (!strcmp(type, RI_FLATNESS))
1105
 
                attr.valueApproximation = value;
1106
 
        else
1107
 
                fprintf(ERROUT, "[WARNING]: GeometricApproximation type unknown: '%s'\n", type);
1108
 
        */
1109
 
}
1110
 
 
1111
 
// Orientation and Sides
1112
 
RtVoid RiOrientation(RtToken orientation)
1113
 
{
1114
 
        if (!mbCheck()) return;
1115
 
        Attributes& attr = State::Instance()->topAttributes();
1116
 
        bool isrh = State::Instance()->currentTransform().handedness();
1117
 
        if (!strcmp(orientation, RI_OUTSIDE))
1118
 
                attr.flags &= ~AF_ORIENTATION;
1119
 
        else if (!strcmp(orientation, RI_INSIDE))
1120
 
                attr.flags |= AF_ORIENTATION;
1121
 
        else if (!strcmp(orientation, RI_LH)) {
1122
 
                if (isrh) attr.flags |= AF_ORIENTATION; else attr.flags &= ~AF_ORIENTATION;
1123
 
        }
1124
 
        else if (!strcmp(orientation, RI_RH)) {
1125
 
                if (isrh) attr.flags &= ~AF_ORIENTATION; else attr.flags |= AF_ORIENTATION;
1126
 
        }
1127
 
        else
1128
 
                fprintf(ERROUT, "[WARNING]: Orientation unknown: '%s'\n", orientation);
1129
 
}
1130
 
 
1131
 
RtVoid RiReverseOrientation()
1132
 
{
1133
 
        if (!mbCheck()) return;
1134
 
        Attributes& attr = State::Instance()->topAttributes();
1135
 
        attr.flags ^= AF_ORIENTATION;
1136
 
}
1137
 
 
1138
 
RtVoid RiSides(RtInt sides)
1139
 
{
1140
 
        if (!mbCheck()) return;
1141
 
        Attributes& attr = State::Instance()->topAttributes();
1142
 
        if (sides == 1)
1143
 
                attr.flags |= AF_SIDES1;
1144
 
        else
1145
 
                attr.flags &= ~AF_SIDES1;
1146
 
}
1147
 
 
1148
 
// Transformations
1149
 
RtVoid RiIdentity()
1150
 
{
1151
 
        if (!mbCheck()) return;
1152
 
        State* state = State::Instance();
1153
 
        const Transform idt = state->transformIdentity();
1154
 
        Transform& curT = state->currentTransform();
1155
 
        for (int i=0; i<4; ++i)
1156
 
                for (int j=0; j<4; ++j)
1157
 
                        curT[i][j] = idt[i][j];
1158
 
}
1159
 
 
1160
 
RtVoid RiTransform(RtMatrix transform)
1161
 
{
1162
 
        if (!mbCheck(true, MB_TRANSFORM)) return;
1163
 
        State* state = State::Instance();
1164
 
        const Transform idt = state->transformIdentity();
1165
 
        RtMatrix nm;
1166
 
        mulMMM(nm, *idt.getRtMatrixPtr(), transform);
1167
 
        // NOTE motion_pos is already incremented at this point, so have to subtract 1,
1168
 
        // is ok, since currentTransform only checks for negative val. anyway
1169
 
        Transform& curT = state->currentTransform(motion_pos - 1);
1170
 
        for (int i=0; i<4; ++i)
1171
 
                for (int j=0; j<4; ++j)
1172
 
                        curT[i][j] = nm[i][j];
1173
 
}
1174
 
 
1175
 
RtVoid RiConcatTransform(RtMatrix transform)
1176
 
{
1177
 
        if (!mbCheck(true, MB_CONCATTRANSFORM)) return;
1178
 
        Transform& curT = State::Instance()->currentTransform(motion_pos - 1);
1179
 
        curT *= Transform(transform);
1180
 
}
1181
 
 
1182
 
RtVoid RiPerspective(RtFloat fov)
1183
 
{
1184
 
        if (!mbCheck(true, MB_PERSPECTIVE)) return;
1185
 
        State* state = State::Instance();
1186
 
        Transform& curT = state->currentTransform(motion_pos - 1);
1187
 
        Options &options = state->topOptions();
1188
 
        curT.perspective(fov, options.nearClip, options.farClip);
1189
 
}
1190
 
 
1191
 
RtVoid RiTranslate(RtFloat dx, RtFloat dy, RtFloat dz)
1192
 
{
1193
 
        if (!mbCheck(true, MB_TRANSLATE)) return;
1194
 
        Transform& curT = State::Instance()->currentTransform(motion_pos - 1);
1195
 
        curT.translate(dx, dy, dz);
1196
 
}
1197
 
 
1198
 
RtVoid RiRotate(RtFloat angle, RtFloat dx, RtFloat dy, RtFloat dz)
1199
 
{
1200
 
        if (!mbCheck(true, MB_ROTATE)) return;
1201
 
        Transform& curT = State::Instance()->currentTransform(motion_pos - 1);
1202
 
        curT.rotate(angle, dx, dy, dz);
1203
 
}
1204
 
 
1205
 
RtVoid RiScale(RtFloat sx, RtFloat sy, RtFloat sz)
1206
 
{
1207
 
        if (!mbCheck(true, MB_SCALE)) return;
1208
 
        Transform& curT = State::Instance()->currentTransform(motion_pos - 1);
1209
 
        curT.scale(sx, sy, sz);
1210
 
}
1211
 
 
1212
 
RtVoid RiSkew(RtFloat angle, RtFloat dx1, RtFloat dy1, RtFloat dz1,
1213
 
                                                        RtFloat dx2, RtFloat dy2, RtFloat dz2)
1214
 
{
1215
 
        if (!mbCheck(true, MB_SKEW)) return;
1216
 
        Transform& curT = State::Instance()->currentTransform(motion_pos - 1);
1217
 
        curT.skew(angle, dx1, dy1, dz1, dx2, dy2, dz2);
1218
 
}
1219
 
 
1220
 
RtVoid RiDeformation(RtToken name, ...)
1221
 
{
1222
 
        BUILD_TOKENPARAM_LIST(name)
1223
 
        RiDeformationV(name, n, _tokens, _parms);
1224
 
}
1225
 
 
1226
 
RtVoid RiDeformationV(RtToken name, RtInt n, RtToken tokens[], RtPointer parms[])
1227
 
{
1228
 
        if (!mbCheck(true, MB_DEFORMATION)) return;
1229
 
        // not implemented
1230
 
        fprintf(ERROUT, "'Deformation' not implemented (yet)\n");
1231
 
}
1232
 
 
1233
 
// Named Coordinate Systems
1234
 
RtVoid RiCoordinateSystem(RtToken space)
1235
 
{
1236
 
        if (!mbCheck()) return;
1237
 
        State::Instance()->addNamedCoordSys(space);
1238
 
}
1239
 
 
1240
 
RtVoid RiCoordSysTransform(RtToken space)
1241
 
{
1242
 
        if (!mbCheck()) return;
1243
 
        State::Instance()->activateNamedCoordSys(space);
1244
 
}
1245
 
 
1246
 
RtPoint* RiTransformPoints(RtToken fromspace, RtToken tospace, RtInt n, RtPoint points[])
1247
 
{
1248
 
        if (!mbCheck()) return NULL;
1249
 
        // TODO (?)
1250
 
        fprintf(ERROUT, "RiTransformPoints() not implemented (yet)\n");
1251
 
        return NULL;
1252
 
}
1253
 
 
1254
 
// Transformation Stack
1255
 
RtVoid RiTransformBegin()
1256
 
{
1257
 
        State::Instance()->transformBegin();
1258
 
}
1259
 
 
1260
 
RtVoid RiTransformEnd()
1261
 
{
1262
 
        State::Instance()->transformEnd();
1263
 
}
1264
 
 
1265
 
// Implementation-specific Attributes
1266
 
RtVoid RiAttribute(RtToken name, ...)
1267
 
{
1268
 
        BUILD_TOKENPARAM_LIST(name)
1269
 
        RiAttributeV(name, n, _tokens, _parms);
1270
 
}
1271
 
 
1272
 
RtVoid RiAttributeV(RtToken name, RtInt n, RtToken tokens[], RtPointer parms[])
1273
 
{
1274
 
        if (!mbCheck()) return;
1275
 
        Attributes& attr = State::Instance()->topAttributes();
1276
 
        if (!strcmp(name, "displacementbound")) {
1277
 
                for (int i=0; i<n; ++i) {
1278
 
                        if (!strcmp(tokens[i], RI_SPHERE))
1279
 
                                attr.displacementbound_sphere = *((RtFloat*)parms[i]);
1280
 
                        // TODO coordinatesystem
1281
 
                        else
1282
 
                                fprintf(ERROUT, "Unknown displacementbound attribute: '%s'\n", tokens[i]);
1283
 
                }
1284
 
        }
1285
 
        else if (!strcmp(name, "dice")) {
1286
 
                for (int i=0; i<n; ++i) {
1287
 
                        if (!strcmp(tokens[i], RI_BINARY))
1288
 
                                attr.flags |= (*((int*)parms[i]) != 0) ? AF_DICE_BINARY : 0;
1289
 
                        else
1290
 
                                fprintf(ERROUT, "Unknown dice attribute: '%s'\n", tokens[i]);
1291
 
                }
1292
 
        }
1293
 
        else fprintf(ERROUT, "Unknown attribute: '%s'\n", name);
1294
 
}
1295
 
 
1296
 
//------------------------------------------------------------------------------
1297
 
// Primitives
1298
 
 
1299
 
// Polygons
1300
 
RtVoid RiPolygon(RtInt nverts, ...)
1301
 
{
1302
 
        BUILD_TOKENPARAM_LIST(nverts)
1303
 
        RiPolygonV(nverts, n, _tokens, _parms);
1304
 
}
1305
 
 
1306
 
RtVoid RiPolygonV(RtInt nverts, RtInt n, RtToken tokens[], RtPointer parms[])
1307
 
{
1308
 
        if (!mbCheck(true, MB_POLYGON)) return;
1309
 
        // three verts at least
1310
 
        if (nverts < 3) {
1311
 
                fprintf(ERROUT, "[ERROR]: RiPolygonV() -> must have at least three vertices\n");
1312
 
                return;
1313
 
        }
1314
 
        if (!haveP("RiPolygonV", n, tokens, parms)) return;
1315
 
        State::Instance()->insert(new Polygon(nverts, n, tokens, parms), motion_pos);
1316
 
}
1317
 
 
1318
 
RtVoid RiGeneralPolygon(RtInt nloops, RtInt nverts[], ...)
1319
 
{
1320
 
        BUILD_TOKENPARAM_LIST(nverts)
1321
 
        RiGeneralPolygonV(nloops, nverts, n, _tokens, _parms);
1322
 
}
1323
 
 
1324
 
RtVoid RiGeneralPolygonV(RtInt nloops, RtInt nverts[],
1325
 
                         RtInt n, RtToken tokens[], RtPointer parms[])
1326
 
{
1327
 
        // TODO
1328
 
        fprintf(ERROUT, "'GeneralPolygon' not implemented (yet)\n");
1329
 
        // not implemented, so no motion block update
1330
 
}
1331
 
 
1332
 
RtVoid RiPointsPolygons(RtInt npolys, RtInt nverts[], RtInt verts[], ...)
1333
 
{
1334
 
        BUILD_TOKENPARAM_LIST(verts)
1335
 
        RiPointsPolygonsV(npolys, nverts, verts, n, _tokens, _parms);
1336
 
}
1337
 
 
1338
 
RtVoid RiPointsPolygonsV(RtInt npolys, RtInt nverts[], RtInt verts[],
1339
 
                         RtInt n, RtToken tokens[], RtPointer parms[])
1340
 
{
1341
 
        if (!mbCheck(true, MB_POINTSPOLYGONS)) return;
1342
 
        if (!haveP("RiPointsPolygons", n, tokens, parms)) return;
1343
 
        State::Instance()->insert(new PointsPolygons(npolys, nverts, verts, n, tokens, parms), motion_pos);
1344
 
}
1345
 
 
1346
 
RtVoid RiPointsGeneralPolygons(RtInt npolys, RtInt nloops[], RtInt nverts[], RtInt verts[], ...)
1347
 
{
1348
 
        BUILD_TOKENPARAM_LIST(verts)
1349
 
        RiPointsGeneralPolygonsV(npolys, nloops, nverts, verts, n, _tokens, _parms);
1350
 
}
1351
 
 
1352
 
RtVoid RiPointsGeneralPolygonsV(RtInt npolys, RtInt nloops[], RtInt nverts[],
1353
 
                                RtInt verts[], RtInt n, RtToken tokens[], RtPointer parms[])
1354
 
{
1355
 
        // TODO
1356
 
        fprintf(ERROUT, "'PointsGeneralPolygons' not implemented (yet)\n");
1357
 
        // not implemented, so no motion block update
1358
 
}
1359
 
 
1360
 
// Patches
1361
 
RtVoid RiBasis(RtBasis ubasis, RtInt ustep, RtBasis vbasis, RtInt vstep)
1362
 
{
1363
 
        if (!mbCheck()) return;
1364
 
        State* state = State::Instance();
1365
 
        // basis allocation is handled by state
1366
 
        state->newCubicBasis(ubasis, vbasis);
1367
 
        Attributes& attr = state->topAttributes();
1368
 
        attr.cubicBasisStep[0] = ustep;
1369
 
        attr.cubicBasisStep[1] = vstep;
1370
 
}
1371
 
 
1372
 
RtVoid RiPatch(RtToken type, ...)
1373
 
{
1374
 
        BUILD_TOKENPARAM_LIST(type)
1375
 
        RiPatchV(type, n, _tokens, _parms);
1376
 
}
1377
 
 
1378
 
RtVoid RiPatchV(RtToken type, RtInt n, RtToken tokens[], RtPointer parms[])
1379
 
{
1380
 
        if (!mbCheck(true, MB_PATCH)) return;
1381
 
        if (!haveP_any("RiPatchV", n, tokens, parms)) return;
1382
 
        State* state = State::Instance();
1383
 
        if (!strcmp(type, RI_BILINEAR))
1384
 
                state->insert(new BilinearPatch(n, tokens, parms), motion_pos);
1385
 
        else if (!strcmp(type, RI_BICUBIC))
1386
 
                state->insert(new BicubicPatch(n, tokens, parms), motion_pos);
1387
 
        else
1388
 
                fprintf(ERROUT, "RiPatchV(): Unknown type '%s'\n", type);
1389
 
}
1390
 
 
1391
 
RtVoid RiPatchMesh(RtToken type, RtInt nu, RtToken uwrap,
1392
 
                   RtInt nv, RtToken vwrap, ...)
1393
 
{
1394
 
        BUILD_TOKENPARAM_LIST(vwrap)
1395
 
        RiPatchMeshV(type, nu, uwrap, nv, vwrap, n, _tokens, _parms);
1396
 
}
1397
 
 
1398
 
RtVoid RiPatchMeshV(RtToken type, RtInt nu, RtToken uwrap,
1399
 
                    RtInt nv, RtToken vwrap,
1400
 
                    RtInt n, RtToken tokens[], RtPointer parms[])
1401
 
{
1402
 
        if (!mbCheck(true, MB_PATCHMESH)) return;
1403
 
        if (!haveP_any("RiPatchMeshV", n, tokens, parms)) return;
1404
 
        bool bilinear = true;  // BILINEAR default
1405
 
        if (!strcmp(type, RI_BICUBIC))
1406
 
                bilinear = false;
1407
 
        else if (strcmp(type, RI_BILINEAR)) {
1408
 
                // unknown type
1409
 
                fprintf(ERROUT, "RiPatchV(): Unknown type '%s'", type);
1410
 
                return;
1411
 
        }
1412
 
        // wrap type
1413
 
        bool uperiodic = false, vperiodic = false;
1414
 
        if (!strcmp(uwrap, RI_PERIODIC))
1415
 
                uperiodic = true;
1416
 
        else if (strcmp(uwrap, RI_NONPERIODIC)) // unknown, assume uperiodic == false
1417
 
                fprintf(ERROUT, "RiPatchMeshV(): unknown uwrap mode '%s'\n", uwrap);
1418
 
        if (!strcmp(vwrap, RI_PERIODIC))
1419
 
                vperiodic = true;
1420
 
        else if (strcmp(vwrap, RI_NONPERIODIC)) // unknown, assume vperiodic == false
1421
 
                fprintf(ERROUT, "RiPatchMeshV(): unknown vwrap mode '%s'\n", vwrap);
1422
 
        if (bilinear)
1423
 
                State::Instance()->insert(new BilinearPatchMesh(nu, uperiodic, nv, vperiodic, n, tokens, parms), motion_pos);
1424
 
        else
1425
 
                State::Instance()->insert(new BicubicPatchMesh(nu, uperiodic, nv, vperiodic, n, tokens, parms), motion_pos);
1426
 
}
1427
 
 
1428
 
RtVoid RiNuPatch(RtInt nu, RtInt uorder, RtFloat uknot[], RtFloat umin,
1429
 
                 RtFloat umax, RtInt nv, RtInt vorder, RtFloat vknot[],
1430
 
                 RtFloat vmin, RtFloat vmax, ...)
1431
 
{
1432
 
        BUILD_TOKENPARAM_LIST(vmax)
1433
 
        RiNuPatchV(nu, uorder, uknot, umin, umax, nv, vorder, vknot, vmin, vmax, n, _tokens, _parms);
1434
 
}
1435
 
 
1436
 
RtVoid RiNuPatchV(RtInt nu, RtInt uorder, RtFloat uknot[], RtFloat umin,
1437
 
                  RtFloat umax, RtInt nv, RtInt vorder, RtFloat vknot[],
1438
 
                  RtFloat vmin, RtFloat vmax,
1439
 
                  RtInt n, RtToken tokens[], RtPointer parms[])
1440
 
{
1441
 
        if (!mbCheck(true, MB_NUPATCH)) return;
1442
 
        if (!haveP_Pw("RiNuPatchV", n, tokens, parms)) return;
1443
 
        // check that knots arrays are in increasing order
1444
 
        for (int i=0; i<(nu + uorder - 1); ++i)
1445
 
                if (uknot[i] > uknot[i+1]) {
1446
 
                        fprintf(ERROUT, "RiNuPatchV(): invalid decreasing knot value in uknot array\n");
1447
 
                        return;
1448
 
                }
1449
 
        for (int i=0; i<(nv + vorder - 1); ++i)
1450
 
                if (vknot[i] > vknot[i+1]) {
1451
 
                        fprintf(ERROUT, "RiNuPatchV(): invalid decreasing knot value in vknot array\n");
1452
 
                        return;
1453
 
                }
1454
 
        // check that u/v min/max range is in valid range from the given knot arrays
1455
 
        if (umin < uknot[uorder-1]) {
1456
 
                fprintf(ERROUT, "RiNuPatchV(): umin value out of valid range [%f %f]\n", uknot[uorder-1], uknot[nu]);
1457
 
                return;
1458
 
        }
1459
 
        if (umax > uknot[nu]) {
1460
 
                fprintf(ERROUT, "RiNuPatchV(): umax value out of valid range [%f %f]\n", uknot[uorder-1], uknot[nu]);
1461
 
                return;
1462
 
        }
1463
 
        if (vmin < vknot[vorder-1]) {
1464
 
                fprintf(ERROUT, "RiNuPatchV(): vmin value out of valid range [%f %f]\n", vknot[vorder-1], vknot[nv]);
1465
 
                return;
1466
 
        }
1467
 
        if (vmax > vknot[nv]) {
1468
 
                fprintf(ERROUT, "RiNuPatchV(): vmax value out of valid range [%f %f]\n", vknot[vorder-1], vknot[nv]);
1469
 
                return;
1470
 
        }
1471
 
        State::Instance()->insert(new NuPatch(nu, uorder, uknot, umin, umax,
1472
 
                                                                  nv, vorder, vknot, vmin, vmax,
1473
 
                                                                  n, tokens, parms), motion_pos);
1474
 
}
1475
 
 
1476
 
RtVoid RiTrimCurve(RtInt nloops, RtInt ncurves[], RtInt order[],
1477
 
                   RtFloat knot[], RtFloat min[], RtFloat max[], RtInt n[],
1478
 
                   RtFloat u[], RtFloat v[], RtFloat w[])
1479
 
{
1480
 
        if (!mbCheck()) return;
1481
 
        // TODO
1482
 
        fprintf(ERROUT, "'TrimCurve' not implemented (yet)\n");
1483
 
}
1484
 
 
1485
 
// Subdivision Meshes
1486
 
RtVoid RiSubdivisionMesh(RtToken mask, RtInt nf, RtInt nverts[],
1487
 
                         RtInt verts[],
1488
 
                         RtInt ntags, RtToken tags[], RtInt numargs[],
1489
 
                         RtInt intargs[], RtFloat floatargs[], ...)
1490
 
{
1491
 
        BUILD_TOKENPARAM_LIST(floatargs)
1492
 
        RiSubdivisionMeshV(mask, nf, nverts, verts, ntags, tags, numargs, intargs, floatargs, n, _tokens, _parms);
1493
 
}
1494
 
 
1495
 
RtVoid RiSubdivisionMeshV(RtToken mask, RtInt nf, RtInt nverts[],
1496
 
                          RtInt verts[], RtInt ntags, RtToken tags[],
1497
 
                          RtInt nargs[], RtInt intargs[],
1498
 
                          RtFloat floatargs[], RtInt n,
1499
 
                          RtToken tokens[], RtPointer *parms)
1500
 
{
1501
 
        if (!mbCheck(true, MB_SUBDIVISIONMESH)) return;
1502
 
        if (strcmp(mask, "catmull-clark")) {
1503
 
                fprintf(ERROUT, "Unknown subdivision scheme '%s'\n", mask);
1504
 
                return;
1505
 
        }
1506
 
        State::Instance()->insert(new CCSubdivisionMesh(nf, nverts, verts, ntags, tags,
1507
 
                                                        nargs, intargs, floatargs, n, tokens, parms), motion_pos);
1508
 
}
1509
 
 
1510
 
 
1511
 
// Quadrics
1512
 
RtVoid RiSphere(RtFloat radius, RtFloat zmin, RtFloat zmax, RtFloat tmax, ...)
1513
 
{
1514
 
        BUILD_TOKENPARAM_LIST(tmax)
1515
 
        RiSphereV(radius, zmin, zmax, tmax, n, _tokens, _parms);
1516
 
}
1517
 
 
1518
 
RtVoid RiSphereV(RtFloat radius, RtFloat zmin, RtFloat zmax, RtFloat tmax,
1519
 
                 RtInt n, RtToken tokens[], RtPointer parms[])
1520
 
{
1521
 
        if (!mbCheck(true, MB_SPHERE)) return;
1522
 
        State::Instance()->insert(new Sphere(radius, zmin, zmax, tmax, n, tokens, parms), motion_pos);
1523
 
}
1524
 
 
1525
 
RtVoid RiCone(RtFloat height, RtFloat radius, RtFloat tmax, ...)
1526
 
{
1527
 
        BUILD_TOKENPARAM_LIST(tmax)
1528
 
        RiConeV(height, radius, tmax, n, _tokens, _parms);
1529
 
}
1530
 
 
1531
 
RtVoid RiConeV(RtFloat height, RtFloat radius, RtFloat tmax,
1532
 
               RtInt n, RtToken tokens[], RtPointer parms[])
1533
 
{
1534
 
        if (!mbCheck(true, MB_CONE)) return;
1535
 
        State::Instance()->insert(new Cone(height, radius, tmax, n, tokens, parms), motion_pos);
1536
 
}
1537
 
 
1538
 
RtVoid RiCylinder(RtFloat radius, RtFloat zmin, RtFloat zmax, RtFloat tmax, ...)
1539
 
{
1540
 
        BUILD_TOKENPARAM_LIST(tmax)
1541
 
        RiCylinderV(radius, zmin, zmax, tmax, n, _tokens, _parms);
1542
 
}
1543
 
 
1544
 
RtVoid RiCylinderV(RtFloat radius, RtFloat zmin, RtFloat zmax, RtFloat tmax,
1545
 
                   RtInt n, RtToken tokens[], RtPointer parms[])
1546
 
{
1547
 
        if (!mbCheck(true, MB_CYLINDER)) return;
1548
 
        State::Instance()->insert(new Cylinder(radius, zmin, zmax, tmax, n, tokens, parms), motion_pos);
1549
 
}
1550
 
 
1551
 
RtVoid RiHyperboloid(RtPoint point1, RtPoint point2, RtFloat tmax, ...)
1552
 
{
1553
 
        BUILD_TOKENPARAM_LIST(tmax)
1554
 
        RiHyperboloidV(point1, point2, tmax, n, _tokens, _parms);
1555
 
}
1556
 
 
1557
 
RtVoid RiHyperboloidV(RtPoint point1, RtPoint point2, RtFloat tmax,
1558
 
                      RtInt n, RtToken tokens[], RtPointer parms[])
1559
 
{
1560
 
        if (!mbCheck(true, MB_HYPERBOLOID)) return;
1561
 
        Point3 pt1(point1[0], point1[1], point1[2]);
1562
 
        Point3 pt2(point2[0], point2[1], point2[2]);
1563
 
        State::Instance()->insert(new Hyperboloid(pt1, pt2, tmax, n, tokens, parms), motion_pos);
1564
 
}
1565
 
 
1566
 
RtVoid RiParaboloid(RtFloat rmax, RtFloat zmin, RtFloat zmax, RtFloat tmax, ...)
1567
 
{
1568
 
        BUILD_TOKENPARAM_LIST(tmax)
1569
 
        RiParaboloidV(rmax, zmin, zmax, tmax, n, _tokens, _parms);
1570
 
}
1571
 
 
1572
 
RtVoid RiParaboloidV(RtFloat rmax, RtFloat zmin, RtFloat zmax, RtFloat tmax,
1573
 
                     RtInt n, RtToken tokens[], RtPointer parms[])
1574
 
{
1575
 
        if (!mbCheck(true, MB_PARABOLOID)) return;
1576
 
        State::Instance()->insert(new Paraboloid(rmax, zmin, zmax, tmax, n, tokens, parms), motion_pos);
1577
 
}
1578
 
 
1579
 
RtVoid RiDisk(RtFloat height, RtFloat radius, RtFloat tmax, ...)
1580
 
{
1581
 
        BUILD_TOKENPARAM_LIST(tmax)
1582
 
        RiDiskV(height, radius, tmax, n, _tokens, _parms);
1583
 
}
1584
 
 
1585
 
RtVoid RiDiskV(RtFloat height, RtFloat radius, RtFloat tmax,
1586
 
               RtInt n, RtToken tokens[], RtPointer parms[])
1587
 
{
1588
 
        if (!mbCheck(true, MB_DISK)) return;
1589
 
        State::Instance()->insert(new Disk(height, radius, tmax, n, tokens, parms), motion_pos);
1590
 
}
1591
 
 
1592
 
RtVoid RiTorus(RtFloat majrad, RtFloat minrad, RtFloat phimin,
1593
 
               RtFloat phimax, RtFloat tmax, ...)
1594
 
{
1595
 
        BUILD_TOKENPARAM_LIST(tmax)
1596
 
        RiTorusV(majrad, minrad, phimin, phimax, tmax, n, _tokens, _parms);
1597
 
}
1598
 
 
1599
 
RtVoid RiTorusV(RtFloat majrad, RtFloat minrad,
1600
 
                RtFloat phimin, RtFloat phimax, RtFloat tmax,
1601
 
                RtInt n, RtToken tokens[], RtPointer parms[])
1602
 
{
1603
 
        if (!mbCheck(true, MB_TORUS)) return;
1604
 
        State::Instance()->insert(new Torus(majrad, minrad, phimin, phimax, tmax, n, tokens, parms), motion_pos);
1605
 
}
1606
 
 
1607
 
// Point & Curve Primitives
1608
 
RtVoid RiPoints(RtInt nverts,...)
1609
 
{
1610
 
        BUILD_TOKENPARAM_LIST(nverts)
1611
 
        RiPointsV(nverts, n, _tokens, _parms);
1612
 
}
1613
 
 
1614
 
RtVoid RiPointsV(RtInt nverts, RtInt n, RtToken tokens[], RtPointer parms[])
1615
 
{
1616
 
        if (!mbCheck(true, MB_POINTS)) return;
1617
 
        if (!haveP("RiPointsV", n, tokens, parms)) return;
1618
 
        State::Instance()->insert(new PointSet(nverts, n, tokens, parms), motion_pos);
1619
 
}
1620
 
 
1621
 
RtVoid RiCurves(RtToken type, RtInt ncurves,
1622
 
                RtInt nvertices[], RtToken wrap, ...)
1623
 
{
1624
 
        BUILD_TOKENPARAM_LIST(wrap)
1625
 
        RiCurvesV(type, ncurves, nvertices, wrap, n, _tokens, _parms);
1626
 
}
1627
 
 
1628
 
RtVoid RiCurvesV(RtToken type, RtInt ncurves, RtInt nvertices[], RtToken wrap,
1629
 
                 RtInt n, RtToken tokens[], RtPointer parms[])
1630
 
{
1631
 
        if (!mbCheck(true, MB_CURVES)) return;
1632
 
        if (!haveP("RiCurvesV", n, tokens, parms)) return;
1633
 
        bool islinear;
1634
 
        if (!strcmp(type, RI_LINEAR))
1635
 
                islinear = true;
1636
 
        else if (!strcmp(type, RI_CUBIC))
1637
 
                islinear = false;
1638
 
        else {
1639
 
                fprintf(ERROUT, "RiCurvesV(): unknown type '%s'\n", type);
1640
 
                return;
1641
 
        }
1642
 
        bool _wrap;
1643
 
        if (!strcmp(wrap, RI_PERIODIC))
1644
 
                _wrap = true;
1645
 
        else if (!strcmp(wrap, RI_NONPERIODIC))
1646
 
                _wrap = false;
1647
 
        else {
1648
 
                fprintf(ERROUT, "RiCurvesV():  unknown wrap type '%s'\n", wrap);
1649
 
                return;
1650
 
        }
1651
 
        State::Instance()->insert(new CurveSet(islinear, ncurves, nvertices, _wrap, n, tokens, parms), motion_pos);
1652
 
}
1653
 
 
1654
 
 
1655
 
// 'Blobby' Implicit Surfaces
1656
 
RtVoid RiBlobby(RtInt nleaf, RtInt ncode, RtInt code[],
1657
 
                RtInt nflt, RtFloat flt[],
1658
 
                RtInt nstr, RtToken str[], ...)
1659
 
{
1660
 
        BUILD_TOKENPARAM_LIST(str)
1661
 
        RiBlobbyV(nleaf, ncode, code, nflt, flt, nstr, str, n, _tokens, _parms);
1662
 
}
1663
 
 
1664
 
RtVoid RiBlobbyV(RtInt nleaf, RtInt ncode, RtInt code[],
1665
 
                 RtInt nflt, RtFloat flt[],
1666
 
                 RtInt nstr, RtToken str[],
1667
 
                 RtInt n, RtToken tokens[], RtPointer parms[])
1668
 
{
1669
 
        if (!mbCheck(true, MB_BLOBBY)) return;
1670
 
        // TODO
1671
 
        fprintf(ERROUT, "'Blobby' not implemented (yet)\n");
1672
 
}
1673
 
 
1674
 
 
1675
 
// Procedural Primitives
1676
 
RtVoid RiProcedural(RtPointer data, RtBound bound,
1677
 
                    RtVoid (*subdivfunc)(RtPointer, RtFloat),
1678
 
                    RtVoid (*freefunc)(RtPointer))
1679
 
{
1680
 
        if (!mbCheck()) return;
1681
 
        // TODO
1682
 
        fprintf(ERROUT, "'Procedural' not implemented (yet)\n");
1683
 
}
1684
 
 
1685
 
 
1686
 
RtVoid RiProcDelayedReadArchive(RtPointer data, RtFloat detail)
1687
 
{
1688
 
        if (!mbCheck()) return;
1689
 
        // TODO
1690
 
        fprintf(ERROUT, "'ProcDelayedReadArchive' not implemented (yet)\n");
1691
 
}
1692
 
 
1693
 
RtVoid RiProcRunProgram(RtPointer data, RtFloat detail)
1694
 
{
1695
 
        if (!mbCheck()) return;
1696
 
        // TODO
1697
 
        fprintf(ERROUT, "'ProcRunProgram' not implemented (yet)\n");
1698
 
}
1699
 
 
1700
 
RtVoid RiProcDynamicLoad(RtPointer data, RtFloat detail)
1701
 
{
1702
 
        if (!mbCheck()) return;
1703
 
        // TODO
1704
 
        fprintf(ERROUT, "'ProcDynamicLoad' not implemented (yet)\n");
1705
 
}
1706
 
 
1707
 
// Implementation-specific Geometric Primitives
1708
 
RtVoid RiGeometry(RtToken type, ...)
1709
 
{
1710
 
        BUILD_TOKENPARAM_LIST(type)
1711
 
        RiSurfaceV(type, n, _tokens, _parms);
1712
 
}
1713
 
 
1714
 
RtVoid RiGeometryV(RtToken type, RtInt n, RtToken tokens[], RtPointer parms[])
1715
 
{
1716
 
        if (!mbCheck()) return;
1717
 
        // TODO
1718
 
        fprintf(ERROUT, "'Geometry' not implemented (yet)\n");
1719
 
}
1720
 
 
1721
 
//------------------------------------------------------------------------------
1722
 
// Solids & Spatial Set operations
1723
 
 
1724
 
RtVoid RiSolidBegin(RtToken operation)
1725
 
{
1726
 
        // TODO
1727
 
        fprintf(ERROUT, "'SolidBegin' not implemented (yet)\n");
1728
 
}
1729
 
 
1730
 
RtVoid RiSolidEnd()
1731
 
{
1732
 
        // TODO
1733
 
        fprintf(ERROUT, "'SolidEnd' not implemented (yet)\n");
1734
 
}
1735
 
 
1736
 
// Retained Geometry
1737
 
RtObjectHandle RiObjectBegin()
1738
 
{
1739
 
        // TODO
1740
 
        fprintf(ERROUT, "'ObjectBegin' not implemented (yet)\n");
1741
 
        return NULL;
1742
 
}
1743
 
 
1744
 
RtVoid RiObjectEnd()
1745
 
{
1746
 
        // TODO
1747
 
        fprintf(ERROUT, "'ObjectEnd' not implemented (yet)\n");
1748
 
}
1749
 
 
1750
 
RtVoid RiObjectInstance(RtObjectHandle handle)
1751
 
{
1752
 
        // TODO
1753
 
        fprintf(ERROUT, "'ObjectInstance' not implemented (yet)\n");
1754
 
}
1755
 
 
1756
 
//------------------------------------------------------------------------------
1757
 
// Motion
1758
 
 
1759
 
RtVoid RiMotionBegin(RtInt n2, ...)
1760
 
{
1761
 
        va_list args;
1762
 
 
1763
 
        float* times = new float [n2];
1764
 
 
1765
 
        va_start(args, n2);
1766
 
        for (int i=0; i<n2; ++i)
1767
 
                times[i] = (float)(va_arg(args, double));
1768
 
        va_end(args);
1769
 
 
1770
 
        RiMotionBeginV(n2, times);
1771
 
        delete times;
1772
 
}
1773
 
 
1774
 
RtVoid RiMotionBeginV(RtInt n, RtFloat times[])
1775
 
{
1776
 
        State::Instance()->motionBegin(n, times);
1777
 
        prev_motion_cmd = MB_NONE;
1778
 
        motion_pos = 0;
1779
 
}
1780
 
 
1781
 
RtVoid RiMotionEnd()
1782
 
{
1783
 
        State::Instance()->motionEnd();
1784
 
        prev_motion_cmd = MB_NONE;
1785
 
        motion_pos = -1;
1786
 
}
1787
 
 
1788
 
//------------------------------------------------------------------------------
1789
 
// External Resources
1790
 
 
1791
 
// Texture maps
1792
 
RtVoid RiMakeTexture(const char* pic, const char* tex, RtToken swrap, RtToken twrap,
1793
 
                     RtFilterFunc filterfunc, RtFloat swidth, RtFloat twidth, ...)
1794
 
{
1795
 
        BUILD_TOKENPARAM_LIST(twidth)
1796
 
        RiMakeTextureV(pic, tex, swrap, twrap, filterfunc, swidth, twidth, n, _tokens, _parms);
1797
 
}
1798
 
 
1799
 
RtVoid RiMakeTextureV(const char* pic, const char* tex, RtToken swrap, RtToken twrap,
1800
 
                      RtFilterFunc filterfunc, RtFloat swidth, RtFloat twidth,
1801
 
                      RtInt n, RtToken tokens[], RtPointer parms[])
1802
 
{
1803
 
        if (!mbCheck()) return;
1804
 
        // TODO
1805
 
        fprintf(ERROUT, "'MakeTexture' not implemented (yet)\n");
1806
 
}
1807
 
 
1808
 
// Environment maps
1809
 
RtVoid RiMakeLatLongEnvironment(const char* pic, const char* tex,
1810
 
                                RtFilterFunc filterfunc,
1811
 
                                RtFloat swidth, RtFloat twidth, ...)
1812
 
{
1813
 
        BUILD_TOKENPARAM_LIST(twidth)
1814
 
        RiMakeLatLongEnvironmentV(pic, tex, filterfunc, swidth, twidth, n, _tokens, _parms);
1815
 
}
1816
 
 
1817
 
RtVoid RiMakeLatLongEnvironmentV(const char* pic, const char* tex,
1818
 
                                RtFilterFunc filterfunc,
1819
 
                                RtFloat swidth, RtFloat twidth,
1820
 
                                RtInt n, RtToken tokens[], RtPointer parms[])
1821
 
{
1822
 
        if (!mbCheck()) return;
1823
 
        // TODO
1824
 
        fprintf(ERROUT, "'MakeLatLongEnvironment' not implemented (yet)\n");
1825
 
}
1826
 
 
1827
 
RtVoid RiMakeCubeFaceEnvironment(const char* px, const char* nx, const char* py, const char* ny,
1828
 
                                 const char* pz, const char* nz, const char* tex, RtFloat fov,
1829
 
                                 RtFilterFunc filterfunc, RtFloat swidth, RtFloat ywidth, ...)
1830
 
{
1831
 
        BUILD_TOKENPARAM_LIST(ywidth)
1832
 
        RiMakeCubeFaceEnvironmentV(px, nx, py, ny, pz, nz, tex, fov, filterfunc, swidth, ywidth, n, _tokens, _parms);
1833
 
}
1834
 
 
1835
 
RtVoid RiMakeCubeFaceEnvironmentV(const char* px, const char* nx, const char* py, const char* ny,
1836
 
                                  const char* pz, const char* nz, const char* tex, RtFloat fov,
1837
 
                                  RtFilterFunc filterfunc, RtFloat swidth, RtFloat ywidth,
1838
 
                                  RtInt n, RtToken tokens[], RtPointer parms[])
1839
 
{
1840
 
        if (!mbCheck()) return;
1841
 
        // TODO
1842
 
        fprintf(ERROUT, "'MakeCubeFaceEnvironment' not implemented (yet)\n");
1843
 
}
1844
 
 
1845
 
// Shadow maps
1846
 
RtVoid RiMakeShadow(const char* pic, const char* tex, ...)
1847
 
{
1848
 
        BUILD_TOKENPARAM_LIST(tex)
1849
 
        RiMakeShadowV(pic, tex, n, _tokens, _parms);
1850
 
}
1851
 
 
1852
 
RtVoid RiMakeShadowV(const char* pic, const char* tex, RtInt n, RtToken tokens[], RtPointer parms[])
1853
 
{
1854
 
        if (!mbCheck()) return;
1855
 
        // TODO
1856
 
        fprintf(ERROUT, "'MakeShadow' not implemented (yet)\n");
1857
 
}
1858
 
 
1859
 
// Bump maps (not really supported anymore? 3.2 removed, use displacement instead
1860
 
RtVoid RiMakeBump(const char* pic, const char* tex, RtToken swrap, RtToken twrap,
1861
 
                  RtFilterFunc filterfunc, RtFloat swidth, RtFloat twidth, ...)
1862
 
{
1863
 
        BUILD_TOKENPARAM_LIST(twidth)
1864
 
        RiMakeBumpV(pic, tex, swrap, twrap, filterfunc, swidth, twidth, n, _tokens, _parms);
1865
 
}
1866
 
 
1867
 
RtVoid RiMakeBumpV(const char* pic, const char* tex, RtToken swrap, RtToken twrap,
1868
 
                   RtFilterFunc filterfunc, RtFloat swidth, RtFloat twidth,
1869
 
                   RtInt n, RtToken tokens[], RtPointer parms[])
1870
 
{
1871
 
        if (!mbCheck()) return;
1872
 
        // TODO
1873
 
        fprintf(ERROUT, "'MakeBump' not implemented (yet)\n");
1874
 
}
1875
 
 
1876
 
//------------------------------------------------------------------------------
1877
 
// all below TODO or ignore...
1878
 
 
1879
 
// Errors
1880
 
RtVoid RiErrorHandler(RtErrorHandler handler)
1881
 
{
1882
 
}
1883
 
 
1884
 
RtVoid RiErrorIgnore(RtInt code, RtInt severity, const char* msg)
1885
 
{
1886
 
}
1887
 
 
1888
 
RtVoid RiErrorPrint(RtInt code, RtInt severity, const char* msg)
1889
 
{
1890
 
}
1891
 
 
1892
 
RtVoid RiErrorAbort(RtInt code, RtInt severity, const char* msg)
1893
 
{
1894
 
}
1895
 
 
1896
 
//------------------------------------------------------------------------------
1897
 
// Archive Files
1898
 
 
1899
 
RtVoid RiArchiveRecord(RtToken type, const char* format, ...)
1900
 
{
1901
 
}
1902
 
 
1903
 
RtVoid RiReadArchive(RtToken name, RtArchiveCallback callback, ...)
1904
 
{
1905
 
        BUILD_TOKENPARAM_LIST(callback)
1906
 
        RiReadArchiveV(name, callback, n, _tokens, _parms);
1907
 
}
1908
 
 
1909
 
RtVoid RiReadArchiveV(RtToken name, RtArchiveCallback callback,
1910
 
                                                                                        RtInt n, RtToken tokens[], RtPointer parms[])
1911
 
{
1912
 
        if (!mbCheck(true, MB_READARCHIVE)) return;
1913
 
        Options& options = State::Instance()->topOptions();
1914
 
        RIBparse_t rp;
1915
 
        char fname[512] = {0};
1916
 
        snprintf(fname, 512, "%s%s", options.basepath, name);
1917
 
        RtInt err = rp.parse(fname, false);
1918
 
        if (err!=RIE_NOERROR) {
1919
 
                switch (err) {
1920
 
                        case RIE_NOFILE:
1921
 
                                fprintf(ERROUT, "No file: '%s'\n", name);
1922
 
                                break;
1923
 
                        case RIE_BADFILE:
1924
 
                                fprintf(ERROUT, "File read error\n");
1925
 
                                break;
1926
 
                        default:
1927
 
                                fprintf(ERROUT, "Unknown error: %d\n", err);
1928
 
                }
1929
 
        }
1930
 
        in_readarchive = false;
1931
 
}
1932
 
 
1933
 
//------------------------------------------------------------------------------