Tachyon (current)  Current Main Branch
parse.c
Go to the documentation of this file.
1 /*
2  * parse.c - an UltraLame (tm) recursive descent scene file parser...
3  *
4  * (C) Copyright 1994-2022 John E. Stone
5  * SPDX-License-Identifier: BSD-3-Clause
6  *
7  * $Id: parse.c,v 1.93 2022/04/01 15:43:11 johns Exp $
8  *
9  */
10 
11 #include <stdio.h>
12 #include <math.h>
13 #include <string.h>
14 #include <stdlib.h>
15 #include <ctype.h> /* needed for toupper(), macro.. */
16 
17 #include "tachyon.h" /* Tachyon ray tracer API */
18 
19 #ifdef USELIBMGF
20 #include "mgfparse.h" /* MGF parser code */
21 #endif
22 
23 #define PARSE_INTERNAL
24 #include "parse.h" /* self protos */
25 #undef PARSE_INTERNAL
26 
27 #define ERROR_READBUF_SIZE 65536
28 
29 /*
30  * a is unknown compared string, b must be upper case already...)
31  */
32 static int stringcmp(const char * a, const char * b) {
33  int i, s, l;
34 
35  s=strlen(a);
36  l=strlen(b);
37 
38  if (s != l)
39  return 1;
40 
41  for (i=0; i<s; i++) {
42  if (toupper(a[i]) != b[i]) {
43  return 1;
44  }
45  }
46  return 0;
47 }
48 
49 static void reset_tex_table(parsehandle * ph, SceneHandle scene) {
50  apitexture apitex;
51 
52  ph->maxtextures=512;
53  ph->numtextures=0;
54  ph->textable = (texentry *) malloc(ph->maxtextures * sizeof(texentry));
55  memset(ph->textable, 0, ph->maxtextures * sizeof(texentry));
56 
57  apitex.col.r=1.0;
58  apitex.col.g=1.0;
59  apitex.col.b=1.0;
60  apitex.ambient=0.1;
61  apitex.diffuse=0.9;
62  apitex.specular=0.0;
63  apitex.opacity=1.0;
64  apitex.texturefunc=0;
65 
66  ph->defaulttex.tex=rt_texture(scene, &apitex);
67  rt_hash_init(&ph->texhash, 1024);
68 }
69 
70 static void free_tex_table(parsehandle * ph, SceneHandle scene) {
71  int i;
72 
73  rt_hash_destroy(&ph->texhash);
74 
75  for (i=0; i<ph->numtextures; i++) {
76  free(ph->textable[i].name);
77  }
78 
79  free(ph->textable);
80  ph->textable = NULL;
81 
82  ph->numtextures = 0;
83 }
84 
85 static errcode add_texture(parsehandle * ph, void * tex, const char * name) {
86  ph->textable[ph->numtextures].tex=tex;
87  ph->textable[ph->numtextures].name = malloc(strlen(name) + 1);
88  strcpy(ph->textable[ph->numtextures].name, name);
89  rt_hash_insert(&ph->texhash, ph->textable[ph->numtextures].name, ph->numtextures);
90 
91  ph->numtextures++;
92  if (ph->numtextures >= ph->maxtextures) {
93  texentry * newblock;
94  int newsize;
95 
96  newsize = 2 * ph->maxtextures;
97  newblock = realloc(ph->textable, newsize * sizeof(texentry));
98  if (newblock != NULL) {
99  ph->maxtextures = newsize;
100  ph->textable = newblock;
101  return PARSENOERR;
102  } else {
103  printf("Parse: %d textures allocated, texture slots full!\n", ph->numtextures);
104  ph->numtextures--; /* keep writing over last texture if we've run out.. */
105  return PARSEALLOCERR;
106  }
107  }
108 
109  return PARSENOERR;
110 }
111 
112 static void * find_texture(parsehandle * ph, const char * name) {
113  int i;
114 
115  i=rt_hash_lookup(&ph->texhash, name);
116  if (i != HASH_FAIL) {
117  return ph->textable[i].tex;
118  }
119 
120  printf("Undefined texture '%s', using default. \n", name);
121  return(ph->defaulttex.tex);
122 }
123 
125  apiflt tmp;
126  tmp=deg * 3.1415926 / 180.0;
127  return tmp;
128 }
129 
130 static void degvectoradvec(apivector * degvec) {
131  apivector tmp;
132 
133  tmp.x=degtorad(degvec->x);
134  tmp.y=degtorad(degvec->y);
135  tmp.z=degtorad(degvec->z);
136  *degvec=tmp;
137 }
138 
139 static void InitRot3d(RotMat * rot, apiflt x, apiflt y, apiflt z) {
140  rot->rx1=cos(y)*cos(z);
141  rot->rx2=sin(x)*sin(y)*cos(z) - cos(x)*sin(z);
142  rot->rx3=sin(x)*sin(z) + cos(x)*cos(z)*sin(y);
143 
144  rot->ry1=cos(y)*sin(z);
145  rot->ry2=cos(x)*cos(z) + sin(x)*sin(y)*sin(z);
146  rot->ry3=cos(x)*sin(y)*sin(z) - sin(x)*cos(z);
147 
148  rot->rz1=sin(y);
149  rot->rz2=sin(x)*cos(y);
150  rot->rz3=cos(x)*cos(y);
151 }
152 
153 static void Rotate3d(RotMat * rot, apivector * vec) {
154  apivector tmp;
155  tmp.x=(vec->x*(rot->rx1) + vec->y*(rot->rx2) + vec->z*(rot->rx3));
156  tmp.y=(vec->x*(rot->ry1) + vec->y*(rot->ry2) + vec->z*(rot->ry3));
157  tmp.z=(vec->x*(rot->rz1) + vec->y*(rot->rz2) + vec->z*(rot->rz3));
158  *vec=tmp;
159 }
160 
161 static void Scale3d(apivector * scale, apivector * vec) {
162  vec->x=vec->x * scale->x;
163  vec->y=vec->y * scale->y;
164  vec->z=vec->z * scale->z;
165 }
166 
167 static void Trans3d(apivector * trans, apivector * vec) {
168  vec->x+=trans->x;
169  vec->y+=trans->y;
170  vec->z+=trans->z;
171 }
172 
173 static void PrintSyntaxError(parsehandle * ph,
174  const char * string, const char * found) {
175  long streampos, readsize;
176  long i, j, linecount;
177  char cbuf[ERROR_READBUF_SIZE];
178 
179  streampos = ftell(ph->ifp);
180 
181  /* count lines up to approximate position where error occured */
182  fseek(ph->ifp, 0, SEEK_SET);
183 
184  i=0;
185  linecount=0;
186  while (i < streampos) {
187  if ((streampos - i) > ERROR_READBUF_SIZE) {
188  readsize = ERROR_READBUF_SIZE;
189  } else {
190  readsize = streampos - i;
191  }
192 
193  fread(cbuf, readsize, 1, ph->ifp);
194  i+=readsize;
195  for (j=0; j<readsize; j++) {
196  if (cbuf[j] == '\n') {
197  linecount++;
198  }
199  }
200  }
201 
202  printf("Parse Error:\n");
203  printf(" Encountered a syntax error in file %s\n", ph->filename);
204  printf(" Expected to find %s\n", string);
205  printf(" Actually found: %s\n", found);
206  printf(" Error occured at or prior to file offset %ld, line %ld\n",
207  streampos, linecount);
208  printf(" Error position is only approximate, but should be close\n\n");
209 
210  fseek(ph->ifp, streampos, SEEK_SET); /* return to previous offset */
211 }
212 
213 static errcode GetString(parsehandle * ph, const char * string) {
214  char data[255];
215 
216  fscanf(ph->ifp, "%s", data);
217  if (stringcmp(data, string) != 0) {
218  PrintSyntaxError(ph, string, data);
219  return PARSEBADSYNTAX;
220  }
221 
222  return PARSENOERR;
223 }
224 
225 unsigned int readmodel(const char * modelfile, SceneHandle scene) {
226  parsehandle ph;
227  errcode rc;
228  int done;
229 
230  memset(&ph, 0, sizeof(ph));
231  ph.transmode = RT_TRANS_ORIG;
232  ph.filename = modelfile;
233  ph.ifp=fopen(modelfile, "r");
234  if (ph.ifp == NULL) {
235  return PARSEBADFILE;
236  }
237 
238  reset_tex_table(&ph, scene);
239 
240  rc = PARSENOERR;
241 
242  /* skip comment blocks, and search for BEGIN_SCENE */
243  done = 0;
244  while (!done) {
245  char tmp[256];
246  fscanf(ph.ifp, "%s", tmp);
247 
248  if (!stringcmp(tmp, "BEGIN_SCENE")) {
249  done=1;
250  } else if (!stringcmp(tmp, "#")) {
251  int c;
252  while (1) {
253  c=fgetc(ph.ifp);
254  if (c == EOF || c == '\n') /* eat comment text */
255  break;
256  }
257  } else {
258  fclose(ph.ifp);
259  return PARSEBADSYNTAX;
260  }
261  }
262 
263  rc |= GetScenedefs(&ph, scene);
264 
265  if (rc == PARSENOERR) {
266  ph.numobjectsparsed=0;
267  while ((rc = GetObject(&ph, scene)) == PARSENOERR) {
268  ph.numobjectsparsed++;
269  }
270 
271  if (rc == PARSEEOF)
272  rc = PARSENOERR;
273  }
274 
275  fclose(ph.ifp);
276 
277  free_tex_table(&ph, scene);
278 
279  return rc;
280 }
281 
282 static errcode ReadIncludeFile(parsehandle * ph, const char * includefile, SceneHandle scene) {
283  errcode rc;
284  const char * oldfilename = ph->filename;
285  FILE * oldfp = ph->ifp;
286 
287  if (strcmp(includefile, ph->filename) == 0) {
288  printf("Warning: possible self-recursive include of file %s\n",
289  includefile);
290  }
291 
292  ph->filename=includefile;
293  ph->ifp=fopen(includefile, "r");
294  if (ph->ifp == NULL) {
295  printf("Parser failed trying to open file: %s\n", includefile);
296 
297  /* restore old file pointers etc */
298  ph->filename=oldfilename;
299  ph->ifp = oldfp;
300 
301  return PARSEBADSUBFILE;
302  }
303 
304  while ((rc = GetObject(ph, scene)) == PARSENOERR) {
305  ph->numobjectsparsed++;
306  }
307  fclose(ph->ifp);
308 
309  /* restore old file pointers etc */
310  ph->filename=oldfilename;
311  ph->ifp = oldfp;
312 
313  if (rc == PARSEEOF){
314  rc = PARSENOERR;
315  }
316 
317  return rc;
318 }
319 
320 static errcode GetScenedefs(parsehandle * ph, SceneHandle scene) {
321  int xres, yres;
322  errcode rc = PARSENOERR;
323 
324  rc |= GetString(ph, "RESOLUTION");
325  fscanf(ph->ifp, "%d %d", &xres, &yres);
326 
327  rt_outputfile(scene, "outfile.tga");
328  rt_resolution(scene, xres, yres);
329  rt_verbose(scene, 0);
330 
331  return rc;
332 }
333 
334 static errcode GetShaderMode(parsehandle * ph, SceneHandle scene) {
335  errcode rc = PARSENOERR;
336  char data[255];
337 
338  fscanf(ph->ifp, "%s", data);
339  if (!stringcmp(data, "FULL")) {
341  } else if (!stringcmp(data, "MEDIUM")) {
343  } else if (!stringcmp(data, "LOW")) {
345  } else if (!stringcmp(data, "LOWEST")) {
347  } else {
348  printf("Bad token '%s' while reading shader mode block\n", data);
349  return PARSEBADSYNTAX;
350  }
351 
352  while (rc == PARSENOERR) {
353  fscanf(ph->ifp, "%s", data);
354  if (!stringcmp(data, "END_SHADER_MODE")) {
355  return rc;
356  } else if (!stringcmp(data, "SHADOW_FILTER_ON")) {
357  rt_shadow_filtering(scene, 1);
358  } else if (!stringcmp(data, "SHADOW_FILTER_OFF")) {
359  rt_shadow_filtering(scene, 0);
360  } else if (!stringcmp(data, "TRANS_MAX_SURFACES")) {
361  int transmaxsurf;
362  fscanf(ph->ifp, "%d", &transmaxsurf);
363  rt_trans_max_surfaces(scene, transmaxsurf);
364  } else if (!stringcmp(data, "TRANS_ORIG")) {
365  ph->transmode = RT_TRANS_ORIG; /* reset to standard mode */
366  rt_trans_mode(scene, ph->transmode);
367  } else if (!stringcmp(data, "TRANS_RASTER3D")) {
368  ph->transmode |= RT_TRANS_RASTER3D; /* add Raster3D emulation flag */
369  rt_trans_mode(scene, ph->transmode);
370  } else if (!stringcmp(data, "TRANS_VMD")) {
371  ph->transmode |= RT_TRANS_VMD; /* add VMD transparency flag */
372  rt_trans_mode(scene, ph->transmode);
373  } else if (!stringcmp(data, "FOG_VMD")) {
375  } else if (!stringcmp(data, "AMBIENT_OCCLUSION")) {
376  char tmp[255];
377  int aosamples;
378  float aodirect;
379  apicolor aoambient;
380  float maxdist = RT_AO_MAXDIST_UNLIMITED;
381 
382  /* read optional maxdist parameter */
383  fscanf(ph->ifp, "%s", tmp);
384  if (!stringcmp(tmp, "MAXDIST")) {
385  fscanf(ph->ifp, "%f", &maxdist);
386 
387  rc |= GetString(ph, "AMBIENT_COLOR");
388  fscanf(ph->ifp, "%f %f %f", &aoambient.r, &aoambient.g, &aoambient.b);
389  } else if (!stringcmp(tmp, "AMBIENT_COLOR")) {
390  fscanf(ph->ifp, "%f %f %f", &aoambient.r, &aoambient.g, &aoambient.b);
391  }
392 
393  rc |= GetString(ph, "RESCALE_DIRECT");
394  fscanf(ph->ifp, "%f", &aodirect);
395 
396  rc |= GetString(ph, "SAMPLES");
397  fscanf(ph->ifp, "%d", &aosamples);
398 
399  rt_rescale_lights(scene, aodirect);
400  rt_ambient_occlusion(scene, aosamples, maxdist, aoambient);
401  } else {
402  printf("Bad token '%s' while reading optional shader modes\n", data);
403  return PARSEBADSYNTAX;
404  }
405  }
406 
407  return rc;
408 }
409 
410 static errcode GetCamera(parsehandle * ph, SceneHandle scene) {
411  apivector Ccenter, Cview, Cup;
412  apiflt zoom, aspectratio, eyesep;
413  int raydepth, antialiasing;
414  float a, b, c, d;
415  errcode rc = PARSENOERR;
416  char data[255];
417 
418  eyesep = 0.0;
419 
420  fscanf(ph->ifp, "%s", data);
421  if (stringcmp(data, "PROJECTION") == 0) {
422  fscanf(ph->ifp, "%s", data);
423  if (stringcmp(data, "EQUIRECTANGULAR") == 0) {
425  } else if (stringcmp(data, "FISHEYE") == 0) {
427  } else if (stringcmp(data, "PERSPECTIVE") == 0) {
429  } else if (stringcmp(data, "PERSPECTIVE_DOF") == 0) {
431 
432  rc |= GetString(ph, "FOCALDIST");
433  fscanf(ph->ifp, "%f", &a);
434 
435  rc |= GetString(ph, "APERTURE");
436  fscanf(ph->ifp, "%f", &b);
437 
438  rt_camera_dof(scene, a, b);
439  } else if (stringcmp(data, "ORTHOGRAPHIC") ==0) {
441  } else if (stringcmp(data, "STEREO_EQUIRECTANGULAR") == 0) {
443  rc |= GetString(ph, "EYESEPARATION");
444  fscanf(ph->ifp, "%f", &a);
445  eyesep = a;
446  }
447 
448  rc |= GetString(ph, "ZOOM");
449  fscanf(ph->ifp, "%f", &a);
450  zoom=a;
451  } else if (stringcmp(data, "ZOOM") == 0) {
452  fscanf(ph->ifp, "%f", &a);
453  zoom=a;
454  } else {
455  rc = PARSEBADSYNTAX;
456  return rc;
457  }
458 
459  rc |= GetString(ph, "ASPECTRATIO");
460  fscanf(ph->ifp, "%f", &b);
461  aspectratio=b;
462 
463  rc |= GetString(ph, "ANTIALIASING");
464  fscanf(ph->ifp, "%d", &antialiasing);
465 
466  rc |= GetString(ph, "RAYDEPTH");
467  fscanf(ph->ifp, "%d", &raydepth);
468 
469  rc |= GetString(ph, "CENTER");
470  fscanf(ph->ifp, "%f %f %f", &a, &b, &c);
471  Ccenter.x = a;
472  Ccenter.y = b;
473  Ccenter.z = c;
474 
475  rc |= GetString(ph, "VIEWDIR");
476  fscanf(ph->ifp, "%f %f %f", &a, &b, &c);
477  Cview.x = a;
478  Cview.y = b;
479  Cview.z = c;
480 
481  rc |= GetString(ph, "UPDIR");
482  fscanf(ph->ifp, "%f %f %f", &a, &b, &c);
483  Cup.x = a;
484  Cup.y = b;
485  Cup.z = c;
486 
487  rt_camera_setup(scene, zoom, aspectratio, antialiasing, raydepth,
488  Ccenter, Cview, Cup);
489 
490  /* set stereoscopic eye separation if specified */
491  if (eyesep > 0.0) {
492  rt_camera_eye_separation(scene, eyesep);
493  }
494 
495  fscanf(ph->ifp, "%s", data);
496  if (stringcmp(data, "FRUSTUM") == 0) {
497  fscanf(ph->ifp, "%f %f %f %f", &a, &b, &c, &d);
498  rt_camera_frustum(scene, a, b, c, d);
499  fscanf(ph->ifp, "%s", data);
500  if (stringcmp(data, "END_CAMERA") != 0) {
501  rc |= PARSEBADSYNTAX;
502  return rc;
503  }
504  } else if (stringcmp(data, "END_CAMERA") != 0) {
505  rc |= PARSEBADSYNTAX;
506  return rc;
507  }
508 
509 
510  return rc;
511 }
512 
513 static errcode GetObject(parsehandle * ph, SceneHandle scene) {
514  char objtype[256];
515 
516  if (fscanf(ph->ifp, "%s", objtype) == EOF) {
517  return PARSEEOF;
518  }
519  if (!stringcmp(objtype, "TRI")) {
520  return GetTri(ph, scene);
521  }
522  if (!stringcmp(objtype, "STRI")) {
523  return GetSTri(ph, scene);
524  }
525  if (!stringcmp(objtype, "VCSTRI")) {
526  return GetVCSTri(ph, scene);
527  }
528  if (!stringcmp(objtype, "VERTEXARRAY")) {
529  return GetVertexArray(ph, scene);
530  }
531  if (!stringcmp(objtype, "SPHERE")) {
532  return GetSphere(ph, scene);
533  }
534 #if 0
535  if (!stringcmp(objtype, "SPHEREARRAY")) {
536  return GetSphereArray(ph, scene);
537  }
538 #endif
539  if (!stringcmp(objtype, "FCYLINDER")) {
540  return GetFCylinder(ph, scene);
541  }
542  if (!stringcmp(objtype, "RING")) {
543  return GetRing(ph, scene);
544  }
545  if (!stringcmp(objtype, "POLYCYLINDER")) {
546  return GetPolyCylinder(ph, scene);
547  }
548  if (!stringcmp(objtype, "CYLINDER")) {
549  return GetCylinder(ph, scene);
550  }
551  if (!stringcmp(objtype, "PLANE")) {
552  return GetPlane(ph, scene);
553  }
554  if (!stringcmp(objtype, "BOX")) {
555  return GetBox(ph, scene);
556  }
557  if (!stringcmp(objtype, "SCALARVOL")) {
558  return GetVol(ph, scene);
559  }
560  if (!stringcmp(objtype, "IMAGEDEF")) {
561  return GetImageDef(ph, scene);
562  }
563  if (!stringcmp(objtype, "TEXDEF")) {
564  return GetTexDef(ph, scene);
565  }
566  if (!stringcmp(objtype, "TEXALIAS")) {
567  return GetTexAlias(ph);
568  }
569  if (!stringcmp(objtype, "LIGHT")) {
570  return GetLight(ph, scene);
571  }
572  if (!stringcmp(objtype, "DIRECTIONAL_LIGHT")) {
573  return GetDirLight(ph, scene);
574  }
575  if (!stringcmp(objtype, "SKY_LIGHT")) {
576  return GetSkyLight(ph, scene);
577  }
578  if (!stringcmp(objtype, "SPOTLIGHT")) {
579  return GetSpotLight(ph, scene);
580  }
581  if (!stringcmp(objtype, "SCAPE")) {
582  return GetLandScape(ph, scene);
583  }
584  if (!stringcmp(objtype, "SHADER_MODE")) {
585  return GetShaderMode(ph, scene);
586  }
587  if (!stringcmp(objtype, "CAMERA")) {
588  return GetCamera(ph, scene);
589  }
590  if (!stringcmp(objtype, "TPOLYFILE")) {
591  return GetTPolyFile(ph, scene);
592  }
593  if (!stringcmp(objtype, "MGFFILE")) {
594 #ifdef USELIBMGF
595  return GetMGFFile(ph, scene);
596 #else
597  printf("MGF File Parsing is not available in this build.\n");
598  return PARSEBADSYNTAX;
599 #endif
600  }
601  if (!stringcmp(objtype, "#")) {
602  int c;
603  while (1) {
604  c=fgetc(ph->ifp);
605  if (c == EOF || c == '\n') /* eat comment text */
606  return PARSENOERR;
607  }
608  }
609  if (!stringcmp(objtype, "BACKGROUND")) {
610  return GetBackGnd(ph, scene);
611  }
612  if (!stringcmp(objtype, "BACKGROUND_GRADIENT")) {
613  return GetBackGndGradient(ph, scene);
614  }
615  if (!stringcmp(objtype, "FOG")) {
616  return GetFog(ph, scene);
617  }
618  if (!stringcmp(objtype, "INCLUDE")) {
619  char includefile[FILENAME_MAX];
620  fscanf(ph->ifp, "%s", includefile);
621  return ReadIncludeFile(ph, includefile, scene);
622  }
623  if (!stringcmp(objtype, "START_CLIPGROUP")) {
624  return GetClipGroup(ph, scene);
625  }
626  if (!stringcmp(objtype, "END_CLIPGROUP")) {
627  return GetClipGroupEnd(ph, scene);
628  }
629  if (!stringcmp(objtype, "END_SCENE")) {
630  return PARSEEOF; /* end parsing */
631  }
632 
633  PrintSyntaxError(ph, "an object or other declaration", objtype);
634 
635  return PARSEBADSYNTAX;
636 }
637 
638 static errcode GetInt(parsehandle * ph, int * i) {
639  int a;
640  if (fscanf(ph->ifp, "%d", &a) != 1)
641  return PARSEBADSYNTAX;
642 
643  *i = a;
644 
645  return PARSENOERR;
646 }
647 
648 static errcode GetVector(parsehandle * ph, apivector * v1) {
649  float a, b, c;
650 
651  if (fscanf(ph->ifp, "%f %f %f", &a, &b, &c) != 3)
652  return PARSEBADSYNTAX;
653 
654  v1->x=a;
655  v1->y=b;
656  v1->z=c;
657 
658  return PARSENOERR;
659 }
660 
661 #if 0
662 static errcode GetFloat(parsehandle * ph, apiflt * f) {
663  float a;
664  if (fscanf(ph->ifp, "%f", &a) != 1)
665  return PARSEBADSYNTAX;
666 
667  *f = a;
668 
669  return PARSENOERR;
670 }
671 #endif
672 
673 static errcode GetColor(parsehandle * ph, apicolor * c1) {
674  float r, g, b;
675  int rc;
676 
677  rc = GetString(ph, "COLOR");
678  fscanf(ph->ifp, "%f %f %f", &r, &g, &b);
679  c1->r=r;
680  c1->g=g;
681  c1->b=b;
682 
683  return rc;
684 }
685 
686 static errcode GetImageDef(parsehandle * ph, SceneHandle scene) {
687  char texname[TEXNAMELEN];
688  int x, y, z;
689  int rc;
690  unsigned char *rgb=NULL;
691  int xres=0, yres=0, zres=0;
692 
693  fscanf(ph->ifp, "%s", texname);
694 
695  rc = GetString(ph, "FORMAT");
696  rc |= GetString(ph, "RGB24");
697 
698  rc |= GetString(ph, "RESOLUTION");
699  rc |= GetInt(ph, &xres);
700  rc |= GetInt(ph, &yres);
701  rc |= GetInt(ph, &zres);
702 
703  rgb = (unsigned char *) malloc(xres * yres * zres * 3);
704 
705  rc |= GetString(ph, "ENCODING");
706  rc |= GetString(ph, "HEX");
707 
708  /* loop over inline pixel color definitions */
709  for (z=0; z<zres; z++) {
710  for (y=0; y<yres; y++) {
711  for (x=0; x<xres; x++) {
712  char clrstr[1024];
713  int red, green, blue;
714  int addr = ((z*xres*yres) + (y*xres) + x) * 3;
715  int n=0;
716 
717  fscanf(ph->ifp, "%s", clrstr);
718 
719  /* parse colors stored as triplets of hexadecimal values with */
720  /* either one, two, three, or four nibbles of significant bits, */
721  /* converting to an 8-bit per channel color representation. */
722  switch (strlen(clrstr)) {
723  case 3:
724  n = sscanf(clrstr,"%01x%01x%01x", &red, &green, &blue);
725  red |= (red << 4);
726  green |= (green << 4);
727  blue |= (blue << 4);
728  break;
729 
730  case 6:
731  n = sscanf(clrstr,"%02x%02x%02x", &red, &green, &blue);
732  break;
733 
734  case 9:
735  n = sscanf(clrstr,"%03x%03x%03x", &red, &green, &blue);
736  red >>= 4;
737  green >>= 4;
738  blue >>= 4;
739  break;
740 
741  case 12:
742  n = sscanf(clrstr,"%04x%04x%04x", &red, &green, &blue);
743  red >>= 8;
744  green >>= 8;
745  blue >>= 8;
746  break;
747  }
748 
749  if (n != 3 ) {
750  rc |= PARSEBADSYNTAX; /* unparsed hex color occured */
751  }
752 
753  /* save RGB data to texture map */
754  rgb[addr ] = red & 0xff;
755  rgb[addr + 1] = green & 0xff;
756  rgb[addr + 2] = blue & 0xff;
757  }
758  }
759  }
760 
761  if (rc == PARSENOERR) {
762  rt_define_teximage_rgb24(texname, xres, yres, zres, rgb);
763  }
764 
765  return rc;
766 }
767 
768 static errcode GetTexDef(parsehandle * ph, SceneHandle scene) {
769  char texname[TEXNAMELEN];
770 
771  fscanf(ph->ifp, "%s", texname);
772  add_texture(ph, GetTexBody(ph, scene, 0), texname);
773 
774  return PARSENOERR;
775 }
776 
777 static errcode GetTexAlias(parsehandle * ph) {
778  char texname[TEXNAMELEN];
779  char aliasname[TEXNAMELEN];
780 
781  fscanf(ph->ifp, "%s", texname);
782  fscanf(ph->ifp, "%s", aliasname);
783  add_texture(ph, find_texture(ph, aliasname), texname);
784 
785  return PARSENOERR;
786 }
787 
788 
789 static errcode GetTexture(parsehandle * ph, SceneHandle scene, void ** tex) {
790  char tmp[255];
791  errcode rc = PARSENOERR;
792 
793  fscanf(ph->ifp, "%s", tmp);
794  if (!stringcmp(tmp, "TEXTURE")) {
795  *tex = GetTexBody(ph, scene, 0);
796  }
797  else
798  *tex = find_texture(ph, tmp);
799 
800  return rc;
801 }
802 
803 void * GetTexBody(parsehandle * ph, SceneHandle scene, int modeflag) {
804  char tmp[255];
805  float a,b,c,d;
806  int transmode;
807  float outline, outlinewidth;
808  float phong, phongexp;
809  int phongtype;
810  apitexture tex;
811  void * voidtex;
812  errcode rc;
813 
814  /* default texture properties if not overridden */
815  transmode=RT_TRANS_ORIG;
816  outline=0.0f;
817  outlinewidth=0.0f;
818  phong = 0.0f;
819  phongexp = 100.0f;
820  phongtype = RT_PHONG_PLASTIC;
821 
822  rc = GetString(ph, "AMBIENT");
823  fscanf(ph->ifp, "%f", &a);
824  tex.ambient=a;
825 
826  rc |= GetString(ph, "DIFFUSE");
827  fscanf(ph->ifp, "%f", &b);
828  tex.diffuse=b;
829 
830  rc |= GetString(ph, "SPECULAR");
831  fscanf(ph->ifp, "%f", &c);
832  tex.specular=c;
833 
834  rc |= GetString(ph, "OPACITY");
835  fscanf(ph->ifp, "%f", &d);
836  tex.opacity=d;
837 
838  fscanf(ph->ifp, "%s", tmp);
839  if (!stringcmp(tmp, "TRANSMODE")) {
840  fscanf(ph->ifp, "%s", tmp);
841  if (!stringcmp(tmp, "R3D")) {
842  transmode = RT_TRANS_RASTER3D;
843  }
844  fscanf(ph->ifp, "%s", tmp); /* read next item */
845  }
846 
847  if (!stringcmp(tmp, "OUTLINE")) {
848  fscanf(ph->ifp, "%f", &outline);
849  GetString(ph, "OUTLINE_WIDTH");
850  fscanf(ph->ifp, "%f", &outlinewidth);
851  fscanf(ph->ifp, "%s", tmp); /* read next item */
852  }
853 
854  if (!stringcmp(tmp, "PHONG")) {
855  fscanf(ph->ifp, "%s", tmp);
856 
857  /* if not overridden, phong type is set to plastic by default */
858  if (!stringcmp(tmp, "METAL")) {
859  phongtype = RT_PHONG_METAL;
860  } else if (!stringcmp(tmp, "PLASTIC")) {
861  phongtype = RT_PHONG_PLASTIC;
862  }
863 
864  fscanf(ph->ifp, "%f", &phong);
865  GetString(ph, "PHONG_SIZE");
866  fscanf(ph->ifp, "%f", &phongexp);
867  fscanf(ph->ifp, "%s", tmp);
868  } else {
869  /* assume we found "COLOR" otherwise */
870  }
871 
872  /* if we're processing normal objects, use the regular */
873  /* texture definition pattern. */
874  /* VCSTri objects skip the normal color and texture */
875  /* function definition since they are unused. */
876  if (modeflag == 0) {
877  if (stringcmp(tmp, "COLOR")) {
878  rc |= PARSEBADSYNTAX;
879  }
880 
881  fscanf(ph->ifp, "%f %f %f", &a, &b, &c);
882  tex.col.r = a;
883  tex.col.g = b;
884  tex.col.b = c;
885 
886  rc |= GetString(ph, "TEXFUNC");
887 
888  /* this really ought to be a string, not a number... */
889  fscanf(ph->ifp, "%d", &tex.texturefunc);
890 
891  switch (tex.texturefunc) {
892  case RT_TEXTURE_CONSTANT:
893  default:
894  break;
895 
897  case RT_TEXTURE_GRIT:
898  case RT_TEXTURE_MARBLE:
899  case RT_TEXTURE_WOOD:
900  case RT_TEXTURE_GRADIENT:
902  rc |= GetString(ph, "CENTER");
903  rc |= GetVector(ph, &tex.ctr);
904  rc |= GetString(ph, "ROTATE");
905  rc |= GetVector(ph, &tex.rot);
906  rc |= GetString(ph, "SCALE");
907  rc |= GetVector(ph, &tex.scale);
908  break;
909 
912  fscanf(ph->ifp, "%s", tex.imap);
913  rc |= GetString(ph, "CENTER");
914  rc |= GetVector(ph, &tex.ctr);
915  rc |= GetString(ph, "ROTATE");
916  rc |= GetVector(ph, &tex.rot);
917  rc |= GetString(ph, "SCALE");
918  rc |= GetVector(ph, &tex.scale);
919  break;
920 
922  fscanf(ph->ifp, "%s", tex.imap);
923  rc |= GetString(ph, "CENTER");
924  rc |= GetVector(ph, &tex.ctr);
925  rc |= GetString(ph, "ROTATE");
926  rc |= GetVector(ph, &tex.rot);
927  rc |= GetString(ph, "SCALE");
928  rc |= GetVector(ph, &tex.scale);
929  rc |= GetString(ph, "UAXIS");
930  rc |= GetVector(ph, &tex.uaxs);
931  rc |= GetString(ph, "VAXIS");
932  rc |= GetVector(ph, &tex.vaxs);
933  break;
934 
936  fscanf(ph->ifp, "%s", tex.imap);
937  rc |= GetString(ph, "CENTER");
938  rc |= GetVector(ph, &tex.ctr);
939  rc |= GetString(ph, "ROTATE");
940  rc |= GetVector(ph, &tex.rot);
941  rc |= GetString(ph, "SCALE");
942  rc |= GetVector(ph, &tex.scale);
943  rc |= GetString(ph, "UAXIS");
944  rc |= GetVector(ph, &tex.uaxs);
945  rc |= GetString(ph, "VAXIS");
946  rc |= GetVector(ph, &tex.vaxs);
947  rc |= GetString(ph, "WAXIS");
948  rc |= GetVector(ph, &tex.waxs);
949  break;
950  }
951  } else {
952  if (stringcmp(tmp, "VCST")) {
953  rc |= PARSEBADSYNTAX;
954  }
955 
956  /* if we're processing VCSTri objects, set some defaults */
957  tex.col.r = 1.0;
958  tex.col.g = 1.0;
959  tex.col.b = 1.0;
960  tex.texturefunc = 0; /* set to none by default, gets reset anyway */
961  }
962 
963  voidtex = rt_texture(scene, &tex);
964  rt_tex_phong(voidtex, phong, phongexp, phongtype);
965  rt_tex_transmode(voidtex, transmode);
966  rt_tex_outline(voidtex, outline, outlinewidth);
967 
968  return voidtex;
969 }
970 
971 static errcode GetDirLight(parsehandle * ph, SceneHandle scene) {
972  char tmp[255];
973  apivector dir;
974  apitexture tex;
975  float r, g, b;
976  errcode rc;
977 
978  memset(&tex, 0, sizeof(apitexture));
979 
980  rc = GetString(ph, "DIRECTION");
981  rc |= GetVector(ph, &dir);
982 
983  fscanf(ph->ifp, "%s", tmp);
984  if (!stringcmp(tmp, "COLOR")) {
985  fscanf(ph->ifp, "%f %f %f", &r, &g, &b);
986  tex.col.r=r;
987  tex.col.g=g;
988  tex.col.b=b;
989 
990  rt_directional_light(scene, rt_texture(scene, &tex), dir);
991  }
992 
993  return rc;
994 }
995 
996 static errcode GetLight(parsehandle * ph, SceneHandle scene) {
997  char tmp[255];
998  apiflt rad, Kc, Kl, Kq;
999  apivector ctr;
1000  apitexture tex;
1001  float r, g, b, a;
1002  errcode rc;
1003  void * li;
1004 
1005  memset(&tex, 0, sizeof(apitexture));
1006 
1007  rc = GetString(ph, "CENTER");
1008  rc |= GetVector(ph, &ctr);
1009  rc |= GetString(ph, "RAD");
1010  fscanf(ph->ifp, "%f", &a); /* read in radius */
1011  rad=a;
1012 
1013  fscanf(ph->ifp, "%s", tmp);
1014  if (!stringcmp(tmp, "COLOR")) {
1015  fscanf(ph->ifp, "%f %f %f", &r, &g, &b);
1016  tex.col.r=r;
1017  tex.col.g=g;
1018  tex.col.b=b;
1019 
1020  li = rt_light(scene, rt_texture(scene, &tex), ctr, rad);
1021  }
1022  else {
1023  if (stringcmp(tmp, "ATTENUATION"))
1024  return -1;
1025 
1026  rc |= GetString(ph, "CONSTANT");
1027  fscanf(ph->ifp, "%f", &a);
1028  Kc=a;
1029  rc |= GetString(ph, "LINEAR");
1030  fscanf(ph->ifp, "%f", &a);
1031  Kl=a;
1032  rc |= GetString(ph, "QUADRATIC");
1033  fscanf(ph->ifp, "%f", &a);
1034  Kq=a;
1035  rc |= GetColor(ph, &tex.col);
1036 
1037  li = rt_light(scene, rt_texture(scene, &tex), ctr, rad);
1038 
1039  rt_light_attenuation(li, Kc, Kl, Kq);
1040  }
1041 
1042  return rc;
1043 }
1044 
1045 static errcode GetSkyLight(parsehandle * ph, SceneHandle scene) {
1046  char tmp[255];
1047  errcode rc;
1048  apicolor ambcol;
1049  int numsamples = 128;
1050  float maxdist = RT_AO_MAXDIST_UNLIMITED;
1051  ambcol.r = 1.0;
1052  ambcol.g = 1.0;
1053  ambcol.b = 1.0;
1054 
1055  rc = GetString(ph, "NUMSAMPLES");
1056  fscanf(ph->ifp, "%d", &numsamples);
1057 
1058  /* read optional maxdist parameter */
1059  fscanf(ph->ifp, "%s", tmp);
1060  if (!stringcmp(tmp, "MAXDIST")) {
1061  fscanf(ph->ifp, "%f", &maxdist);
1062 
1063  rc |= GetString(ph, "COLOR");
1064  fscanf(ph->ifp, "%f %f %f", &ambcol.r, &ambcol.g, &ambcol.b);
1065  } else if (!stringcmp(tmp, "COLOR")) {
1066  fscanf(ph->ifp, "%f %f %f", &ambcol.r, &ambcol.g, &ambcol.b);
1067  }
1068 
1069  rt_ambient_occlusion(scene, numsamples, maxdist, ambcol);
1070 
1071  return rc;
1072 }
1073 
1074 static errcode GetSpotLight(parsehandle * ph, SceneHandle scene) {
1075  char tmp[255];
1076  apiflt rad, Kc, Kl, Kq;
1077  apivector ctr;
1078  apitexture tex;
1079  apivector direction;
1080  apiflt start, end;
1081  float r, g, b, a;
1082  errcode rc;
1083  void * li;
1084 
1085  memset(&tex, 0, sizeof(apitexture));
1086 
1087  rc = GetString(ph, "CENTER");
1088  rc |= GetVector(ph, &ctr);
1089  rc |= GetString(ph,"RAD");
1090  fscanf(ph->ifp, "%f", &a); /* read in radius */
1091  rad=a;
1092 
1093  rc |= GetString(ph, "DIRECTION");
1094  rc |= GetVector(ph, &direction);
1095  rc |= GetString(ph, "FALLOFF_START");
1096  fscanf(ph->ifp, "%f",&a);
1097  start=a;
1098  rc |= GetString(ph, "FALLOFF_END");
1099  fscanf(ph->ifp, "%f", &a);
1100  end=a;
1101 
1102  fscanf(ph->ifp, "%s", tmp);
1103  if (!stringcmp(tmp, "COLOR")) {
1104  fscanf(ph->ifp, "%f %f %f", &r, &g, &b);
1105  tex.col.r=r;
1106  tex.col.g=g;
1107  tex.col.b=b;
1108 
1109  li = rt_spotlight(scene, rt_texture(scene, &tex), ctr, rad, direction, start, end);
1110  }
1111  else {
1112  if (stringcmp(tmp, "ATTENUATION"))
1113  return -1;
1114  rc |= GetString(ph, "CONSTANT");
1115  fscanf(ph->ifp, "%f", &a);
1116  Kc=a;
1117  rc |= GetString(ph, "LINEAR");
1118  fscanf(ph->ifp, "%f", &a);
1119  Kl=a;
1120  rc |= GetString(ph, "QUADRATIC");
1121  fscanf(ph->ifp, "%f", &a);
1122  Kq=a;
1123  rc |= GetColor(ph, &tex.col);
1124 
1125  li = rt_spotlight(scene, rt_texture(scene, &tex), ctr, rad, direction, start, end);
1126  rt_light_attenuation(li, Kc, Kl, Kq);
1127  }
1128 
1129  return rc;
1130 }
1131 
1132 
1133 static errcode GetFog(parsehandle * ph, SceneHandle scene) {
1134  char tmp[255];
1135  apicolor fogcol;
1136  float start, end, density;
1137  errcode rc = PARSENOERR;
1138 
1139  fscanf(ph->ifp, "%s", tmp);
1140  if (!stringcmp(tmp, "LINEAR")) {
1141  rt_fog_mode(scene, RT_FOG_LINEAR);
1142  } else if (!stringcmp(tmp, "EXP")) {
1143  rt_fog_mode(scene, RT_FOG_EXP);
1144  } else if (!stringcmp(tmp, "EXP2")) {
1145  rt_fog_mode(scene, RT_FOG_EXP2);
1146  } else if (!stringcmp(tmp, "OFF")) {
1147  rt_fog_mode(scene, RT_FOG_NONE);
1148  }
1149 
1150  rc |= GetString(ph, "START");
1151  fscanf(ph->ifp, "%f", &start);
1152 
1153  rc |= GetString(ph, "END");
1154  fscanf(ph->ifp, "%f", &end);
1155 
1156  rc |= GetString(ph, "DENSITY");
1157  fscanf(ph->ifp, "%f", &density);
1158 
1159  rc |= GetColor(ph, &fogcol);
1160 
1161  rt_fog_parms(scene, fogcol, start, end, density);
1162 
1163  return PARSENOERR;
1164 }
1165 
1166 
1167 static errcode GetBackGnd(parsehandle * ph, SceneHandle scene) {
1168  float r,g,b;
1170 
1171  fscanf(ph->ifp, "%f %f %f", &r, &g, &b);
1172 
1173  scenebackcol.r=r;
1174  scenebackcol.g=g;
1175  scenebackcol.b=b;
1176  rt_background(scene, scenebackcol);
1177 
1178  return PARSENOERR;
1179 }
1180 
1181 static errcode GetBackGndGradient(parsehandle * ph, SceneHandle scene) {
1182  char gradienttype[1024];
1183  float topval, botval;
1184  float topcol[3], botcol[3];
1185  float updir[3];
1186  int rc=0;
1187 
1188  fscanf(ph->ifp, "%s", gradienttype); /* read next array type */
1189 
1190  /* read vertex coordinates */
1191  if (!stringcmp(gradienttype, "SKY_SPHERE")) {
1193  } else if (!stringcmp(gradienttype, "SKY_ORTHO_PLANE")) {
1195  } else {
1196  printf("Expected either a sky sphere or sky ortho plane background\n");
1197  printf("gradient texture definition.\n");
1198  return PARSEBADSYNTAX;
1199  }
1200 
1201  rc = GetString(ph, "UPDIR");
1202  fscanf(ph->ifp, "%f %f %f", &updir[0], &updir[1], &updir[2]);
1203 
1204  rc |= GetString(ph, "TOPVAL");
1205  fscanf(ph->ifp, "%f", &topval);
1206 
1207  rc |= GetString(ph, "BOTTOMVAL");
1208  fscanf(ph->ifp, "%f", &botval);
1209 
1210  rc |= GetString(ph, "TOPCOLOR");
1211  fscanf(ph->ifp, "%f %f %f", &topcol[0], &topcol[1], &topcol[2]);
1212 
1213  rc |= GetString(ph, "BOTTOMCOLOR");
1214  fscanf(ph->ifp, "%f %f %f", &botcol[0], &botcol[1], &botcol[2]);
1215 
1216  rt_background_gradient(scene,
1217  rt_vector(updir[0], updir[1], updir[2]),
1218  topval, botval,
1219  rt_color(topcol[0], topcol[1], topcol[2]),
1220  rt_color(botcol[0], botcol[1], botcol[2]));
1221 
1222  return rc;
1223 }
1224 
1225 static errcode GetCylinder(parsehandle * ph, SceneHandle scene) {
1226  apiflt rad;
1227  apivector ctr, axis;
1228  void * tex;
1229  float a;
1230  errcode rc;
1231 
1232  rc = GetString(ph, "CENTER");
1233  rc |= GetVector(ph, &ctr);
1234  rc |= GetString(ph, "AXIS");
1235  rc |= GetVector(ph, &axis);
1236  rc |= GetString(ph, "RAD");
1237  fscanf(ph->ifp, "%f", &a);
1238  rad=a;
1239 
1240  rc |= GetTexture(ph, scene, &tex);
1241  rt_cylinder(scene, tex, ctr, axis, rad);
1242 
1243  return rc;
1244 }
1245 
1246 static errcode GetFCylinder(parsehandle * ph, SceneHandle scene) {
1247  apiflt rad;
1248  apivector ctr, axis;
1249  apivector pnt1={0,0,0};
1250  apivector pnt2={0,0,0};
1251  void * tex;
1252  float a;
1253  errcode rc;
1254 
1255  rc = GetString(ph, "BASE");
1256  rc |= GetVector(ph, &pnt1);
1257  rc |= GetString(ph, "APEX");
1258  rc |= GetVector(ph, &pnt2);
1259 
1260  ctr=pnt1;
1261  axis.x=pnt2.x - pnt1.x;
1262  axis.y=pnt2.y - pnt1.y;
1263  axis.z=pnt2.z - pnt1.z;
1264 
1265  rc |= GetString(ph, "RAD");
1266  fscanf(ph->ifp, "%f", &a);
1267  rad=a;
1268 
1269  rc |= GetTexture(ph, scene, &tex);
1270  rt_fcylinder(scene, tex, ctr, axis, rad);
1271 
1272  return rc;
1273 }
1274 
1275 static errcode GetPolyCylinder(parsehandle * ph, SceneHandle scene) {
1276  apiflt rad;
1277  apivector * temp;
1278  void * tex;
1279  float a;
1280  int numpts, i;
1281  errcode rc;
1282 
1283  rc = GetString(ph, "POINTS");
1284  fscanf(ph->ifp, "%d", &numpts);
1285 
1286  temp = (apivector *) malloc(numpts * sizeof(apivector));
1287 
1288  for (i=0; i<numpts; i++) {
1289  rc |= GetVector(ph, &temp[i]);
1290  }
1291 
1292  rc |= GetString(ph, "RAD");
1293  fscanf(ph->ifp, "%f", &a);
1294  rad=a;
1295 
1296  rc |= GetTexture(ph, scene, &tex);
1297  rt_polycylinder(scene, tex, temp, numpts, rad);
1298 
1299  free(temp);
1300 
1301  return rc;
1302 }
1303 
1304 
1305 static errcode GetSphere(parsehandle * ph, SceneHandle scene) {
1306  apiflt rad;
1307  apivector ctr;
1308  void * tex;
1309  float a;
1310  errcode rc;
1311 
1312  rc = GetString(ph, "CENTER");
1313  rc |= GetVector(ph, &ctr);
1314  rc |= GetString(ph, "RAD");
1315  fscanf(ph->ifp, "%f", &a);
1316  rad=a;
1317 
1318  rc |= GetTexture(ph, scene, &tex);
1319 
1320  rt_sphere(scene, tex, ctr, rad);
1321 
1322  return rc;
1323 }
1324 
1325 static errcode GetPlane(parsehandle * ph, SceneHandle scene) {
1326  apivector normal;
1327  apivector ctr;
1328  void * tex;
1329  errcode rc;
1330 
1331  rc = GetString(ph, "CENTER");
1332  rc |= GetVector(ph, &ctr);
1333  rc |= GetString(ph, "NORMAL");
1334  rc |= GetVector(ph, &normal);
1335  rc |= GetTexture(ph, scene, &tex);
1336 
1337  rt_plane(scene, tex, ctr, normal);
1338 
1339  return rc;
1340 }
1341 
1342 static errcode GetVol(parsehandle * ph, SceneHandle scene) {
1343  apivector min, max;
1344  int x,y,z;
1345  char fname[255];
1346  void * tex;
1347  errcode rc;
1348 
1349  rc = GetString(ph, "MIN");
1350  rc |= GetVector(ph, &min);
1351  rc |= GetString(ph, "MAX");
1352  rc |= GetVector(ph, &max);
1353  rc |= GetString(ph, "DIM");
1354  fscanf(ph->ifp, "%d %d %d ", &x, &y, &z);
1355  rc |= GetString(ph, "FILE");
1356  fscanf(ph->ifp, "%s", fname);
1357  rc |= GetTexture(ph, scene, &tex);
1358 
1359  rt_scalarvol(scene, tex, min, max, x, y, z, fname, NULL);
1360 
1361  return rc;
1362 }
1363 
1364 static errcode GetBox(parsehandle * ph, SceneHandle scene) {
1365  apivector min, max;
1366  void * tex;
1367  errcode rc;
1368 
1369  rc = GetString(ph, "MIN");
1370  rc |= GetVector(ph, &min);
1371  rc |= GetString(ph, "MAX");
1372  rc |= GetVector(ph, &max);
1373  rc |= GetTexture(ph, scene, &tex);
1374 
1375  rt_box(scene, tex, min, max);
1376 
1377  return rc;
1378 }
1379 
1380 static errcode GetRing(parsehandle * ph, SceneHandle scene) {
1381  apivector normal;
1382  apivector ctr;
1383  void * tex;
1384  float a,b;
1385  errcode rc;
1386 
1387  rc = GetString(ph, "CENTER");
1388  rc |= GetVector(ph, &ctr);
1389  rc |= GetString(ph, "NORMAL");
1390  rc |= GetVector(ph, &normal);
1391  rc |= GetString(ph, "INNER");
1392  fscanf(ph->ifp, " %f ", &a);
1393  rc |= GetString(ph, "OUTER");
1394  fscanf(ph->ifp, " %f ", &b);
1395  rc |= GetTexture(ph, scene, &tex);
1396 
1397  rt_ring(scene, tex, ctr, normal, a, b);
1398 
1399  return rc;
1400 }
1401 
1402 static errcode GetTri(parsehandle * ph, SceneHandle scene) {
1403  apivector v0,v1,v2;
1404  void * tex;
1405  errcode rc;
1406 
1407  rc = GetString(ph, "V0");
1408  rc |= GetVector(ph, &v0);
1409 
1410  rc |= GetString(ph, "V1");
1411  rc |= GetVector(ph, &v1);
1412 
1413  rc |= GetString(ph, "V2");
1414  rc |= GetVector(ph, &v2);
1415 
1416  rc |= GetTexture(ph, scene, &tex);
1417 
1418  rt_tri(scene, tex, v0, v1, v2);
1419 
1420  return rc;
1421 }
1422 
1423 static errcode GetSTri(parsehandle * ph, SceneHandle scene) {
1424  apivector v0,v1,v2,n0,n1,n2;
1425  void * tex;
1426  errcode rc;
1427 
1428  rc = GetString(ph, "V0");
1429  rc |= GetVector(ph, &v0);
1430 
1431  rc |= GetString(ph, "V1");
1432  rc |= GetVector(ph, &v1);
1433 
1434  rc |= GetString(ph, "V2");
1435  rc |= GetVector(ph, &v2);
1436 
1437  rc |= GetString(ph, "N0");
1438  rc |= GetVector(ph, &n0);
1439 
1440  rc |= GetString(ph, "N1");
1441  rc |= GetVector(ph, &n1);
1442 
1443  rc |= GetString(ph, "N2");
1444  rc |= GetVector(ph, &n2);
1445 
1446  rc |= GetTexture(ph, scene, &tex);
1447 
1448  rt_stri(scene, tex, v0, v1, v2, n0, n1, n2);
1449 
1450  return rc;
1451 }
1452 
1453 static errcode GetVCSTri(parsehandle * ph, SceneHandle scene) {
1454  apivector v0,v1,v2,n0,n1,n2;
1455  apicolor c0,c1,c2;
1456  float a, b, c;
1457 
1458  void * tex;
1459  errcode rc;
1460 
1461  rc = GetString(ph, "V0");
1462  rc |= GetVector(ph, &v0);
1463 
1464  rc |= GetString(ph, "V1");
1465  rc |= GetVector(ph, &v1);
1466 
1467  rc |= GetString(ph, "V2");
1468  rc |= GetVector(ph, &v2);
1469 
1470  rc |= GetString(ph, "N0");
1471  rc |= GetVector(ph, &n0);
1472 
1473  rc |= GetString(ph, "N1");
1474  rc |= GetVector(ph, &n1);
1475 
1476  rc |= GetString(ph, "N2");
1477  rc |= GetVector(ph, &n2);
1478 
1479  rc |= GetString(ph, "C0");
1480  fscanf(ph->ifp, "%f %f %f", &a, &b, &c);
1481  c0.r = a;
1482  c0.g = b;
1483  c0.b = c;
1484 
1485  rc |= GetString(ph, "C1");
1486  fscanf(ph->ifp, "%f %f %f", &a, &b, &c);
1487  c1.r = a;
1488  c1.g = b;
1489  c1.b = c;
1490 
1491  rc |= GetString(ph, "C2");
1492  fscanf(ph->ifp, "%f %f %f", &a, &b, &c);
1493  c2.r = a;
1494  c2.g = b;
1495  c2.b = c;
1496 
1497  tex = GetTexBody(ph, scene, 1);
1498 
1499  rt_vcstri(scene, tex, v0, v1, v2, n0, n1, n2, c0, c1, c2);
1500 
1501  return rc;
1502 }
1503 
1504 
1505 #if 0
1506 static errcode GetSphereArray(parsehandle * ph, SceneHandle scene) {
1507  char arraytype[1024];
1508  int i;
1509  int spherecount=0;
1510  errcode rc=PARSENOERR;
1511  void * tex=NULL;
1512  float * v = NULL;
1513  float * r = NULL;
1514  float * c = NULL;
1515 
1516  rc |= GetString(ph, "NUMSPHERES");
1517  rc |= GetInt(ph, &spherecount);
1518  if (rc!= PARSENOERR)
1519  return rc;
1520 
1521  fscanf(ph->ifp, "%s", arraytype); /* read next array type */
1522 
1523  /* read sphere coordinates */
1524  if (!stringcmp(arraytype, "CENTERS")) {
1525  v = (float *) malloc(spherecount * 3 * sizeof(float));
1526  for (i=0; i<spherecount * 3; i+=3) {
1527  fscanf(ph->ifp, "%f %f %f", &v[i], &v[i+1], &v[i+2]);
1528  }
1529  } else {
1530  printf("Expected sphere array centers block\n");
1531  return PARSEBADSYNTAX;
1532  }
1533 
1534  /* use the default texture until we parse a subsequent texture command */
1535  tex = ph->defaulttex.tex;
1536  fscanf(ph->ifp, "%s", arraytype); /* read next array type */
1537 
1538  /* read sphere radii */
1539  if (!stringcmp(arraytype, "RADII")) {
1540  r = (float *) malloc(spherecount * sizeof(float));
1541  for (i=0; i<spherecount; i++) {
1542  fscanf(ph->ifp, "%f", &r[i]);
1543  }
1544  } else {
1545  printf("Expected sphere array radii block\n");
1546  return PARSEBADSYNTAX;
1547  }
1548 
1549  /* read sphere colors */
1550  if (!stringcmp(arraytype, "COLORS")) {
1551  c = (float *) malloc(spherecount * 3 * sizeof(float));
1552  for (i=0; i<spherecount * 3; i+=3) {
1553  fscanf(ph->ifp, "%f %f %f", &c[i], &c[i+1], &c[i+2]);
1554  }
1555  } else {
1556  printf("Expected sphere array colors block\n");
1557  return PARSEBADSYNTAX;
1558  }
1559 
1560  /* read sphere array texture, same for all spheres */
1561  if (!stringcmp(arraytype, "TEXTURE")) {
1562  /* read in texture to use for all sphere geometry */
1563  /* don't require texture color since it won't be used */
1564  /* in the current implementation. */
1565  tex = GetTexBody(ph, scene, 0);
1566  if (tex == NULL) {
1567  printf("Failed to parse vertex array texture block\n");
1568  rc |= PARSEBADSYNTAX;
1569  }
1570  }
1571 
1572  /* generate the spheres */
1573  if (rc == PARSENOERR) {
1574  for (i=0; i<spherecount * 3; i+=3) {
1575  rt_sphere3fv(scene, tex, &c[i], r[i]);
1576  }
1577  }
1578 
1579  return rc;
1580 }
1581 #endif
1582 
1583 
1584 static errcode GetVertexArray(parsehandle * ph, SceneHandle scene) {
1585  char arraytype[1024];
1586  int done, i, texusecount;
1587  int vertexcount=0;
1588  errcode rc=PARSENOERR;
1589  void * tex=NULL;
1590  float * v = NULL;
1591  float * n = NULL;
1592  float * c = NULL;
1593 
1594  rc |= GetString(ph, "NUMVERTS");
1595  rc |= GetInt(ph, &vertexcount);
1596  if (rc!= PARSENOERR)
1597  return rc;
1598 
1599  fscanf(ph->ifp, "%s", arraytype); /* read next array type */
1600 
1601  /* read vertex coordinates */
1602  if (!stringcmp(arraytype, "COORDS")) {
1603  v = (float *) malloc(vertexcount * 3 * sizeof(float));
1604  for (i=0; i<vertexcount * 3; i+=3) {
1605  fscanf(ph->ifp, "%f %f %f", &v[i], &v[i+1], &v[i+2]);
1606  }
1607  fscanf(ph->ifp, "%s", arraytype); /* read next array type */
1608  } else {
1609  printf("Expected vertex array coords block\n");
1610  return PARSEBADSYNTAX;
1611  }
1612 
1613  /* read vertex normals */
1614  if (!stringcmp(arraytype, "NORMALS")) {
1615  n = (float *) malloc(vertexcount * 3 * sizeof(float));
1616  for (i=0; i<vertexcount * 3; i+=3) {
1617  fscanf(ph->ifp, "%f %f %f", &n[i], &n[i+1], &n[i+2]);
1618  }
1619  fscanf(ph->ifp, "%s", arraytype); /* read next array type */
1620  } else {
1621  free(v);
1622  printf("Expected vertex array normals block\n");
1623  return PARSEBADSYNTAX;
1624  }
1625 
1626 
1627  /* use the default texture until we parse a subsequent texture command */
1628  tex = ph->defaulttex.tex;
1629 
1630  texusecount=1;
1631  done = 0;
1632  while (!done) {
1633  /* read vertex colors */
1634  if (!stringcmp(arraytype, "COLORS")) {
1635  c = (float *) malloc(vertexcount * 3 * sizeof(float));
1636  for (i=0; i<vertexcount * 3; i+=3) {
1637  fscanf(ph->ifp, "%f %f %f", &c[i], &c[i+1], &c[i+2]);
1638  }
1639 #if 0
1640  } else if (!stringcmp(arraytype, "TEXCOORDS3")) {
1641  /* read vertex texture coordinates */
1642  texmode = 3;
1643  t = (float *) malloc(vertexcount * 3 * sizeof(float));
1644  for (i=0; i<vertexcount * 3; i++) {
1645  fscanf(ph->ifp, "%f %f %f", &t[i], &t[i+1], &t[i+2]);
1646  }
1647  } else if (!stringcmp(arraytype, "TEXCOORDS2")) {
1648  texmode = 2;
1649  t = (float *) malloc(vertexcount * 2 * sizeof(float));
1650  for (i=0; i<vertexcount * 3; i++) {
1651  fscanf(ph->ifp, "%f %f", &t[i], &t[i+1]);
1652  }
1653 #endif
1654  } else if (!stringcmp(arraytype, "TEXTURE")) {
1655  /* read in texture to use for all following geometry */
1656  /* don't require texture color since it won't be used */
1657  /* in the current implementation. */
1658  tex = GetTexBody(ph, scene, 0);
1659  if (tex == NULL) {
1660  printf("Failed to parse vertex array texture block\n");
1661  rc |= PARSEBADSYNTAX;
1662  done = 1;
1663  }
1664  texusecount=0;
1665  } else if (!stringcmp(arraytype, "TRISTRIP")) {
1666  int t;
1667  int numv=0;
1668  int stripaddr[2][3] = { {0, 1, 2}, {1, 0, 2} };
1669  int * facets=NULL;
1670 
1671  rc |= GetInt(ph, &numv);
1672  if (rc!= PARSENOERR)
1673  return PARSEBADSYNTAX;
1674 
1675  facets = (int *) malloc(numv * sizeof(int));
1676  for (i=0; i<numv; i++) {
1677  fscanf(ph->ifp, "%d", &facets[i]);
1678  }
1679 
1680  /* render triangle strips one triangle at a time */
1681  /* triangle winding order is: */
1682  /* v0, v1, v2, then v2, v1, v3, then v2, v3, v4, etc. */
1683 
1684  /* loop over all triangles in this triangle strip */
1685  for (t=0; t < (numv - 2); t++) {
1686  /* render one triangle, using lookup table to fix winding order */
1687  int v0 = facets[t + (stripaddr[t & 0x01][0])];
1688  int v1 = facets[t + (stripaddr[t & 0x01][1])];
1689  int v2 = facets[t + (stripaddr[t & 0x01][2])];
1690 
1691  if ((v0 >= 0) && (v0 < vertexcount) &&
1692  (v1 >= 0) && (v1 < vertexcount) &&
1693  (v2 >= 0) && (v2 < vertexcount)) {
1694  v0 *= 3;
1695  v1 *= 3;
1696  v2 *= 3;
1697 
1698  if (c != NULL) {
1699  if (texusecount > 0)
1700  tex = rt_texture_copy_vcstri(scene, tex); /* create a new one */
1701 
1702  rt_vcstri(scene, tex,
1703  rt_vector(v[v0], v[v0 + 1], v[v0 + 2]),
1704  rt_vector(v[v1], v[v1 + 1], v[v1 + 2]),
1705  rt_vector(v[v2], v[v2 + 1], v[v2 + 2]),
1706  rt_vector(n[v0], n[v0 + 1], n[v0 + 2]),
1707  rt_vector(n[v1], n[v1 + 1], n[v1 + 2]),
1708  rt_vector(n[v2], n[v2 + 1], n[v2 + 2]),
1709  rt_color(c[v0], c[v0 + 1], c[v0 + 2]),
1710  rt_color(c[v1], c[v1 + 1], c[v1 + 2]),
1711  rt_color(c[v2], c[v2 + 1], c[v2 + 2]));
1712  } else {
1713  rt_stri(scene, tex,
1714  rt_vector(v[v0], v[v0 + 1], v[v0 + 2]),
1715  rt_vector(v[v1], v[v1 + 1], v[v1 + 2]),
1716  rt_vector(v[v2], v[v2 + 1], v[v2 + 2]),
1717  rt_vector(n[v0], n[v0 + 1], n[v0 + 2]),
1718  rt_vector(n[v1], n[v1 + 1], n[v1 + 2]),
1719  rt_vector(n[v2], n[v2 + 1], n[v2 + 2]));
1720  }
1721  } else {
1722  printf("tristrip error: skipping invalid strip vertex %d\n", t);
1723  printf(" vertexcount: %d\n", vertexcount);
1724  printf(" verts: %d %d %d\n", v0, v1, v2);
1725  rc |= PARSEBADSYNTAX;
1726  done = 1;
1727  break;
1728  }
1729 
1730  texusecount++; /* don't reuse textures */
1731  }
1732 
1733  free(facets);
1734  } else if (!stringcmp(arraytype, "TRIMESH")) {
1735  int numfacets=0;
1736  int * facets;
1737 
1738  rc |= GetInt(ph, &numfacets);
1739  if (rc!= PARSENOERR)
1740  return PARSEBADSYNTAX;
1741 
1742  facets = (int *) malloc(numfacets * 3 * sizeof(int));
1743  for (i=0; i<numfacets*3; i+=3) {
1744  fscanf(ph->ifp, "%d %d %d", &facets[i], &facets[i+1], &facets[i+2]);
1745  }
1746 
1747  /* loop over all triangles in this mesh */
1748  for (i=0; i < numfacets*3; i+=3) {
1749  int v0 = facets[i ];
1750  int v1 = facets[i + 1];
1751  int v2 = facets[i + 2];
1752 
1753 
1754  if ((v0 >= 0) && (v0 < vertexcount) &&
1755  (v1 >= 0) && (v1 < vertexcount) &&
1756  (v2 >= 0) && (v2 < vertexcount)) {
1757  v0 *= 3;
1758  v1 *= 3;
1759  v2 *= 3;
1760 
1761  if (c != NULL) {
1762  if (texusecount > 0)
1763  tex = rt_texture_copy_vcstri(scene, tex); /* create a new one */
1764  rt_vcstri(scene, tex,
1765  rt_vector(v[v0], v[v0 + 1], v[v0 + 2]),
1766  rt_vector(v[v1], v[v1 + 1], v[v1 + 2]),
1767  rt_vector(v[v2], v[v2 + 1], v[v2 + 2]),
1768  rt_vector(n[v0], n[v0 + 1], n[v0 + 2]),
1769  rt_vector(n[v1], n[v1 + 1], n[v1 + 2]),
1770  rt_vector(n[v2], n[v2 + 1], n[v2 + 2]),
1771  rt_color(c[v0], c[v0 + 1], c[v0 + 2]),
1772  rt_color(c[v1], c[v1 + 1], c[v1 + 2]),
1773  rt_color(c[v2], c[v2 + 1], c[v2 + 2]));
1774  } else {
1775  rt_stri(scene, tex,
1776  rt_vector(v[v0], v[v0 + 1], v[v0 + 2]),
1777  rt_vector(v[v1], v[v1 + 1], v[v1 + 2]),
1778  rt_vector(v[v2], v[v2 + 1], v[v2 + 2]),
1779  rt_vector(n[v0], n[v0 + 1], n[v0 + 2]),
1780  rt_vector(n[v1], n[v1 + 1], n[v1 + 2]),
1781  rt_vector(n[v2], n[v2 + 1], n[v2 + 2]));
1782  }
1783  } else {
1784  printf("trimesh error: skipping invalid vertex in facet %d\n", i/3);
1785  printf(" numfacets: %d vertexcount: %d\n", numfacets, vertexcount);
1786  printf(" verts: %d %d %d\n", v0, v1, v2);
1787  rc |= PARSEBADSYNTAX;
1788  done = 1;
1789  break;
1790  }
1791 
1792  texusecount++; /* don't reuse textures */
1793  }
1794 
1795  free(facets);
1796  } else if (!stringcmp(arraytype, "END_VERTEXARRAY")) {
1797  done = 1;
1798  } else {
1799  printf("Unrecognized vertex array block `%s`\n", arraytype);
1800  rc |= PARSEBADSYNTAX;
1801  done = 1;
1802  }
1803 
1804  if (!done) {
1805  fscanf(ph->ifp, "%s", arraytype); /* read next array type */
1806  }
1807  }
1808 
1809  if (v != NULL)
1810  free(v);
1811  if (n != NULL)
1812  free(n);
1813  if (c != NULL)
1814  free(c);
1815 
1816  return rc;
1817 }
1818 
1819 
1820 static errcode GetLandScape(parsehandle * ph, SceneHandle scene) {
1821  void * tex;
1822  apivector ctr;
1823  apiflt wx, wy;
1824  int m, n;
1825  float a,b;
1826  errcode rc;
1827 
1828  rc = GetString(ph, "RES");
1829  fscanf(ph->ifp, "%d %d", &m, &n);
1830 
1831  rc |= GetString(ph, "SCALE");
1832  fscanf(ph->ifp, "%f %f", &a, &b);
1833  wx=a;
1834  wy=b;
1835 
1836  rc |= GetString(ph, "CENTER");
1837  rc |= GetVector(ph, &ctr);
1838 
1839  rc |= GetTexture(ph, scene, &tex);
1840 
1841  rt_landscape(scene, tex, m, n, ctr, wx, wy);
1842 
1843  return rc;
1844 }
1845 
1846 static errcode GetTPolyFile(parsehandle * ph, SceneHandle scene) {
1847  void * tex;
1848  char ifname[255];
1849  FILE *ifp;
1850  int v;
1851  RotMat RotA;
1852  errcode rc=0;
1853  int totalpolys=0;
1854  apivector ctr={0,0,0};
1855  apivector rot={0,0,0};
1856  apivector scale={0,0,0};
1857  apivector v0={0,0,0};
1858  apivector v1={0,0,0};
1859  apivector v2={0,0,0};
1860 
1861  rc = GetString(ph, "SCALE");
1862  rc |= GetVector(ph, &scale);
1863 
1864  rc |= GetString(ph, "ROT");
1865  rc |= GetVector(ph, &rot);
1866 
1867  degvectoradvec(&rot);
1868  InitRot3d(&RotA, rot.x, rot.y, rot.z);
1869 
1870  rc |= GetString(ph, "CENTER");
1871  rc |= GetVector(ph, &ctr);
1872 
1873  rc |= GetString(ph, "FILE");
1874  fscanf(ph->ifp, "%s", ifname);
1875 
1876  rc |= GetTexture(ph, scene, &tex);
1877 
1878  if ((ifp=fopen(ifname, "r")) == NULL) {
1879  printf("Can't open data file %s for input!! Aborting...\n", ifname);
1880  return PARSEBADSUBFILE;
1881  }
1882 
1883  while (!feof(ifp)) {
1884  fscanf(ifp, "%d", &v);
1885  if (v != 3) { break; }
1886 
1887  totalpolys++;
1888  v=0;
1889 
1890  rc |= GetVector(ph, &v0);
1891  rc |= GetVector(ph, &v1);
1892  rc |= GetVector(ph, &v2);
1893 
1894  Scale3d(&scale, &v0);
1895  Scale3d(&scale, &v1);
1896  Scale3d(&scale, &v2);
1897 
1898  Rotate3d(&RotA, &v0);
1899  Rotate3d(&RotA, &v1);
1900  Rotate3d(&RotA, &v2);
1901 
1902  Trans3d(&ctr, &v0);
1903  Trans3d(&ctr, &v1);
1904  Trans3d(&ctr, &v2);
1905 
1906  rt_tri(scene, tex, v1, v0, v2);
1907  }
1908 
1909  fclose(ifp);
1910 
1911  return rc;
1912 }
1913 
1914 
1915 static errcode GetClipGroup(parsehandle * ph, SceneHandle scene) {
1916  char objtype[256];
1917 
1918  if (fscanf(ph->ifp, "%s", objtype) == EOF) {
1919  return PARSEEOF;
1920  }
1921 
1922  if (!stringcmp(objtype, "NUMPLANES")) {
1923  int numplanes, i;
1924  float * planes;
1925 
1926  if (fscanf(ph->ifp, "%d", &numplanes) != 1)
1927  return PARSEBADSYNTAX;
1928 
1929  planes = (float *) malloc(numplanes * 4 * sizeof(float));
1930 
1931  for (i=0; i<(numplanes * 4); i++) {
1932  if (fscanf(ph->ifp, "%f", &planes[i]) != 1)
1933  return PARSEBADSYNTAX;
1934  }
1935 
1936  rt_clip_fv(scene, numplanes, planes);
1937  free(planes);
1938 
1939  return PARSENOERR;
1940  }
1941 
1942  return PARSEBADSYNTAX;
1943 }
1944 
1945 
1946 static errcode GetClipGroupEnd(parsehandle * ph, SceneHandle scene) {
1947  rt_clip_off(scene);
1948  return PARSENOERR;
1949 }
1950 
1951 
1952 #ifdef USELIBMGF
1953 static errcode GetMGFFile(parsehandle * ph, SceneHandle scene) {
1954  char ifname[255];
1955 
1956  fscanf(ph->ifp, "%s", ifname); /* get MGF filename */
1957  if (ParseMGF(ifname, scene, 0) == MGF_NOERR)
1958  return PARSENOERR;
1959 
1960  return PARSENOERR; /* XXX hack */
1961 }
1962 #endif
1963 
1964 
1965 
1966 
void rt_background_gradient(SceneHandle voidscene, apivector up, flt topval, flt botval, apicolor topcol, apicolor botcol)
Set parameters for gradient (sky plane or sphere) background texturing.
Definition: api.c:497
static errcode GetPlane(parsehandle *ph, SceneHandle scene)
Definition: parse.c:1325
static errcode GetBackGndGradient(parsehandle *ph, SceneHandle scene)
Definition: parse.c:1181
#define PARSEALLOCERR
Definition: ac3dparse.h:16
#define HASH_FAIL
Return code when a hash key is not find, or there&#39;s no collision upon insertion.
Definition: hash.h:30
void rt_hash_init(rt_hash_t *tptr, int buckets)
Definition: hash.c:87
float g
Green color component.
Definition: tachyon.h:61
void rt_camera_setup(SceneHandle voidscene, flt zoom, flt aspectratio, int antialiasing, int raydepth, apivector camcent, apivector viewvec, apivector upvec)
Define a camera for a perspective projection, given the specified zoom factor, aspect ratio...
Definition: api.c:229
void rt_hash_destroy(rt_hash_t *tptr)
Definition: hash.c:218
float r
Red color component.
Definition: tachyon.h:60
static errcode GetVol(parsehandle *ph, SceneHandle scene)
Definition: parse.c:1342
#define RT_TEXTURE_GRIT
"grit" procedural texture
Definition: tachyon.h:604
void * rt_texture(SceneHandle sc, apitexture *apitex)
Translate a texture definition into the internal format used by Tachyon, and returns an opaque pointe...
Definition: api.c:933
static errcode GetVCSTri(parsehandle *ph, SceneHandle scene)
Definition: parse.c:1453
void rt_camera_eye_separation(SceneHandle voidscene, flt eyesep)
Set camera stereoscopic eye separation.
Definition: api.c:307
static errcode GetScenedefs(parsehandle *ph, SceneHandle scene)
Definition: parse.c:320
apicolor col
base object color
Definition: tachyon.h:67
static errcode GetSphere(parsehandle *ph, SceneHandle scene)
Definition: parse.c:1305
static void Trans3d(apivector *trans, apivector *vec)
Definition: parse.c:167
void rt_shadermode(SceneHandle voidscene, int mode)
Set the shading mode for the specified scene.
Definition: api.c:646
apivector rot
rotation of texture around origin
Definition: tachyon.h:74
void rt_resolution(SceneHandle voidscene, int hres, int vres)
Set the horizontal and vertical resolution (in pixels) for the specified scene.
Definition: api.c:372
static errcode GetSpotLight(parsehandle *ph, SceneHandle scene)
Definition: parse.c:1074
#define PARSENOERR
Definition: ac3dparse.h:11
static errcode GetBackGnd(parsehandle *ph, SceneHandle scene)
Definition: parse.c:1167
#define RT_FOG_LINEAR
linear fog
Definition: tachyon.h:441
void rt_light_attenuation(void *vli, flt Kc, flt Kl, flt Kq)
Set light attenuation parameters for an existing light.
Definition: api.c:1142
#define RT_TRANS_VMD
mult shaded color by opacity, for VMD
Definition: tachyon.h:459
void rt_trans_mode(SceneHandle voidscene, int mode)
Set transparency rendering mode.
Definition: api.c:619
flt diffuse
diffuse reflection
Definition: tachyon.h:70
flt opacity
how opaque the object is
Definition: tachyon.h:72
#define RT_TEXTURE_3D_CHECKER
checkerboard texture
Definition: tachyon.h:603
void rt_trans_max_surfaces(SceneHandle voidscene, int count)
Set the maximum number of transparent surfaces that will be rendered.
Definition: api.c:224
void rt_fog_rendering_mode(SceneHandle voidscene, int mode)
Set fog rendering mode, either radial fog (native Tachyon behavior), or an OpenGL- or VMD-like planar...
Definition: api.c:581
#define RT_TEXTURE_WOOD
"wood" procedural texture
Definition: tachyon.h:606
static errcode GetFCylinder(parsehandle *ph, SceneHandle scene)
Definition: parse.c:1246
static errcode GetCylinder(parsehandle *ph, SceneHandle scene)
Definition: parse.c:1225
#define RT_PROJECTION_EQUIRECTANGULAR
360 lat-long equirectangular
Definition: tachyon.h:504
flt specular
specular reflection
Definition: tachyon.h:71
#define RT_TEXTURE_MARBLE
"marble" procedural texture
Definition: tachyon.h:605
#define RT_SHADER_LOW
low quality shading
Definition: tachyon.h:657
#define RT_TEXTURE_CONSTANT
solid color
Definition: tachyon.h:602
#define RT_TRANS_ORIG
original transparency mode
Definition: tachyon.h:458
#define RT_TEXTURE_CYLINDRICAL_IMAGE
cylindrical image map
Definition: tachyon.h:609
static errcode GetVector(parsehandle *ph, apivector *v1)
Definition: parse.c:648
void rt_landscape(SceneHandle scene, void *tex, int m, int n, apivector ctr, flt wx, flt wy)
Define an auto-generated height field.
Definition: apigeom.c:225
#define RT_SHADER_FULL
Highest quality shading available.
Definition: tachyon.h:660
static errcode GetObject(parsehandle *ph, SceneHandle scene)
Definition: parse.c:513
void rt_fog_parms(SceneHandle voidscene, apicolor col, flt start, flt end, flt density)
Set fog rendering parameters.
Definition: api.c:573
apicolor rt_color(flt r, flt g, flt b)
Helper function to make colors.
Definition: api.c:169
void * rt_spotlight(SceneHandle voidscene, void *tex, apivector ctr, flt rad, apivector dir, flt start, flt end)
Define a spotlight with associated texture, position, radius, direction, falloff start, and falloff end parameters.
Definition: api.c:1107
apivector ctr
origin of texture
Definition: tachyon.h:73
static errcode GetLandScape(parsehandle *ph, SceneHandle scene)
Definition: parse.c:1820
static void * find_texture(parsehandle *ph, const char *name)
Definition: parse.c:112
static errcode GetCamera(parsehandle *ph, SceneHandle scene)
Definition: parse.c:410
unsigned int ParseMGF(char *mgfname, SceneHandle scene, int defaultflag)
#define RT_TEXTURE_VOLUME_IMAGE
volumetric image map
Definition: tachyon.h:612
char imap[96]
name of image map
Definition: tachyon.h:79
static errcode add_texture(parsehandle *ph, void *tex, const char *name)
Definition: parse.c:85
static errcode GetTexAlias(parsehandle *ph)
Definition: parse.c:777
void rt_fog_mode(SceneHandle voidscene, int mode)
Set fog style (linear, exponential, exponential-squared).
Definition: api.c:596
static errcode ReadIncludeFile(parsehandle *ph, const char *includefile, SceneHandle scene)
Definition: parse.c:282
void rt_box(SceneHandle scene, void *tex, apivector min, apivector max)
Define an axis-aligned box.
Definition: api.c:1156
void rt_sphere(SceneHandle scene, void *tex, apivector ctr, flt rad)
Define a sphere with associated texture, center, and radius.
Definition: api.c:1212
void rt_ambient_occlusion(SceneHandle voidscene, int numsamples, apiflt maxdist, apicolor col)
Ambient occlusion lighting, with monte carlo sampling of omnidirectional "sky" light.
Definition: api.c:563
unsigned int readmodel(const char *modelfile, SceneHandle scene)
Definition: parse.c:225
void rt_sphere3fv(SceneHandle scene, void *tex, const float *ctr, float rad)
Define a sphere with associated texture, center, and radius.
Definition: api.c:1216
static errcode GetInt(parsehandle *ph, int *i)
Definition: parse.c:638
#define RT_TRANS_RASTER3D
angle-dependent opacity modulation
Definition: tachyon.h:460
static apicolor scenebackcol
Definition: ac3dparse.c:31
#define RT_PROJECTION_FISHEYE
Fisheye projection mode.
Definition: tachyon.h:505
void rt_rescale_lights(SceneHandle voidscene, flt lightscale)
Rescale all light sources in the scene by factor lightscale.
Definition: api.c:673
#define RT_BACKGROUND_TEXTURE_SKY_SPHERE
gradient bg, persp
Definition: tachyon.h:387
#define RT_PROJECTION_STEREO_EQUIRECTANGULAR
over/under omnistereo equirectangular
Definition: tachyon.h:506
apiflt degtorad(apiflt deg)
Definition: parse.c:124
static errcode GetTexture(parsehandle *ph, SceneHandle scene, void **tex)
Definition: parse.c:789
static errcode GetSkyLight(parsehandle *ph, SceneHandle scene)
Definition: parse.c:1045
#define RT_FOG_VMD
planar OpenGL-like fog
Definition: tachyon.h:420
void rt_scalarvol(SceneHandle scene, void *tex, apivector min, apivector max, int xs, int ys, int zs, const char *fname, void *voidvol)
Define an axis-aligned scalar volumetric data set, loaded from a file.
Definition: api.c:1146
void rt_tri(SceneHandle voidscene, void *tex, apivector v0, apivector v1, apivector v2)
Define a flat-shaded triangle.
Definition: api.c:1224
static void PrintSyntaxError(parsehandle *ph, const char *string, const char *found)
Definition: parse.c:173
#define RT_SHADER_LOWEST
lowest quality shading available
Definition: tachyon.h:656
static errcode GetBox(parsehandle *ph, SceneHandle scene)
Definition: parse.c:1364
static errcode GetTexDef(parsehandle *ph, SceneHandle scene)
Definition: parse.c:768
flt x
X coordinate or direction component.
Definition: tachyon.h:54
void * rt_directional_light(SceneHandle voidscene, void *tex, apivector dir)
Define a directional light with associated texture and direction.
Definition: api.c:1077
void rt_clip_fv(SceneHandle voidscene, int numplanes, const float *planes)
Enable or update a clipping plane group.
Definition: api.c:1433
#define RT_PROJECTION_PERSPECTIVE
Perspective projection mode.
Definition: tachyon.h:500
void rt_camera_projection(SceneHandle voidscene, int mode)
Set camera projection mode.
Definition: api.c:251
flt apiflt
for backward compatibility
Definition: tachyon.h:49
#define RT_AO_MAXDIST_UNLIMITED
unlimited AO distaned macro
Definition: tachyon.h:737
flt y
Y coordinate or direction component.
Definition: tachyon.h:55
#define PARSEBADSUBFILE
Definition: ac3dparse.h:13
#define RT_TEXTURE_SPHERICAL_IMAGE
spherical image map
Definition: tachyon.h:610
#define PARSEBADSYNTAX
Definition: ac3dparse.h:14
apivector scale
scale of texture in x,y,z
Definition: tachyon.h:75
static void Scale3d(apivector *scale, apivector *vec)
Definition: parse.c:161
static errcode GetVertexArray(parsehandle *ph, SceneHandle scene)
Definition: parse.c:1584
void rt_tex_transmode(void *voidtex, int transmode)
Set transparent surface shading parameters for an existing texture, enabling or disabling angle-modul...
Definition: api.c:1002
void rt_fcylinder(SceneHandle scene, void *tex, apivector ctr, apivector axis, flt rad)
Define a finite-length cylinder.
Definition: api.c:1173
static void degvectoradvec(apivector *degvec)
Definition: parse.c:130
void rt_outputfile(SceneHandle voidscene, const char *outname)
Set the filename for the output image for the specified scene.
Definition: api.c:350
apivector uaxs
planar map u axis
Definition: tachyon.h:76
static errcode GetImageDef(parsehandle *ph, SceneHandle scene)
Definition: parse.c:686
#define MGF_NOERR
Definition: mgfparse.h:11
void * GetTexBody(parsehandle *ph, SceneHandle scene, int modeflag)
Definition: parse.c:803
#define PARSEEOF
Definition: ac3dparse.h:15
static errcode GetLight(parsehandle *ph, SceneHandle scene)
Definition: parse.c:996
#define ERROR_READBUF_SIZE
Definition: parse.c:27
static errcode GetClipGroup(parsehandle *ph, SceneHandle scene)
Definition: parse.c:1915
static int stringcmp(const char *a, const char *b)
Definition: parse.c:32
static void InitRot3d(RotMat *rot, apiflt x, apiflt y, apiflt z)
Definition: parse.c:139
static errcode GetFog(parsehandle *ph, SceneHandle scene)
Definition: parse.c:1133
void * SceneHandle
Definition: tachyon.h:51
void rt_camera_dof(SceneHandle voidscene, flt focaldist, flt aperture)
Set depth-of-field rendering options.
Definition: api.c:361
void rt_stri(SceneHandle voidscene, void *tex, apivector v0, apivector v1, apivector v2, apivector n0, apivector n1, apivector n2)
Define a smooth-shaded triangle using interpolated vertex normals.
Definition: api.c:1252
int texturefunc
which texture function to use
Definition: tachyon.h:66
apivector rt_vector(flt x, flt y, flt z)
Helper function to make vectors.
Definition: api.c:159
static errcode GetSTri(parsehandle *ph, SceneHandle scene)
Definition: parse.c:1423
flt ambient
ambient lighting
Definition: tachyon.h:69
apivector vaxs
planar map v axis
Definition: tachyon.h:77
static errcode GetShaderMode(parsehandle *ph, SceneHandle scene)
Definition: parse.c:334
static errcode GetTri(parsehandle *ph, SceneHandle scene)
Definition: parse.c:1402
void rt_background(SceneHandle voidscene, apicolor col)
Set the background color of the specified scene.
Definition: api.c:490
void rt_clip_off(SceneHandle voidscene)
Disable active clipping plane group.
Definition: api.c:1483
void rt_camera_frustum(SceneHandle voidscene, flt left, flt right, flt bottom, flt top)
Set view frustum for active camera.
Definition: api.c:345
#define RT_PHONG_PLASTIC
Dielectric Phong highlight.
Definition: tachyon.h:684
void * rt_texture_copy_vcstri(SceneHandle sc, void *oldvoidtex)
Do not use this unless you know what you&#39;re doing, this is a short-term workaround until new object t...
Definition: api.c:973
int rt_hash_insert(rt_hash_t *tptr, const char *key, int data)
Definition: hash.c:144
#define RT_SHADER_MEDIUM
Medium quality shading.
Definition: tachyon.h:658
#define RT_BACKGROUND_TEXTURE_SKY_ORTHO_PLANE
gradient bg, ortho
Definition: tachyon.h:388
static errcode GetPolyCylinder(parsehandle *ph, SceneHandle scene)
Definition: parse.c:1275
#define RT_FOG_EXP2
exponential-squared fog
Definition: tachyon.h:443
#define RT_TEXTURE_GRADIENT
gradient noise procedural texture
Definition: tachyon.h:607
static errcode GetColor(parsehandle *ph, apicolor *c1)
Definition: parse.c:673
float b
Blue color component.
Definition: tachyon.h:62
void rt_define_teximage_rgb24(const char *name, int xs, int ys, int zs, unsigned char *rgb)
Define a named 1-D, 2-D, or 3-D texture image with a 24-bit RGB image buffer, without any file refere...
Definition: api.c:951
static errcode GetClipGroupEnd(parsehandle *ph, SceneHandle scene)
Definition: parse.c:1946
static void free_tex_table(parsehandle *ph, SceneHandle scene)
Definition: parse.c:70
void rt_tex_phong(void *voidtex, flt phong, flt phongexp, int type)
Set Phong shading parameters for an existing texture.
Definition: api.c:994
#define RT_FOG_NONE
no fog
Definition: tachyon.h:440
#define RT_FOG_EXP
exponential fog
Definition: tachyon.h:442
#define RT_PROJECTION_PERSPECTIVE_DOF
Perspective projection mode.
Definition: tachyon.h:502
static void Rotate3d(RotMat *rot, apivector *vec)
Definition: parse.c:153
void rt_polycylinder(SceneHandle scene, void *tex, apivector *points, int numpts, flt rad)
Define a sequence of connected cylinders.
Definition: apigeom.c:20
void rt_plane(SceneHandle scene, void *tex, apivector ctr, apivector norm)
Define a plane.
Definition: api.c:1186
void rt_ring(SceneHandle scene, void *tex, apivector ctr, apivector norm, flt inner, flt outer)
Define an annular ring.
Definition: api.c:1199
void rt_background_mode(SceneHandle voidscene, int mode)
Set the background texturing mode to use.
Definition: api.c:544
#define RT_PROJECTION_ORTHOGRAPHIC
Orthographic projection mode.
Definition: tachyon.h:501
void rt_tex_outline(void *voidtex, flt outline, flt outlinewidth)
Set edge cueing outline shading parameters for an existing texture.
Definition: api.c:1008
Tachyon public API function prototypes and declarations used to drive the ray tracing engine...
apivector waxs
volume map W axis
Definition: tachyon.h:78
int rt_hash_lookup(rt_hash_t *tptr, const char *key)
Definition: hash.c:119
static errcode GetDirLight(parsehandle *ph, SceneHandle scene)
Definition: parse.c:971
void rt_cylinder(SceneHandle scene, void *tex, apivector ctr, apivector axis, flt rad)
Define an infinite cylinder.
Definition: api.c:1160
static errcode GetRing(parsehandle *ph, SceneHandle scene)
Definition: parse.c:1380
static errcode GetTPolyFile(parsehandle *ph, SceneHandle scene)
Definition: parse.c:1846
static void reset_tex_table(parsehandle *ph, SceneHandle scene)
Definition: parse.c:49
void * rt_light(SceneHandle voidscene, void *tex, apivector ctr, flt rad)
Define a point light with associated texture, position, and radius.
Definition: api.c:1049
flt z
Z coordinate or direction component.
Definition: tachyon.h:56
#define RT_TEXTURE_PLANAR_IMAGE
planar image map
Definition: tachyon.h:611
#define RT_PHONG_METAL
Metallic Phong highlight.
Definition: tachyon.h:685
void rt_verbose(SceneHandle voidscene, int v)
Enables or Disables verbose messages from the Tachyon library during rendering.
Definition: api.c:414
#define PARSEBADFILE
Definition: ac3dparse.h:12
void rt_vcstri(SceneHandle voidscene, void *tex, apivector v0, apivector v1, apivector v2, apivector n0, apivector n1, apivector n2, apicolor c0, apicolor c1, apicolor c2)
Define a smooth-shaded triangle using interpolated vertex normals and per-vertex colors.
Definition: api.c:1288
static errcode GetString(parsehandle *ph, const char *string)
Definition: parse.c:213
#define RT_TEXTURE_CYLINDRICAL_CHECKER
cylindrical checkerboard
Definition: tachyon.h:608
void rt_shadow_filtering(SceneHandle voidscene, int onoff)
Control whether or not transparent surfaces modulate incident light or not.
Definition: api.c:219