diff --git a/Scenery/Makefile b/Scenery/Makefile index aa230a809..81b199a70 100644 --- a/Scenery/Makefile +++ b/Scenery/Makefile @@ -26,7 +26,7 @@ TARGET = libScenery.a -CFILES = common.c mesh.c scenery.c +CFILES = common.c mesh.c scenery.c scanner.c parser.c geometry.c HFILES = OFILES = $(CFILES:.c=.o) @@ -41,7 +41,7 @@ CFLAGS = $(FG_CFLAGS) # Primary Targets #--------------------------------------------------------------------------- -$(TARGET): $(OFILES) $(HFILES) +$(TARGET): $(OFILES) $(HFILES) $(AR) rv $(TARGET) $(OFILES) all: $(TARGET) @@ -49,6 +49,9 @@ all: $(TARGET) clean: rm -f *.o $(TARGET) lib*.a *~ core +realclean: clean + rm -f scanner.c parser.c parser.h parser.output + #--------------------------------------------------------------------------- # Secondary Targets @@ -56,6 +59,21 @@ clean: include depend +scanner.c: scanner.l parser.h + $(FLEX) -oscanner.c scanner.l + +parser.h: parser.y + $(BISON) -o parser.c -d parser.y + +parser.c: parser.y + $(BISON) -o parser.c parser.y + +scanner.o: scanner.c + $(CC) $(CFLAGS) -c scanner.c + +parser.o: parser.c + $(CC) $(CFLAGS) -c parser.c + common.o: $(CC) $(CFLAGS) -c common.c @@ -65,9 +83,14 @@ mesh.o: scenery.o: $(CC) $(CFLAGS) -c scenery.c +geometry.o: + $(CC) $(CFLAGS) -c geometry.c #--------------------------------------------------------------------------- # $Log$ +# Revision 1.14 1997/06/29 21:16:47 curt +# More twiddling with the Scenery Management system. +# # Revision 1.13 1997/06/27 21:38:10 curt # Working on Makefile structure. # diff --git a/Scenery/depend b/Scenery/depend index 45d2bf0c4..7a6e5240e 100644 --- a/Scenery/depend +++ b/Scenery/depend @@ -1,3 +1,6 @@ common.o: common.c common.h +geometry.o: geometry.c geometry.h mesh.h mesh.o: mesh.c mesh.h common.h -scenery.o: scenery.c scenery.h ParseVRML/parsevrml.h +parser.o: parser.c parsevrml.h geometry.h common.h mesh.h scenery.h +scanner.o: scanner.c parser.h +scenery.o: scenery.c scenery.h parsevrml.h diff --git a/Scenery/geometry.c b/Scenery/geometry.c new file mode 100644 index 000000000..f2ec13016 --- /dev/null +++ b/Scenery/geometry.c @@ -0,0 +1,121 @@ +/************************************************************************** + * geometry.c -- data structures and routines for processing vrml geometry + * + * Written by Curtis Olson, started June 1997. + * + * Copyright (C) 1997 Curtis L. Olson - curt@infoplane.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id$ + * (Log is kept at end of this file) + **************************************************************************/ + + +#include +#include +#include + +#include "geometry.h" +#include "mesh.h" + + +static vrmlGeometryType; +static struct mesh eg; + + +/* Begin a new vrml geometry statement */ +int vrmlInitGeometry(char *type) { + printf("Beginning geometry item = %s\n", type); + + if ( strcmp(type, "ElevationGrid") == 0 ) { + vrmlGeometryType = VRML_ELEV_GRID; + mesh_init(&eg); + } else { + vrmlGeometryType = -1; + printf("Unimplemented geometry type = %s\n", type); + } + + return(vrmlGeometryType); +} + + +/* Set current vrml geometry option name */ +void vrmlGeomOptionName(char *name) { + /* printf("Found vrml geometry option = %s\n", name); */ + + switch(vrmlGeometryType) { + case VRML_ELEV_GRID: + if ( strcmp(name, "xDimension") == 0 ) { + mesh_set_option_name(&eg, "rows"); + } else if ( strcmp(name, "zDimension") == 0 ) { + mesh_set_option_name(&eg, "cols"); + } else if ( strcmp(name, "xSpacing") == 0 ) { + mesh_set_option_name(&eg, "row_step"); + } else if ( strcmp(name, "zSpacing") == 0 ) { + mesh_set_option_name(&eg, "col_step"); + } else if ( strcmp(name, "height") == 0 ) { + eg.mesh_data = new_mesh_data(eg.rows, eg.cols); + mesh_set_option_name(&eg, "do_data"); + } else { + printf("Unknown ElevationGrid option = %s\n", name); + } + break; + } +} + + +/* Set current vrml geometry value */ +void vrmlGeomOptionsValue(char *value) { + /* printf("Found vrml geometry value = %s\n", value); */ + + switch(vrmlGeometryType) { + case VRML_ELEV_GRID: + mesh_set_option_value(&eg, value); + } +} + + +/* We've finished parsing the current geometry. Now do whatever needs + * to be done with it (like generating the OpenGL call list for + * instance */ +void vrmlHandleGeometry() { + switch(vrmlGeometryType) { + case VRML_ELEV_GRID: + mesh_do_it(&eg); + } +} + + +/* Finish up the current vrml geometry statement */ +int vrmlFreeGeometry() { + printf("Freeing geometry type = %d\n", vrmlGeometryType); + + switch(vrmlGeometryType) { + case VRML_ELEV_GRID: + free(eg.mesh_data); + } + return(vrmlGeometryType); +} + + +/* $Log$ +/* Revision 1.1 1997/06/29 21:16:48 curt +/* More twiddling with the Scenery Management system. +/* + * Revision 1.1 1997/06/22 21:42:35 curt + * Initial revision of VRML (subset) parser. + * + */ diff --git a/Scenery/geometry.h b/Scenery/geometry.h new file mode 100644 index 000000000..456160b7c --- /dev/null +++ b/Scenery/geometry.h @@ -0,0 +1,65 @@ +/************************************************************************** + * geometry.h -- data structures and routines for handling vrml geometry + * + * Written by Curtis Olson, started June 1997. + * + * Copyright (C) 1997 Curtis L. Olson - curt@infoplane.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id$ + * (Log is kept at end of this file) + **************************************************************************/ + + +#ifndef GEOMETRY_H +#define GEOMETRY_H + + +#define VRML_BOX 0 +#define VRML_CYLINDER 1 +#define VRML_CONE 2 +#define VRML_ELEV_GRID 3 + + +/* Begin a new vrml geometry statement */ +int vrmlInitGeometry(char *type); + +/* Set current vrml geometry option name */ +void vrmlGeomOptionName(char *name); + +/* Set current vrml geometry value */ +void vrmlGeomOptionsValue(char *value); + +/* We've finished parsing the current geometry. Now do whatever needs + * to be done with it (like generating the OpenGL call list for + * instance */ +void vrmlHandleGeometry(); + +/* Finish up the current vrml geometry statement */ +int vrmlFreeGeometry(); + + +#endif GEOMETRY_H + + +/* $Log$ +/* Revision 1.1 1997/06/29 21:16:48 curt +/* More twiddling with the Scenery Management system. +/* + * Revision 1.1 1997/06/22 21:42:35 curt + * Initial revision of VRML (subset) parser. + * + */ diff --git a/Scenery/mesh.c b/Scenery/mesh.c index f112bfe70..89fa0d7ce 100644 --- a/Scenery/mesh.c +++ b/Scenery/mesh.c @@ -29,10 +29,16 @@ #include /* atof(), atoi() */ #include +#include + #include "mesh.h" #include "common.h" +/* Temporary hack until we get the scenery management system running */ +extern GLint mesh_hack; + + /* initialize the non-array mesh values */ void mesh_init(struct mesh *m) { m->originx = 0.0; @@ -140,14 +146,17 @@ void mesh_set_option_value(struct mesh *m, char *value) { /* do whatever needs to be done with the mesh now that it's been loaded, such as generating the OpenGL call list. */ void mesh_do_it(struct mesh *m) { - mesh2GL(m); + mesh_hack = mesh2GL(m); } /* $Log$ -/* Revision 1.5 1997/06/22 21:44:41 curt -/* Working on intergrating the VRML (subset) parser. +/* Revision 1.6 1997/06/29 21:16:49 curt +/* More twiddling with the Scenery Management system. /* + * Revision 1.5 1997/06/22 21:44:41 curt + * Working on intergrating the VRML (subset) parser. + * * Revision 1.4 1997/05/30 19:30:17 curt * The LaRCsim flight model is starting to look like it is working. * diff --git a/Scenery/parser.y b/Scenery/parser.y new file mode 100644 index 000000000..0088067c9 --- /dev/null +++ b/Scenery/parser.y @@ -0,0 +1,189 @@ +/************************************************************************** + * parser.y -- scenery file parser + * + * Written by Curtis Olson, started June 1997. + * + * Copyright (C) 1997 Curtis L. Olson - curt@infoplane.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id$ + **************************************************************************/ + + +/* C pass through */ +%{ +#include +#include +#include +#include + +#include "parsevrml.h" +#include "geometry.h" +#include "common.h" +#include "mesh.h" +#include "scenery.h" + + + /*#DEFINE YYDEBUG 1 */ + + /* interfacing with scanner.l (lex) */ + extern int line_num; + extern char *yytext; + int push_input_stream ( char *input ); + + /* we must define this ourselves */ + int yyerror(char *s); + + /* handle for a mesh structure */ + struct mesh *mesh_ptr; +%} + + +/* top level reserved words */ +%token IncludeSym ShapeSym GeometrySym ElevationGridSym + +/* basic tokens */ +%token Identifier Number StringLiteral + +/* symbol tokens */ +%token EqualSym LBraceSym RBraceSym LParenSym RParenSym +%token LSqBracketSym RSqBracketSym CommaSym + +/* error tokens */ +%token BadStringLiteral ErrorMisc + + +/* Start Symbol */ +%start vrml + + +/* Rules Section */ +%% + +vrml : + node_list +; + +node_list : + node + | node_list node +; + +node : + include + | shape +; + +/* includes */ +include : + IncludeSym StringLiteral + { + yytext = strip_quotes(yytext); + printf("Need to include %s\n", yytext); + push_input_stream(yytext); + } +; + +/* Shape rules */ + +shape : + ShapeSym LBraceSym shape_body RBraceSym +; + +shape_body : + /* appearance */ geometry +; + +/* appearance : */ +/* Empty OK */ +/* ; */ + +geometry : + GeometrySym + Identifier + { + vrmlInitGeometry(yytext); + } + LBraceSym geom_item_list RBraceSym + { + vrmlHandleGeometry(); + vrmlFreeGeometry(); + } +; + +geom_item_list : + geom_item + | geom_item_list geom_item +; + +geom_item : + Identifier { vrmlGeomOptionName(yytext); } + geom_rvalue +; + +geom_rvalue : + value + | LSqBracketSym value_list RSqBracketSym +; + +value_list : + value + | value_list value +; + +value : + Number { vrmlGeomOptionsValue(yytext); } +; + + +/* C Function Section */ +%% + + +int yyerror(char *s) { + printf("Error: %s at line %d.\n", s, line_num); + return 0; +} + + +/* this is a simple main for testing the parser */ + +/* +int main(int argc, char **argv) { +#ifdef YYDEBUG + yydebug = 1; +#endif + + printf("input file = %s\n", argv[1]); + push_input_stream(argv[1]); + yyparse(); + + return 0; +} +*/ + + +/* parse a VRML scenery file */ +int fgParseVRML(char *file) { + int result; + + printf("input file = %s\n", file); + push_input_stream(file); + result = yyparse(); + + /* return(result) */ + return(result); +} diff --git a/Scenery/parsevrml.h b/Scenery/parsevrml.h new file mode 100644 index 000000000..e23222503 --- /dev/null +++ b/Scenery/parsevrml.h @@ -0,0 +1,44 @@ +/************************************************************************** + * parsevrml.h -- top level include file for accessing the vrml parser + * + * Written by Curtis Olson, started June 1997. + * + * Copyright (C) 1997 Curtis L. Olson - curt@infoplane.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id$ + * (Log is kept at end of this file) + **************************************************************************/ + + +#ifndef PARSEVRML_H +#define PARSEVRML_H + + +/* parse a VRML scenery file */ +int fgParseVRML(char *file); + +#endif PARSEVRML_H + + +/* $Log$ +/* Revision 1.1 1997/06/29 21:16:49 curt +/* More twiddling with the Scenery Management system. +/* + * Revision 1.1 1997/06/27 02:25:13 curt + * Initial revision. + * + */ diff --git a/Scenery/scanner.l b/Scenery/scanner.l new file mode 100644 index 000000000..437d66a61 --- /dev/null +++ b/Scenery/scanner.l @@ -0,0 +1,247 @@ +/************************************************************************** + * scenery.l -- Lexical Analyzer for scenery files + * + * Written by Curtis Olson, started May 1997. + * + * Copyright (C) 1997 Curtis L. Olson - curt@infoplane.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * NOTE: Compiles with flex and gcc. + * + * $Id$ + **************************************************************************/ + + +/* C Pass Through */ +%{ + #include + #include "parser.h" + + int line_num = 1; + char c; + + /* custom print routine */ + static int scanner_debug = 0; + + /* Routines to manage a stack of nested input buffers (for + processing the #include directive */ + #define MAX_INCLUDE_DEPTH 10 + static YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH]; + static int include_stack_ptr = 0; + + int push_input_stream ( char *input ) { + FILE *yyin_save; + if ( include_stack_ptr >= MAX_INCLUDE_DEPTH ) { + fprintf( stderr, "Scanner says: Includes nested too deeply\n" ); + return(0); + } + + /* save yyin in case the following fails */ + yyin_save = yyin; + + yyin = fopen( input, "r" ); + if ( ! yyin ) { + fprintf( stderr, "Scanner says: cannot open '%s'\n", input ); + + /* The failed attempt destroyed yyin, so restore it */ + yyin = yyin_save; + + return(0); + } + + include_stack[include_stack_ptr++] = YY_CURRENT_BUFFER; + yy_switch_to_buffer( yy_create_buffer(yyin, YY_BUF_SIZE) ); + + return(1); + } + + int pop_input_stream () { + if ( --include_stack_ptr < 1 ) { + /* end of last input stream */ + return(0); + } else { + /* end of current input stream, restore previous and continue */ + yy_delete_buffer( YY_CURRENT_BUFFER ); + yy_switch_to_buffer( include_stack[include_stack_ptr] ); + return(1); + } + } +%} + + +/* Definitions */ +letter [A-Za-z] +digit [0-9] +connecter [_-] +ident {letter}({letter}|{digit}|{connecter})* + +integer [+-]?{digit}+ + +plain_real {integer}"."{integer} +short_exp_real {integer}[Ee][+-]?{integer} +exp_real {plain_real}[Ee][+-]?{integer} +real [+-]?{plain_real}|{short_exp_real}|{exp_real} + +number {real}|{integer} + +string \"[^"\n]+\" + +bad_string \"([^"\n]|\n)+\" + +ws [ \t]+ +other . + + +/* Rules */ +%% + +include { if ( scanner_debug ) { + printf("return IncludeSym\n"); + } + return IncludeSym; + } + +Shape { if ( scanner_debug ) { + printf("return ShapeSym\n"); + } + return ShapeSym; + } + +Geometry { if ( scanner_debug ) { + printf("return GeometrySym\n"); + } + return GeometrySym; + } + +{ident} { if ( scanner_debug ) { + printf("return Identifier = %s\n", yytext); + } + return Identifier; + } + +{number} { if ( scanner_debug ) { + printf("return Number\n"); + } + return Number; + } + +{string} { if ( scanner_debug ) { + printf("return StringLiteral = %s\n", yytext); + } + return StringLiteral; + } + +{bad_string} { if ( scanner_debug ) { + printf("return BadStringLiteral = %s\n", yytext); + } + return BadStringLiteral; + } + +"\n" { line_num++; + if ( scanner_debug ) { + printf("Line number = %d\n", line_num); + } + } + +"=" { if ( scanner_debug ) { + printf("return EqualSym\n"); + } + return EqualSym; + } + +"," { if ( scanner_debug ) { + printf("return CommaSym\n"); + } + return CommaSym; + } + +"{" { if ( scanner_debug ) { + printf("return LBraceSym\n"); + } + return LBraceSym; + } + +"}" { if ( scanner_debug ) { + printf("return RBraceSym\n"); + } + return RBraceSym; + } + +"(" { if ( scanner_debug ) { + printf("return LParenSym\n"); + } + return LParenSym; + } + +")" { if ( scanner_debug ) { + printf("return RParenSym\n"); + } + return RParenSym; + } + +"[" { if ( scanner_debug ) { + printf("return LSqBracketSym\n"); + } + return LSqBracketSym; + } + +"]" { if ( scanner_debug ) { + printf("return RSqBracketSym\n"); + } + return RSqBracketSym; + } + +"//" { /* burn through "//" comment to end of line */ + if ( scanner_debug ) { + printf("Skipping comment: "); + } + c = input(); + while ( (c != '\n') ) { + c = input(); + if ( scanner_debug ) { + printf("%c", c); + } + } + unput(c); + } + +"#" { /* burn through "#" comment to end of line */ + if ( scanner_debug ) { + printf("Skipping comment: "); + } + c = input(); + while ( (c != '\n') ) { + c = input(); + if ( scanner_debug ) { + printf("%c", c); + } + } + unput(c); + } + +{ws} { ; } + +{other} { if ( scanner_debug ) { + printf("Scanned some unexpected text = `%s'\n", yytext); + } + return ErrorMisc; + } + +<> { if ( pop_input_stream() == 0 ) { + /* End of last input stream */ + yyterminate(); + } + } diff --git a/Scenery/scenery.c b/Scenery/scenery.c index 96c58ec06..d40cd3724 100644 --- a/Scenery/scenery.c +++ b/Scenery/scenery.c @@ -24,8 +24,14 @@ **************************************************************************/ +#include + #include "scenery.h" -#include "ParseVRML/parsevrml.h" +#include "parsevrml.h" + + +/* Temporary hack until we get the scenery management system running */ +GLint mesh_hack; /* Initialize the Scenery Management system */ @@ -41,19 +47,25 @@ void fgSceneryUpdate(double lon, double lat, double elev) { /* this routine should parse the file, and make calls back to the * scenery management system to build the appropriate structures */ - fgParseVRML("test.wrl"); + fgParseVRML("mesa-e.wrl"); } /* Render out the current scene */ void fgSceneryRender() { + glPushMatrix(); + glCallList(mesh_hack); + glPopMatrix(); } /* $Log$ -/* Revision 1.2 1997/06/27 20:03:37 curt -/* Working on Makefile structure. +/* Revision 1.3 1997/06/29 21:16:50 curt +/* More twiddling with the Scenery Management system. /* + * Revision 1.2 1997/06/27 20:03:37 curt + * Working on Makefile structure. + * * Revision 1.1 1997/06/27 02:26:30 curt * Initial revision. *