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