+
+struct tile *find_level_tile(struct level *lvl, int type)
+{
+ struct tile *tile = lvl->tiles;
+ while(tile) {
+ if(tile->type == type) {
+ return tile;
+ }
+ tile = tile->next;
+ }
+ return 0;
+}
+
+int gen_cell_geom(struct level *lvl, struct cell *cell)
+{
+ int i;
+ struct meshgroup *wallgeom;
+ struct tile *tstr;
+ struct mesh *mesh, *tmesh;
+ float xform[16];
+
+ if(!(tstr = find_level_tile(lvl, TILE_STRAIGHT))) {
+ return -1;
+ }
+
+ if(!(wallgeom = malloc(sizeof *wallgeom))) {
+ return -1;
+ }
+ init_meshgroup(wallgeom);
+
+ for(i=0; i<4; i++) {
+ if(cell->wall[i] == TILE_STRAIGHT) { /* TODO: support other wall types */
+ cgm_mrotation_y(xform, i * M_PI / 2.0f);
+
+ tmesh = tstr->scn.meshlist;
+ while(tmesh) {
+ if(!(mesh = malloc(sizeof *mesh))) {
+ return -1;
+ }
+
+ /* create a copy of the tile mesh */
+ if(copy_mesh(mesh, tmesh) == -1) {
+ free(mesh);
+ return -1;
+ }
+ if(i) xform_mesh(mesh, xform); /* rotate it to match the wall angle */
+
+ /* add it to the level meshlist */
+ mesh->next = lvl->meshlist;
+ lvl->meshlist = mesh;
+
+ /* add it to the meshgroup */
+ if(add_meshgroup_mesh(wallgeom, mesh) == -1) {
+ destroy_mesh(mesh);
+ free(mesh);
+ return -1;
+ }
+
+ tmesh = tmesh->next;
+ }
+ }
+ }
+
+ /* TODO: append to other existing meshgroups for detail objects */
+ cell->mgrp = wallgeom;
+ cell->num_mgrp = 1;
+
+ return 0;
+}
+
+int gen_level_geom(struct level *lvl)
+{
+ int i, j;
+ struct cell *cell;
+
+ for(i=0; i<lvl->height; i++) {
+ for(j=0; j<lvl->width; j++) {
+ cell = lvl->cells + i * lvl->width + j;
+ if(cell->type != CELL_SOLID) {
+ if(gen_cell_geom(lvl, cell) == -1) {
+ printf("failed to generate cell\n");
+ return -1;
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+#else
+
+static int load_tileset(struct level *lvl, struct ts_node *tsn)
+{
+ return 0; /* in the level editor we don't need tileset loading */
+}
+
+#endif /* !LEVEL_EDITOR */