]>
Dogcows Code - chaz/rasterize/blob - model.c
c136ae940ddf2200e80bd6134e4703884c8b279e
3 * CS5600 University of Utah
5 * mcgarvey@eng.utah.edu
25 static int _model_read_raw(model_t
* m
, const char* filename
);
26 static int _model_read_obj(model_t
* m
, const char* filename
);
28 static int _model_try_read_cache(const char* filename
, list_t
** l
);
29 static void _model_write_cache(const char* filename
, int count
, list_t
* l
);
32 model_t
* model_alloc(const char* filename
)
35 char* ext
= strrchr(filename
, '.');
41 if (strcmp(ext
, "raw") == 0) {
42 return model_alloc2(filename
, MODEL_TYPE_RAW
);
44 if (strcmp(ext
, "obj") == 0) {
45 return model_alloc2(filename
, MODEL_TYPE_OBJ
);
49 fprintf(stderr
, "Unknown file type: %s", filename
);
53 model_t
* model_alloc2(const char* filename
, int type
)
55 model_t
* m
= (model_t
*)mem_alloc(sizeof(model_t
));
57 m
->model
= MAT_IDENTITY
;
58 m
->specular
= COLOR_WHITE
;
59 m
->shininess
= S(64.0);
60 m
->name
= mem_strdup(filename
);
64 int count
= _model_try_read_cache(filename
, &m
->triangles
);
73 load
= _model_read_raw(m
, filename
);
76 load
= _model_read_obj(m
, filename
);
85 _model_write_cache(filename
, m
->count
, m
->triangles
);
91 void model_destroy(model_t
* m
)
93 list_destroy(&m
->triangles
);
99 const list_t
* model_geometry(const model_t
* m
)
104 int model_size(const model_t
* m
)
109 const char* model_name(const model_t
* m
)
114 color_t
model_specular(const model_t
* m
)
119 scal_t
model_shininess(const model_t
* m
)
124 void model_transformation(const model_t
* m
, mat_t
* transform
)
126 *transform
= m
->model
;
130 void model_transform(model_t
* m
, const mat_t
* transform
)
132 m
->model
= mat_mult(m
->model
, *transform
);
135 void model_material(model_t
* m
, color_t specular
, scal_t shininess
)
137 m
->specular
= specular
;
138 m
->shininess
= shininess
;
145 DECLARE_AND_DEFINE_MAP_TYPE3(vec_t
, list_t
*, vnorm
, vec_compare(*a
, *b
));
149 * Associate a triangle with one of its vertices.
151 static void _find_normals_add_vertex(map_t
* m
, vec_t v
, tri_t
* t
)
153 list_t
** l
= map_vnorm_search(m
, v
);
155 map_vnorm_data_t
* d
= map_vnorm_insert(m
, v
, NULL
);
162 * Associate a triangle with all of its vertices.
164 static void _find_normals_add_triangle(map_t
* m
, tri_t
* t
)
166 _find_normals_add_vertex(m
, t
->a
.v
, t
);
167 _find_normals_add_vertex(m
, t
->b
.v
, t
);
168 _find_normals_add_vertex(m
, t
->c
.v
, t
);
172 * Calculate an averaged normal from a list of triangles that share a common
175 static void _find_normals_average(const vec_t
* v
, list_t
** l
)
177 // first, compute the average normal
179 for (list_t
* i
= *l
; i
; i
= i
->link
) {
180 tri_t
* t
= (tri_t
*)i
->val
;
181 n
= vec_add(n
, tri_normal(*t
));
183 n
= vec_normalize(n
);
185 // set the normal on each triangle's vertex that is shared
187 tri_t
* t
= (tri_t
*)(*l
)->val
;
188 if (vec_isequal(*v
, t
->a
.v
)) {
191 else if (vec_isequal(*v
, t
->b
.v
)) {
194 else if (vec_isequal(*v
, t
->c
.v
)) {
201 #endif // CALC_NORMALS
204 static int _model_read_raw(model_t
* m
, const char* filename
)
206 FILE* file
= fopen(filename
, "r");
208 fprintf(stderr
, "Cannot read %s: %s\n", filename
, strerror(errno
));
213 map_t
* nlookup
= map_vnorm_alloc();
216 double x1
, y1
, z1
, x2
, y2
, z2
, x3
, y3
, z3
;
217 while (fscanf(file
, " %lf %lf %lf %lf %lf %lf %lf %lf %lf",
218 &x1
, &y1
, &z1
, &x2
, &y2
, &z2
, &x3
, &y3
, &z3
) == 9) {
219 tri_t
* t
= tri_alloc(
220 vert_new2((scal_t
)x1
, (scal_t
)y1
, (scal_t
)z1
),
221 vert_new2((scal_t
)x2
, (scal_t
)y2
, (scal_t
)z2
),
222 vert_new2((scal_t
)x3
, (scal_t
)y3
, (scal_t
)z3
)
224 list_push2(&m
->triangles
, t
, mem_free
);
228 _find_normals_add_triangle(nlookup
, t
);
230 vec_t n
= vec_normalize(tri_normal(*t
));
238 map_vnorm_call(nlookup
, _find_normals_average
);
239 rbtree_destroy(nlookup
);
243 if (m
->triangles
== NULL
) {
244 fprintf(stderr
, "No triangles read from %s\n", filename
);
250 static int _model_read_obj(model_t
* m
, const char* filename
)
255 #define _CHECK_IO(X) if ((X) <= 0) goto fail
258 * Try to read the triangle geometry from the cache file.
260 static int _model_try_read_cache(const char* filename
, list_t
** l
)
263 char* cachename
= mem_strcat(".", filename
);
264 FILE* file
= fopen(cachename
, "rb");
269 _CHECK_IO(fread(&count
, sizeof(count
), 1, file
));
271 float x1
, y1
, z1
, x2
, y2
, z2
, x3
, y3
, z3
;
272 for (int i
= 0; i
< count
; ++i
) {
273 _CHECK_IO(fread(&x1
, sizeof(float), 1, file
));
274 _CHECK_IO(fread(&y1
, sizeof(float), 1, file
));
275 _CHECK_IO(fread(&z1
, sizeof(float), 1, file
));
276 _CHECK_IO(fread(&x2
, sizeof(float), 1, file
));
277 _CHECK_IO(fread(&y2
, sizeof(float), 1, file
));
278 _CHECK_IO(fread(&z2
, sizeof(float), 1, file
));
279 _CHECK_IO(fread(&x3
, sizeof(float), 1, file
));
280 _CHECK_IO(fread(&y3
, sizeof(float), 1, file
));
281 _CHECK_IO(fread(&z3
, sizeof(float), 1, file
));
282 tri_t
* t
= tri_alloc(
283 vert_new2((scal_t
)x1
, (scal_t
)y1
, (scal_t
)z1
),
284 vert_new2((scal_t
)x2
, (scal_t
)y2
, (scal_t
)z2
),
285 vert_new2((scal_t
)x3
, (scal_t
)y3
, (scal_t
)z3
)
287 list_push2(l
, t
, mem_free
);
288 _CHECK_IO(fread(&x1
, sizeof(float), 1, file
));
289 _CHECK_IO(fread(&y1
, sizeof(float), 1, file
));
290 _CHECK_IO(fread(&z1
, sizeof(float), 1, file
));
291 _CHECK_IO(fread(&x2
, sizeof(float), 1, file
));
292 _CHECK_IO(fread(&y2
, sizeof(float), 1, file
));
293 _CHECK_IO(fread(&z2
, sizeof(float), 1, file
));
294 _CHECK_IO(fread(&x3
, sizeof(float), 1, file
));
295 _CHECK_IO(fread(&y3
, sizeof(float), 1, file
));
296 _CHECK_IO(fread(&z3
, sizeof(float), 1, file
));
297 t
->a
.n
= vec_new((scal_t
)x1
, (scal_t
)y1
, (scal_t
)z1
);
298 t
->b
.n
= vec_new((scal_t
)x2
, (scal_t
)y2
, (scal_t
)z2
);
299 t
->c
.n
= vec_new((scal_t
)x3
, (scal_t
)y3
, (scal_t
)z3
);
312 * Write the triangle data to the cache.
314 static void _model_write_cache(const char* filename
, int count
, list_t
* l
)
316 char* cachename
= mem_strcat(".", filename
);
317 FILE* file
= fopen(cachename
, "wb");
319 fprintf(stderr
, "Cannot write %s: %s\n", cachename
, strerror(errno
));
323 _CHECK_IO(fwrite(&count
, sizeof(count
), 1, file
));
324 for (list_t
* i
= l
; i
; i
= i
->link
) {
325 tri_t
* t
= (tri_t
*)i
->val
;
326 _CHECK_IO(fwrite(&t
->a
.v
.x
, sizeof(float), 1, file
));
327 _CHECK_IO(fwrite(&t
->a
.v
.y
, sizeof(float), 1, file
));
328 _CHECK_IO(fwrite(&t
->a
.v
.z
, sizeof(float), 1, file
));
329 _CHECK_IO(fwrite(&t
->b
.v
.x
, sizeof(float), 1, file
));
330 _CHECK_IO(fwrite(&t
->b
.v
.y
, sizeof(float), 1, file
));
331 _CHECK_IO(fwrite(&t
->b
.v
.z
, sizeof(float), 1, file
));
332 _CHECK_IO(fwrite(&t
->c
.v
.x
, sizeof(float), 1, file
));
333 _CHECK_IO(fwrite(&t
->c
.v
.y
, sizeof(float), 1, file
));
334 _CHECK_IO(fwrite(&t
->c
.v
.z
, sizeof(float), 1, file
));
335 _CHECK_IO(fwrite(&t
->a
.n
.x
, sizeof(float), 1, file
));
336 _CHECK_IO(fwrite(&t
->a
.n
.y
, sizeof(float), 1, file
));
337 _CHECK_IO(fwrite(&t
->a
.n
.z
, sizeof(float), 1, file
));
338 _CHECK_IO(fwrite(&t
->b
.n
.x
, sizeof(float), 1, file
));
339 _CHECK_IO(fwrite(&t
->b
.n
.y
, sizeof(float), 1, file
));
340 _CHECK_IO(fwrite(&t
->b
.n
.z
, sizeof(float), 1, file
));
341 _CHECK_IO(fwrite(&t
->c
.n
.x
, sizeof(float), 1, file
));
342 _CHECK_IO(fwrite(&t
->c
.n
.y
, sizeof(float), 1, file
));
343 _CHECK_IO(fwrite(&t
->c
.n
.z
, sizeof(float), 1, file
));
This page took 0.043004 seconds and 3 git commands to generate.