From 4a6a108d06f6ca67c851a84602bbe2dfb05c092a Mon Sep 17 00:00:00 2001 From: Shariq Shah Date: Sat, 27 Apr 2019 11:46:42 +1000 Subject: [PATCH] Implemented circle and arc drawing in immediate mode renderer and fixed bug with immediate renderer. Also changed all linmath functions to use degrees as parameters and change to radians inside the function --- assets/shaders/blinn_phong.frag.orig | 130 ---- src/common/linmath.c | 1051 +++++++++++++------------- src/game/editor.c | 53 +- src/game/editor.h | 2 + src/game/geometry.c | 8 +- src/game/geometry.h | 2 + src/game/im_render.c | 45 +- src/game/im_render.h | 4 +- src/game/transform.c | 2 +- todo.txt | 6 +- 10 files changed, 612 insertions(+), 691 deletions(-) delete mode 100755 assets/shaders/blinn_phong.frag.orig diff --git a/assets/shaders/blinn_phong.frag.orig b/assets/shaders/blinn_phong.frag.orig deleted file mode 100755 index f4bf122..0000000 --- a/assets/shaders/blinn_phong.frag.orig +++ /dev/null @@ -1,130 +0,0 @@ -//include fog.glsl common.glsl commonFrag.glsl version.glsl - -struct Light -{ - vec3 position; - vec3 direction; - float outer_angle; - float inner_angle; - float falloff; - float intensity; - vec3 color; - uint pcf_enabled; - int type; - int radius; - float depth_bias; -}; - -const int LT_SPOT = 0; -const int LT_DIR = 1; -const int LT_POINT = 2; - -const int MAX_LIGHTS = 128; - -uniform sampler2D diffuse_texture; -uniform Light lights[MAX_LIGHTS]; -uniform int total_active_lights; - -uniform float specular; -uniform float diffuse; -uniform float specular_strength; -out vec4 frag_color; - -vec3 calc_point_light(in Light light) -{ - vec3 diffuse_comp = vec3(0.0); - vec3 specular_comp = vec3(0.0); - vec3 light_direction = vertex - light.position; - float dist = abs(length(light_direction)); - if(dist <= light.radius) - { - light_direction = normalize(light_direction); - vec3 normalized_normal = normalize(normal); - float cos_ang_incidence = dot(normalized_normal, -light_direction); - cos_ang_incidence = clamp(cos_ang_incidence, 0, 1); - - if(cos_ang_incidence > 0) - { - diffuse_comp = light.color * diffuse * cos_ang_incidence; - vec3 vertex_to_eye = normalize(camera_pos - vertex); - vec3 halfway = normalize(light.direction + vertex_to_eye); - float specular_factor = max(0.0, dot(normalized_normal, halfway)); - specular_factor = pow(specular_factor, specular_strength); - specular_comp = light.color * specular * specular_factor; - } - float attenuation = pow(max(0.0, (1.0 - (dist / light.radius))), light.falloff + 1.0f); - return (((diffuse_comp + specular_comp) * attenuation) * light.intensity); - } - else - { - return vec3(0.0); - } -} - -vec3 calc_dir_light(in Light light) -{ - vec3 diffuse_comp = vec3(0.0); - vec3 specular_comp = vec3(0.0); - vec3 normalized_normal = normalize(normal); - float cos_ang_incidence = dot(normalized_normal, -light.direction); - cos_ang_incidence = clamp(cos_ang_incidence, 0, 1); - float shadow_factor = 1.0; - - if(cos_ang_incidence > 0) - { - diffuse_comp = light.color * diffuse * cos_ang_incidence; - - vec3 vertex_to_eye = normalize(camera_pos - vertex); - vec3 light_reflect = normalize(reflect(light.direction, normalized_normal)); - vec3 halfway = normalize(light.direction + vertex_to_eye); - float specular_factor = max(0.0, dot(normalized_normal, halfway)); - specular_factor = pow(specular_factor, specular_strength); - specular_comp = light.color * specular * specular_factor; - // if(light.castShadow == 1) - // { - // shadow_factor = calcShadowFactor(vertLightSpace.xyz); - // } - } - //return (light.intensity * (diffuse_comp + specular_comp)) * shadow_factor; - return (light.intensity * (diffuse_comp + specular_comp)); -} - -vec3 calc_spot_light(in Light light) -{ - vec3 color = vec3(0.0); - vec3 light_to_surface = vertex - light.position; - float angle = dot(light.direction, normalize(light_to_surface)); - if(acos(angle) < light.outer_angle) - { - color = calc_point_light(light); - color *= smoothstep(cos(light.outer_angle), cos(light.inner_angle), angle); - // if(light.cast_shadow != 0) - // { - // float shadow_factor = calc_shadow_factor(vert_light_space.xyz / vert_light_space.w); - // color *= shadow_factor; - // } - } - return color;// * shadowFactor; -} - - -void main() -{ - vec4 albedo_color = diffuse_color * texture(diffuse_texture, uv); - vec3 light_contribution = vec3(0.0, 0.0, 0.0); - - for(int i = 0; i < total_active_lights; i++) - { - if(i == total_active_lights) break; - - if(lights[i].type == LT_POINT) - light_contribution += calc_point_light(lights[i]); - else if(lights[i].type == LT_DIR) - light_contribution += calc_dir_light(lights[i]); - else - light_contribution += calc_spot_light(lights[i]); - } - - //frag_color = apply_fog((albedo_color * vec4(light_contribution + ambient_light, 1.0))); - frag_color = diffuse_color; -} diff --git a/src/common/linmath.c b/src/common/linmath.c index 6ae68e7..7253589 100755 --- a/src/common/linmath.c +++ b/src/common/linmath.c @@ -4,686 +4,689 @@ #include -const vec3 UNIT_X = {.x = 1, .y = 0, .z = 0}; -const vec3 UNIT_Y = {.x = 0, .y = 1, .z = 0}; -const vec3 UNIT_Z = {.x = 0, .y = 0, .z = 1}; - -const vec3 UNIT_X_NEG = {.x = -1, .y = 0, .z = 0}; -const vec3 UNIT_Y_NEG = {.x = 0, .y = -1, .z = 0}; -const vec3 UNIT_Z_NEG = {.x = 0, .y = 0, .z = -1}; +const vec3 UNIT_X = { 1, 0, 0 }; +const vec3 UNIT_Y = { 0, 1, 0 }; +const vec3 UNIT_Z = { 0, 0, 1 }; + +const vec3 UNIT_X_NEG = { -1, 0, 0 }; +const vec3 UNIT_Y_NEG = { 0, -1, 0 }; +const vec3 UNIT_Z_NEG = { 0, 0, -1 }; void vec2_fill(vec2* res, float x, float y) { - res->x = x; - res->y = y; + res->x = x; + res->y = y; } void vec2_add(vec2* res, vec2* v1, vec2* v2) { - res->x = v1->x + v2->x; - res->y = v1->y + v2->y; + res->x = v1->x + v2->x; + res->y = v1->y + v2->y; } void vec2_sub(vec2* res, vec2* v1, vec2* v2) { - res->x = v1->x - v2->x; - res->y = v1->y - v2->y; + res->x = v1->x - v2->x; + res->y = v1->y - v2->y; } void vec2_assign(vec2* res, const vec2* val) { - res->x = val->x; - res->y = val->y; + res->x = val->x; + res->y = val->y; } float vec2_len(vec2* val) { - return sqrtf((val->x * val->x) + (val->y * val->y)); + return sqrtf((val->x * val->x) + (val->y * val->y)); } void vec2_norm(vec2* res, vec2* val) { - if (!val->x && !val->y) - { - vec2_assign(res, val); - return; - } + if(!val->x && !val->y) + { + vec2_assign(res, val); + return; + } + + float l = 1.0f / vec2_len(val); + vec2 v; + v.x = val->x * l; + v.y = val->y * l; - float l = 1.0f / vec2_len(val); - vec2 v; - v.x = val->x * l; - v.y = val->y * l; - - res->x = v.x; - res->y = v.y; + res->x = v.x; + res->y = v.y; } void vec2_mul(vec2* res, vec2* v1, vec2* v2) { - res->x = v1->x * v2->x; - res->y = v1->y * v2->y; + res->x = v1->x * v2->x; + res->y = v1->y * v2->y; } void vec3_fill(vec3* res, float x, float y, float z) { - res->x = x; - res->y = y; - res->z = z; + res->x = x; + res->y = y; + res->z = z; } void vec3_add(vec3* res, const vec3* v1, const vec3* v3) { - res->x = v1->x + v3->x; - res->y = v1->y + v3->y; - res->z = v1->z + v3->z; + res->x = v1->x + v3->x; + res->y = v1->y + v3->y; + res->z = v1->z + v3->z; } void vec3_sub(vec3* res, const vec3* v1, const vec3* v3) { - res->x = v1->x - v3->x; - res->y = v1->y - v3->y; - res->z = v1->z - v3->z; + res->x = v1->x - v3->x; + res->y = v1->y - v3->y; + res->z = v1->z - v3->z; } void vec3_assign(vec3* res, const vec3* val) { - res->x = val->x; - res->y = val->y; - res->z = val->z; + res->x = val->x; + res->y = val->y; + res->z = val->z; } void vec3_cross(vec3* res, const vec3* v1, const vec3* v2) { - vec3 v; - v.x = (v1->y * v2->z) - (v1->z * v2->y); - v.y = (v1->z * v2->x) - (v1->x * v2->z); - v.z = (v1->x * v2->y) - (v1->y * v2->x); + vec3 v; + v.x = (v1->y * v2->z) - (v1->z * v2->y); + v.y = (v1->z * v2->x) - (v1->x * v2->z); + v.z = (v1->x * v2->y) - (v1->y * v2->x); - res->x = v.x; - res->y = v.y; - res->z = v.z; + res->x = v.x; + res->y = v.y; + res->z = v.z; } float vec3_len(vec3* val) { - return sqrtf((val->x * val->x) + (val->y * val->y) + (val->z * val->z)); + return sqrtf((val->x * val->x) + (val->y * val->y) + (val->z * val->z)); } void vec3_norm(vec3* res, vec3* val) { - if (!val->x && !val->y && !val->z) - { - vec3_assign(res, val); - return; - } + if(!val->x && !val->y && !val->z) + { + vec3_assign(res, val); + return; + } + + float l = 1.0f / vec3_len(val); + vec3 v; + v.x = val->x * l; + v.y = val->y * l; + v.z = val->z * l; - float l = 1.0f / vec3_len(val); - vec3 v; - v.x = val->x * l; - v.y = val->y * l; - v.z = val->z * l; - - res->x = v.x; - res->y = v.y; - res->z = v.z; + res->x = v.x; + res->y = v.y; + res->z = v.z; } void vec3_mul(vec3* res, vec3* v1, vec3* v3) { - res->x = v1->x * v3->x; - res->y = v1->y * v3->y; - res->z = v1->z * v3->z; + res->x = v1->x * v3->x; + res->y = v1->y * v3->y; + res->z = v1->z * v3->z; } void vec3_mul_mat4(vec3* res, vec3* val, mat4* mat) { - vec3 v; - v.x = val->x * mat->mat[0] + val->y * mat->mat[4] + val->z * mat->mat[8] + mat->mat[12]; - v.y = val->x * mat->mat[1] + val->y * mat->mat[5] + val->z * mat->mat[9] + mat->mat[13]; - v.z = val->x * mat->mat[2] + val->y * mat->mat[6] + val->z * mat->mat[10] + mat->mat[14]; - res->x = v.x; - res->y = v.y; - res->z = v.z; + vec3 v; + v.x = val->x * mat->mat[0] + val->y * mat->mat[4] + val->z * mat->mat[8] + mat->mat[12]; + v.y = val->x * mat->mat[1] + val->y * mat->mat[5] + val->z * mat->mat[9] + mat->mat[13]; + v.z = val->x * mat->mat[2] + val->y * mat->mat[6] + val->z * mat->mat[10] + mat->mat[14]; + res->x = v.x; + res->y = v.y; + res->z = v.z; } void vec3_scale(vec3* res, const vec3* val, float s) { - res->x = val->x * s; - res->y = val->y * s; - res->z = val->z * s; + res->x = val->x * s; + res->y = val->y * s; + res->z = val->z * s; } int vec3_equals(vec3* v1, vec3* v2) { - if ((v1->x < (v2->x + EPSILON) && v1->x > (v2->x - EPSILON)) && - (v1->y < (v2->y + EPSILON) && v1->y > (v2->y - EPSILON)) && - (v1->z < (v2->z + EPSILON) && v1->z > (v2->z - EPSILON))) - return 1; + if((v1->x < (v2->x + EPSILON) && v1->x >(v2->x - EPSILON)) && + (v1->y < (v2->y + EPSILON) && v1->y >(v2->y - EPSILON)) && + (v1->z < (v2->z + EPSILON) && v1->z >(v2->z - EPSILON))) + return 1; - return 0; + return 0; } void vec3_transform_norm(vec3* res, const vec3* val, const mat4* mat) { - /* - a = (Vx, Vy, Vz, 0) - b = (a×M)T - Out = (bx, by, bz) + /* + a = (Vx, Vy, Vz, 0) + b = (a×M)T + Out = (bx, by, bz) - Omits the translation, only scaling + rotating*/ - vec3 v; - v.x = val->x * mat->mat[0] + val->y * mat->mat[4] + val->z * mat->mat[8]; - v.y = val->x * mat->mat[1] + val->y * mat->mat[5] + val->z * mat->mat[9]; - v.z = val->x * mat->mat[2] + val->y * mat->mat[6] + val->z * mat->mat[10]; - res->x = v.x; - res->y = v.y; - res->z = v.z; + Omits the translation, only scaling + rotating*/ + vec3 v; + v.x = val->x * mat->mat[0] + val->y * mat->mat[4] + val->z * mat->mat[8]; + v.y = val->x * mat->mat[1] + val->y * mat->mat[5] + val->z * mat->mat[9]; + v.z = val->x * mat->mat[2] + val->y * mat->mat[6] + val->z * mat->mat[10]; + res->x = v.x; + res->y = v.y; + res->z = v.z; } float vec3_dot(vec3* v1, vec3* v2) { - return (v1->x * v2->x + - v1->y * v2->y + - v1->z * v2->z); + return (v1->x * v2->x + + v1->y * v2->y + + v1->z * v2->z); } void vec4_fill(vec4* res, float x, float y, float z, float w) { - res->x = x; - res->y = y; - res->z = z; - res->w = w; + res->x = x; + res->y = y; + res->z = z; + res->w = w; } void vec4_fill_vec3(vec4* res, const vec3* v, float w) { - res->x = v->x; - res->y = v->y; - res->z = v->z; - res->w = w; + res->x = v->x; + res->y = v->y; + res->z = v->z; + res->w = w; } void vec4_add(vec4* res, vec4* v1, vec4* v4) { - res->x = v1->x + v4->x; - res->y = v1->y + v4->y; - res->z = v1->z + v4->z; - res->w = v1->w + v4->w; + res->x = v1->x + v4->x; + res->y = v1->y + v4->y; + res->z = v1->z + v4->z; + res->w = v1->w + v4->w; } void vec4_sub(vec4* res, vec4* v1, vec4* v4) { - res->x = v1->x - v4->x; - res->y = v1->y - v4->y; - res->z = v1->z - v4->z; - res->w = v1->w - v4->w; + res->x = v1->x - v4->x; + res->y = v1->y - v4->y; + res->z = v1->z - v4->z; + res->w = v1->w - v4->w; } void vec4_assign(vec4* res, const vec4* val) { - res->x = val->x; - res->y = val->y; - res->z = val->z; - res->w = val->w; + res->x = val->x; + res->y = val->y; + res->z = val->z; + res->w = val->w; } float vec4_len(vec4* val) { - return sqrtf((val->x * val->x) + - (val->y * val->y) + - (val->z * val->z) + - (val->w * val->w)); + return sqrtf((val->x * val->x) + + (val->y * val->y) + + (val->z * val->z) + + (val->w * val->w)); } void vec4_norm(vec4* res, vec4* val) { - if (!val->x && !val->y && !val->z && !val->w) - { - vec4_assign(res, val); - return; - } - - float l = 1.0f / vec4_len(val); - vec4 v; - v.x = val->x * l; - v.y = val->y * l; - v.z = val->z * l; - v.w = val->w * l; - - res->x = v.x; - res->y = v.y; - res->z = v.z; - res->w = v.w; + if(!val->x && !val->y && !val->z && !val->w) + { + vec4_assign(res, val); + return; + } + + float l = 1.0f / vec4_len(val); + vec4 v; + v.x = val->x * l; + v.y = val->y * l; + v.z = val->z * l; + v.w = val->w * l; + + res->x = v.x; + res->y = v.y; + res->z = v.z; + res->w = v.w; } void vec4_mul(vec4* res, vec4* v1, vec4* v4) { - res->x = v1->x * v4->x; - res->y = v1->y * v4->y; - res->z = v1->z * v4->z; - res->w = v1->w * v4->w; + res->x = v1->x * v4->x; + res->y = v1->y * v4->y; + res->z = v1->z * v4->z; + res->w = v1->w * v4->w; } void vec4_mul_mat4(vec4* res, vec4* val, mat4* mat) { - vec4 v; - v.x = val->x * mat->mat[0] + val->y * mat->mat[4] + val->z * mat->mat[8] + val->w * mat->mat[12]; - v.y = val->x * mat->mat[1] + val->y * mat->mat[5] + val->z * mat->mat[9] + val->w * mat->mat[13]; - v.z = val->x * mat->mat[2] + val->y * mat->mat[6] + val->z * mat->mat[10] + val->w * mat->mat[14]; - v.w = val->x * mat->mat[3] + val->y * mat->mat[7] + val->z * mat->mat[11] + val->w * mat->mat[15]; - res->x = v.x; - res->y = v.y; - res->z = v.z; - res->w = v.w; + vec4 v; + v.x = val->x * mat->mat[0] + val->y * mat->mat[4] + val->z * mat->mat[8] + val->w * mat->mat[12]; + v.y = val->x * mat->mat[1] + val->y * mat->mat[5] + val->z * mat->mat[9] + val->w * mat->mat[13]; + v.z = val->x * mat->mat[2] + val->y * mat->mat[6] + val->z * mat->mat[10] + val->w * mat->mat[14]; + v.w = val->x * mat->mat[3] + val->y * mat->mat[7] + val->z * mat->mat[11] + val->w * mat->mat[15]; + res->x = v.x; + res->y = v.y; + res->z = v.z; + res->w = v.w; } void vec4_scale(vec4* res, const vec4* val, float s) { - res->x = val->x * s; - res->y = val->y * s; - res->z = val->z * s; - res->w = val->w * s; + res->x = val->x * s; + res->y = val->y * s; + res->z = val->z * s; + res->w = val->w * s; } int vec4_equals(vec4* v1, vec4* v2) { - if ((v1->x < (v2->x + EPSILON) && v1->x > (v2->x - EPSILON)) && - (v1->y < (v2->y + EPSILON) && v1->y > (v2->y - EPSILON)) && - (v1->z < (v2->z + EPSILON) && v1->z > (v2->z - EPSILON)) && - (v1->w < (v2->w + EPSILON) && v1->w > (v2->w - EPSILON))) - return 1; + if((v1->x < (v2->x + EPSILON) && v1->x >(v2->x - EPSILON)) && + (v1->y < (v2->y + EPSILON) && v1->y >(v2->y - EPSILON)) && + (v1->z < (v2->z + EPSILON) && v1->z >(v2->z - EPSILON)) && + (v1->w < (v2->w + EPSILON) && v1->w >(v2->w - EPSILON))) + return 1; - return 0; + return 0; } void vec4_transform_norm(vec4* res, const vec4* val, const mat4* mat) { - /* - a = (Vx, Vy, Vz, 0) - b = (a×M)T - Out = (bx, by, bz) + /* + a = (Vx, Vy, Vz, 0) + b = (a×M)T + Out = (bx, by, bz) - Omits the translation, only scaling + rotating*/ - vec4 v; - v.x = val->x * mat->mat[0] + val->y * mat->mat[4] + val->z * mat->mat[8]; - v.y = val->x * mat->mat[1] + val->y * mat->mat[5] + val->z * mat->mat[9]; - v.z = val->x * mat->mat[2] + val->y * mat->mat[6] + val->z * mat->mat[10]; - res->x = v.x; - res->y = v.y; - res->z = v.z; + Omits the translation, only scaling + rotating*/ + vec4 v; + v.x = val->x * mat->mat[0] + val->y * mat->mat[4] + val->z * mat->mat[8]; + v.y = val->x * mat->mat[1] + val->y * mat->mat[5] + val->z * mat->mat[9]; + v.z = val->x * mat->mat[2] + val->y * mat->mat[6] + val->z * mat->mat[10]; + res->x = v.x; + res->y = v.y; + res->z = v.z; } void mat4_identity(mat4* res) { - memset(res->mat, 0, sizeof(float) * 16); - res->mat[0] = res->mat[5] = res->mat[10] = res->mat[15] = 1.0f; + memset(res->mat, 0, sizeof(float) * 16); + res->mat[0] = res->mat[5] = res->mat[10] = res->mat[15] = 1.0f; } void mat4_mul(mat4* res, const mat4* mat1, const mat4* mat2) { - float mat[16]; - const float *m1 = mat1->mat, *m2 = mat2->mat; + float mat[16]; + const float *m1 = mat1->mat, *m2 = mat2->mat; + + mat[0] = m1[0] * m2[0] + m1[4] * m2[1] + m1[8] * m2[2] + m1[12] * m2[3]; + mat[1] = m1[1] * m2[0] + m1[5] * m2[1] + m1[9] * m2[2] + m1[13] * m2[3]; + mat[2] = m1[2] * m2[0] + m1[6] * m2[1] + m1[10] * m2[2] + m1[14] * m2[3]; + mat[3] = m1[3] * m2[0] + m1[7] * m2[1] + m1[11] * m2[2] + m1[15] * m2[3]; - mat[0] = m1[0] * m2[0] + m1[4] * m2[1] + m1[8] * m2[2] + m1[12] * m2[3]; - mat[1] = m1[1] * m2[0] + m1[5] * m2[1] + m1[9] * m2[2] + m1[13] * m2[3]; - mat[2] = m1[2] * m2[0] + m1[6] * m2[1] + m1[10] * m2[2] + m1[14] * m2[3]; - mat[3] = m1[3] * m2[0] + m1[7] * m2[1] + m1[11] * m2[2] + m1[15] * m2[3]; + mat[4] = m1[0] * m2[4] + m1[4] * m2[5] + m1[8] * m2[6] + m1[12] * m2[7]; + mat[5] = m1[1] * m2[4] + m1[5] * m2[5] + m1[9] * m2[6] + m1[13] * m2[7]; + mat[6] = m1[2] * m2[4] + m1[6] * m2[5] + m1[10] * m2[6] + m1[14] * m2[7]; + mat[7] = m1[3] * m2[4] + m1[7] * m2[5] + m1[11] * m2[6] + m1[15] * m2[7]; - mat[4] = m1[0] * m2[4] + m1[4] * m2[5] + m1[8] * m2[6] + m1[12] * m2[7]; - mat[5] = m1[1] * m2[4] + m1[5] * m2[5] + m1[9] * m2[6] + m1[13] * m2[7]; - mat[6] = m1[2] * m2[4] + m1[6] * m2[5] + m1[10] * m2[6] + m1[14] * m2[7]; - mat[7] = m1[3] * m2[4] + m1[7] * m2[5] + m1[11] * m2[6] + m1[15] * m2[7]; + mat[8] = m1[0] * m2[8] + m1[4] * m2[9] + m1[8] * m2[10] + m1[12] * m2[11]; + mat[9] = m1[1] * m2[8] + m1[5] * m2[9] + m1[9] * m2[10] + m1[13] * m2[11]; + mat[10] = m1[2] * m2[8] + m1[6] * m2[9] + m1[10] * m2[10] + m1[14] * m2[11]; + mat[11] = m1[3] * m2[8] + m1[7] * m2[9] + m1[11] * m2[10] + m1[15] * m2[11]; - mat[8] = m1[0] * m2[8] + m1[4] * m2[9] + m1[8] * m2[10] + m1[12] * m2[11]; - mat[9] = m1[1] * m2[8] + m1[5] * m2[9] + m1[9] * m2[10] + m1[13] * m2[11]; - mat[10] = m1[2] * m2[8] + m1[6] * m2[9] + m1[10] * m2[10] + m1[14] * m2[11]; - mat[11] = m1[3] * m2[8] + m1[7] * m2[9] + m1[11] * m2[10] + m1[15] * m2[11]; + mat[12] = m1[0] * m2[12] + m1[4] * m2[13] + m1[8] * m2[14] + m1[12] * m2[15]; + mat[13] = m1[1] * m2[12] + m1[5] * m2[13] + m1[9] * m2[14] + m1[13] * m2[15]; + mat[14] = m1[2] * m2[12] + m1[6] * m2[13] + m1[10] * m2[14] + m1[14] * m2[15]; + mat[15] = m1[3] * m2[12] + m1[7] * m2[13] + m1[11] * m2[14] + m1[15] * m2[15]; - mat[12] = m1[0] * m2[12] + m1[4] * m2[13] + m1[8] * m2[14] + m1[12] * m2[15]; - mat[13] = m1[1] * m2[12] + m1[5] * m2[13] + m1[9] * m2[14] + m1[13] * m2[15]; - mat[14] = m1[2] * m2[12] + m1[6] * m2[13] + m1[10] * m2[14] + m1[14] * m2[15]; - mat[15] = m1[3] * m2[12] + m1[7] * m2[13] + m1[11] * m2[14] + m1[15] * m2[15]; - - memcpy(res->mat, mat, sizeof(float)*16); + memcpy(res->mat, mat, sizeof(float) * 16); } void mat4_translate(mat4* res, float x, float y, float z) { - memset(res->mat, 0, sizeof(float) * 16); - res->mat[0] = 1.0f; - res->mat[5] = 1.0f; - res->mat[10] = 1.0f; + memset(res->mat, 0, sizeof(float) * 16); + res->mat[0] = 1.0f; + res->mat[5] = 1.0f; + res->mat[10] = 1.0f; - res->mat[12] = x; - res->mat[13] = y; - res->mat[14] = z; - res->mat[15] = 1.0f; + res->mat[12] = x; + res->mat[13] = y; + res->mat[14] = z; + res->mat[15] = 1.0f; } void mat4_lookat(mat4* res, const vec3* eye, const vec3* center, const vec3* up_vec) { - vec3 f, up, s, u; - mat4 translate; + vec3 f, up, s, u; + mat4 translate; - vec3_sub(&f, center, eye); - vec3_norm(&f, &f); + vec3_sub(&f, center, eye); + vec3_norm(&f, &f); - vec3_assign(&up, up_vec); - vec3_norm(&up, &up); + vec3_assign(&up, up_vec); + vec3_norm(&up, &up); - vec3_cross(&s, &f, &up); - vec3_norm(&s, &s); + vec3_cross(&s, &f, &up); + vec3_norm(&s, &s); - vec3_cross(&u, &s, &f); - vec3_norm(&s, &s); + vec3_cross(&u, &s, &f); + vec3_norm(&s, &s); - mat4_identity(res); + mat4_identity(res); - res->mat[0] = s.x; - res->mat[4] = s.y; - res->mat[8] = s.z; + res->mat[0] = s.x; + res->mat[4] = s.y; + res->mat[8] = s.z; - res->mat[1] = u.x; - res->mat[5] = u.y; - res->mat[9] = u.z; + res->mat[1] = u.x; + res->mat[5] = u.y; + res->mat[9] = u.z; - res->mat[2] = -f.x; - res->mat[6] = -f.y; - res->mat[10] = -f.z; + res->mat[2] = -f.x; + res->mat[6] = -f.y; + res->mat[10] = -f.z; - mat4_translate(&translate, -eye->x, -eye->y, -eye->z); - mat4_mul(res, res, &translate); + mat4_translate(&translate, -eye->x, -eye->y, -eye->z); + mat4_mul(res, res, &translate); } -void mat4_perspective(mat4* res, float fov, float aspect, float nearz, float farz ) +void mat4_perspective(mat4* res, float fov, float aspect, float nearz, float farz) { - float r = TO_RADIANS(fov / 2); - float deltaz = farz - nearz; - float s = (float)sin(r); - float cotangent = 0; + float r = TO_RADIANS(fov / 2); + float deltaz = farz - nearz; + float s = (float)sin(r); + float cotangent = 0; - if (deltaz == 0 || s == 0 || aspect == 0) - return; + if(deltaz == 0 || s == 0 || aspect == 0) + return; - cotangent = (float)cos(r) / s; - mat4_identity(res); - res->mat[0] = cotangent / aspect; - res->mat[5] = cotangent; - res->mat[10] = -(farz + nearz) / deltaz; - res->mat[11] = -1; - res->mat[14] = -2 * nearz * farz / deltaz; - res->mat[15] = 0; + cotangent = (float)cos(r) / s; + mat4_identity(res); + res->mat[0] = cotangent / aspect; + res->mat[5] = cotangent; + res->mat[10] = -(farz + nearz) / deltaz; + res->mat[11] = -1; + res->mat[14] = -2 * nearz * farz / deltaz; + res->mat[15] = 0; } void mat4_ortho(mat4* res, - float left, float right, - float bottom, float top, - float nearz, float farz) -{ - float tx = -((right + left) / (right - left)); - float ty = -((top + bottom) / (top - bottom)); - float tz = -((farz + nearz) / (farz - nearz)); - mat4_identity(res); - res->mat[0] = 2 / (right - left); - res->mat[5] = 2 / (top - bottom); - res->mat[10] = -2 / (farz - nearz); - res->mat[12] = tx; - res->mat[13] = ty; - res->mat[14] = tz; + float left, float right, + float bottom, float top, + float nearz, float farz) +{ + float tx = -((right + left) / (right - left)); + float ty = -((top + bottom) / (top - bottom)); + float tz = -((farz + nearz) / (farz - nearz)); + mat4_identity(res); + res->mat[0] = 2 / (right - left); + res->mat[5] = 2 / (top - bottom); + res->mat[10] = -2 / (farz - nearz); + res->mat[12] = tx; + res->mat[13] = ty; + res->mat[14] = tz; } void mat4_scale(mat4* res, float x, float y, float z) { - memset(res->mat, 0, sizeof(float) * 16); - res->mat[0] = x; - res->mat[5] = y; - res->mat[10] = z; - res->mat[15] = 1.0f; + memset(res->mat, 0, sizeof(float) * 16); + res->mat[0] = x; + res->mat[5] = y; + res->mat[10] = z; + res->mat[15] = 1.0f; } void mat4_from_quat(mat4* res, const quat* q) { - float xx = q->x * q->x; - float xy = q->x * q->y; - float xz = q->x * q->z; - float xw = q->x * q->w; + float xx = q->x * q->x; + float xy = q->x * q->y; + float xz = q->x * q->z; + float xw = q->x * q->w; - float yy = q->y * q->y; - float yz = q->y * q->z; - float yw = q->y * q->w; + float yy = q->y * q->y; + float yz = q->y * q->z; + float yw = q->y * q->w; - float zz = q->z * q->z; - float zw = q->z * q->w; + float zz = q->z * q->z; + float zw = q->z * q->w; - res->mat[0] = 1 - 2 * (yy + zz); - res->mat[1] = 2 * (xy + zw); - res->mat[2] = 2 * (xz - yw); - res->mat[3] = 0; + res->mat[0] = 1 - 2 * (yy + zz); + res->mat[1] = 2 * (xy + zw); + res->mat[2] = 2 * (xz - yw); + res->mat[3] = 0; - res->mat[4] = 2 * (xy - zw); - res->mat[5] = 1 - 2 * (xx + zz); - res->mat[6] = 2 * (yz + xw); - res->mat[7] = 0.0; + res->mat[4] = 2 * (xy - zw); + res->mat[5] = 1 - 2 * (xx + zz); + res->mat[6] = 2 * (yz + xw); + res->mat[7] = 0.0; - res->mat[8] = 2 * (xz + yw); - res->mat[9] = 2 * (yz - xw); - res->mat[10] = 1 - 2 * (xx + yy); - res->mat[11] = 0.0; + res->mat[8] = 2 * (xz + yw); + res->mat[9] = 2 * (yz - xw); + res->mat[10] = 1 - 2 * (xx + yy); + res->mat[11] = 0.0; - res->mat[12] = 0.0; - res->mat[13] = 0.0; - res->mat[14] = 0.0; - res->mat[15] = 1.0; + res->mat[12] = 0.0; + res->mat[13] = 0.0; + res->mat[14] = 0.0; + res->mat[15] = 1.0; } void mat4_rot_x(mat4* res, const float angle) { - res->mat[0] = 1.0f; - res->mat[1] = 0.0f; - res->mat[2] = 0.0f; - res->mat[3] = 0.0f; + float angle_radians = TO_RADIANS(angle); + res->mat[0] = 1.0f; + res->mat[1] = 0.0f; + res->mat[2] = 0.0f; + res->mat[3] = 0.0f; - res->mat[4] = 0.0f; - res->mat[5] = cosf(angle); - res->mat[6] = sinf(angle); - res->mat[7] = 0.0f; + res->mat[4] = 0.0f; + res->mat[5] = cosf(angle_radians); + res->mat[6] = sinf(angle_radians); + res->mat[7] = 0.0f; - res->mat[8] = 0.0f; - res->mat[9] = -sinf(angle); - res->mat[10] = cosf(angle); - res->mat[11] = 0.0f; + res->mat[8] = 0.0f; + res->mat[9] = -sinf(angle_radians); + res->mat[10] = cosf(angle_radians); + res->mat[11] = 0.0f; - res->mat[12] = 0.0f; - res->mat[13] = 0.0f; - res->mat[14] = 0.0f; - res->mat[15] = 1.0f; + res->mat[12] = 0.0f; + res->mat[13] = 0.0f; + res->mat[14] = 0.0f; + res->mat[15] = 1.0f; } void mat4_rot_y(mat4* res, float angle) { - res->mat[0] = cosf(angle); - res->mat[1] = 0.0f; - res->mat[2] = -sinf(angle); - res->mat[3] = 0.0f; + float angle_radians = TO_RADIANS(angle); + res->mat[0] = cosf(angle_radians); + res->mat[1] = 0.0f; + res->mat[2] = -sinf(angle_radians); + res->mat[3] = 0.0f; - res->mat[4] = 0.0f; - res->mat[5] = 1.0f; - res->mat[6] = 0.0f; - res->mat[7] = 0.0f; + res->mat[4] = 0.0f; + res->mat[5] = 1.0f; + res->mat[6] = 0.0f; + res->mat[7] = 0.0f; - res->mat[8] = sinf(angle); - res->mat[9] = 0.0f; - res->mat[10] = cosf(angle); - res->mat[11] = 0.0f; + res->mat[8] = sinf(angle_radians); + res->mat[9] = 0.0f; + res->mat[10] = cosf(angle_radians); + res->mat[11] = 0.0f; - res->mat[12] = 0.0f; - res->mat[13] = 0.0f; - res->mat[14] = 0.0f; - res->mat[15] = 1.0f; + res->mat[12] = 0.0f; + res->mat[13] = 0.0f; + res->mat[14] = 0.0f; + res->mat[15] = 1.0f; } void mat4_rot_z(mat4* res, float angle) { - res->mat[0] = cosf(angle); - res->mat[1] = sinf(angle); - res->mat[2] = 0.0f; - res->mat[3] = 0.0f; + float angle_radians = TO_RADIANS(angle); + res->mat[0] = cosf(angle_radians); + res->mat[1] = sinf(angle_radians); + res->mat[2] = 0.0f; + res->mat[3] = 0.0f; - res->mat[4] = -sinf(angle); - res->mat[5] = cosf(angle); - res->mat[6] = 0.0f; - res->mat[7] = 0.0f; + res->mat[4] = -sinf(angle_radians); + res->mat[5] = cosf(angle_radians); + res->mat[6] = 0.0f; + res->mat[7] = 0.0f; - res->mat[8] = 0.0f; - res->mat[9] = 0.0f; - res->mat[10] = 1.0f; - res->mat[11] = 0.0f; + res->mat[8] = 0.0f; + res->mat[9] = 0.0f; + res->mat[10] = 1.0f; + res->mat[11] = 0.0f; - res->mat[12] = 0.0f; - res->mat[13] = 0.0f; - res->mat[14] = 0.0f; - res->mat[15] = 1.0f; + res->mat[12] = 0.0f; + res->mat[13] = 0.0f; + res->mat[14] = 0.0f; + res->mat[15] = 1.0f; } void mat4_assign(mat4* res, const mat4* m) { - if(res == m) - return; - memcpy(res->mat, m->mat, sizeof(float) * 16); + if(res == m) + return; + memcpy(res->mat, m->mat, sizeof(float) * 16); } void mat4_inverse(mat4* res, mat4* mat) { - mat4 tmp; - float det; - int i; - - tmp.mat[0] = mat->mat[5] * mat->mat[10] * mat->mat[15] - - mat->mat[5] * mat->mat[11] * mat->mat[14] - - mat->mat[9] * mat->mat[6] * mat->mat[15] + - mat->mat[9] * mat->mat[7] * mat->mat[14] + - mat->mat[13] * mat->mat[6] * mat->mat[11] - - mat->mat[13] * mat->mat[7] * mat->mat[10]; - - tmp.mat[4] = -mat->mat[4] * mat->mat[10] * mat->mat[15] + - mat->mat[4] * mat->mat[11] * mat->mat[14] + - mat->mat[8] * mat->mat[6] * mat->mat[15] - - mat->mat[8] * mat->mat[7] * mat->mat[14] - - mat->mat[12] * mat->mat[6] * mat->mat[11] + - mat->mat[12] * mat->mat[7] * mat->mat[10]; - - tmp.mat[8] = mat->mat[4] * mat->mat[9] * mat->mat[15] - - mat->mat[4] * mat->mat[11] * mat->mat[13] - - mat->mat[8] * mat->mat[5] * mat->mat[15] + - mat->mat[8] * mat->mat[7] * mat->mat[13] + - mat->mat[12] * mat->mat[5] * mat->mat[11] - - mat->mat[12] * mat->mat[7] * mat->mat[9]; - - tmp.mat[12] = -mat->mat[4] * mat->mat[9] * mat->mat[14] + - mat->mat[4] * mat->mat[10] * mat->mat[13] + - mat->mat[8] * mat->mat[5] * mat->mat[14] - - mat->mat[8] * mat->mat[6] * mat->mat[13] - - mat->mat[12] * mat->mat[5] * mat->mat[10] + - mat->mat[12] * mat->mat[6] * mat->mat[9]; - - tmp.mat[1] = -mat->mat[1] * mat->mat[10] * mat->mat[15] + - mat->mat[1] * mat->mat[11] * mat->mat[14] + - mat->mat[9] * mat->mat[2] * mat->mat[15] - - mat->mat[9] * mat->mat[3] * mat->mat[14] - - mat->mat[13] * mat->mat[2] * mat->mat[11] + - mat->mat[13] * mat->mat[3] * mat->mat[10]; - - tmp.mat[5] = mat->mat[0] * mat->mat[10] * mat->mat[15] - - mat->mat[0] * mat->mat[11] * mat->mat[14] - - mat->mat[8] * mat->mat[2] * mat->mat[15] + - mat->mat[8] * mat->mat[3] * mat->mat[14] + - mat->mat[12] * mat->mat[2] * mat->mat[11] - - mat->mat[12] * mat->mat[3] * mat->mat[10]; - - tmp.mat[9] = -mat->mat[0] * mat->mat[9] * mat->mat[15] + - mat->mat[0] * mat->mat[11] * mat->mat[13] + - mat->mat[8] * mat->mat[1] * mat->mat[15] - - mat->mat[8] * mat->mat[3] * mat->mat[13] - - mat->mat[12] * mat->mat[1] * mat->mat[11] + - mat->mat[12] * mat->mat[3] * mat->mat[9]; - - tmp.mat[13] = mat->mat[0] * mat->mat[9] * mat->mat[14] - - mat->mat[0] * mat->mat[10] * mat->mat[13] - - mat->mat[8] * mat->mat[1] * mat->mat[14] + - mat->mat[8] * mat->mat[2] * mat->mat[13] + - mat->mat[12] * mat->mat[1] * mat->mat[10] - - mat->mat[12] * mat->mat[2] * mat->mat[9]; - - tmp.mat[2] = mat->mat[1] * mat->mat[6] * mat->mat[15] - - mat->mat[1] * mat->mat[7] * mat->mat[14] - - mat->mat[5] * mat->mat[2] * mat->mat[15] + - mat->mat[5] * mat->mat[3] * mat->mat[14] + - mat->mat[13] * mat->mat[2] * mat->mat[7] - - mat->mat[13] * mat->mat[3] * mat->mat[6]; - - tmp.mat[6] = -mat->mat[0] * mat->mat[6] * mat->mat[15] + - mat->mat[0] * mat->mat[7] * mat->mat[14] + - mat->mat[4] * mat->mat[2] * mat->mat[15] - - mat->mat[4] * mat->mat[3] * mat->mat[14] - - mat->mat[12] * mat->mat[2] * mat->mat[7] + - mat->mat[12] * mat->mat[3] * mat->mat[6]; - - tmp.mat[10] = mat->mat[0] * mat->mat[5] * mat->mat[15] - - mat->mat[0] * mat->mat[7] * mat->mat[13] - - mat->mat[4] * mat->mat[1] * mat->mat[15] + - mat->mat[4] * mat->mat[3] * mat->mat[13] + - mat->mat[12] * mat->mat[1] * mat->mat[7] - - mat->mat[12] * mat->mat[3] * mat->mat[5]; - - tmp.mat[14] = -mat->mat[0] * mat->mat[5] * mat->mat[14] + - mat->mat[0] * mat->mat[6] * mat->mat[13] + - mat->mat[4] * mat->mat[1] * mat->mat[14] - - mat->mat[4] * mat->mat[2] * mat->mat[13] - - mat->mat[12] * mat->mat[1] * mat->mat[6] + - mat->mat[12] * mat->mat[2] * mat->mat[5]; - - tmp.mat[3] = -mat->mat[1] * mat->mat[6] * mat->mat[11] + - mat->mat[1] * mat->mat[7] * mat->mat[10] + - mat->mat[5] * mat->mat[2] * mat->mat[11] - - mat->mat[5] * mat->mat[3] * mat->mat[10] - - mat->mat[9] * mat->mat[2] * mat->mat[7] + - mat->mat[9] * mat->mat[3] * mat->mat[6]; - - tmp.mat[7] = mat->mat[0] * mat->mat[6] * mat->mat[11] - - mat->mat[0] * mat->mat[7] * mat->mat[10] - - mat->mat[4] * mat->mat[2] * mat->mat[11] + - mat->mat[4] * mat->mat[3] * mat->mat[10] + - mat->mat[8] * mat->mat[2] * mat->mat[7] - - mat->mat[8] * mat->mat[3] * mat->mat[6]; - - tmp.mat[11] = -mat->mat[0] * mat->mat[5] * mat->mat[11] + - mat->mat[0] * mat->mat[7] * mat->mat[9] + - mat->mat[4] * mat->mat[1] * mat->mat[11] - - mat->mat[4] * mat->mat[3] * mat->mat[9] - - mat->mat[8] * mat->mat[1] * mat->mat[7] + - mat->mat[8] * mat->mat[3] * mat->mat[5]; - - tmp.mat[15] = mat->mat[0] * mat->mat[5] * mat->mat[10] - - mat->mat[0] * mat->mat[6] * mat->mat[9] - - mat->mat[4] * mat->mat[1] * mat->mat[10] + - mat->mat[4] * mat->mat[2] * mat->mat[9] + - mat->mat[8] * mat->mat[1] * mat->mat[6] - - mat->mat[8] * mat->mat[2] * mat->mat[5]; - - det = mat->mat[0] * tmp.mat[0] + mat->mat[1] * tmp.mat[4] + mat->mat[2] * tmp.mat[8] + mat->mat[3] * tmp.mat[12]; - - if (det == 0) { - return; - } - - det = 1.f / det; - - for (i = 0; i < 16; i++) { - res->mat[i] = tmp.mat[i] * det; - } + mat4 tmp; + float det; + int i; + + tmp.mat[0] = mat->mat[5] * mat->mat[10] * mat->mat[15] - + mat->mat[5] * mat->mat[11] * mat->mat[14] - + mat->mat[9] * mat->mat[6] * mat->mat[15] + + mat->mat[9] * mat->mat[7] * mat->mat[14] + + mat->mat[13] * mat->mat[6] * mat->mat[11] - + mat->mat[13] * mat->mat[7] * mat->mat[10]; + + tmp.mat[4] = -mat->mat[4] * mat->mat[10] * mat->mat[15] + + mat->mat[4] * mat->mat[11] * mat->mat[14] + + mat->mat[8] * mat->mat[6] * mat->mat[15] - + mat->mat[8] * mat->mat[7] * mat->mat[14] - + mat->mat[12] * mat->mat[6] * mat->mat[11] + + mat->mat[12] * mat->mat[7] * mat->mat[10]; + + tmp.mat[8] = mat->mat[4] * mat->mat[9] * mat->mat[15] - + mat->mat[4] * mat->mat[11] * mat->mat[13] - + mat->mat[8] * mat->mat[5] * mat->mat[15] + + mat->mat[8] * mat->mat[7] * mat->mat[13] + + mat->mat[12] * mat->mat[5] * mat->mat[11] - + mat->mat[12] * mat->mat[7] * mat->mat[9]; + + tmp.mat[12] = -mat->mat[4] * mat->mat[9] * mat->mat[14] + + mat->mat[4] * mat->mat[10] * mat->mat[13] + + mat->mat[8] * mat->mat[5] * mat->mat[14] - + mat->mat[8] * mat->mat[6] * mat->mat[13] - + mat->mat[12] * mat->mat[5] * mat->mat[10] + + mat->mat[12] * mat->mat[6] * mat->mat[9]; + + tmp.mat[1] = -mat->mat[1] * mat->mat[10] * mat->mat[15] + + mat->mat[1] * mat->mat[11] * mat->mat[14] + + mat->mat[9] * mat->mat[2] * mat->mat[15] - + mat->mat[9] * mat->mat[3] * mat->mat[14] - + mat->mat[13] * mat->mat[2] * mat->mat[11] + + mat->mat[13] * mat->mat[3] * mat->mat[10]; + + tmp.mat[5] = mat->mat[0] * mat->mat[10] * mat->mat[15] - + mat->mat[0] * mat->mat[11] * mat->mat[14] - + mat->mat[8] * mat->mat[2] * mat->mat[15] + + mat->mat[8] * mat->mat[3] * mat->mat[14] + + mat->mat[12] * mat->mat[2] * mat->mat[11] - + mat->mat[12] * mat->mat[3] * mat->mat[10]; + + tmp.mat[9] = -mat->mat[0] * mat->mat[9] * mat->mat[15] + + mat->mat[0] * mat->mat[11] * mat->mat[13] + + mat->mat[8] * mat->mat[1] * mat->mat[15] - + mat->mat[8] * mat->mat[3] * mat->mat[13] - + mat->mat[12] * mat->mat[1] * mat->mat[11] + + mat->mat[12] * mat->mat[3] * mat->mat[9]; + + tmp.mat[13] = mat->mat[0] * mat->mat[9] * mat->mat[14] - + mat->mat[0] * mat->mat[10] * mat->mat[13] - + mat->mat[8] * mat->mat[1] * mat->mat[14] + + mat->mat[8] * mat->mat[2] * mat->mat[13] + + mat->mat[12] * mat->mat[1] * mat->mat[10] - + mat->mat[12] * mat->mat[2] * mat->mat[9]; + + tmp.mat[2] = mat->mat[1] * mat->mat[6] * mat->mat[15] - + mat->mat[1] * mat->mat[7] * mat->mat[14] - + mat->mat[5] * mat->mat[2] * mat->mat[15] + + mat->mat[5] * mat->mat[3] * mat->mat[14] + + mat->mat[13] * mat->mat[2] * mat->mat[7] - + mat->mat[13] * mat->mat[3] * mat->mat[6]; + + tmp.mat[6] = -mat->mat[0] * mat->mat[6] * mat->mat[15] + + mat->mat[0] * mat->mat[7] * mat->mat[14] + + mat->mat[4] * mat->mat[2] * mat->mat[15] - + mat->mat[4] * mat->mat[3] * mat->mat[14] - + mat->mat[12] * mat->mat[2] * mat->mat[7] + + mat->mat[12] * mat->mat[3] * mat->mat[6]; + + tmp.mat[10] = mat->mat[0] * mat->mat[5] * mat->mat[15] - + mat->mat[0] * mat->mat[7] * mat->mat[13] - + mat->mat[4] * mat->mat[1] * mat->mat[15] + + mat->mat[4] * mat->mat[3] * mat->mat[13] + + mat->mat[12] * mat->mat[1] * mat->mat[7] - + mat->mat[12] * mat->mat[3] * mat->mat[5]; + + tmp.mat[14] = -mat->mat[0] * mat->mat[5] * mat->mat[14] + + mat->mat[0] * mat->mat[6] * mat->mat[13] + + mat->mat[4] * mat->mat[1] * mat->mat[14] - + mat->mat[4] * mat->mat[2] * mat->mat[13] - + mat->mat[12] * mat->mat[1] * mat->mat[6] + + mat->mat[12] * mat->mat[2] * mat->mat[5]; + + tmp.mat[3] = -mat->mat[1] * mat->mat[6] * mat->mat[11] + + mat->mat[1] * mat->mat[7] * mat->mat[10] + + mat->mat[5] * mat->mat[2] * mat->mat[11] - + mat->mat[5] * mat->mat[3] * mat->mat[10] - + mat->mat[9] * mat->mat[2] * mat->mat[7] + + mat->mat[9] * mat->mat[3] * mat->mat[6]; + + tmp.mat[7] = mat->mat[0] * mat->mat[6] * mat->mat[11] - + mat->mat[0] * mat->mat[7] * mat->mat[10] - + mat->mat[4] * mat->mat[2] * mat->mat[11] + + mat->mat[4] * mat->mat[3] * mat->mat[10] + + mat->mat[8] * mat->mat[2] * mat->mat[7] - + mat->mat[8] * mat->mat[3] * mat->mat[6]; + + tmp.mat[11] = -mat->mat[0] * mat->mat[5] * mat->mat[11] + + mat->mat[0] * mat->mat[7] * mat->mat[9] + + mat->mat[4] * mat->mat[1] * mat->mat[11] - + mat->mat[4] * mat->mat[3] * mat->mat[9] - + mat->mat[8] * mat->mat[1] * mat->mat[7] + + mat->mat[8] * mat->mat[3] * mat->mat[5]; + + tmp.mat[15] = mat->mat[0] * mat->mat[5] * mat->mat[10] - + mat->mat[0] * mat->mat[6] * mat->mat[9] - + mat->mat[4] * mat->mat[1] * mat->mat[10] + + mat->mat[4] * mat->mat[2] * mat->mat[9] + + mat->mat[8] * mat->mat[1] * mat->mat[6] - + mat->mat[8] * mat->mat[2] * mat->mat[5]; + + det = mat->mat[0] * tmp.mat[0] + mat->mat[1] * tmp.mat[4] + mat->mat[2] * tmp.mat[8] + mat->mat[3] * tmp.mat[12]; + + if(det == 0) { + return; + } + + det = 1.f / det; + + for(i = 0; i < 16; i++) { + res->mat[i] = tmp.mat[i] * det; + } } @@ -691,138 +694,138 @@ void mat4_inverse(mat4* res, mat4* mat) void quat_fill(quat* res, float x, float y, float z, float w) { - res->x = x; - res->y = y; - res->z = z; - res->w = w; + res->x = x; + res->y = y; + res->z = z; + res->w = w; } void quat_identity(quat* res) { - res->x = 0.0; - res->y = 0.0; - res->z = 0.0; - res->w = 1.0; + res->x = 0.0; + res->y = 0.0; + res->z = 0.0; + res->w = 1.0; } void quat_mul_vec3(vec3* res, const quat* q, const vec3* v) { - vec3 uv, uuv, qvec; - qvec.x = q->x; - qvec.y = q->y; - qvec.z = q->z; + vec3 uv, uuv, qvec; + qvec.x = q->x; + qvec.y = q->y; + qvec.z = q->z; - vec3_cross(&uv, &qvec, v); - vec3_cross(&uuv, &qvec, &uv); + vec3_cross(&uv, &qvec, v); + vec3_cross(&uuv, &qvec, &uv); - vec3_scale(&uv, &uv, (2.0f * q->w)); - vec3_scale(&uuv, &uuv, 2.0f); + vec3_scale(&uv, &uv, (2.0f * q->w)); + vec3_scale(&uuv, &uuv, 2.0f); - vec3_add(res, v, &uv); - vec3_add(res, res, &uuv); + vec3_add(res, v, &uv); + vec3_add(res, res, &uuv); } void quat_assign(quat* res, const quat* val) { - res->x = val->x; - res->y = val->y; - res->z = val->z; - res->w = val->w; + res->x = val->x; + res->y = val->y; + res->z = val->z; + res->w = val->w; } void quat_mul(quat* res, const quat* q1, const quat* q2) { - quat tmp1, tmp2; - quat_assign(&tmp1, q1); - quat_assign(&tmp2, q2); + quat tmp1, tmp2; + quat_assign(&tmp1, q1); + quat_assign(&tmp2, q2); - res->x = tmp1.w * tmp2.x + tmp1.x * tmp2.w + tmp1.y * tmp2.z - tmp1.z * tmp2.y; - res->y = tmp1.w * tmp2.y + tmp1.y * tmp2.w + tmp1.z * tmp2.x - tmp1.x * tmp2.z; - res->z = tmp1.w * tmp2.z + tmp1.z * tmp2.w + tmp1.x * tmp2.y - tmp1.y * tmp2.x; - res->w = tmp1.w * tmp2.w - tmp1.x * tmp2.x - tmp1.y * tmp2.y - tmp1.z * tmp2.z; + res->x = tmp1.w * tmp2.x + tmp1.x * tmp2.w + tmp1.y * tmp2.z - tmp1.z * tmp2.y; + res->y = tmp1.w * tmp2.y + tmp1.y * tmp2.w + tmp1.z * tmp2.x - tmp1.x * tmp2.z; + res->z = tmp1.w * tmp2.z + tmp1.z * tmp2.w + tmp1.x * tmp2.y - tmp1.y * tmp2.x; + res->w = tmp1.w * tmp2.w - tmp1.x * tmp2.x - tmp1.y * tmp2.y - tmp1.z * tmp2.z; } float quat_len_sq(const quat* q) { - return (q->x * q->x) + (q->y * q->y) + (q->z * q->z) + (q->w * q->w); + return (q->x * q->x) + (q->y * q->y) + (q->z * q->z) + (q->w * q->w); } float quat_len(const quat* q) { - return (float)sqrt(quat_len_sq(q)); + return (float)sqrt(quat_len_sq(q)); } void quat_norm(quat* res, const quat* val) { - float length = quat_len(val); - if(fabs(length) < EPSILON) - { - quat_fill(res, 0.0f, 0.0f, 0.0f, 0.0f); - return; - } + float length = quat_len(val); + if(fabs(length) < EPSILON) + { + quat_fill(res, 0.0f, 0.0f, 0.0f, 0.0f); + return; + } - quat_fill(res, res->x / length, res->y / length, res->z / length, res->w / length); + quat_fill(res, res->x / length, res->y / length, res->z / length, res->w / length); } void quat_axis_angle(quat* res, const vec3* v, float angle) { - float half_angle = angle * 0.5f; - float scale = sinf(half_angle); + float half_angle = TO_RADIANS(angle) * 0.5f; + float scale = sinf(half_angle); - res->x = v->x * scale; - res->y = v->y * scale; - res->z = v->z * scale; - res->w = cosf(half_angle); - quat_norm(res, res); + res->x = v->x * scale; + res->y = v->y * scale; + res->z = v->z * scale; + res->w = cosf(half_angle); + quat_norm(res, res); } void quat_get_forward_rh(vec3* res, const quat* q) { - quat_mul_vec3(res, q, &UNIT_Z_NEG); + quat_mul_vec3(res, q, &UNIT_Z_NEG); } void quat_get_forward_lh(vec3* res, const quat* q) { - quat_mul_vec3(res, q, &UNIT_Z); + quat_mul_vec3(res, q, &UNIT_Z); } void quat_get_up(vec3* res, const quat* q) { - quat_mul_vec3(res, q, &UNIT_Y); + quat_mul_vec3(res, q, &UNIT_Y); } void quat_get_right(vec3* res, const quat* q) { - quat_mul_vec3(res, q, &UNIT_X); + quat_mul_vec3(res, q, &UNIT_X); } float quat_get_pitch(const quat* q) { - float result = (float)atan2(2 * (q->y * q->z + q->w * q->x), q->w * q->w - q->x * q->x - q->y * q->y + q->z * q->z); - return result; + float result = (float)atan2(2 * (q->y * q->z + q->w * q->x), q->w * q->w - q->x * q->x - q->y * q->y + q->z * q->z); + return result; } float quat_get_yaw(const quat* q) { - float result = (float)asin(-2 * (q->x * q->z - q->w * q->y)); - return result; + float result = (float)asin(-2 * (q->x * q->z - q->w * q->y)); + return result; } float quat_get_roll(const quat* q) { - float result = atan2(2 * (q->x * q->y + q->w * q->z), q->w * q->w + q->x * q->x - q->y * q->y - q->z * q->z); - return result; + float result = atan2(2 * (q->x * q->y + q->w * q->z), q->w * q->w + q->x * q->x - q->y * q->y - q->z * q->z); + return result; } void quat_mul_mat4(quat* res, quat* val, mat4* mat) { - vec4 v; - vec4_fill(&v, val->x, val->y, val->z, val->w); - vec4_mul_mat4(&v, &v, mat); - res->x = v.x; - res->y = v.y; - res->z = v.z; - res->w = v.w; + vec4 v; + vec4_fill(&v, val->x, val->y, val->z, val->w); + vec4_mul_mat4(&v, &v, mat); + res->x = v.x; + res->y = v.y; + res->z = v.z; + res->w = v.w; } void plane_init(Plane* plane, vec3* normal, vec3* point) diff --git a/src/game/editor.c b/src/game/editor.c index 6718988..c2b551f 100755 --- a/src/game/editor.c +++ b/src/game/editor.c @@ -117,16 +117,18 @@ void editor_init(struct Editor* editor) editor->grid_relative = 1; editor->grid_num_lines = 100; editor->grid_scale = 1.f; - editor->tool_mesh_draw_enabled = 0; + editor->tool_mesh_draw_enabled = 1; editor->tool_snap_enabled = 1; + editor->tool_rotate_arc_radius = 10.f; + editor->tool_rotate_arc_segments = 20.f; editor->axis_line_length = 500.f; vec3_fill(&editor->tool_mesh_position, 0.f, 0.f, 0.f); vec4_fill(&editor->tool_mesh_color, 0.f, 1.f, 1.f, 1.f); - vec4_fill(&editor->selected_entity_colour, 1.f, 1.f, 0.f, 1.f); + vec4_fill(&editor->selected_entity_colour, 0.96, 0.61, 0.17, 1.f); vec4_fill(&editor->grid_color, 0.3f, 0.3f, 0.3f, 0.1f); - vec4_fill(&editor->axis_color_x, 1.f, 0.f, 0.f, 1.f); - vec4_fill(&editor->axis_color_y, 0.f, 1.f, 0.f, 1.f); - vec4_fill(&editor->axis_color_z, 0.f, 0.f, 1.f, 1.f); + vec4_fill(&editor->axis_color_x, 0.87, 0.32, 0.40, 1.f); + vec4_fill(&editor->axis_color_y, 0.53, 0.67, 0.28, 1.f); + vec4_fill(&editor->axis_color_z, 0.47, 0.67, 0.89, 1.f); debug_vars_list = array_new(struct Debug_Variable); empty_indices = array_new(int); @@ -183,9 +185,9 @@ void editor_render(struct Editor* editor, struct Camera * active_camera) float half_axis_line_length = editor->axis_line_length / 2.f; - im_line((vec3) { -half_axis_line_length, 0.f, 0.f }, (vec3) { half_axis_line_length, 0.f, 0.f }, position, rotation, scale, editor->axis_color_x, GDM_LINES, 1); // X Axis - im_line((vec3) { 0.f, -half_axis_line_length, 0.f }, (vec3) { 0.f, half_axis_line_length, 0.f }, position, rotation, scale, editor->axis_color_y, GDM_LINES, 1); // Y Axis - im_line((vec3) { 0.f, 0.f, -half_axis_line_length }, (vec3) { 0.f, 0.f, half_axis_line_length }, position, rotation, scale, editor->axis_color_z, GDM_LINES, 1); // Z Axis + im_line((vec3) { -half_axis_line_length, 0.f, 0.f }, (vec3) { half_axis_line_length, 0.f, 0.f }, position, rotation, scale, editor->axis_color_x, 1); // X Axis + im_line((vec3) { 0.f, -half_axis_line_length, 0.f }, (vec3) { 0.f, half_axis_line_length, 0.f }, position, rotation, scale, editor->axis_color_y, 1); // Y Axis + im_line((vec3) { 0.f, 0.f, -half_axis_line_length }, (vec3) { 0.f, 0.f, half_axis_line_length }, position, rotation, scale, editor->axis_color_z, 1); // Z Axis //Draw Grid if(editor->grid_enabled) @@ -428,7 +430,9 @@ void editor_update(struct Editor* editor, float dt) if(editor->tool_mesh_draw_enabled) { - if(editor->current_mode == EDITOR_MODE_TRANSLATE) + switch(editor->current_mode) + { + case EDITOR_MODE_TRANSLATE: { quat rotation = { 0.f, 0.f, 0.f, 1.f }; vec3 scale = { 1.f, 1.f, 1.f }; @@ -438,20 +442,32 @@ void editor_update(struct Editor* editor, float dt) switch(editor->current_axis) { case EDITOR_AXIS_XZ: - im_line((vec3) { -editor->axis_line_length, 0.f, 0.f }, (vec3) { editor->axis_line_length, 0.f, 0.f }, editor->tool_mesh_position, rotation, scale, editor->axis_color_x, GDM_LINES, 3); - im_line((vec3) { 0.f, 0.f, -editor->axis_line_length }, (vec3) { 0.f, 0.f, editor->axis_line_length }, editor->tool_mesh_position, rotation, scale, editor->axis_color_z, GDM_LINES, 3); + im_line((vec3) { -editor->axis_line_length, 0.f, 0.f }, (vec3) { editor->axis_line_length, 0.f, 0.f }, editor->tool_mesh_position, rotation, scale, editor->axis_color_x, 3); + im_line((vec3) { 0.f, 0.f, -editor->axis_line_length }, (vec3) { 0.f, 0.f, editor->axis_line_length }, editor->tool_mesh_position, rotation, scale, editor->axis_color_z, 3); break; case EDITOR_AXIS_Y: - im_line((vec3) { 0.f, -editor->axis_line_length, 0.f }, (vec3) { 0.f, editor->axis_line_length, 0.f }, editor->tool_mesh_position, rotation, scale, editor->axis_color_y, GDM_LINES, 3); + im_line((vec3) { 0.f, -editor->axis_line_length, 0.f }, (vec3) { 0.f, editor->axis_line_length, 0.f }, editor->tool_mesh_position, rotation, scale, editor->axis_color_y, 3); break; case EDITOR_AXIS_X: - im_line((vec3) { -editor->axis_line_length, 0.f, 0.f }, (vec3) { editor->axis_line_length, 0.f, 0.f }, editor->tool_mesh_position, rotation, scale, editor->axis_color_x, GDM_LINES, 3); + im_line((vec3) { -editor->axis_line_length, 0.f, 0.f }, (vec3) { editor->axis_line_length, 0.f, 0.f }, editor->tool_mesh_position, rotation, scale, editor->axis_color_x, 3); break; case EDITOR_AXIS_Z: - im_line((vec3) { 0.f, 0.f, -editor->axis_line_length }, (vec3) { 0.f, 0.f, editor->axis_line_length }, editor->tool_mesh_position, rotation, scale, editor->axis_color_z, GDM_LINES, 3); + im_line((vec3) { 0.f, 0.f, -editor->axis_line_length }, (vec3) { 0.f, 0.f, editor->axis_line_length }, editor->tool_mesh_position, rotation, scale, editor->axis_color_z, 3); break; } } + break; + case EDITOR_MODE_ROTATE: + { + quat rotation = { 0.f, 0.f, 0.f, 1.f }; + quat_axis_angle(&rotation, &UNIT_X, -90.f); + vec3 scale = { 1.f, 1.f, 1.f }; + //im_circle(editor->tool_rotate_arc_radius, editor->tool_rotate_arc_segments, editor->tool_mesh_position, rotation, editor->axis_color_x, 3); + im_arc(editor->tool_rotate_arc_radius, 0.f, 90.f, editor->tool_rotate_arc_segments, editor->tool_mesh_position, rotation, editor->axis_color_y, 3); + } + break; + + } } } @@ -626,11 +642,12 @@ void editor_mode_set(struct Editor* editor, int mode) if(editor->current_mode != mode) { editor->current_mode = mode; - if(editor->current_mode == EDITOR_MODE_TRANSLATE) - editor->tool_mesh_draw_enabled = 1; - else - editor->tool_mesh_draw_enabled = 0; } + + if(editor->selected_entity) + transform_get_absolute_position(editor->selected_entity, &editor->tool_mesh_position); + else + vec3_fill(&editor->tool_mesh_position, 0.f, 0.f, 0.f); } void editor_entity_select(struct Editor* editor, struct Entity* entity) diff --git a/src/game/editor.h b/src/game/editor.h index 854978a..c603758 100755 --- a/src/game/editor.h +++ b/src/game/editor.h @@ -34,6 +34,8 @@ struct Editor vec3 tool_mesh_position; vec4 tool_mesh_color; int tool_mesh_draw_enabled; + float tool_rotate_arc_radius; + int tool_rotate_arc_segments; float axis_line_length; vec4 axis_color_x; vec4 axis_color_y; diff --git a/src/game/geometry.c b/src/game/geometry.c index b66941c..c478eac 100755 --- a/src/game/geometry.c +++ b/src/game/geometry.c @@ -26,9 +26,11 @@ void geom_init(void) geometry_list = array_new(struct Geometry); empty_indices = array_new(int); draw_modes = array_new_cap(GLenum, GDM_NUM_DRAWMODES); - draw_modes[GDM_TRIANGLES] = GL_TRIANGLES; - draw_modes[GDM_LINES] = GL_LINES; - draw_modes[GDM_POINTS] = GL_POINTS; + draw_modes[GDM_TRIANGLES] = GL_TRIANGLES; + draw_modes[GDM_LINES] = GL_LINES; + draw_modes[GDM_POINTS] = GL_POINTS; + draw_modes[GDM_LINE_STRIP] = GL_LINE_STRIP; + draw_modes[GDM_LINE_LOOP] = GL_LINE_LOOP; } int geom_find(const char* filename) diff --git a/src/game/geometry.h b/src/game/geometry.h index 6004212..bd87086 100755 --- a/src/game/geometry.h +++ b/src/game/geometry.h @@ -15,6 +15,8 @@ enum Geometry_Draw_Mode GDM_TRIANGLES = 0, GDM_LINES, GDM_POINTS, + GDM_LINE_STRIP, + GDM_LINE_LOOP, GDM_NUM_DRAWMODES }; diff --git a/src/game/im_render.c b/src/game/im_render.c index d57d3f7..8009ef2 100755 --- a/src/game/im_render.c +++ b/src/game/im_render.c @@ -10,13 +10,14 @@ #include #include +#include #define MAX_IM_VERTICES 2048 #define MAX_IM_GEOMETRIES (MAX_IM_VERTICES / 2) static struct { - struct IM_Vertex vertices[MAX_IM_VERTICES]; + struct IM_Vertex current_vertices[MAX_IM_VERTICES]; struct IM_Geom geometries[MAX_IM_GEOMETRIES]; uint vao; uint vbo; @@ -27,7 +28,7 @@ static struct IM_State; static struct IM_Geom* active_geom = NULL; -static int active_vertex_index = 0; +static int current_vertex_index = 0; static void im_geom_reset(struct IM_Geom* geom); static int im_sort_func(const void* p1, const void* p2); @@ -54,7 +55,7 @@ void im_init(void) glBindVertexArray(0); memset(&IM_State.geometries[0], 0, sizeof(struct IM_Geom) * MAX_IM_GEOMETRIES); - memset(&IM_State.vertices[0], 0, sizeof(struct IM_Vertex) * MAX_IM_VERTICES); + memset(&IM_State.current_vertices[0], 0, sizeof(struct IM_Vertex) * MAX_IM_VERTICES); IM_State.curr_geom = -1; IM_State.curr_vertex = 0; @@ -68,7 +69,7 @@ void im_cleanup(void) glDeleteVertexArrays(1, &IM_State.vao); memset(&IM_State.geometries[0], 0, sizeof(struct IM_Geom) * MAX_IM_GEOMETRIES); - memset(&IM_State.vertices[0], 0, sizeof(struct IM_Vertex) * MAX_IM_VERTICES); + memset(&IM_State.current_vertices[0], 0, sizeof(struct IM_Vertex) * MAX_IM_VERTICES); IM_State.vao = 0; IM_State.vbo = 0; IM_State.curr_geom = -1; @@ -103,9 +104,9 @@ void im_pos(float x, float y, float z) log_error("im_pos", "Buffer full!"); return; } - vec3_fill(&IM_State.vertices[active_vertex_index].position, x, y, z); + current_vertex_index++; + vec3_fill(&IM_State.current_vertices[current_vertex_index].position, x, y, z); IM_State.curr_vertex++; - active_vertex_index++; } void im_box(float x, float y, float z, vec3 position, quat rotation, vec4 color, int draw_mode, int draw_order) @@ -152,27 +153,47 @@ void im_sphere(float radius, vec3 position, quat rotation, vec4 color, int draw_ active_geom = NULL; } -void im_line(vec3 p1, vec3 p2, vec3 position, quat rotation, vec3 scale, vec4 color, int draw_mode, int draw_order) +void im_line(vec3 p1, vec3 p2, vec3 position, quat rotation, vec3 scale, vec4 color, int draw_order) { - im_begin(position, rotation, scale, color, draw_mode, draw_order); + im_begin(position, rotation, scale, color, GDM_LINES, draw_order); im_pos(p1.x, p1.y, p1.z); im_pos(p2.x, p2.y, p2.z); im_end(); } +void im_circle(float radius, int num_divisions, vec3 position, quat rotation, vec4 color, int draw_order) +{ + im_arc(radius, 0.f, 360.f, num_divisions, position, rotation, color, draw_order); +} + +void im_arc(float radius, float angle_start, float angle_end, int num_divisions, vec3 position, quat rotation, vec4 color, int draw_order) +{ + im_begin(position, rotation, (vec3) { 1.f, 1.f, 1.f }, color, GDM_LINE_LOOP, draw_order); + float arc_degrees = angle_end - angle_start; + float increment = arc_degrees / num_divisions; + + if(arc_degrees != 360) + im_pos(0.f, 0.f, 0.f); + + for(float i = angle_start; i <= angle_end; i+= increment) + im_pos(sinf(i * M_PI / 180.f) * radius, cosf(i * M_PI / 180.f) * radius, 0.f); + + im_end(); +} + void im_end(void) { - active_geom->num_vertices = active_vertex_index + 1; + active_geom->num_vertices = current_vertex_index + 1; GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, IM_State.vbo)); GL_CHECK(glBufferSubData(GL_ARRAY_BUFFER, sizeof(struct IM_Vertex) * active_geom->start_index, sizeof(struct IM_Vertex) * active_geom->num_vertices, - &IM_State.vertices[0])); + &IM_State.current_vertices[0])); glBindBuffer(GL_ARRAY_BUFFER, 0); active_geom = NULL; - active_vertex_index = 0; - memset(&IM_State.vertices[0], 0, sizeof(struct IM_Vertex) * MAX_IM_VERTICES); + current_vertex_index = -1; + memset(&IM_State.current_vertices[0], 0, sizeof(struct IM_Vertex) * MAX_IM_VERTICES); } void im_render(struct Camera* active_viewer) diff --git a/src/game/im_render.h b/src/game/im_render.h index 9770863..0991171 100755 --- a/src/game/im_render.h +++ b/src/game/im_render.h @@ -43,7 +43,9 @@ void im_begin(vec3 position, quat rotation, vec3 scale, vec4 color, int draw_mod void im_pos(float x, float y, float z); void im_box(float x, float y, float z, vec3 position, quat rotation, vec4 color, int draw_mode, int draw_order); void im_sphere(float radius, vec3 position, quat rotation, vec4 color, int draw_mode, int draw_order); -void im_line(vec3 p1, vec3 p2, vec3 position, quat rotation, vec3 scale, vec4 color, int draw_mode, int draw_order); +void im_line(vec3 p1, vec3 p2, vec3 position, quat rotation, vec3 scale, vec4 color, int draw_order); +void im_circle(float radius, int num_divisions, vec3 position, quat rotation, vec4 color, int draw_order); +void im_arc(float radius, float angle_start, float angle_end, int num_divisions, vec3 position, quat rotation, vec4 color, int draw_order); void im_end(void); void im_render(struct Camera* active_viewer); diff --git a/src/game/transform.c b/src/game/transform.c index dfb740c..03a68c1 100755 --- a/src/game/transform.c +++ b/src/game/transform.c @@ -96,7 +96,7 @@ void transform_rotate(struct Entity* entity, struct Transform* transform = &entity->transform; quat new_rot; quat_identity(&new_rot); - quat_axis_angle(&new_rot, axis, TO_RADIANS(angle)); + quat_axis_angle(&new_rot, axis, angle); if(space == TS_LOCAL) quat_mul(&transform->rotation, &transform->rotation, &new_rot); diff --git a/todo.txt b/todo.txt index 71cebfd..427af26 100644 --- a/todo.txt +++ b/todo.txt @@ -1,6 +1,4 @@ Todo: - - Implement circle drawing with immediate mode renderer - - Implement arc drawing with renderer - Rotate mode tool widget - Complete rotate mode - Better, more accurate picking @@ -20,6 +18,8 @@ Todo: ? Improve bounding sphere calculation - Change the way lights are set as uniforms to remove snprintf calls per frame for every light attribute - Filter Scene heirarchy by search using entity name + - Command interface that allows applying commands to selected entity like r x 30 would rotate the selected entity or entities on x axis by 30 degrees + - Quick scene filter and entity selection by popping up a menu which has list of entities and fuzzy matches them based on the typed name - Screen mouse coordinates to world-coordinates for aiming - Player projectiles and sounds - Console commands @@ -247,4 +247,6 @@ Done: * Draw coloured axes lines at world origin or grid origin * Make axis lines always follow the same colour scheme for consistency across all tools, red for X axis, green for Y axis and blue for Z axis * Toggle between relative and static grid i.e, grid that moves along with the selected object or grid that remains stationary at the origin + * Implement circle drawing with immediate mode renderer + * Implement arc drawing with renderer