#include "treestore.h"
#include "mesh.h"
-static struct material *add_material(struct level *lvl, struct material *mtl);
-static int append_polygons(struct bvhnode *bnode, struct triangle *faces, int num_faces, struct material *mtl);
+static int add_mesh_faces(struct bvhnode *bnode, struct mesh *mesh);
int load_level(struct level *lvl, const char *fname)
{
char path[256];
struct ts_node *root, *node;
struct scenefile scn;
- struct mesh *mesh;
- struct material *mtl;
+ struct mesh *mesh, *tail;
memset(lvl, 0, sizeof *lvl);
if(!(lvl->st_root = calloc(1, sizeof *lvl->st_root)) ||
if(load_scenefile(&scn, path) == -1) {
goto cont;
}
- mesh = scn.meshlist;
+ mesh = tail = scn.meshlist;
while(mesh) {
- mtl = add_material(lvl, &mesh->mtl);
- append_polygons(lvl->st_root, mesh->faces, mesh->num_faces, mtl);
+ add_mesh_faces(lvl->st_root, mesh);
+ tail = mesh;
mesh = mesh->next;
}
+ if(tail) {
+ tail->next = lvl->meshlist;
+ lvl->meshlist = scn.meshlist;
+ scn.meshlist = 0;
+ }
destroy_scenefile(&scn);
}
cont: node = node->next;
void destroy_level(struct level *lvl)
{
+ struct mesh *mesh;
+
free_bvh_tree(lvl->st_root);
free_bvh_tree(lvl->dyn_root);
- free(lvl->mtls);
+
+ while(lvl->meshlist) {
+ mesh = lvl->meshlist;
+ lvl->meshlist = lvl->meshlist->next;
+ destroy_mesh(mesh);
+ }
}
if(!bn) return;
if(bn->faces) {
- tri = bn->faces;
- curmtl = tri->mtl;
+ curmtl = bn->faces[0]->mtl;
glBegin(GL_TRIANGLES);
for(i=0; i<bn->num_faces; i++) {
+ tri = bn->faces[i];
if(tri->mtl != curmtl) {
glEnd();
color[0] = tri->mtl->color.x;
glTexCoord2fv(&tri->v[j].tex.x);
glVertex3fv(&tri->v[j].pos.x);
}
- tri++;
}
glEnd();
}
draw_level_rec(lvl->dyn_root);
}
-static struct material *add_material(struct level *lvl, struct material *mtl)
-{
- int i, newsz;
- struct material *tmp;
-
- for(i=0; i<lvl->num_mtls; i++) {
- if(memcmp(lvl->mtls + i, mtl, sizeof *mtl) == 0) {
- return lvl->mtls + i;
- }
- }
-
- if(lvl->num_mtls >= lvl->max_mtls) {
- newsz = lvl->max_mtls ? lvl->max_mtls * 2 : 16;
- if(!(tmp = realloc(lvl->mtls, newsz * sizeof *lvl->mtls))) {
- fprintf(stderr, "add_material: failed to resize materials array to %d\n", newsz);
- return 0;
- }
- lvl->mtls = tmp;
- lvl->max_mtls = newsz;
- }
- lvl->mtls[lvl->num_mtls] = *mtl;
-
- return lvl->mtls + lvl->num_mtls++;
-}
-
-static int append_polygons(struct bvhnode *bnode, struct triangle *faces, int num_faces, struct material *mtl)
+static int add_mesh_faces(struct bvhnode *bnode, struct mesh *mesh)
{
int i, j, newsz;
- struct triangle *tri;
+ void *tmp;
+ struct triangle *tri, **triptr;
- newsz = bnode->num_faces + num_faces;
- if(!(tri = realloc(bnode->faces, newsz * sizeof *bnode->faces))) {
+ newsz = bnode->num_faces + mesh->num_faces;
+ if(!(tmp = realloc(bnode->faces, newsz * sizeof *bnode->faces))) {
fprintf(stderr, "append_polygons: failed to resize faces array to %d\n", newsz);
return -1;
}
- bnode->faces = tri;
- tri += bnode->num_faces;
+ bnode->faces = tmp;
+ triptr = bnode->faces + bnode->num_faces;
bnode->num_faces = newsz;
- for(i=0; i<num_faces; i++) {
- *tri = *faces++;
- tri->mtl = mtl;
-
+ tri = mesh->faces;
+ for(i=0; i<mesh->num_faces; i++) {
+ *triptr++ = tri;
for(j=0; j<3; j++) {
cgm_vec3 *p = &tri->v[j].pos;
if(p->x < bnode->aabb.vmin.x) bnode->aabb.vmin.x = p->x;