Tachyon (current)  Current Main Branch
mgfparse.c
Go to the documentation of this file.
1 /*
2  * mgfparse.c - parser for Radiance MGF (materials and geometry format) files
3  *
4  * (C) Copyright 1994-2022 John E. Stone
5  * SPDX-License-Identifier: BSD-3-Clause
6  *
7  * $Id: mgfparse.c,v 1.15 2022/02/18 18:18:36 johns Exp $
8  *
9  */
10 
11 #ifdef USELIBMGF
12 
13 #include <stdio.h>
14 #include <math.h>
15 #include <string.h>
16 #include <stdlib.h>
17 #include "tachyon.h" /* Ray Tracer API */
18 #include "parser.h" /* MGF parser library */
19 #include "mgfparse.h" /* self proto */
20 
21 static void * globtex = NULL;
22 static SceneHandle globscene = NULL;
23 
24 int put_material(void);
25 int mgf2rgb(C_COLOR *cin, double intensity, float cout[3]);
26 
27 char tabs[] = " ";
28 
29 #define curmatname (c_cmname == NULL ? "mat" : c_cmname)
30 
31 /*
32  * Convert MGF color to RGB representation defined below.
33  */
34  /* Change the following to suit your standard */
35 #define CIE_x_r 0.640 /* nominal CRT primaries */
36 #define CIE_y_r 0.330
37 #define CIE_x_g 0.290
38 #define CIE_y_g 0.600
39 #define CIE_x_b 0.150
40 #define CIE_y_b 0.060
41 #define CIE_x_w 0.3333 /* use true white */
42 #define CIE_y_w 0.3333
43 
44 #define CIE_C_rD ( (1./CIE_y_w) * \
45  ( CIE_x_w*(CIE_y_g - CIE_y_b) - \
46  CIE_y_w*(CIE_x_g - CIE_x_b) + \
47  CIE_x_g*CIE_y_b - CIE_x_b*CIE_y_g ) )
48 #define CIE_C_gD ( (1./CIE_y_w) * \
49  ( CIE_x_w*(CIE_y_b - CIE_y_r) - \
50  CIE_y_w*(CIE_x_b - CIE_x_r) - \
51  CIE_x_r*CIE_y_b + CIE_x_b*CIE_y_r ) )
52 #define CIE_C_bD ( (1./CIE_y_w) * \
53  ( CIE_x_w*(CIE_y_r - CIE_y_g) - \
54  CIE_y_w*(CIE_x_r - CIE_x_g) + \
55  CIE_x_r*CIE_y_g - CIE_x_g*CIE_y_r ) )
56 
57 
58 static float xyz2rgbmat[3][3] = { /* XYZ to RGB conversion matrix */
59  {(CIE_y_g - CIE_y_b - CIE_x_b*CIE_y_g + CIE_y_b*CIE_x_g)/CIE_C_rD,
60  (CIE_x_b - CIE_x_g - CIE_x_b*CIE_y_g + CIE_x_g*CIE_y_b)/CIE_C_rD,
61  (CIE_x_g*CIE_y_b - CIE_x_b*CIE_y_g)/CIE_C_rD},
62  {(CIE_y_b - CIE_y_r - CIE_y_b*CIE_x_r + CIE_y_r*CIE_x_b)/CIE_C_gD,
63  (CIE_x_r - CIE_x_b - CIE_x_r*CIE_y_b + CIE_x_b*CIE_y_r)/CIE_C_gD,
64  (CIE_x_b*CIE_y_r - CIE_x_r*CIE_y_b)/CIE_C_gD},
65  {(CIE_y_r - CIE_y_g - CIE_y_r*CIE_x_g + CIE_y_g*CIE_x_r)/CIE_C_bD,
66  (CIE_x_g - CIE_x_r - CIE_x_g*CIE_y_r + CIE_x_r*CIE_y_g)/CIE_C_bD,
67  (CIE_x_r*CIE_y_g - CIE_x_g*CIE_y_r)/CIE_C_bD}
68 };
69 
70 
71 /* mgf2rgb() - convert MGF color to RGB */
72 /* cin - input MGF chrominance */
73 /* intensity - input luminance or reflectance */
74 /* cout - output RGB color */
75 int mgf2rgb(C_COLOR *cin, double intensity, float cout[3]) {
76  static double cie[3]; /* get CIE XYZ representation */
77  c_ccvt(cin, C_CSXY);
78  cie[0] = intensity*cin->cx/cin->cy;
79  cie[1] = intensity;
80  cie[2] = intensity*(1./cin->cy - 1.) - cie[0];
81  /* convert to RGB */
82  cout[0] = xyz2rgbmat[0][0]*cie[0] + xyz2rgbmat[0][1]*cie[1]
83  + xyz2rgbmat[0][2]*cie[2];
84  if(cout[0] < 0.) cout[0] = 0.;
85  cout[1] = xyz2rgbmat[1][0]*cie[0] + xyz2rgbmat[1][1]*cie[1]
86  + xyz2rgbmat[1][2]*cie[2];
87  if(cout[1] < 0.) cout[1] = 0.;
88  cout[2] = xyz2rgbmat[2][0]*cie[0] + xyz2rgbmat[2][1]*cie[1]
89  + xyz2rgbmat[2][2]*cie[2];
90  if(cout[2] < 0.) cout[2] = 0.;
91 
92  return MG_OK;
93 }
94 
95 int put_material(void) {
96  float rgbval[3];
97  apitexture tex;
98 #if 0
99  char *mname = curmatname;
100 
101  if (!c_cmaterial->clock) { /* current, just use it */
102  printf("USE %s\n", mname);
103  }
104  else {
105  printf("%sDEF %s Group {\n", tabs, mname);
106  }
107  printf("%sMaterial {\n", tabs);
108 #endif
109 
110  memset(&tex, 0, sizeof(tex));
111 
112  mgf2rgb(&c_cmaterial->rd_c, 1.0, rgbval);
113  tex.col = rt_color(rgbval[0], rgbval[1], rgbval[2]);
114  tex.ambient = 0.1;
115  tex.diffuse = c_cmaterial->rd;
116  tex.opacity = 1.0 - (c_cmaterial->td + c_cmaterial->ts);
117  tex.texturefunc = 0;
118 
119  if (c_cmaterial->ed > FTINY) {
120  mgf2rgb(&c_cmaterial->ed_c, 1.0, rgbval);
121  tex.col = rt_color(rgbval[0], rgbval[1], rgbval[2]);
122  tex.ambient = c_cmaterial->ed;
123 
124  if (tex.ambient > 1.0)
125  tex.ambient = 1.0;
126  if (tex.ambient < 0.1)
127  tex.ambient = 0.1;
128  }
129 
130  globtex = rt_texture(globscene, &tex); /* XXX memory leak city, */
131  /* we aren't keeping track of these... */
132 
133  if (c_cmaterial->rs > 0.0) {
134  tex.specular = c_cmaterial->rs - (c_cmaterial->rs_a / 2.0);
135  if (tex.specular < 0.0) tex.specular = 0.0;
136 
137  if (c_cmaterial->rs_a > 0.09) {
138  flt pexp, pval ;
139  pval = c_cmaterial->rs * 4;
140  pval = 0.8; /* XXX hack */
141  pexp = 12.0 / c_cmaterial->rs_a;
142  rt_tex_phong(globtex, pval, pexp, RT_PHONG_PLASTIC);
143  }
144  }
145 
146  c_cmaterial->clock = 0;
147 
148  return MG_OK;
149 }
150 
151 
152 static int myfaceh(int ac, char **av) { /* face handling routine */
153  static char lastmat[256];
154  C_VERTEX *vp; /* vertex structure pointer */
155  FVECT vert; /* vertex point location */
156  FVECT normal; /* vertex point location */
157  int i;
158  apivector v0, v1, v2;
159  apivector n0, n1, n2;
160  if (ac < 4) /* check # arguments */
161  return(MG_EARGC);
162 
163  if (strcmp(lastmat, curmatname) || c_cmaterial->clock) {
164  put_material();
165  strcpy(lastmat, curmatname);
166  }
167 
168  if ((vp = c_getvert(av[1])) == NULL) /* vertex from name */
169  return(MG_EUNDEF);
170  xf_xfmpoint(vert, vp->p); /* transform vertex */
171  v0 = rt_vector(vert[0], vert[1], vert[2]);
172  xf_rotvect(normal, vp->n); /* transform normal */
173  n0 = rt_vector(normal[0], normal[1], normal[2]);
174 
175  if ((vp = c_getvert(av[2])) == NULL) /* vertex from name */
176  return(MG_EUNDEF);
177  xf_xfmpoint(vert, vp->p); /* transform vertex */
178  v1 = rt_vector(vert[0], vert[1], vert[2]);
179  xf_rotvect(normal, vp->n); /* transform normal */
180  n1 = rt_vector(normal[0], normal[1], normal[2]);
181 
182  for (i = 3; i < ac; i++) {
183  if ((vp = c_getvert(av[i])) == NULL) /* vertex from name */
184  return(MG_EUNDEF);
185  xf_xfmpoint(vert, vp->p); /* transform vertex */
186  v2 = rt_vector(vert[0], vert[1], vert[2]);
187  xf_rotvect(normal, vp->n); /* transform normal */
188  n2 = rt_vector(normal[0], normal[1], normal[2]);
189 
190  if (((n0.x*n0.x + n0.y*n0.y + n0.z*n0.z) < 0.9) ||
191  ((n1.x*n1.x + n1.y*n1.y + n1.z*n1.z) < 0.9) ||
192  ((n2.x*n2.x + n2.y*n2.y + n2.z*n2.z) < 0.9)) {
193  rt_tri(globscene, globtex, v0, v1, v2);
194  } else {
195  rt_stri(globscene, globtex, v0, v1, v2, n0, n1, n2);
196  }
197 
198  v1 = v2;
199  n1 = n2;
200  }
201 
202  return(MG_OK); /* normal exit */
203 }
204 
205 static void DefaultTex(SceneHandle scene) {
206  apitexture apitex;
207 
208  apitex.col.r=1.0;
209  apitex.col.g=1.0;
210  apitex.col.b=1.0;
211  apitex.ambient=0.1;
212  apitex.diffuse=0.9;
213  apitex.specular=0.0;
214  apitex.opacity=1.0;
215  apitex.texturefunc=0;
216 
217  globtex = rt_texture(globscene, &apitex);
218 }
219 
220 
221 static void DefaultLight(SceneHandle scene) {
222  /* lighting hack */
223  apivector ctr;
224  apitexture tex;
225 
226  memset(&tex, 0, sizeof(apitexture));
227 
228  tex.col.r = 1.0;
229  tex.col.g = 1.0;
230  tex.col.b = 1.0;
231  ctr.x = 1000.0;
232  ctr.y = 1000.0;
233  ctr.z = -1000.0;
234 
235  rt_light(scene, rt_texture(globscene, &tex), ctr, 1.0);
236 }
237 
238 static void DefaultScene(char *mgfname, SceneHandle scene) {
239  FILE * ifp;
240  char fname[1024];
241  float x, y, z, zoom, len;
242  apivector vp, vd, vup;
243 
244  strcpy(fname, mgfname);
245  strcat(fname, ".scn");
246  if ((ifp = fopen(fname, "r")) == NULL) {
247  printf("No scene settings file found, using defaults\n");
248  return;
249  }
250  printf("Reading default scene parameters from %s\n", fname);
251 
252  zoom = 1.0;
253  fscanf(ifp, "%f", &zoom);
254 
255  fscanf(ifp, "%f %f %f", &x, &y, &z);
256  vp = rt_vector(x, y, z);
257 
258  fscanf(ifp, "%f %f %f", &x, &y, &z);
259  len = sqrt(x*x + y*y + z*z);
260  vd = rt_vector(x/len, y/len, z/len);
261 
262  fscanf(ifp, "%f %f %f", &x, &y, &z);
263  vup = rt_vector(x, y, z);
264 
265  rt_camera_setup(scene, zoom, 1.0, 0, 6, vp, vd, vup);
266 
267  fclose(ifp);
268 }
269 
270 unsigned int ParseMGF(char *mgfname, SceneHandle scene, int defaultflag) {
271  DefaultTex(scene); /* hack, paranoia */
272 
273  globscene = scene;
274 
275  if (defaultflag == 1) {
276  DefaultLight(scene); /* hack */
277  DefaultScene(mgfname, scene); /* hack */
278  }
279 
280  printf("MGF: loading %s\n", mgfname);
281 
282  /* initialize dispatch table */
283  mg_ehand[MG_E_FACE] = myfaceh; /* we do faces */
284  mg_ehand[MG_E_VERTEX] = c_hvertex; /* parser lib */
285  mg_ehand[MG_E_POINT] = c_hvertex; /* parser lib */
286  mg_ehand[MG_E_NORMAL] = c_hvertex; /* parser lib */
287  mg_ehand[MG_E_XF] = xf_handler; /* parser lib */
288 
289  /* lighting and coloring handling */
290  mg_ehand[MG_E_COLOR] = c_hcolor; /* they get color */
291  mg_ehand[MG_E_CMIX] = c_hcolor; /* they mix colors */
292  mg_ehand[MG_E_CSPEC] = c_hcolor; /* they get spectra */
293  mg_ehand[MG_E_CXY] = c_hcolor; /* they get chromaticities */
294  mg_ehand[MG_E_CCT] = c_hcolor; /* they get color temp's */
295  mg_ehand[MG_E_ED] = c_hmaterial; /* they get emission */
296  mg_ehand[MG_E_MATERIAL] = c_hmaterial; /* they get materials */
297  mg_ehand[MG_E_RD] = c_hmaterial; /* they get diffuse refl. */
298  mg_ehand[MG_E_RS] = c_hmaterial; /* they get specular refl. */
299  mg_ehand[MG_E_SIDES] = c_hmaterial; /* they get # sides */
300  mg_ehand[MG_E_TD] = c_hmaterial; /* they get diffuse trans. */
301  mg_ehand[MG_E_TS] = c_hmaterial; /* they get specular trans. */
302 
303  mg_init(); /* initialize parser */
304  if (mg_load(mgfname) != MG_OK) /* and check for error */
305  return MGF_BADSYNTAX;
306 
307  return MGF_NOERR;
308 }
309 
310 #endif
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
float r
Red color component.
Definition: tachyon.h:60
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
apicolor col
base object color
Definition: tachyon.h:67
#define MGF_BADSYNTAX
Definition: mgfparse.h:13
flt diffuse
diffuse reflection
Definition: tachyon.h:70
flt opacity
how opaque the object is
Definition: tachyon.h:72
flt specular
specular reflection
Definition: tachyon.h:71
apicolor rt_color(flt r, flt g, flt b)
Helper function to make colors.
Definition: api.c:169
unsigned int ParseMGF(char *mgfname, SceneHandle scene, int defaultflag)
double flt
generic floating point number, using double
Definition: tachyon.h:47
void rt_tri(SceneHandle voidscene, void *tex, apivector v0, apivector v1, apivector v2)
Define a flat-shaded triangle.
Definition: api.c:1224
flt x
X coordinate or direction component.
Definition: tachyon.h:54
flt y
Y coordinate or direction component.
Definition: tachyon.h:55
#define MGF_NOERR
Definition: mgfparse.h:11
void * SceneHandle
Definition: tachyon.h:51
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
flt ambient
ambient lighting
Definition: tachyon.h:69
#define RT_PHONG_PLASTIC
Dielectric Phong highlight.
Definition: tachyon.h:684
float b
Blue color component.
Definition: tachyon.h:62
void rt_tex_phong(void *voidtex, flt phong, flt phongexp, int type)
Set Phong shading parameters for an existing texture.
Definition: api.c:994
Tachyon public API function prototypes and declarations used to drive the ray tracing engine...
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