Main Page Class Hierarchy Compound List File List Compound Members File Members

ParseSC.cc

Go to the documentation of this file.
00001 /*
00002 File: ParseSC.cc
00003 
00004 Purpose: Parses Paul's .sc format
00005 
00006 Author: Mainly uses code from Paul Heckbert & John Murphy.
00007 */
00008 
00009 #include "gcl/GCLConfig.h"
00010 
00011 #ifdef GCL_PARSE_SC
00012 
00013 #include <stdlib.h>
00014 #include <string.h>
00015 #include <ctype.h>
00016 #include <stdio.h>
00017 
00018 #include "gcl/SceneLang.h"
00019 
00020 
00022 static int lc; // current line number in scene file
00023 
00024 // read whatever is left on a line (for comments)
00025 Void fread_to_eol(FILE *fp) {
00026 char c;
00027 do c = getc(fp); while (c!='\n');
00028 do {c = getc(fp); lc++;} while (c=='\n');
00029 if (!feof(fp)) ungetc(c, fp);
00030 }
00031 
00032 // Chomp away white space, but keep track of the newlines
00033 Void eatspace(FILE *fp) {
00034 char c;
00035 do {
00036 c = getc(fp);
00037 if (c=='#') {c = ' '; fread_to_eol(fp);}
00038 if (c=='\n') lc++;
00039 if (feof(fp)) return;
00040 } while (isspace(c));
00041 ungetc(c, fp);
00042 }
00043 
00044 // read the next string from the file, returns ptr to static
00045 char *fread_word(FILE *fp) {
00046 static char word[80]; // sets maximum word length
00047 eatspace(fp);
00048 int test = fscanf(fp, "%s", word);
00049 if (test==EOF) strcpy(word, "end");
00050 else if (test!=1) {
00051 cerr << "Scene Error, line " << lc
00052 << ": scanf returned " << test << endl;
00053 exit(1);
00054 }
00055 return word;
00056 }
00057 
00058 // read the next number from the file
00059 double fread_number(FILE *fp) {
00060 eatspace(fp);
00061 double number;
00062 int test = fscanf(fp, "%lf", &number);
00063 if (test!=1) {
00064 cerr << "Scene Error, line " << lc
00065 << ": scanf returned " << test << endl;
00066 exit(1);
00067 }
00068 return number;
00069 }
00070 
00071 Vector fread_Vector(FILE *fp)
00072 {
00073 double x = fread_number(fp);
00074 double y = fread_number(fp);
00075 double z = fread_number(fp);
00076 return(Vector(x, y, z));
00077 }
00078 
00079 Colour fread_Colour(FILE *fp)
00080 {
00081 double x = fread_number(fp);
00082 double y = fread_number(fp);
00083 double z = fread_number(fp);
00084 return(Colour(x, y, z));
00085 }
00086 
00087 // parse a scene file
00088 // add to existing scene
00089 
00090 scScenePtr ParseSCFile(const Char *filename)
00091 {
00092 FILE *fp;
00093 scScenePtr result;
00094 
00095 if ((fp = fopen(filename, "r")) == NULL)
00096 {
00097 cerr << "Cannot access " << filename << endl;
00098 return(0);
00099 }
00100 
00101 result = slBeginObject(filename);
00102 slCamera();
00103 
00104 Bool bad;
00105 lc = 1;
00106 char *word = NULL;
00107 
00108 for (;;) {
00109 if (feof(fp)) strcpy(word, "end");
00110 else word = fread_word(fp);
00111 bad = false;
00112 
00113 switch (word[0]) {
00114 case '#': // comment
00115 fread_to_eol(fp);
00116 break;
00117 
00118 case '/': // comment
00119 fread_to_eol(fp);
00120 break;
00121 
00122 case 'a':
00123 if (!strcmp(word, "ambient")) {
00124 // ambient = fread_Vector(fp);
00125 // ambient *= fread_number(fp);
00126 fread_Vector(fp);
00127 fread_number(fp);
00128 }
00129 else bad = true;
00130 break;
00131 case 'b':
00132 if (!strcmp(word, "background")) {
00133 // background = fread_Vector(fp);
00134 // background *= fread_number(fp);
00135 fread_Vector(fp);
00136 fread_number(fp);
00137 }
00138 else bad = true;
00139 break;
00140 case 'd':
00141 if (!strcmp(word, "diffuse")) {
00142 /*
00143 cur_material().color = fread_Vector(fp);
00144 cur_material().kdiffrefl = fread_number(fp);
00145 cur_material().kspecrefl = 0.;
00146 cur_material().kspectran = 0.;
00147 cur_material().exponent = 0.;
00148 cur_material().indexrefr = 1.;
00149 cur_material().kemission = 0.;
00150 new_material = true;
00151 */
00152 Colour c = fread_Colour(fp);
00153 slColour(c * fread_number(fp));
00154 
00155 }
00156 else if (!strcmp(word, "diffspec")) {
00157 /*
00158 cur_material().color = fread_Vector(fp);
00159 cur_material().kdiffrefl = fread_number(fp);
00160 cur_material().kspecrefl = fread_number(fp);
00161 cur_material().kspectran = fread_number(fp);
00162 cur_material().exponent = fread_number(fp);
00163 cur_material().indexrefr = fread_number(fp);
00164 cur_material().kemission = 0.;
00165 new_material = true;
00166 */
00167 Colour c = fread_Colour(fp);
00168 slColour(c * fread_number(fp));
00169 
00170 fread_number(fp);
00171 fread_number(fp);
00172 fread_number(fp);
00173 fread_number(fp);
00174 }
00175 else bad = true;
00176 break;
00177 case 'e':
00178 if (!strcmp(word, "emissive")) {
00179 /*
00180 cur_material().color = fread_Vector(fp);
00181 cur_material().kdiffrefl = 0.;
00182 cur_material().kspecrefl = 0.;
00183 cur_material().kspectran = 0.;
00184 cur_material().exponent = 0.;
00185 cur_material().indexrefr = 1.;
00186 cur_material().kemission = fread_number(fp);
00187 new_material = true;
00188 */
00189 Colour c = fread_Colour(fp);
00190 slEmittance(c * fread_number(fp));
00191 
00192 }
00193 else if (!strcmp(word, "end")) {
00194 cout << "Completed reading the scene\n";
00195 fclose(fp);
00196 slEndObject();
00197 return(result);
00198 }
00199 else bad = true;
00200 break;
00201 case 'g':
00202 if (!strcmp(word, "gpop")) {
00203 
00204 /* if (!gstack.first()->next()) {
00205 cerr << "Scene Error, line " << lc
00206 << ": Can't pop top level gstate" << endl;
00207 exit(1);
00208 }
00209 gstack.pop();
00210 cout << "popped stack" << endl;
00211 cout << gstack.first();
00212 */
00213 slEndObject();
00214 
00215 }
00216 else if (!strcmp(word, "gpush")) {
00217 
00218 /* gstack.dup();
00219 // dup() copies the material structure, light list
00220 // header, and matrix stack headers.
00221 // At this point, cur_matrix() points to the same
00222 // matrix as before the dup().
00223 
00224 // Set up matrix stack in new Gstate so that it contains a
00225 // copy of current matrix, and nothing else.
00226 // That way, if someone does too many pops, they'll get
00227 // an error message.
00228 // (push and pop must be nested within gpush, gpop)
00229 Matrix_item *m = new Matrix_item(*cur_matrix());
00230 gstack.first()->matrix_stack.init();
00231 gstack.first()->matrix_stack.push(*m);
00232 */
00233 
00234 slBeginObject("bob");
00235 
00236 }
00237 else bad = true;
00238 break;
00239 case 'l':
00240 if (!strcmp(word, "lookat")) {
00241 Vec3d from = fread_Vector(fp);
00242 Vec3d to = fread_Vector(fp);
00243 Vec3d up = fread_Vector(fp);
00244 Vec3d vec = to-from;
00245 
00246 if (up[2] > 0)
00247 slTransform(Rotation(vl_x, -vl_pi / 2.0));
00248 else if (up[1] > 0)
00249 slTransform(Rotation(vl_z, vl_pi / 2.0));
00250 
00251 /* double alpha;
00252 if (vec[1]!=0 || vec[2]!=0) alpha = atan2(-vec[1], -vec[2]);
00253 else alpha = 0.;
00254 double beta
00255 = atan2(vec[0], sqrt(vec[1]*vec[1] + vec[2]*vec[2]));
00256 Matrix rm;
00257 rm.MakeUnit(); // identity
00258 rm.rotate('x', -alpha);
00259 rm.rotate('y', -beta);
00260 
00261 double gamma
00262 = atan2(up[0]*rm[0][0]+up[1]*rm[1][0]+up[2]*rm[2][0],
00263 up[0]*rm[0][1]+up[1]*rm[1][1]+up[2]*rm[2][1]);
00264 cur_matrix()->rotate('z', gamma);
00265 cur_matrix()->rotate('y', beta);
00266 cur_matrix()->rotate('x', alpha);
00267 cur_matrix()->translate(-from[0], -from[1], -from[2]);
00268 */
00269 
00270 
00271 }
00272 else bad = true;
00273 break;
00274 case 'p':
00275 if (!strcmp(word, "persp")) {
00276 fread_number(fp);
00277 fread_number(fp);
00278 }
00279 else if (!strcmp(word, "pointlight")) {
00280 // Light_item *light = new Light_item;
00281 Vec3d pos = fread_Vector(fp);
00282 /* light->position = transform33(*cur_matrix(), pos);
00283 light->color = fread_Vector(fp);
00284 light->color *= fread_number(fp);
00285 cur_lights().append(*light);
00286 */
00287 fread_Vector(fp);
00288 fread_number(fp);
00289 }
00290 else if (!strcmp(word, "poly3") || !strcmp(word, "poly2")) {
00291 int poly3 = !strcmp(word, "poly3");
00292 int nvert = (int)fread_number(fp);
00293 
00294 if (nvert<3) {
00295 cerr << "Scene Error, line " << lc
00296 << ": poly needs >=3 vertices." << endl;
00297 exit(1);
00298 }
00299 // Polygon *p = new Polygon;
00300 Vec3d point;
00301 int i;
00302 
00303 slPointList();
00304 
00305 for (i=0; i<nvert; i++) {
00306 point[0] = fread_number(fp);
00307 point[1] = fread_number(fp);
00308 if (poly3) point[2] = fread_number(fp);
00309 else point[2] = 0.;
00310 // point = transform33(*cur_matrix(), point);
00311 // p->append_vertex(point);
00312 
00313 slPoint(point);
00314 }
00315 slPoly();
00316 
00317 // p->precompute(); // set plane & edge equations
00318 // append_prim(*p);
00319 }
00320 else if (!strcmp(word, "pop")) {
00321 /* if (!cur_matrix()->next()) {
00322 cerr << "Scene Error, line " << lc
00323 << ": Attempt to pop last matrix on stack" << endl;
00324 exit(1);
00325 }
00326 gstack.first()->matrix_stack.pop();
00327 */
00328 
00329 slEndObject();
00330 }
00331 else if (!strcmp(word, "push")) {
00332 // gstack.first()->matrix_stack.dup();
00333 slBeginObject("bob");
00334 }
00335 else bad = true;
00336 break;
00337 case 'r':
00338 if (!strcmp(word, "rotate")) {
00339 char *axis = fread_word(fp);
00340 double angle = fread_number(fp);
00341 if (!axis[1] && (axis[0]=='x' || axis[0]=='y' || axis[0]=='z'))
00342 // cur_matrix()->rotate(axis[0], angle*M_PI/180.);
00343 slTransform(Rotation(vl_axis(axis[0] - 'x'), DegsToRads(angle)));
00344 else {
00345 cerr << "Scene Error, line " << lc
00346 << ": Illegal rotate axis (" << axis << ")" << endl;
00347 exit(1);
00348 }
00349 }
00350 else if (!strcmp(word, "rotgen")) {
00351 Vec3d v = fread_Vector(fp);
00352 double angle = fread_number(fp);
00353 slTransform(Rotation(v, DegsToRads(angle)));
00354 }
00355 else bad = true;
00356 break;
00357 case 's':
00358 if (!strcmp(word, "scale")) {
00359 double sx, sy, sz;
00360 sx = fread_number(fp);
00361 sy = fread_number(fp);
00362 sz = fread_number(fp);
00363 slTransform(Scale(Vector(sx, sy, sz)));
00364 }
00365 else if (!strcmp(word, "screensize")) {
00366 /*
00367 double dscale = (double)scale / 100.0;
00368 double sx = dscale * fread_number(fp);
00369 double sy = dscale * fread_number(fp);
00370 double sz = dscale * fread_number(fp);
00371 width = (int)sx;
00372 height = (int)sy;
00373 cur_matrix()->scale(sx/2.0, -sy/2.0, sz/2);
00374 cur_matrix()->translate(1, -1, 0);
00375 */
00376 
00377 fread_number(fp);
00378 fread_number(fp);
00379 fread_number(fp);
00380 
00381 }
00382 else if (!strcmp(word, "sphere")) {
00383 Vec3d center = fread_Vector(fp);
00384 double radius = fread_number(fp);
00385 }
00386 else bad = true;
00387 break;
00388 case 't':
00389 if (!strcmp(word, "translate")) {
00390 double tx, ty, tz;
00391 tx = fread_number(fp);
00392 ty = fread_number(fp);
00393 tz = fread_number(fp);
00394 
00395 slTransform(Shift(Vector(tx, ty, tz)));
00396 }
00397 else bad = true;
00398 break;
00399 case 'w':
00400 if (!strcmp(word, "world_space")) {
00401 // currently, all matrices in matrix stacks transform to screen
00402 // space
00403 
00404 // save world-to-screen transform
00405 // world_to_screen = *cur_matrix();
00406 
00407 // Step through matrix stacks of all previous graphics states
00408 // and premultiply their matrices by screen_to_world space,
00409 // so that all matrices henceforth transform to world space.
00410 
00411 // We could just flush all previous graphics states and all
00412 // matrix stacks, but that is less elegant.
00413 // Doing it this way allows you to place geometry relative to
00414 // camera, and even in screen space.
00415 // Gstate_item *gs;
00416 // Matrix_item *m;
00417 // Matrix sw = inv(world_to_screen);
00418 // for (gs=gstack.first(); gs; gs=gs->next())
00419 // for (m=gs->matrix_stack.first(); m; m=m->next())
00420 // *m = sw * *m; // 4x4 matrix multiply
00421 
00422 // cur_matrix() is identity+roundoff at this point
00423 // cur_matrix()->MakeUnit(); // to eliminate the roundoff
00424 // (just being fussy)
00425 }
00426 else bad = true;
00427 break;
00428 case 'x':
00429 if (!strcmp(word, "xyzrange")) {
00430 // double xn, xf, yn, yf, zn, zf;
00431 /*xn =*/ fread_number(fp);
00432 /*xf =*/ fread_number(fp);
00433 /*yn =*/ fread_number(fp);
00434 /*yf =*/ fread_number(fp);
00435 /*zn =*/ fread_number(fp);
00436 /*zf =*/ fread_number(fp);
00437 // cur_matrix()->scale(2./(xf-xn), 2./(yf-yn), 2./(zf-zn));
00438 // cur_matrix()->translate((xf+xn)/-2., (yf+yn)/-2., (zf+zn)/-2.);
00439 }
00440 else bad = true;
00441 break;
00442 case 'z':
00443 if (!strcmp(word, "zrange")) {
00444 //double zn, zf;
00445 /*zn =*/ fread_number(fp);
00446 /*zf =*/ fread_number(fp);
00447 // cur_matrix()->translate(0., 0., (zf+zn)/(zf-zn));
00448 // cur_matrix()->scale(1., 1., -2./(1./zn-1./zf));
00449 }
00450 else bad = true;
00451 break;
00452 default:
00453 bad = true;
00454 break;
00455 }
00456 
00457 if (bad) {
00458 cerr << "Scene Error, line " << lc
00459 << ": bad keyword (" << word << ")." << endl;
00460 exit(1);
00461 }
00462 }
00463 }
00464 
00465 #endif

Generated at Sat Aug 5 00:17:01 2000 for Graphics Class Library by doxygen 1.1.0 written by Dimitri van Heesch, © 1997-2000

AltStyle によって変換されたページ (->オリジナル) /