foo
[vrlugburz] / src / scenefile.c
index 39d9b92..25cdf28 100644 (file)
@@ -61,6 +61,7 @@ int load_scenefile(struct scenefile *scn, const char *fname)
        char *sep;
        struct rbtree *rbtree = 0;
 
+       memset(scn, 0, sizeof *scn);
 
        varr_size = varr_max = narr_size = narr_max = tarr_size = tarr_max = 0;
        varr = narr = 0;
@@ -73,8 +74,7 @@ int load_scenefile(struct scenefile *scn, const char *fname)
 
        if(!(rbtree = rb_create(cmp_facevert))) {
                fprintf(stderr, "load_scenefile: failed to create facevertex search tree\n");
-               fclose(fp);
-               return -1;
+               goto fail;
        }
        rb_set_delete_func(rbtree, free_rbnode_key, 0);
 
@@ -87,6 +87,14 @@ int load_scenefile(struct scenefile *scn, const char *fname)
        path_prefix = alloca(strlen(buf) + 1);
        strcpy(path_prefix, buf);
 
+       if(sep) {
+               sep = (char*)fname + (sep - buf);
+       }
+       if(!(scn->fname = strdup(sep ? sep + 1 : fname))) {
+               fprintf(stderr, "failed to allocate scenefile name buffer\n");
+               goto fail;
+       }
+
        if(!(mesh = malloc(sizeof *mesh))) {
                fprintf(stderr, "failed to allocate mesh\n");
                fclose(fp);
@@ -162,6 +170,7 @@ int load_scenefile(struct scenefile *scn, const char *fname)
                                        goto fail;
                                }
                                init_mesh(mesh);
+                               mesh->name = strdup(cleanline(line + 2));
                        }
                        break;
 
@@ -199,12 +208,16 @@ int load_scenefile(struct scenefile *scn, const char *fname)
        }
        mesh = 0;
 
-       printf("load_scenefile: loaded %d meshes, %d vertices\n", scn->num_meshes,
-                       varr_size);
+       printf("load_scenefile %s: loaded %d meshes, %d vertices\n", scn->fname,
+                       scn->num_meshes, varr_size);
 
        res = 0;
 
+       if(0) {
 fail:
+               free(scn->fname);
+       }
+
        fclose(fp);
        free(mesh);
        free(varr);
@@ -260,6 +273,19 @@ void destroy_scenefile(struct scenefile *scn)
        }
 }
 
+struct mesh *find_mesh_prefix(struct scenefile *scn, const char *prefix)
+{
+       int len = strlen(prefix);
+       struct mesh *m = scn->meshlist;
+       while(m) {
+               if(m->name && memcmp(m->name, prefix, len) == 0) {
+                       return m;
+               }
+               m = m->next;
+       }
+       return 0;
+}
+
 static char *cleanline(char *s)
 {
        char *ptr;
@@ -320,7 +346,7 @@ static int load_mtllib(struct scenefile *scn, const char *path_prefix, const cha
        FILE *fp;
        char buf[256], *line;
        struct objmtl om;
-       struct material *mtl;
+       struct material *mtl = 0;
 
        if(path_prefix && *path_prefix) {
                sprintf(buf, "%s/%s", path_prefix, mtlfname);
@@ -339,14 +365,18 @@ static int load_mtllib(struct scenefile *scn, const char *path_prefix, const cha
 
                if(memcmp(line, "newmtl", 6) == 0) {
                        if(mtl) {
+                               conv_mtl(mtl, &om, path_prefix);
                                mtl->next = scn->mtllist;
                                scn->mtllist = mtl;
                        }
-                       if((mtl = calloc(1, sizeof *mtl))) {
-                               if((line = cleanline(line + 6))) {
-                                       mtl->name = strdup(line);
-                               }
+                       mtl = calloc(1, sizeof *mtl);
+
+                       memset(&om, 0, sizeof om);
+
+                       if((line = cleanline(line + 6))) {
+                               om.name = strdup(line);
                        }
+
                } else if(memcmp(line, "Kd", 2) == 0) {
                        sscanf(line + 3, "%f %f %f", &om.kd.x, &om.kd.y, &om.kd.z);
                } else if(memcmp(line, "Ks", 2) == 0) {
@@ -370,10 +400,10 @@ static int load_mtllib(struct scenefile *scn, const char *path_prefix, const cha
                                om.map_alpha = strdup(line);
                        }
                }
-               conv_mtl(mtl, &om, path_prefix);
        }
 
        if(mtl) {
+               conv_mtl(mtl, &om, path_prefix);
                mtl->next = scn->mtllist;
                scn->mtllist = mtl;
        }
@@ -397,7 +427,7 @@ static void conv_mtl(struct material *mm, struct objmtl *om, const char *path_pr
        int len, prefix_len, maxlen = 0;
 
        memset(mm, 0, sizeof *mm);
-       mm->name = strdup(om->name);
+       mm->name = om->name;
        mm->color = om->kd;
        mm->spec = om->ks;
        mm->shininess = om->shin;