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

ParseMGF.cc

Go to the documentation of this file.
00001 /*
00002     File:       ParseMGF.cc
00003 
00004     Function:   Provides routine to parse .mgf files into a scene.
00005 
00006     Author:     Andrew Willmott
00007 
00008     Notes:      Need to support shared vertices, vertex normals.
00009 
00010     Copyright:  (c) 1996-2000, Andrew Willmott
00011 */
00012 
00013 #include "gcl/GCLConfig.h"
00014 #ifdef GCL_MGF
00015 #include "gcl/SceneLang.h"
00016 #include <stdio.h>
00017 #include <string.h>
00018 
00019 extern "C" 
00020 {
00021 #include <string.h>
00022 #include "parser.h"
00023 #include "lookup.h"
00024 }
00025 
00026 static int myObject(int ac, char **av);
00027 static int myTransform(int ac, char **av);
00028 static int myCylinder(int ac, char **av);
00029 static int myFace(int ac, char **av);
00030 static int mySphere(int ac, char **av);
00031 static int myComment(int ac, char **av);
00032 
00033 #ifdef DEBUG
00034 #define DBG_COUT if (0) cerr
00035 //#define MGF_DUMP
00036 #else
00037 #define DBG_COUT if (0) cerr
00038 #endif
00039 
00040 Colour MGF2Colour(
00041         C_COLOR     *cin,           // input MGF chrominance
00042         Double      intensity       // input luminance or reflectance 
00043     );
00044 
00051 scScenePtr ParseMGFFile(const Char *filename)
00052 {
00053     scScenePtr result;
00054 
00055     result = slBeginObject(filename);
00056     
00057     // rotate from MGF's standard zup to our standard yup
00058     slTransform(Rotation(vl_x, -vl_halfPi));
00059     // initialize dispatch table 
00060 
00061     mg_ehand[MG_E_COMMENT] = myComment; 
00062     mg_ehand[MG_E_COLOR] = c_hcolor;    
00063     mg_ehand[MG_E_CMIX] = c_hcolor;     
00064     mg_ehand[MG_E_CSPEC] = c_hcolor;    
00065     mg_ehand[MG_E_CXY] = c_hcolor;      
00066     mg_ehand[MG_E_CCT] = c_hcolor;      
00067     //mg_ehand[MG_E_CYL] = myCylinder;  
00068     mg_ehand[MG_E_ED] = c_hmaterial;    
00069     mg_ehand[MG_E_FACE] = myFace;       
00070     mg_ehand[MG_E_MATERIAL] = c_hmaterial;
00071     mg_ehand[MG_E_NORMAL] = c_hvertex;  
00072     //mg_ehand[MG_E_OBJECT] = myObject; 
00073     mg_ehand[MG_E_POINT] = c_hvertex;   
00074     mg_ehand[MG_E_RD] = c_hmaterial;    
00075     mg_ehand[MG_E_RS] = c_hmaterial;    
00076     mg_ehand[MG_E_SIDES] = c_hmaterial; 
00077     //mg_ehand[MG_E_SPH] = mySphere;    
00078     mg_ehand[MG_E_TD] = c_hmaterial;    
00079     mg_ehand[MG_E_TS] = c_hmaterial;    
00080     mg_ehand[MG_E_VERTEX] = c_hvertex;  
00081     mg_ehand[MG_E_XF] = xf_handler;     
00082 
00083     DBG_COUT << "initialising parser" << endl;
00084     
00085     mg_init();                          /* initialize the parser */
00086     
00087     if (mg_load((char*)filename) != MG_OK)
00088     {
00089         slEndObject();
00090         return(0);
00091     }
00092     slEndObject();
00093     return(result);
00094 }
00095 
00096 
00097 static Int myObject(int ac, char **av)          /* group object name */
00098 {
00099     static int  objnest;
00100 
00101 #ifdef MGF_DUMP
00102     int i;
00103     for (i = 0; i < ac; i++)
00104         printf("%s ", av[i]);
00105     printf("\n");
00106 #endif
00107 
00108     return(MG_OK);
00109 }
00110 
00111 static int myComment(int ac, char **av)
00112 {
00113 #ifdef MGF_DUMP
00114     int i;
00115     printf("comment:\n");
00116     for (i = 0; i < ac; i++)
00117         printf("%s ", av[i]);
00118     printf("\n");
00119 #endif
00120     return(MG_OK);
00121 }
00122 
00123 #if 0
00124 // shared vertex lookup table
00125 const Char *kVertFmt    = "%+16.9e %+16.9e %+16.9e %+6.3f %+6.3f %+6.3f";
00126 const Char *kVZVect     = "+0.000 +0.000 +0.000";
00127 const Int kVFLen        = 72;
00128 const Int kMaxVert      10240;  /* maximum cached vertices */
00129 
00130 #define setvkey(k,v)    sprintf(k,VERTFMT,(v)->p[0],(v)->p[1],(v)->p[2],\
00131                     (v)->n[0],(v)->n[1],(v)->n[2]);
00132 
00133 char    vlist[MAXVERT][VFLEN];  /* our vertex cache */
00134 int nverts;         /* current cache size */
00135 
00136 LUTAB   vert_tab = LU_SINIT(NULL,NULL);
00137 
00138 #endif
00139 
00140 
00141 static int myFace(int ac, char **av)            /* translate an N-sided face */
00142 {
00143     C_VERTEX    *vp;
00144     int         i;
00145     FVECT       n, p;
00146     Bool        doNormals = false, ctxChange = false;
00147     Int         idx;
00148     
00149     static Int          gLastXID = -1;
00150     static Colour       gLastRClr(-1, -1, -1), gLastEClr(-1, -1, -1);
00151 
00152     if (ac < 4)
00153         return(MG_EARGC);
00154     
00155     if (xf_context && xf_context->xid != gLastXID)
00156     {
00157         gLastXID = xf_context->xid;
00158         ctxChange = true;
00159         DBG_COUT << "transform context changed: rev = " << xf_context->rev << endl;
00160     }
00161         
00162     DBG_COUT << "mtl: " << c_cmname << ' ' << c_cmaterial << ' ' << c_cmaterial->clock << endl;
00163     if (c_cmaterial->clock != 0)
00164     // material has changed...
00165     {
00166         Colour  rClr, eClr;
00167         
00168         DBG_COUT << "material change: clock = " << c_cmaterial->clock << endl;
00169         
00170         rClr = MGF2Colour(&c_cmaterial->rd_c, c_cmaterial->rd);
00171         eClr = MGF2Colour(&c_cmaterial->ed_c, c_cmaterial->ed);
00172         // the MGF 'ed' is measured in lux, photometric irradiance.
00173         // convert to our pure irradiance
00174         eClr /= 179.0;
00175 
00176         if (rClr != gLastRClr)
00177         {
00178             DBG_COUT << "reflectance = " << rClr << endl;
00179             slColour(rClr);
00180             gLastRClr = rClr;
00181             ctxChange = true;
00182         }
00183         if (eClr != gLastEClr)
00184         {
00185             DBG_COUT << "emittance = " << eClr << endl;
00186             slEmittance(eClr);
00187             gLastEClr = eClr;
00188             ctxChange = true;
00189         }
00190 
00191         c_cmaterial->clock = 0;
00192     }
00193         
00194 #ifdef MGF_DUMP
00195     printf("face:\n");
00196     for (i = 0; i < ac; i++)
00197         printf("%s ", av[i]);
00198     printf("\n");
00199 #endif
00200 
00201     slPointList();
00202 
00203     for (i = 1; i < ac; i++) 
00204     {
00205         if (xf_context && xf_context->rev) 
00206             vp = c_getvert(av[ac - i]);
00207         else
00208             vp = c_getvert(av[i]);
00209         
00210         if (vp == NULL)
00211             return(MG_EUNDEF);
00212         
00213         // we wish to use shared vertices -- it appears the only
00214         // way to do this is to use a hash =P
00215 
00216 #ifdef MGF_SHARED_VERTS
00217         // XXX unfinished!
00218         lu_init(&vert_tab, MAXVERT);
00219 
00220         setvkey(vlist[nverts], vp);
00221         lp = lu_find(&vert_tab, vlist[nverts]);
00222         if (lp == NULL)
00223             return(MG_EMEM);
00224         if (lp->key == NULL)
00225             lp->key = (char *)vlist[nverts++];
00226         newf->vl[i] = ((char (*)[VFLEN])lp->key - vlist);
00227 
00228         idx = (Int) vp->client_data;
00229 
00230         if (ctxChange || vp->clock != 0 || idx == 0)
00231         {
00232             vp->clock = 0;
00233             xf_xfmpoint(p, vp->p);
00234             idx = slPoint(Vector(p[0], p[1], p[2]));
00235             vp->client_data = (char*) (idx + 1);
00236             DBG_COUT << "create index = " << idx << ", " << vp << endl;
00237 
00238             if (i == 1 && (vp->n[0] != 0.0 || vp->n[1] != 0.0 || vp->n[2] != 0.0))
00239             {
00240                 // if the first vertex has a vertex normal defined, assume the
00241                 // rest do too.
00242                 slNormalList();
00243                 doNormals = true;
00244             }
00245 
00246             if (doNormals)
00247             {
00248                 Vector  nrm;
00249 
00250                 xf_rotvect(n, vp->n);
00251                 nrm = Vector(n[0], n[1], n[2]);
00252                 DBG_COUT << "norm = " << nrm << endl;
00253                 nrm.Normalise();
00254                 slNormal(nrm);
00255             }
00256         }
00257         else
00258         {
00259             idx = idx - 1;
00260             DBG_COUT << "reused index = " << idx << ", " << vp << endl;
00261         }
00262         //slIndex(idx);
00263     }
00264 #else
00265         xf_xfmpoint(p, vp->p);
00266         slPoint(Vector(p[0], p[1], p[2]));
00267 
00268         if (i == 1 && (vp->n[0] != 0.0 || vp->n[1] != 0.0 || vp->n[2] != 0.0))
00269         {
00270             // if the first vertex has a vertex normal defined, assume the
00271             // rest do too.
00272             slNormalList();
00273             doNormals = true;
00274         }
00275 
00276         if (doNormals)
00277         {
00278             Vector  nrm;
00279 
00280             xf_rotvect(n, vp->n);
00281             nrm = Vector(n[0], n[1], n[2]);
00282             DBG_COUT << "norm = " << nrm << endl;
00283             nrm.Normalise();
00284             slNormal(nrm);
00285         }
00286     }
00287     slPoly();
00288 #endif
00289     
00290     return(MG_OK);          
00291 }
00292 
00293 
00294 static int mySphere(int ac, char **av)          /* translate sphere description */
00295 {
00296 #ifdef MGF_DUMP
00297     printf("sphere:\n");
00298 #endif
00299     return(MG_OK);      /* we'll actually put it out later */
00300 }
00301 
00302 
00303 static int myCylinder(int ac, char **av)            /* translate a cylinder description */
00304 {
00305 #ifdef MGF_DUMP
00306     printf("cyl:\n");
00307     int i;
00308     for (i = 0; i < ac; i++)
00309         printf("%s ", av[i]);
00310     printf("\n");
00311 #endif
00312     return(MG_OK);      /* we'll actually put it out later */
00313 }
00314 
00315 
00316 #ifndef OLD
00317                         /* Change the following to suit your standard */
00318 #define  CIE_x_r                0.640           /* nominal CRT primaries */
00319 #define  CIE_y_r                0.330
00320 #define  CIE_x_g                0.290
00321 #define  CIE_y_g                0.600
00322 #define  CIE_x_b                0.150
00323 #define  CIE_y_b                0.060
00324 #define  CIE_x_w                0.3333          /* use true white */
00325 #define  CIE_y_w                0.3333
00326 
00327 #define CIE_D           (       CIE_x_r*(CIE_y_g - CIE_y_b) + \
00328                                 CIE_x_g*(CIE_y_b - CIE_y_r) + \
00329                                 CIE_x_b*(CIE_y_r - CIE_y_g)     )
00330 
00331 #define CIE_C_rD        ( (1./CIE_y_w) * \
00332                                 ( CIE_x_w*(CIE_y_g - CIE_y_b) - \
00333                                   CIE_y_w*(CIE_x_g - CIE_x_b) + \
00334                                   CIE_x_g*CIE_y_b - CIE_x_b*CIE_y_g     ) )
00335 #define CIE_C_gD        ( (1./CIE_y_w) * \
00336                                 ( CIE_x_w*(CIE_y_b - CIE_y_r) - \
00337                                   CIE_y_w*(CIE_x_b - CIE_x_r) - \
00338                                   CIE_x_r*CIE_y_b + CIE_x_b*CIE_y_r     ) )
00339 #define CIE_C_bD        ( (1./CIE_y_w) * \
00340                                 ( CIE_x_w*(CIE_y_r - CIE_y_g) - \
00341                                   CIE_y_w*(CIE_x_r - CIE_x_g) + \
00342                                   CIE_x_r*CIE_y_g - CIE_x_g*CIE_y_r     ) )
00343 
00344 #define CIE_rf          (CIE_y_r*CIE_C_rD/CIE_D)
00345 #define CIE_gf          (CIE_y_g*CIE_C_gD/CIE_D)
00346 #define CIE_bf          (CIE_y_b*CIE_C_bD/CIE_D)
00347 
00348 /* XYZ to RGB conversion matrix */
00349 
00350 const ClrMat xyz2rgb
00351 (
00352      (CIE_y_g - CIE_y_b - CIE_x_b * CIE_y_g + CIE_y_b * CIE_x_g) / CIE_C_rD,
00353      (CIE_x_b - CIE_x_g - CIE_x_b * CIE_y_g + CIE_x_g * CIE_y_b) / CIE_C_rD,
00354      (CIE_x_g * CIE_y_b - CIE_x_b * CIE_y_g) / CIE_C_rD,
00355 
00356      (CIE_y_b - CIE_y_r - CIE_y_b * CIE_x_r + CIE_y_r * CIE_x_b) / CIE_C_gD,
00357      (CIE_x_r - CIE_x_b - CIE_x_r * CIE_y_b + CIE_x_b * CIE_y_r) / CIE_C_gD,
00358      (CIE_x_b * CIE_y_r - CIE_x_r * CIE_y_b) / CIE_C_gD,
00359 
00360      (CIE_y_r - CIE_y_g - CIE_y_r * CIE_x_g + CIE_y_g * CIE_x_r) / CIE_C_bD,
00361      (CIE_x_g - CIE_x_r - CIE_x_g * CIE_y_r + CIE_x_r * CIE_y_g) / CIE_C_bD,
00362      (CIE_x_r * CIE_y_g - CIE_x_g * CIE_y_r) / CIE_C_bD
00363 );
00364 
00365 // convert MGF color to RGB 
00366 
00367 Colour  gMGFRGBLum(CIE_rf, CIE_gf, CIE_bf);
00368 
00369 Colour MGF2Colour(
00370         C_COLOR     *cin,          /* input MGF chrominance */
00371         Double      intensity      /* input luminance or reflectance */
00372     )
00373 {
00374     Colour  xyz, rgb;
00375     ClrReal rgbLum;
00376     
00377     // get CIE XYZ representation 
00378     c_ccvt(cin, C_CSXY);
00379 
00380     DBG_COUT << "converting: x y L: " << cin->cx << ' ' << cin->cy << ' ' << intensity << endl;
00381 
00382     xyz[0] = cin->cx;
00383     xyz[1] = cin->cy;
00384     xyz[2] = (1.0 - cin->cx - cin->cy);
00385 
00386     // convert to rgb colour
00387 
00388     // XXX change this to use ColourSystem stuff.
00389     rgb = xyz2rgb * xyz;
00390     // correct for out of gamut
00391     ClipColourZero(rgb);
00392     // normalise rgb luminance to 1
00393     rgbLum = (CIE_rf * rgb[0] + CIE_gf * rgb[1] + CIE_bf * rgb[2]);
00394     if (rgbLum > 0.0)
00395         rgb /= rgbLum;
00396     // set intensity.
00397     rgb *= intensity;
00398 
00399     DBG_COUT << "got: " << rgb << endl;
00400 
00401     return(rgb);
00402 }
00403 #else
00404 
00405 #include "gcl/ColourSystem.h"
00406 
00407 static ColourSystem mgfCS(
00408     Chroma(0.640, 0.330), 
00409     Chroma(0.290, 0.600), 
00410     Chroma(0.150, 0.060),
00411     Chroma(0.3333, 0.3333));
00412 
00413 Colour MGF2Colour(
00414         C_COLOR     *cin,          /* input MGF chrominance */
00415         Double      intensity      /* input luminance or reflectance */
00416     )
00417 {
00418     Colour  rgb;
00419     
00420     // get CIE XYZ representation 
00421     c_ccvt(cin, C_CSXY);
00422 
00423     DBG_COUT << "converting: x y L: " << cin->cx << ' ' << cin->cy << ' ' << intensity << endl;
00424 
00425     rgb = mgfCS.ChromaToGamut(Chroma(cin->cx, cin->cy));
00426     rgb *= intensity;
00427     
00428     DBG_COUT << "got: " << rgb << endl;
00429 
00430     return(rgb);
00431 }
00432 
00433 
00434 #endif
00435 
00436 #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