nuclear@1: #include nuclear@0: #include nuclear@0: #include nuclear@1: #include "tgi_impl.h" nuclear@1: nuclear@1: static int namecount; nuclear@0: nuclear@0: struct tgi_object *tgi_create_object(const char *name) nuclear@0: { nuclear@0: struct tgi_object *o; nuclear@1: int nmsize; nuclear@0: nuclear@0: if(!(o = malloc(sizeof *o))) { nuclear@0: tgi_log("failed to allocate memory\n"); nuclear@0: return 0; nuclear@0: } nuclear@0: memset(o, 0, sizeof *o); nuclear@1: nuclear@1: nmsize = name ? strlen(name) : 15; nuclear@1: if(!(o->name = malloc(nmsize + 1))) { nuclear@1: tgi_log("failed to allocate name string\n"); nuclear@1: free(o); nuclear@1: return 0; nuclear@1: } nuclear@1: nuclear@1: if(!name) { nuclear@1: sprintf(o->name, "tgi_object%03d", namecount++); nuclear@1: } else { nuclear@1: strcpy(o->name, name); nuclear@1: } nuclear@1: nuclear@0: return o; nuclear@0: } nuclear@1: nuclear@1: void tgi_destroy_object(struct tgi_object *o) nuclear@1: { nuclear@1: if(o) { nuclear@1: if(o->shape) { nuclear@1: tgi_destroy_shape(o->shape); nuclear@1: } nuclear@1: free(o->name); nuclear@1: } nuclear@1: } nuclear@1: nuclear@1: void tgi_set_object_shape(struct tgi_object *o, struct tgi_shape *s) nuclear@1: { nuclear@1: if(o->shape) { nuclear@1: tgi_destroy_shape(o->shape); nuclear@1: } nuclear@1: o->shape = s; nuclear@1: } nuclear@1: nuclear@1: /* mat should point to an array of 16 floats (4x4 homogeneous transformation matrix) */ nuclear@1: void tgi_load_matrix(struct tgi_object *o, const float *mat) nuclear@1: { nuclear@1: mat4_t tmp; nuclear@1: memcpy(tmp, mat, 16 * sizeof(float)); nuclear@1: m4_transpose(o->xform, tmp); nuclear@1: m4_inverse(o->inv_xform, o->xform); nuclear@1: } nuclear@1: nuclear@1: void tgi_mult_matrix(struct tgi_object *o, const float *mat) nuclear@1: { nuclear@1: mat4_t tmp; nuclear@1: memcpy(tmp, mat, 16 * sizeof(float)); nuclear@1: m4_transpose(tmp, tmp); nuclear@1: m4_mult(o->xform, o->xform, tmp); nuclear@1: m4_inverse(o->inv_xform, o->xform); nuclear@1: } nuclear@1: nuclear@1: void tgi_load_identity(struct tgi_object *o) nuclear@1: { nuclear@1: static const float id[] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; nuclear@1: tgi_load_matrix(o, id); nuclear@1: } nuclear@1: nuclear@1: void tgi_translate(struct tgi_object *o, float x, float y, float z) nuclear@1: { nuclear@1: float mat[] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; nuclear@1: mat[12] = x; nuclear@1: mat[13] = y; nuclear@1: mat[14] = z; nuclear@1: tgi_mult_matrix(o, mat); nuclear@1: } nuclear@1: nuclear@1: void tgi_rotate(struct tgi_object *o, float angle, float x, float y, float z) nuclear@1: { nuclear@1: mat4_t mat; nuclear@1: m4_rotate_axis(mat, DEG_TO_RAD(angle), x, y, z); nuclear@1: m4_transpose(mat, mat); nuclear@1: tgi_mult_matrix(o, mat[0]); nuclear@1: } nuclear@1: nuclear@1: void tgi_scale(struct tgi_object *o, float x, float y, float z) nuclear@1: { nuclear@1: float mat[] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; nuclear@1: mat[0] = x; nuclear@1: mat[5] = y; nuclear@1: mat[10] = z; nuclear@1: tgi_mult_matrix(o, mat); nuclear@1: } nuclear@1: nuclear@1: void tgi_lookat(struct tgi_object *o, float x, float y, float z, nuclear@1: float tx, float ty, float tz, float ux, float uy, float uz) nuclear@1: { nuclear@1: float mat[16]; nuclear@1: vec3_t vi, vj, vk; nuclear@1: nuclear@1: vk = v3_normalize(v3_cons(tx - x, ty - y, tz - z)); nuclear@1: vj = v3_cons(ux, uy, uz); nuclear@1: vi = v3_normalize(v3_cross(vj, vk)); nuclear@1: vj = v3_normalize(v3_cross(vk, vi)); nuclear@1: nuclear@1: mat[0] = vi.x; mat[1] = vj.x, mat[2] = vk.x; nuclear@1: mat[4] = vi.y; mat[5] = vj.y, mat[6] = vk.y; nuclear@1: mat[8] = vi.z; mat[9] = vj.z, mat[10] = vk.z; nuclear@1: mat[3] = mat[7] = mat[11] = 0.0; nuclear@1: mat[12] = x; mat[13] = y; mat[14] = z; nuclear@1: mat[15] = 1.0f; nuclear@1: nuclear@1: tgi_mult_matrix(o, mat); nuclear@1: }