00001 /* 00002 File: ParseMSDL.cc 00003 00004 Function: Parse Manchester Scene Description Language, using libmsdl.a 00005 00006 Author: Andrew Willmott 00007 00008 Notes: Adapted from the application.c file that comes with the msdl 00009 parser lib. 00010 00011 Most of the MSDL model files don't seem to have consistently 00012 oriented polygons, although their spec does mention that 00013 polygons should follow the right-hand orientation rule. Oh well. 00014 */ 00015 00016 #include "gcl/GCLConfig.h" 00017 #ifdef GCL_MSDL 00018 00019 #include <stdlib.h> 00020 // If I ruled the world, people who #define syscalls to be something else 00021 // would be hunted down like dogs and shot. be warned: msdl_macros.h 00022 // #defines free, which is why stdlib.h must be #included first. 00023 00024 extern "C" { 00025 #include "msdl_types.h" 00026 #include "msdl_macros.h" 00027 #include "msdl_protos.h" 00028 } 00029 #include "gcl/SceneLang.h" 00030 #include "gcl/VecUtil.h" 00031 00032 #ifdef DEBUG 00033 #define VERBOSE 00034 #endif 00035 00036 extern Void yyerror(char *errmess); 00037 00038 scScenePtr ParseMSDLFile(const Char *filename); 00039 00040 static Vec3d gUp; 00041 00042 Colour toColour(const Tspectra &c) 00043 { 00044 return(Colour(c.r, c.g, c.b)); 00045 } 00046 00047 Point toPoint(const Tpt3 &p) 00048 { 00049 return(Point(p.x, p.y, p.z)); 00050 } 00051 00052 scScenePtr ParseMSDLFile(const Char *filename) 00053 { 00054 scScenePtr result = slBeginObject((char*) filename); 00055 FILE *instream; 00056 00057 // msdl generally has ZUP instead of YUP, so correct... 00058 00059 slTransform(Rotation(vl_y, vl_pi) * Rotation(vl_x, -vl_halfPi)); 00060 00061 instream = fopen(filename, "r"); 00062 msdl(instream); 00063 00064 slEndObject(); 00065 00066 return(result); 00067 } 00068 00069 00070 Void HandleProps(Tobject *obj) 00071 { 00072 Colour c; 00073 00074 if (obj->sprops.flags & EMmask) 00075 slEmittance(toColour(obj->sprops.emission)); 00076 if (obj->sprops.flags & DRCmask) 00077 slColour(toColour(obj->sprops.drc)); 00078 } 00079 00080 00081 /***************************************************************************** 00082 * APPLICATION.c this file contains some functions written by me and some 00083 functions written by you. It recurses through the object list and when it 00084 comes to a composite object it calls create_comp(). Upon finishing the 00085 composite it calls end_comp(). If it comes to a simple low level 00086 object such as spere, box, polygon it will call a function 00087 ceate_spere( Tobject* ), create_polygon( Tobject* )... etc.... 00088 You must write these functions to do with teh objects what you want. 00089 If you are not bothered about composite objects just leave the create_comp() 00090 and end_comp() alone... 00091 00092 After the object routines are skeletons of lights and viewing functions. 00093 ***************************************************************************/ 00094 #include <stdio.h> 00095 #define _INCLUDE_XOPEN_SOURCE 00096 #include <math.h> 00097 #include "msdl_types.h" 00098 #include "msdl_protos.h" 00099 00100 /* Function prototype */ 00101 Void print_obj_info( Tobject * ); 00102 00103 00104 /* ************************************************************* */ 00105 /* Error handler */ 00106 00107 Void create_problem(char *probtext, int line_number) 00108 { 00109 fprintf(stderr,"MSDL ERROR : %s at line %d\n", 00110 probtext, line_number); 00111 exit(-1); 00112 } 00113 00114 00115 /***************************************************************************** 00116 **** ****** ******** ******** **** ******** ***** 00117 ** ** ** ** ** ** ** ** ** ** * 00118 ** ** ****** ** ***** ** ** **** 00119 ** ** ** ** * ** ** ** ** ** * ** 00120 **** ****** *** ******** **** ** ***** 00121 *****************************************************************************/ 00122 00123 /*===========================================================================*/ 00124 Void create_comp( Tobject* obj, Tmatrix acc_trans ) 00125 { 00126 #ifdef VERBOSE 00127 printf("Creating a composite\n"); 00128 printf("It's name is %s\n",obj->name ); 00129 #endif 00130 00131 slBeginObject(obj->name); 00132 00133 #ifdef CLEANUP 00134 free( obj ); 00135 #endif 00136 } 00137 /*---------------------------------------------------------------------------*/ 00138 00139 00140 /*===========================================================================*/ 00141 Void end_comp( Void ) 00142 { 00143 #ifdef VERBOSE 00144 printf("Ending composite\n"); 00145 #endif 00146 00147 slEndObject(); 00148 } 00149 /*---------------------------------------------------------------------------*/ 00150 00151 /*===========================================================================*/ 00152 00153 00154 Void create_triangle( Tobject* obj, Tmatrix acc_trans ) 00155 { 00156 #ifdef VERBOSE 00157 printf("Creating a triangle\n"); 00158 print_obj_info( obj ); 00159 printf(" It has %4d vertices \n",obj->spec.tri.vvnfn.no_verts ); 00160 printf(" It has %4d vertex normals \n",obj->spec.tri.vvnfn.no_vnorms ); 00161 printf(" It has %4d facet normals \n",obj->spec.tri.vvnfn.no_fnorms ); 00162 #endif 00163 00164 Int i; 00165 Point q; 00166 00167 Expect(obj->spec.tri.vvnfn.no_verts == 3, "bogus triangle"); 00168 HandleProps(obj); 00169 slPointList(); 00170 00171 for (i = 0; i < obj->spec.tri.vvnfn.no_verts; i++) 00172 slPoint(toPoint(transPt3(obj->spec.tri.vvnfn.data + i, acc_trans))); 00173 00174 slPoly(); 00175 00176 #ifdef CLEANUP 00177 free( obj->spec.tri.vvnfn.data ); 00178 free( obj ); 00179 #endif 00180 } 00181 /*---------------------------------------------------------------------------*/ 00182 00183 /*===========================================================================*/ 00184 00185 Void create_polygon( Tobject* obj, Tmatrix acc_trans ) 00186 { 00187 #ifdef VERBOSE 00188 printf("Creating a polygon\n"); 00189 print_obj_info( obj ); 00190 printf(" It has %4d vertices \n",obj->spec.polg.vvnfn.no_verts ); 00191 printf(" It has %4d vertex normals \n",obj->spec.polg.vvnfn.no_vnorms ); 00192 printf(" It has %4d facet normals \n",obj->spec.polg.vvnfn.no_fnorms ); 00193 #endif 00194 00195 Int i; 00196 Mat4d &t = (Mat4d&) acc_trans[0][0]; 00197 Vec3d p; 00198 00199 HandleProps(obj); 00200 00201 if (obj->spec.polg.vvnfn.no_vnorms > 0) 00202 { 00203 _Warning("poylgon vertex normals ignored"); 00204 cerr << obj->spec.polg.vvnfn.no_vnorms << endl; 00205 } 00206 if (obj->spec.polg.vvnfn.no_fnorms > 0) 00207 { 00208 _Warning("poylgon face normals ignored"); 00209 cerr << obj->spec.polg.vvnfn.no_fnorms << endl; 00210 } 00211 00212 slPointList(); 00213 00214 for (i = 0; i < obj->spec.polg.vvnfn.no_verts; i++) 00215 slPoint(toPoint(transPt3(obj->spec.polg.vvnfn.data + i, acc_trans))); 00216 00217 slPoly(); 00218 00219 #ifdef CLEANUP 00220 free( obj->spec.polg.vvnfn.data ); 00221 free( obj ); 00222 #endif 00223 } 00224 /*---------------------------------------------------------------------------*/ 00225 00226 /*===========================================================================*/ 00227 Void create_sphere( Tobject* obj, Tmatrix acc_trans ) 00228 { 00229 #ifdef VERBOSE 00230 printf("Creating a sphere\n"); 00231 print_obj_info( obj ); 00232 printf(" Centre is "PCF" "PCF" "PCF" \n", 00233 obj->spec.sph.centre.x, 00234 obj->spec.sph.centre.y, 00235 obj->spec.sph.centre.z ); 00236 printf(" It's radius is "PCF"\n", obj->spec.sph.radius ); 00237 #endif 00238 00239 Vec3d ¢re = (Vec3d&) obj->spec.sph.centre; 00240 Vector radius; 00241 Mat4d &t = (Mat4d&) acc_trans[0][0]; 00242 00243 radius.MakeBlock(obj->spec.sph.radius * 2.0); 00244 slObject("sphere"); 00245 slApply(xform(t, xform(Shift(centre), Scale(radius)))); 00246 00247 #ifdef CLEANUP 00248 free( obj ); 00249 #endif 00250 } 00251 /*---------------------------------------------------------------------------*/ 00252 00253 /*===========================================================================*/ 00254 Void create_cylinder( Tobject* obj, Tmatrix acc_trans ) 00255 { 00256 #ifdef VERBOSE 00257 printf("creating a cylinder\n"); 00258 print_obj_info( obj ); 00259 printf(" Radius is "PCF"\n", obj->spec.cyl.radius ); 00260 printf(" Capped? Top %d Bottom %d \n ", 00261 obj->spec.cyl.tcapped, 00262 obj->spec.cyl.bcapped ); 00263 #endif 00264 00265 _Warning("Ignoring MSDL cylinder"); 00266 00267 #ifdef CLEANUP 00268 free( obj ); 00269 #endif 00270 } 00271 /*---------------------------------------------------------------------------*/ 00272 00273 /*===========================================================================*/ 00274 Void create_cone( Tobject* obj, Tmatrix acc_trans ) 00275 { 00276 #ifdef VERBOSE 00277 printf("Creating a cone\n"); 00278 print_obj_info( obj ); 00279 printf(" Radii Top: "PCF" Bottom: "PCF"\n", 00280 obj->spec.cone.tradius, 00281 obj->spec.cone.bradius ); 00282 printf(" Capped? Top %d Bottom %d \n ", 00283 obj->spec.cone.tcapped, 00284 obj->spec.cone.bcapped ); 00285 #endif 00286 00287 _Warning("Ignoring MSDL cone"); 00288 00289 #ifdef CLEANUP 00290 free( obj ); 00291 #endif 00292 } 00293 /*---------------------------------------------------------------------------*/ 00294 00295 /*===========================================================================*/ 00296 Void create_disc( Tobject* obj, Tmatrix acc_trans ) 00297 { 00298 #ifdef VERBOSE 00299 printf("Creating a disc\n"); 00300 print_obj_info( obj ); 00301 printf(" Centre is "PCF" "PCF" "PCF" \n", 00302 obj->spec.disc.centre.x, 00303 obj->spec.disc.centre.y, 00304 obj->spec.disc.centre.z ); 00305 printf(" It's radius is "PCF"\n", obj->spec.disc.radius ); 00306 #endif 00307 00308 /* Do with this object as you will but please be gentle!! */ 00309 _Warning("Ignoring MSDL disc"); 00310 00311 #ifdef CLEANUP 00312 free( obj ); 00313 #endif 00314 } 00315 /*---------------------------------------------------------------------------*/ 00316 00317 /*===========================================================================*/ 00318 Void create_box( Tobject* obj, Tmatrix acc_trans ) 00319 { 00320 #ifdef VERBOSE 00321 printf("Creating a box\n"); 00322 print_obj_info( obj ); 00323 printf(" Top right is "PCF" "PCF" "PCF" \n", 00324 obj->spec.box.tr.x, 00325 obj->spec.box.tr.y, 00326 obj->spec.box.tr.z ); 00327 printf(" Bottom left is "PCF" "PCF" "PCF" \n", 00328 obj->spec.box.bl.x, 00329 obj->spec.box.bl.y, 00330 obj->spec.box.bl.z ); 00331 #endif 00332 Vec3d &p1 = (Vec3d&) obj->spec.box.tr; 00333 Vec3d &p2 = (Vec3d&) obj->spec.box.bl; 00334 Mat4d &t = (Mat4d&) acc_trans[0][0]; 00335 Vector r; 00336 00337 slObject("cube"); 00338 FindMaxElts(p1 - p2, p2 - p1, r); 00339 slApply(xform(t, 00340 xform(Shift((p1 + p2) / 2.0), 00341 Scale(r)))); 00342 00343 #ifdef CLEANUP 00344 free( obj ); 00345 #endif 00346 } 00347 /*---------------------------------------------------------------------------*/ 00348 00349 /*===========================================================================*/ 00350 Void create_nurb( Tobject* obj, Tmatrix acc_trans ) 00351 { 00352 #ifdef VERBOSE 00353 printf("Creating a nurb\n"); 00354 print_obj_info( obj ); 00355 #endif 00356 00357 _Warning("Ignoring MSDL nurb"); 00358 00359 #ifdef CLEANUP 00360 free( obj->spec.nurb.knots_u ); 00361 free( obj->spec.nurb.knots_v ); 00362 free( obj->spec.nurb.cpts ); 00363 free( obj ); 00364 #endif 00365 } 00366 /*---------------------------------------------------------------------------*/ 00367 00368 /*===========================================================================*/ 00369 Void create_polyhedron( Tobject* obj, Tmatrix acc_trans ) 00370 { 00371 #ifdef CLEANUP 00372 int i=0; /* needed for CLEANUP */ 00373 #endif 00374 00375 #ifdef VERBOSE 00376 printf("Creating a polyhedron\n"); 00377 print_obj_info( obj ); 00378 printf(" It has %4d vertices \n",obj->spec.polh.vvnfn.no_verts ); 00379 printf(" It has %4d vertex normals \n",obj->spec.polh.vvnfn.no_vnorms ); 00380 printf(" It has %4d facet normals \n",obj->spec.polh.vvnfn.no_fnorms ); 00381 #endif 00382 00383 Int i, j; 00384 Point q; 00385 00386 HandleProps(obj); 00387 slPointList(); 00388 for (i = 0; i < obj->spec.tri.vvnfn.no_verts; i++) 00389 slPoint(toPoint(transPt3(obj->spec.tri.vvnfn.data + i, acc_trans))); 00390 00391 slBeginFaces(); 00392 for (j = 0; j < obj->spec.polh.flist.no_faces; j++) 00393 { 00394 Tsingleface *f = obj->spec.polh.flist.face[j]; 00395 for (i = 0; i < f->no_verts; i++) 00396 { 00397 Assert(f->vert_index[i] > 0, 00398 "0-based vert_index list"); 00399 slPointIndex(f->vert_index[i] - 1); 00400 } 00401 slFace(); 00402 } 00403 slEndFaces(); 00404 00405 #ifdef CLEANUP 00406 free( obj->spec.polh.vvnfn.data ); 00407 for( i=0 ; i<obj->spec.polh.flist.no_faces ; i++ ) 00408 free( obj->spec.polh.flist.face[i]->vert_index ); 00409 free( obj->spec.polh.flist.face ); 00410 free( obj ); 00411 #endif 00412 } 00413 /*---------------------------------------------------------------------------*/ 00414 00415 Void print_obj_info( Tobject* obj ) 00416 { 00417 /* this prints out info about an object a bit like the sdl command walk 00418 but it executed in the application writers code... that's why it's here!! */ 00419 00420 printf ( " Obj Name: %s\n", obj->name ); 00421 printf ( " Obj Type: %i\n", obj->otype ); 00422 PRINTP(obj->sprops); 00423 printf ( " "PCF" "PCF" "PCF"\n", 00424 obj->box.min.x, obj->box.min.y, obj->box.min.z ); 00425 printf ( " "PCF" "PCF" "PCF"\n", 00426 obj->box.max.x, obj->box.max.y, obj->box.max.z ); 00427 } 00428 /***************************************************************************** 00429 ** ** **** ** ** ******** ***** 00430 ** ** ** ** ** ** ** ** * 00431 ** ** ** **** ******** ** **** 00432 ** ** ** ** ** ** ** * ** 00433 ******** ** **** ** ** ** ***** 00434 *****************************************************************************/ 00435 00436 Void create_point_lt( Tlights* lite ) 00437 { 00438 #ifdef VERBOSE 00439 printf( "Creating point light of type %d\n",lite->ltype ); 00440 printf( "at "PCF" "PCF" "PCF"\n", lite->spec.point.locn.x, 00441 lite->spec.point.locn.y, 00442 lite->spec.point.locn.z ); 00443 PRINTrgb( "Intensity = ", lite->spec.point.inten ); 00444 #endif 00445 00446 _Warning("Ignoring MSDL point light"); 00447 00448 #ifdef CLEANUP 00449 free( lite ); 00450 #endif 00451 } 00452 00453 Void create_directional_lt( Tlights* lite ) 00454 { 00455 #ifdef VERBOSE 00456 printf( "Creating directional light of type %d\n",lite->ltype ); 00457 printf( "towards "PCF" "PCF" "PCF"\n", lite->spec.direc.along.x, 00458 lite->spec.direc.along.y, 00459 lite->spec.direc.along.z ); 00460 PRINTrgb( "Intensity = ", lite->spec.direc.inten ); 00461 #endif 00462 00463 _Warning("Ignoring MSDL directional light"); 00464 00465 #ifdef CLEANUP 00466 free( lite ); 00467 #endif 00468 } 00469 00470 Void create_spot_lt( Tlights* lite ) 00471 { 00472 #ifdef VERBOSE 00473 printf( "Creating point light of type %d\n",lite->ltype ); 00474 printf( "at "PCF" "PCF" "PCF"\n", lite->spec.spot.locn.x, 00475 lite->spec.spot.locn.y, 00476 lite->spec.spot.locn.z ); 00477 printf( "towards "PCF" "PCF" "PCF"\n",lite->spec.spot.at.x, 00478 lite->spec.spot.at.y, 00479 lite->spec.spot.at.z ); 00480 PRINTrgb( "Intensity =" , lite->spec.spot.inten ); 00481 #endif 00482 00483 _Warning("Ignoring MSDL spot light"); 00484 00485 #ifdef CLEANUP 00486 free( lite ); 00487 #endif 00488 } 00489 00490 /*---------------------------------------------------------------------------*/ 00491 00492 /**************************************************************************** 00493 ***** * * ****** * * * ****** * * 00494 * * * * * * * * * * 00495 * ****** ***** * * * ***** * ** * 00496 * * * * * * * * ** ** 00497 * * * ****** ** * ****** * * 00498 ***************************************************************************/ 00499 /*===========================================================================*/ 00500 Void create_view( Tview* view ) 00501 { 00502 #ifdef VERBOSE 00503 printf( "Creating a view\n" ); 00504 printf( " from: "PCF" "PCF" "PCF"\n", view->from.x, 00505 view->from.y, 00506 view->from.z ); 00507 printf( " towards: "PCF" "PCF" "PCF"\n", view->towards.x, 00508 view->towards.y, 00509 view->towards.z ); 00510 printf( " vpnorm: "PCF" "PCF" "PCF"\n", view->vpn.x, 00511 view->vpn.y, 00512 view->vpn.z ); 00513 printf( " up: "PCF" "PCF" "PCF"\n", view->up.x, 00514 view->up.y, 00515 view->up.z ); 00516 printf( " window: "PCF" "PCF" "PCF" "PCF"\n",view->window.bl.u, 00517 view->window.bl.v, 00518 view->window.tr.u, 00519 view->window.tr.v ); 00520 printf( " front: "PCF"\n", view->fpd ); 00521 printf( " back: "PCF"\n", view->bpd ); 00522 printf( " persp: %d\n", view->persp ); 00523 #endif 00524 00525 /* Do with this view as you will but please be gentle!! */ 00526 _Warning("Ignoring MSDL view"); 00527 00528 gUp = (Vec3d&) view->up; 00529 00530 #ifdef CLEANUP 00531 free( view ); 00532 #endif 00533 } 00534 00535 #endif