X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Frasterize;a=blobdiff_plain;f=model.c;h=4ed8a8e2be41e097bc0945002c062db733d44839;hp=522527348bccd90dcee20433373b868adf7b1bf0;hb=3955aa40277c4b86a43b21e78d55d2fea7b643ce;hpb=95850b98f73ad7033af60a30e324e9c3cda55389 diff --git a/model.c b/model.c index 5225273..4ed8a8e 100644 --- a/model.c +++ b/model.c @@ -8,8 +8,9 @@ #include #include "array.h" -#include "tri.h" #include "model.h" +#include "raster.h" +#include "tri.h" // create an interface for a vector array @@ -18,12 +19,13 @@ DEFINE_ARRAY_TYPE(vec); struct model { - list_t* triangles; - mat_t model; - color_t specular; - scal_t shininess; - char* name; - int count; + list_t* triangles; + mat_t model; + color_t specular; + scal_t shininess; + const raster_t* texture; + char* name; + int count; }; @@ -60,14 +62,15 @@ model_t* model_alloc2(const char* filename, int type) model_t* m = (model_t*)mem_alloc(sizeof(model_t)); m->triangles = NULL; m->model = MAT_IDENTITY; - m->specular = COLOR_WHITE; + m->specular = COLOR_BLACK; m->shininess = S(64.0); + m->texture = NULL; m->name = mem_strdup(filename); m->count = 0; #if CACHE_GEOMETRY - int count = _model_try_read_cache(filename, &m->triangles); - if (0 < count) { + m->count = _model_try_read_cache(filename, &m->triangles); + if (0 < m->count) { return m; } #endif @@ -96,6 +99,9 @@ model_t* model_alloc2(const char* filename, int type) void model_destroy(model_t* m) { list_destroy(&m->triangles); + if (m->texture) { + raster_destroy((raster_t*)m->texture); + } mem_free(m->name); mem_free(m); } @@ -131,6 +137,14 @@ void model_transformation(const model_t* m, mat_t* transform) *transform = m->model; } +color_t model_tcolor(const model_t* m, vec_t pt) +{ + if (m->texture) { + return raster_color(m->texture, pt); + } + return COLOR_WHITE; +} + void model_transform(model_t* m, const mat_t* transform) { @@ -143,6 +157,11 @@ void model_material(model_t* m, color_t specular, scal_t shininess) m->shininess = shininess; } +void model_texture(model_t* m, const void* p) +{ + m->texture = (const raster_t*)p; +} + #if CALC_NORMALS @@ -315,7 +334,9 @@ static int _model_read_obj(model_t* m, const char* filename) ); list_push2(&m->triangles, t, mem_free); ++m->count; - + t->a.t = *array_vec_index(vt, i2); + t->b.t = *array_vec_index(vt, i4); + t->c.t = *array_vec_index(vt, i6); #if CALC_NORMALS _find_normals_add_triangle(nlookup, t); #else @@ -347,6 +368,9 @@ static int _model_read_obj(model_t* m, const char* filename) ); list_push2(&m->triangles, t, mem_free); ++m->count; + t->a.t = *array_vec_index(vt, i2); + t->b.t = *array_vec_index(vt, i5); + t->c.t = *array_vec_index(vt, i8); t->a.n = *array_vec_index(vn, i3); t->b.n = *array_vec_index(vn, i6); t->c.n = *array_vec_index(vn, i9); @@ -371,7 +395,7 @@ static int _model_read_obj(model_t* m, const char* filename) } -#define _CHECK_IO(X) if ((X) <= 0) goto fail +#define _DO_OR_DONE(X) if ((X) <= 0) goto done /* * Try to read the triangle geometry from the cache file. @@ -382,43 +406,51 @@ static int _model_try_read_cache(const char* filename, list_t** l) char* cachename = mem_strcat(".", filename); FILE* file = fopen(cachename, "rb"); if (file == NULL) { - goto fail; + goto done; } - _CHECK_IO(fread(&count, sizeof(count), 1, file)); - float x1, y1, z1, x2, y2, z2, x3, y3, z3; - for (int i = 0; i < count; ++i) { - _CHECK_IO(fread(&x1, sizeof(float), 1, file)); - _CHECK_IO(fread(&y1, sizeof(float), 1, file)); - _CHECK_IO(fread(&z1, sizeof(float), 1, file)); - _CHECK_IO(fread(&x2, sizeof(float), 1, file)); - _CHECK_IO(fread(&y2, sizeof(float), 1, file)); - _CHECK_IO(fread(&z2, sizeof(float), 1, file)); - _CHECK_IO(fread(&x3, sizeof(float), 1, file)); - _CHECK_IO(fread(&y3, sizeof(float), 1, file)); - _CHECK_IO(fread(&z3, sizeof(float), 1, file)); + while (1) { + _DO_OR_DONE(fread(&x1, sizeof(float), 1, file)); + _DO_OR_DONE(fread(&y1, sizeof(float), 1, file)); + _DO_OR_DONE(fread(&z1, sizeof(float), 1, file)); + _DO_OR_DONE(fread(&x2, sizeof(float), 1, file)); + _DO_OR_DONE(fread(&y2, sizeof(float), 1, file)); + _DO_OR_DONE(fread(&z2, sizeof(float), 1, file)); + _DO_OR_DONE(fread(&x3, sizeof(float), 1, file)); + _DO_OR_DONE(fread(&y3, sizeof(float), 1, file)); + _DO_OR_DONE(fread(&z3, sizeof(float), 1, file)); tri_t* t = tri_alloc( vert_new2((scal_t)x1, (scal_t)y1, (scal_t)z1), vert_new2((scal_t)x2, (scal_t)y2, (scal_t)z2), vert_new2((scal_t)x3, (scal_t)y3, (scal_t)z3) ); + ++count; list_push2(l, t, mem_free); - _CHECK_IO(fread(&x1, sizeof(float), 1, file)); - _CHECK_IO(fread(&y1, sizeof(float), 1, file)); - _CHECK_IO(fread(&z1, sizeof(float), 1, file)); - _CHECK_IO(fread(&x2, sizeof(float), 1, file)); - _CHECK_IO(fread(&y2, sizeof(float), 1, file)); - _CHECK_IO(fread(&z2, sizeof(float), 1, file)); - _CHECK_IO(fread(&x3, sizeof(float), 1, file)); - _CHECK_IO(fread(&y3, sizeof(float), 1, file)); - _CHECK_IO(fread(&z3, sizeof(float), 1, file)); + _DO_OR_DONE(fread(&x1, sizeof(float), 1, file)); + _DO_OR_DONE(fread(&y1, sizeof(float), 1, file)); + _DO_OR_DONE(fread(&z1, sizeof(float), 1, file)); + _DO_OR_DONE(fread(&x2, sizeof(float), 1, file)); + _DO_OR_DONE(fread(&y2, sizeof(float), 1, file)); + _DO_OR_DONE(fread(&z2, sizeof(float), 1, file)); + _DO_OR_DONE(fread(&x3, sizeof(float), 1, file)); + _DO_OR_DONE(fread(&y3, sizeof(float), 1, file)); + _DO_OR_DONE(fread(&z3, sizeof(float), 1, file)); t->a.n = vec_new((scal_t)x1, (scal_t)y1, (scal_t)z1); t->b.n = vec_new((scal_t)x2, (scal_t)y2, (scal_t)z2); t->c.n = vec_new((scal_t)x3, (scal_t)y3, (scal_t)z3); + _DO_OR_DONE(fread(&x1, sizeof(float), 1, file)); + _DO_OR_DONE(fread(&y1, sizeof(float), 1, file)); + _DO_OR_DONE(fread(&x2, sizeof(float), 1, file)); + _DO_OR_DONE(fread(&y2, sizeof(float), 1, file)); + _DO_OR_DONE(fread(&x3, sizeof(float), 1, file)); + _DO_OR_DONE(fread(&y3, sizeof(float), 1, file)); + t->a.t = vec_new((scal_t)x1, (scal_t)y1, S(0.0)); + t->b.t = vec_new((scal_t)x2, (scal_t)y2, S(0.0)); + t->c.t = vec_new((scal_t)x3, (scal_t)y3, S(0.0)); } -fail: +done: mem_free(cachename); if (file != NULL) { fclose(file); @@ -436,39 +468,54 @@ static void _model_write_cache(const char* filename, int count, list_t* l) FILE* file = fopen(cachename, "wb"); if (file == NULL) { fprintf(stderr, "Cannot write %s: %s\n", cachename, strerror(errno)); - goto fail; + goto done; } - _CHECK_IO(fwrite(&count, sizeof(count), 1, file)); + float x1, y1, z1, x2, y2, z2, x3, y3, z3; for (list_t* i = l; i; i = i->link) { tri_t* t = (tri_t*)i->val; - _CHECK_IO(fwrite(&t->a.v.x, sizeof(float), 1, file)); - _CHECK_IO(fwrite(&t->a.v.y, sizeof(float), 1, file)); - _CHECK_IO(fwrite(&t->a.v.z, sizeof(float), 1, file)); - _CHECK_IO(fwrite(&t->b.v.x, sizeof(float), 1, file)); - _CHECK_IO(fwrite(&t->b.v.y, sizeof(float), 1, file)); - _CHECK_IO(fwrite(&t->b.v.z, sizeof(float), 1, file)); - _CHECK_IO(fwrite(&t->c.v.x, sizeof(float), 1, file)); - _CHECK_IO(fwrite(&t->c.v.y, sizeof(float), 1, file)); - _CHECK_IO(fwrite(&t->c.v.z, sizeof(float), 1, file)); - _CHECK_IO(fwrite(&t->a.n.x, sizeof(float), 1, file)); - _CHECK_IO(fwrite(&t->a.n.y, sizeof(float), 1, file)); - _CHECK_IO(fwrite(&t->a.n.z, sizeof(float), 1, file)); - _CHECK_IO(fwrite(&t->b.n.x, sizeof(float), 1, file)); - _CHECK_IO(fwrite(&t->b.n.y, sizeof(float), 1, file)); - _CHECK_IO(fwrite(&t->b.n.z, sizeof(float), 1, file)); - _CHECK_IO(fwrite(&t->c.n.x, sizeof(float), 1, file)); - _CHECK_IO(fwrite(&t->c.n.y, sizeof(float), 1, file)); - _CHECK_IO(fwrite(&t->c.n.z, sizeof(float), 1, file)); + x1 = (float)t->a.v.x; y1 = (float)t->a.v.y; z1 = (float)t->a.v.z; + x2 = (float)t->b.v.x; y2 = (float)t->b.v.y; z2 = (float)t->b.v.z; + x3 = (float)t->c.v.x; y3 = (float)t->c.v.y; z3 = (float)t->c.v.z; + _DO_OR_DONE(fwrite(&x1, sizeof(float), 1, file)); + _DO_OR_DONE(fwrite(&y1, sizeof(float), 1, file)); + _DO_OR_DONE(fwrite(&z1, sizeof(float), 1, file)); + _DO_OR_DONE(fwrite(&x2, sizeof(float), 1, file)); + _DO_OR_DONE(fwrite(&y2, sizeof(float), 1, file)); + _DO_OR_DONE(fwrite(&z2, sizeof(float), 1, file)); + _DO_OR_DONE(fwrite(&x3, sizeof(float), 1, file)); + _DO_OR_DONE(fwrite(&y3, sizeof(float), 1, file)); + _DO_OR_DONE(fwrite(&z3, sizeof(float), 1, file)); + x1 = (float)t->a.n.x; y1 = (float)t->a.n.y; z1 = (float)t->a.n.z; + x2 = (float)t->b.n.x; y2 = (float)t->b.n.y; z2 = (float)t->b.n.z; + x3 = (float)t->c.n.x; y3 = (float)t->c.n.y; z3 = (float)t->c.n.z; + _DO_OR_DONE(fwrite(&x1, sizeof(float), 1, file)); + _DO_OR_DONE(fwrite(&y1, sizeof(float), 1, file)); + _DO_OR_DONE(fwrite(&z1, sizeof(float), 1, file)); + _DO_OR_DONE(fwrite(&x2, sizeof(float), 1, file)); + _DO_OR_DONE(fwrite(&y2, sizeof(float), 1, file)); + _DO_OR_DONE(fwrite(&z2, sizeof(float), 1, file)); + _DO_OR_DONE(fwrite(&x3, sizeof(float), 1, file)); + _DO_OR_DONE(fwrite(&y3, sizeof(float), 1, file)); + _DO_OR_DONE(fwrite(&z3, sizeof(float), 1, file)); + x1 = (float)t->a.t.x; y1 = (float)t->a.t.y; + x2 = (float)t->b.t.x; y2 = (float)t->b.t.y; + x3 = (float)t->c.t.x; y3 = (float)t->c.t.y; + _DO_OR_DONE(fwrite(&x1, sizeof(float), 1, file)); + _DO_OR_DONE(fwrite(&y1, sizeof(float), 1, file)); + _DO_OR_DONE(fwrite(&x2, sizeof(float), 1, file)); + _DO_OR_DONE(fwrite(&y2, sizeof(float), 1, file)); + _DO_OR_DONE(fwrite(&x3, sizeof(float), 1, file)); + _DO_OR_DONE(fwrite(&y3, sizeof(float), 1, file)); } -fail: +done: mem_free(cachename); if (file != NULL) { fclose(file); } } -#undef _CHECK_IO +#undef _DO_OR_DIE