]> Dogcows Code - chaz/rasterize/blobdiff - model.c
preliminary support for obj files
[chaz/rasterize] / model.c
diff --git a/model.c b/model.c
index c136ae940ddf2200e80bd6134e4703884c8b279e..f02e4c709c83471a1f872b8392023afda5fc2f53 100644 (file)
--- a/model.c
+++ b/model.c
@@ -7,10 +7,15 @@
 
 #include <errno.h>
 
+#include "array.h"
 #include "tri.h"
 #include "model.h"
 
 
+// create an interface for a vector array
+DEFINE_ARRAY_TYPE(vec);
+
+
 struct model
 {
     list_t*     triangles;
@@ -142,7 +147,7 @@ void model_material(model_t* m, color_t specular, scal_t shininess)
 #if CALC_NORMALS
 
 #include "map.h"
-DECLARE_AND_DEFINE_MAP_TYPE3(vec_t, list_t*, vnorm, vec_compare(*a, *b));
+DEFINE_MAP_TYPE3(vec_t, list_t*, vnorm, vec_compare(*a, *b));
 
 
 /*
@@ -249,6 +254,123 @@ static int _model_read_raw(model_t* m, const char* filename)
 
 static int _model_read_obj(model_t* m, const char* filename)
 {
+    FILE* file = fopen(filename, "r");
+    if (file == NULL) {
+        fprintf(stderr, "Cannot read %s: %s\n", filename, strerror(errno));
+        return -1;
+    }
+
+#if CALC_NORMALS
+    map_t* nlookup = map_vnorm_alloc();
+#endif
+
+    array_t* v  = array_vec_alloc();
+    array_t* vt = array_vec_alloc();
+    array_t* vn = array_vec_alloc();
+
+    array_vec_push(v, VEC_ZERO);
+    array_vec_push(vt, VEC_ZERO);
+    array_vec_push(vn, VEC_ZERO);
+
+    char line[4096];
+    while (fgets(line, 4096, file)) {
+        char name[4096];
+        double f1, f2, f3, f4;
+        int meh;
+        int i1, i2, i3, i4, i5, i6, i7, i8, i9;
+        if (sscanf(line, "v %lf %lf %lf %lf ", &f1, &f2, &f3, &f4) == 4) {
+            array_vec_push(v, vec_new2((scal_t)f1, (scal_t)f2, (scal_t)f3, (scal_t)f4));
+        }
+        else if (sscanf(line, "v %lf %lf %lf ", &f1, &f2, &f3) == 3) {
+            array_vec_push(v, vec_new((scal_t)f1, (scal_t)f2, (scal_t)f3));
+        }
+        else if (sscanf(line, "vt %lf %lf ", &f1, &f2) == 2) {
+            array_vec_push(vt, vec_new((scal_t)f1, (scal_t)f2, S(0.0)));
+        }
+        else if (sscanf(line, "vn %lf %lf %lf ", &f1, &f2, &f3) == 3) {
+            array_vec_push(vn, vec_new((scal_t)f1, (scal_t)f2, (scal_t)f3));
+        }
+        else if (sscanf(line, "f %d %d %d ", &i1, &i2, &i3) == 3) {
+            tri_t* t = tri_alloc(
+                vert_new(*array_vec_index(v, i1)),
+                vert_new(*array_vec_index(v, i2)),
+                vert_new(*array_vec_index(v, i3))
+            );
+            list_push2(&m->triangles, t, mem_free);
+            ++m->count;
+
+#if CALC_NORMALS
+            _find_normals_add_triangle(nlookup, t);
+#else
+            vec_t n = vec_normalize(tri_normal(*t));
+            t->a.n = n;
+            t->b.n = n;
+            t->c.n = n;
+#endif
+        }
+        else if (sscanf(line, "f %d/%d %d/%d %d/%d ", &i1, &i4, &i2, &i4, &i3, &i4) == 6) {
+            tri_t* t = tri_alloc(
+                vert_new(*array_vec_index(v, i1)),
+                vert_new(*array_vec_index(v, i2)),
+                vert_new(*array_vec_index(v, i3))
+            );
+            list_push2(&m->triangles, t, mem_free);
+            ++m->count;
+
+#if CALC_NORMALS
+            _find_normals_add_triangle(nlookup, t);
+#else
+            vec_t n = vec_normalize(tri_normal(*t));
+            t->a.n = n;
+            t->b.n = n;
+            t->c.n = n;
+#endif
+        }
+        else if (sscanf(line, "f %d//%d %d//%d %d//%d ",
+                        &i1, &i2, &i3, &i4, &i5, &i6) == 6) {
+            tri_t* t = tri_alloc(
+                vert_new(*array_vec_index(v, i1)),
+                vert_new(*array_vec_index(v, i3)),
+                vert_new(*array_vec_index(v, i5))
+            );
+            list_push2(&m->triangles, t, mem_free);
+            ++m->count;
+            t->a.n = *array_vec_index(vn, i2);
+            t->b.n = *array_vec_index(vn, i4);
+            t->c.n = *array_vec_index(vn, i6);
+        }
+        else if (sscanf(line, "f %d/%d/%d %d/%d/%d %d/%d/%d ",
+                        &i1, &meh, &i2, &i3, &meh, &i4, &i5, &meh, &i6) == 9) {
+            tri_t* t = tri_alloc(
+                vert_new(*array_vec_index(v, i1)),
+                vert_new(*array_vec_index(v, i3)),
+                vert_new(*array_vec_index(v, i5))
+            );
+            list_push2(&m->triangles, t, mem_free);
+            ++m->count;
+            t->a.n = *array_vec_index(vn, i2);
+            t->b.n = *array_vec_index(vn, i4);
+            t->c.n = *array_vec_index(vn, i6);
+        }
+        // f 1/2 3/4 5/6
+        // f 1/2/3 4/5/6 7/8/9
+    }
+
+    array_destroy(v);
+    array_destroy(vt);
+    array_destroy(vn);
+
+#if CALC_NORMALS
+    map_vnorm_call(nlookup, _find_normals_average);
+    rbtree_destroy(nlookup);
+#endif
+
+    fclose(file);
+    if (m->triangles == NULL) {
+        fprintf(stderr, "No triangles read from %s\n", filename);
+        return -1;
+    }
+    return 0;
 }
 
 
This page took 0.021166 seconds and 4 git commands to generate.