# HG changeset patch # User John Tsiombikas # Date 1437356333 -10800 # Node ID bc64090fe3d1d193f5df5eda2967b9c9439e1f64 # Parent 16fdca2a1ef51c880ce453ae112477e438b84114 foo diff -r 16fdca2a1ef5 -r bc64090fe3d1 src/object.c --- a/src/object.c Sun Jul 19 18:30:29 2015 +0300 +++ b/src/object.c Mon Jul 20 04:38:53 2015 +0300 @@ -1,16 +1,133 @@ +#include #include #include -#include "object.h" -#include "logger.h" +#include "tgi_impl.h" + +static int namecount; struct tgi_object *tgi_create_object(const char *name) { struct tgi_object *o; + int nmsize; if(!(o = malloc(sizeof *o))) { tgi_log("failed to allocate memory\n"); return 0; } memset(o, 0, sizeof *o); + + nmsize = name ? strlen(name) : 15; + if(!(o->name = malloc(nmsize + 1))) { + tgi_log("failed to allocate name string\n"); + free(o); + return 0; + } + + if(!name) { + sprintf(o->name, "tgi_object%03d", namecount++); + } else { + strcpy(o->name, name); + } + return o; } + +void tgi_destroy_object(struct tgi_object *o) +{ + if(o) { + if(o->shape) { + tgi_destroy_shape(o->shape); + } + if(o->mtl) { + tgi_destroy_material(o->mtl); + } + free(o->name); + } +} + +void tgi_set_object_shape(struct tgi_object *o, struct tgi_shape *s) +{ + if(o->shape) { + tgi_destroy_shape(o->shape); + } + o->shape = s; +} + +void tgi_set_object_mtl(struct tgi_object *o, struct tgi_material *m) +{ + if(o->mtl) { + tgi_destroy_material(o->mtl); + } + o->mtl = m; +} + +/* mat should point to an array of 16 floats (4x4 homogeneous transformation matrix) */ +void tgi_load_matrix(struct tgi_object *o, const float *mat) +{ + mat4_t tmp; + memcpy(tmp, mat, 16 * sizeof(float)); + m4_transpose(o->xform, tmp); + m4_inverse(o->inv_xform, o->xform); +} + +void tgi_mult_matrix(struct tgi_object *o, const float *mat) +{ + mat4_t tmp; + memcpy(tmp, mat, 16 * sizeof(float)); + m4_transpose(tmp, tmp); + m4_mult(o->xform, o->xform, tmp); + m4_inverse(o->inv_xform, o->xform); +} + +void tgi_load_identity(struct tgi_object *o) +{ + static const float id[] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; + tgi_load_matrix(o, id); +} + +void tgi_translate(struct tgi_object *o, float x, float y, float z) +{ + float mat[] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; + mat[12] = x; + mat[13] = y; + mat[14] = z; + tgi_mult_matrix(o, mat); +} + +void tgi_rotate(struct tgi_object *o, float angle, float x, float y, float z) +{ + mat4_t mat; + m4_rotate_axis(mat, DEG_TO_RAD(angle), x, y, z); + m4_transpose(mat, mat); + tgi_mult_matrix(o, mat[0]); +} + +void tgi_scale(struct tgi_object *o, float x, float y, float z) +{ + float mat[] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; + mat[0] = x; + mat[5] = y; + mat[10] = z; + tgi_mult_matrix(o, mat); +} + +void tgi_lookat(struct tgi_object *o, float x, float y, float z, + float tx, float ty, float tz, float ux, float uy, float uz) +{ + float mat[16]; + vec3_t vi, vj, vk; + + vk = v3_normalize(v3_cons(tx - x, ty - y, tz - z)); + vj = v3_cons(ux, uy, uz); + vi = v3_normalize(v3_cross(vj, vk)); + vj = v3_normalize(v3_cross(vk, vi)); + + mat[0] = vi.x; mat[1] = vj.x, mat[2] = vk.x; + mat[4] = vi.y; mat[5] = vj.y, mat[6] = vk.y; + mat[8] = vi.z; mat[9] = vj.z, mat[10] = vk.z; + mat[3] = mat[7] = mat[11] = 0.0; + mat[12] = x; mat[13] = y; mat[14] = z; + mat[15] = 1.0f; + + tgi_mult_matrix(o, mat); +} diff -r 16fdca2a1ef5 -r bc64090fe3d1 src/object.h --- a/src/object.h Sun Jul 19 18:30:29 2015 +0300 +++ b/src/object.h Mon Jul 20 04:38:53 2015 +0300 @@ -2,10 +2,13 @@ #define TGI_OBJECT_H_ #include "tinygi.h" +#include "vmath/vmath.h" struct tgi_object { char *name; struct tgi_shape *shape; + struct tgi_material *mtl; + mat4_t xform, inv_xform; struct tgi_object *next; /* for linking it into various lists */ }; diff -r 16fdca2a1ef5 -r bc64090fe3d1 src/scene.c --- a/src/scene.c Sun Jul 19 18:30:29 2015 +0300 +++ b/src/scene.c Mon Jul 20 04:38:53 2015 +0300 @@ -50,7 +50,7 @@ assert(tgi->objects); } -int tgi_del_object(struct tinygi *tgi, struct tgi_object *o) +int tgi_remove_object(struct tinygi *tgi, struct tgi_object *o) { int i, idx = -1, sz = dynarr_size(tgi->objects); diff -r 16fdca2a1ef5 -r bc64090fe3d1 src/tgi_impl.h --- a/src/tgi_impl.h Sun Jul 19 18:30:29 2015 +0300 +++ b/src/tgi_impl.h Mon Jul 20 04:38:53 2015 +0300 @@ -4,6 +4,7 @@ #include "tinygi.h" #include "object.h" #include "logger.h" +#include "vmath/vmath.h" struct tinygi { struct tgi_object **objects; /* dynarr */ diff -r 16fdca2a1ef5 -r bc64090fe3d1 src/tinygi.h --- a/src/tinygi.h Sun Jul 19 18:30:29 2015 +0300 +++ b/src/tinygi.h Mon Jul 20 04:38:53 2015 +0300 @@ -6,21 +6,23 @@ struct tinygi; struct tgi_object; struct tgi_shape; +struct tgi_material; struct tinygi *tgi_init(void); void tgi_destroy(struct tinygi *tgi); void tgi_clear_scene(struct tinygi *tgi); int tgi_load_scene(struct tinygi *tgi, const char *fname); +/* tinygi takes ownership of added objects */ void tgi_add_object(struct tinygi *tgi, struct tgi_object *o); -int tgi_del_object(struct tinygi *tgi, struct tgi_object *o); +int tgi_remove_object(struct tinygi *tgi, struct tgi_object *o); struct tgi_object *tgi_find_object(struct tinygi *tgi, const char *name); struct tgi_object *tgi_get_object(struct tinygi *tgi, int idx); int tgi_get_object_count(struct tinygi *tgi); /* shapes */ -struct tgi_shape *tgi_create_sphere(float rad); +struct tgi_shape *tgi_create_sphere(float x, float y, float z, float rad); struct tgi_shape *tgi_create_box(float x0, float y0, float z0, float x1, float y1, float z1); void tgi_destroy_shape(struct tgi_shape *s); @@ -28,7 +30,24 @@ /* name can be null, in which case it's automatically generated */ struct tgi_object *tgi_create_object(const char *name); void tgi_destroy_object(struct tgi_object *o); +/* object takes ownership of the shape */ void tgi_set_object_shape(struct tgi_object *o, struct tgi_shape *s); +/* object takes ownership of the material */ void tgi_set_object_mtl(struct tgi_object *o, struct tgi_material *m); +/* mat should point to an array of 16 floats (4x4 homogeneous transformation matrix) */ +void tgi_load_matrix(struct tgi_object *o, const float *mat); +void tgi_mult_matrix(struct tgi_object *o, const float *mat); +void tgi_load_identity(struct tgi_object *o); +void tgi_translate(struct tgi_object *o, float x, float y, float z); +void tgi_rotate(struct tgi_object *o, float angle, float x, float y, float z); +void tgi_scale(struct tgi_object *o, float x, float y, float z); +void tgi_lookat(struct tgi_object *o, float x, float y, float z, + float tx, float ty, float tz, float ux, float uy, float uz); + +/* materials */ +struct tgi_material *tgi_create_material(void); +void tgi_destroy_material(struct tgi_material *mtl); +/* TODO */ + #endif /* TINYGI_H_ */