From f82493181dd9a7d60df53ac48e1d74c92407fb4c Mon Sep 17 00:00:00 2001 From: Shariq Shah Date: Sun, 13 Sep 2015 16:00:49 +0500 Subject: [PATCH] Fixed rotation problems by using kmMath instead of linmath library --- premake4.lua | 5 + src/camera.c | 26 +- src/entity.c | 2 +- src/game.c | 147 +++--- src/geometry.c | 12 +- src/linmath.h | 1326 +++++++++++++++++++++++++---------------------- src/model.c | 10 +- src/model.h | 3 + src/renderer.c | 1 + src/shader.c | 16 +- src/shader.h | 8 +- src/transform.c | 142 +++-- src/transform.h | 24 +- src/utils.c | 27 + src/utils.h | 10 + 15 files changed, 946 insertions(+), 813 deletions(-) create mode 100644 src/utils.c create mode 100644 src/utils.h diff --git a/premake4.lua b/premake4.lua index 1fee653..b05b789 100644 --- a/premake4.lua +++ b/premake4.lua @@ -6,6 +6,7 @@ includedirs {"include/**"} buildoptions {"-Wall", "-std=c11"} linkoptions { "`pkg-config --libs --static glfw3`" } links {"GLEW"} +local lib_base = "libs" -- local cmd_stream = assert(io.popen("pkg-config --libs --static glfw3", r)) -- local libs_to_link = assert(cmd_stream:read("*all")) @@ -20,10 +21,14 @@ files { "src/*.h", "src/*.c"} configuration "Debug" flags {"Symbols"} +libdirs {path.join(lib_base, "debug/**")} +links {"kazmath"} targetdir "bin/debug" configuration "Release" defines {"NDEBUG"} flags {"Optimize"} +libdirs {path.join(lib_base, "release/**")} +links {"kazmath"} targetdir "bin/release" diff --git a/src/camera.c b/src/camera.c index 4d7a60b..ced6fe1 100644 --- a/src/camera.c +++ b/src/camera.c @@ -58,13 +58,13 @@ int camera_create(int node, int width, int height) new_camera->node = node; new_camera->farz = 1000.f; new_camera->nearz = 0.1f; - new_camera->fov = TO_RADIANS(60.f); + new_camera->fov = 60.f; float aspect_ratio = (float)width / (float)height; new_camera->aspect_ratio = aspect_ratio <= 0.f ? (4.f / 3.f) : aspect_ratio; new_camera->ortho = 0; - mat4_identity(new_camera->view_mat); - mat4_identity(new_camera->proj_mat); - mat4_identity(new_camera->view_proj_mat); + mat4_identity(&new_camera->view_mat); + mat4_identity(&new_camera->proj_mat); + mat4_identity(&new_camera->view_proj_mat); camera_update_view(new_camera); camera_update_proj(new_camera); @@ -73,18 +73,20 @@ int camera_create(int node, int width, int height) void camera_update_view_proj(struct Camera* camera) { - mat4_mul(camera->view_proj_mat, camera->proj_mat, camera->view_mat); + mat4_mul(&camera->view_proj_mat, &camera->proj_mat, &camera->view_mat); } void camera_update_view(struct Camera* camera) { struct Entity* entity = entity_get(camera->node); struct Transform* transform = entity_component_get(entity, C_TRANSFORM); - vec3 lookat = {0.f}, up = {0.f}, position = {0.f}; - transform_get_lookat(transform, lookat); - transform_get_up(transform, up); - transform_get_absolute_pos(transform, position); - mat4_look_at(camera->view_mat, position, lookat, up); + vec3 lookat = {0.f, 0.f, 0.f}; + vec3 up = {0.f, 0.f, 0.f}; + vec3 position = {0.f, 0.f, 0.f}; + transform_get_absolute_lookat(transform, &lookat); + transform_get_absolute_up(transform, &up); + transform_get_absolute_pos(transform, &position); + mat4_lookat(&camera->view_mat, &position, &lookat, &up); camera_update_view_proj(camera); } @@ -92,7 +94,7 @@ void camera_update_proj(struct Camera* camera) { if(!camera->ortho) { - mat4_perspective(camera->proj_mat, + mat4_perspective(&camera->proj_mat, camera->fov, camera->aspect_ratio, camera->nearz, @@ -100,7 +102,7 @@ void camera_update_proj(struct Camera* camera) } else { - mat4_ortho(camera->proj_mat, -1, 1, -1, 1, camera->nearz, camera->farz); + mat4_ortho(&camera->proj_mat, -1, 1, -1, 1, camera->nearz, camera->farz); } camera_update_view_proj(camera); } diff --git a/src/entity.c b/src/entity.c index 2852f60..2ac3757 100644 --- a/src/entity.c +++ b/src/entity.c @@ -105,7 +105,7 @@ struct Entity* entity_find(const char* name) for(int i = 0; i < array_len(entity_list); i++) { struct Entity* curr_ent = &entity_list[i]; - if(!entity->name) + if(!curr_ent->name) continue; if(strcmp(curr_ent->name, name) == 0) { diff --git a/src/game.c b/src/game.c index 8b42e89..dded74d 100644 --- a/src/game.c +++ b/src/game.c @@ -69,31 +69,53 @@ void game_init(void) player_node = player->node; vec3 viewer_pos = {0, 0, 10}; struct Transform* viewer_tran = entity_component_get(player, C_TRANSFORM); - transform_set_position(viewer_tran, viewer_pos); - /* struct Entity* player_pitch = scene_add_as_child("player_pitch", NULL, player); */ - /* player_pitch_node = player_pitch->node; */ - /* entity_component_add(player_pitch, C_CAMERA, 800, 600); */ - struct Camera* camera = entity_component_add(player, C_CAMERA, 800, 600); + transform_set_position(viewer_tran, &viewer_pos); + struct Entity* player_pitch = scene_add_as_child("player_pitch", NULL, player); + player_pitch_node = player_pitch->node; + entity_component_add(player_pitch, C_CAMERA, 800, 600); + /* struct Camera* camera = entity_component_add(player, C_CAMERA, 800, 600); */ struct Entity* new_ent = scene_add_new("Model_Entity", NULL); struct Transform* tran = entity_component_get(new_ent, C_TRANSFORM); vec3 position = {0, 0, -5}; - transform_translate(tran, position, TS_WORLD); - struct Model* model = entity_component_add(new_ent, C_MODEL, "default.pamesh"); + transform_translate(tran, &position, TS_WORLD); + entity_component_add(new_ent, C_MODEL, "default.pamesh"); struct Transform* model_tran = entity_component_get(new_ent, C_TRANSFORM); //vec3 axis = {0.f, 1.f, 0.f}; //transform_rotate(model_tran, axis, (45.f), TS_WORLD); vec3 scale = {1, 1, 2}; - transform_scale(model_tran, scale); + transform_scale(model_tran, &scale); struct Entity* suz = scene_add_as_child("Suzanne", NULL, new_ent); entity_component_add(suz, C_MODEL, "suzanne.pamesh"); struct Transform* s_tran = entity_component_get(suz, C_TRANSFORM); vec3 s_pos = {3, 0, 0}; - transform_translate(s_tran, s_pos, TS_WORLD); + transform_translate(s_tran, &s_pos, TS_WORLD); - /* Set cursor mode */ - input_cursor_mode_set(CM_LOCKED); + struct Entity* ground = scene_add_new("Ground", NULL); + struct Model* ground_model = entity_component_add(ground, C_MODEL, "plane.pamesh"); + ground_model->color.x = 1.f; + struct Transform* ground_tran = entity_component_get(ground, C_TRANSFORM); + vec3 pos = {0, -3, -3}; + vec3 scale_ground = {0.5f, 0.5f, 3.f}; + transform_set_position(ground_tran, &pos); + transform_scale(ground_tran, &scale_ground); + + mat4 m1, m2, r1, r2, f1, f2; + mat4_identity(&m1); + mat4_identity(&m2); + mat4_identity(&r1); + mat4_identity(&r2); + mat4_identity(&f1); + mat4_identity(&f2); + + mat4_rot_x(&m1, TO_RADIANS(25.f)); + mat4_rot_x(&m2, TO_RADIANS(25.f)); + mat4_rot_x(&f1, TO_RADIANS(5.f)); + mat4_rot_x(&f2, TO_RADIANS(5.f)); + + mat4_mul(&r1, &f1, &m1); + mat4_mul(&r2, &m1, &f1); run(); } @@ -101,9 +123,9 @@ void game_init(void) void debug(float dt) { struct Entity* entity = entity_get(player_node); - //struct Entity* entity_pitch = entity_get(player_pitch_node); + struct Entity* entity_pitch = entity_get(player_pitch_node); struct Transform* transform = entity_component_get(entity, C_TRANSFORM); - //struct Transform* pitch_transform = entity_component_get(entity_pitch, C_TRANSFORM); + struct Transform* pitch_transform = entity_component_get(entity_pitch, C_TRANSFORM); float move_speed = 5.f, turn_speed = 50.f; vec3 offset = {0, 0, 0}; float turn_up_down = 0.f; @@ -121,16 +143,18 @@ void debug(float dt) double cursor_lr, cursor_ud; input_cursor_pos_get(&cursor_lr, &cursor_ud); - input_cursor_pos_set(0.0, 0.0); if(input_mousebutton_state_get(GLFW_MOUSE_BUTTON_RIGHT, GLFW_PRESS)) { - const double scale = 0.5; - turn_up_down = cursor_ud * turn_speed * dt * scale; + input_cursor_mode_set(CM_LOCKED); + const double scale = 0.25; + turn_up_down = -cursor_ud * turn_speed * dt * scale; turn_left_right = cursor_lr * turn_speed * dt * scale; + input_cursor_pos_set(0.0, 0.0); } else { + input_cursor_mode_set(CM_NORMAL); turn_up_down *= dt; turn_left_right *= dt; } @@ -146,53 +170,52 @@ void debug(float dt) total_up_down_rot = -max_up_down; turn_up_down = 0.f; } + + struct Entity* ground = scene_find("Ground"); + struct Transform* ground_tran = entity_component_get(ground, C_TRANSFORM); + //transform = ground_tran; + //transform_rotate(ground_tran, rot_axis_left_right, 50.f * dt, TS_WORLD); if(turn_left_right != 0.f) { - transform_rotate(transform, rot_axis_left_right, -turn_left_right, TS_WORLD); - vec3 up = {0.f}; - vec3 forward = {0.f}; - transform_get_up(transform, up); - transform_get_forward(transform, forward); - /* log_message("Up : %.3f, %.3f, %.3f", up[0], up[1], up[2]); */ - /* log_message("Forward : %.3f, %.3f, %.3f", forward[0], forward[1], forward[2]); */ - /* log_message("ROT : %.3f, %.3f, %.3f", */ - /* TO_DEGREES(quat_pitch(transform->rotq)), */ - /* TO_DEGREES(quat_yaw(transform->rotq)), */ - /* TO_DEGREES(quat_roll(transform->rotq))); */ + //transform_rotate(transform, rot_axis_left_right, turn_left_right, TS_WORLD); + transform_rotate(transform, &rot_axis_left_right, -turn_left_right, TS_WORLD); + vec3 up = {0.f, 0.f, 0.f}; + vec3 forward = {0.f, 0.f, 0.f}; + vec3 lookat = {0.f, 0.f, 0.f}; + transform_get_up(transform, &up); + transform_get_forward(transform, &forward); + transform_get_lookat(transform, &lookat); + log_message("Up : %s", tostr_vec3(&up)); + log_message("FR : %s", tostr_vec3(&forward)); } if(turn_up_down != 0.f) { - transform_rotate(transform, rot_axis_up_down, -turn_up_down, TS_LOCAL); - //transform_rotate(pitch_transform, rot_axis_up_down, -turn_up_down, TS_LOCAL); - /* log_message("ROT : %.3f, %.3f, %.3f", */ - /* TO_DEGREES(quat_pitch(pitch_transform->rotq)), */ - /* TO_DEGREES(quat_yaw(pitch_transform->rotq)), */ - /* TO_DEGREES(quat_roll(pitch_transform->rotq))); */ - vec3 up = {0.f}; - vec3 forward = {0.f}; - transform_get_up(transform, up); - transform_get_forward(transform, forward); - log_message("Up : %s", tostr_vec3(up)); - log_message("FR : %s", tostr_vec3(forward)); + //transform_rotate(transform, &rot_axis_up_down, turn_up_down, TS_LOCAL); + transform_rotate(pitch_transform, &rot_axis_up_down, turn_up_down, TS_LOCAL); + vec3 up = {0.f, 0.f, 0.f}; + vec3 forward = {0.f, 0.f, 0.f}; + vec3 lookat = {0.f, 0.f, 0.f}; + transform_get_up(transform, &up); + transform_get_forward(transform, &forward); + transform_get_lookat(transform, &lookat); + log_message("Up : %s", tostr_vec3(&up)); + log_message("FR : %s", tostr_vec3(&forward)); } /* Movement */ - if(input_map_state_get("Move_Forward", GLFW_PRESS)) offset[2] -= move_speed; - if(input_map_state_get("Move_Backward", GLFW_PRESS)) offset[2] += move_speed; - if(input_map_state_get("Move_Left", GLFW_PRESS)) offset[0] -= move_speed; - if(input_map_state_get("Move_Right", GLFW_PRESS)) offset[0] += move_speed; - if(input_map_state_get("Move_Up", GLFW_PRESS)) offset[1] += move_speed; - if(input_map_state_get("Move_Down", GLFW_PRESS)) offset[1] -= move_speed; - - vec3_scale(offset, offset, dt); - if(offset[0] != 0 || offset[2] != 0 || offset[1] != 0) + if(input_map_state_get("Move_Forward", GLFW_PRESS)) offset.z -= move_speed; + if(input_map_state_get("Move_Backward", GLFW_PRESS)) offset.z += move_speed; + if(input_map_state_get("Move_Left", GLFW_PRESS)) offset.x -= move_speed; + if(input_map_state_get("Move_Right", GLFW_PRESS)) offset.x += move_speed; + if(input_map_state_get("Move_Up", GLFW_PRESS)) offset.y += move_speed; + if(input_map_state_get("Move_Down", GLFW_PRESS)) offset.y -= move_speed; + + vec3_scale(&offset, &offset, dt); + if(offset.x != 0 || offset.y != 0 || offset.z != 0) { - transform_translate(transform, offset, TS_LOCAL); - log_message("Position : %.3f, %.3f, %.3f", - transform->position[0], - transform->position[1], - transform->position[2]); + transform_translate(transform, &offset, TS_LOCAL); + log_message("Position : %s", tostr_vec3(&transform->position)); } if(input_key_state_get(GLFW_KEY_SPACE, GLFW_PRESS)) @@ -200,23 +223,27 @@ void debug(float dt) struct Entity* model = entity_get(2); struct Transform* mod_tran = entity_component_get(model, C_TRANSFORM); vec3 x_axis = {1, 0, 0}; - transform_rotate(mod_tran, x_axis, 25.f * dt, TS_WORLD); + transform_rotate(mod_tran, &x_axis, 25.f * dt, TS_WORLD); } if(input_key_state_get(GLFW_KEY_M, GLFW_PRESS)) { - struct Entity* model = entity_get(3); + struct Entity* model = entity_get(2); struct Transform* mod_tran = entity_component_get(model, C_TRANSFORM); - vec3 y_axis = {0, 1, 0}; - transform_rotate(mod_tran, y_axis, 25.f * dt, TS_LOCAL); + vec3 y_axis = {0, 0, 1}; + transform_rotate(mod_tran, &y_axis, 25.f * dt, TS_LOCAL); } if(input_key_state_get(GLFW_KEY_N, GLFW_PRESS)) { - struct Entity* model = entity_get(3); + /* struct Entity* model = entity_get(3); */ + /* struct Transform* mod_tran = entity_component_get(model, C_TRANSFORM); */ + /* vec3 amount = {0, 0, -5 * dt}; */ + /* transform_translate(mod_tran, amount, TS_LOCAL); */ + struct Entity* model = entity_get(2); struct Transform* mod_tran = entity_component_get(model, C_TRANSFORM); - vec3 amount = {0, 0, -5 * dt}; - transform_translate(mod_tran, amount, TS_LOCAL); + vec3 y_axis = {0, 0, 1}; + transform_rotate(mod_tran, &y_axis, 25.f * dt, TS_WORLD); } } diff --git a/src/geometry.c b/src/geometry.c index c88f17c..8b3b505 100644 --- a/src/geometry.c +++ b/src/geometry.c @@ -116,12 +116,12 @@ void geom_remove(int index) geometry->ref_count--; if(geometry->ref_count < 0) { - array_free(geometry->indices); - array_free(geometry->vertices); - array_free(geometry->uvs); - array_free(geometry->normals); - array_free(geometry->vertex_colors); - free(geometry->filename); + if(geometry->indices) array_free(geometry->indices); + if(geometry->vertices) array_free(geometry->vertices); + if(geometry->uvs) array_free(geometry->uvs); + if(geometry->normals) array_free(geometry->normals); + if(geometry->vertex_colors) array_free(geometry->vertex_colors); + if(geometry->filename) free(geometry->filename); array_push(empty_indices, index, int); } } diff --git a/src/linmath.h b/src/linmath.h index faca55f..8340f75 100644 --- a/src/linmath.h +++ b/src/linmath.h @@ -3,644 +3,724 @@ /* Credit : https://github.com/datenwolf/linmath.h */ +#include "../include/kazmath/kazmath/kazmath.h" +#include "../include/kazmath/kazmath/vec4.h" #include +/* Just for convenience & consistency */ +typedef kmVec2 vec2; +typedef kmVec3 vec3; +typedef struct kmVec4 vec4; +typedef kmMat3 mat3; +typedef kmMat4 mat4; +typedef kmQuaternion quat; + +/* vec3 */ +#define vec3_fill kmVec3Fill +#define vec3_add kmVec3Add +#define vec3_assign kmVec3Assign +#define vec3_norm kmVec3Normalize +#define vec3_mul kmVec3Mul +#define vec3_mul_mat4 kmVec3MultiplyMat4 +#define vec3_mul_mat3 kmVec3MultiplyMat3 +#define vec3_scale kmVec3Scale +#define vec3_equals kmVec3Equals +#define vec3_transform kmVec3Transform +#define vec3_transform_norm kmVec3TransformNormal +#define vec3_len kmVec3Length + +/* vec4 */ +#define vec4_fill kmVec4Fill +#define vec4_add kmVec4Add +#define vec4_assign kmVec4Assign +#define vec4_norm kmVec4Normalize +#define vec4_mul kmVec4Mul +#define vec4_mul_mat4 kmVec4MultiplyMat4 +#define vec4_scale kmVec4Scale +#define vec4_equals kmVec4Equals +#define vec4_transform kmVec4Transform +#define vec4_transform_norm kmVec4TransformNormal +#define vec4_len kmVec4Length + +/* mat4 */ +#define mat4_identity kmMat4Identity +#define mat4_mul kmMat4Multiply +#define mat4_lookat kmMat4LookAt +#define mat4_perspective kmMat4PerspectiveProjection +#define mat4_ortho kmMat4OrthographicProjection +#define mat4_scale kmMat4Scaling +#define mat4_translate kmMat4Translation +#define mat4_from_quat kmMat4RotationQuaternion +#define mat4_rot_x kmMat4RotationX +#define mat4_rot_y kmMat4RotationY +#define mat4_rot_z kmMat4RotationZ + +/* quat */ +#define quat_identity kmQuaternionIdentity +#define quat_mul_vec3 kmQuaternionMultiplyVec3 +#define quat_mul kmQuaternionMultiply +#define quat_axis_angle kmQuaternionRotationAxisAngle +#define quat_get_forward_rh kmQuaternionGetForwardVec3RH +#define quat_get_forward_lh kmQuaternionGetForwardVec3LH +#define quat_get_up kmQuaternionGetUpVec3 +#define quat_get_right kmQuaternionGetRightVec3 + + #define M_PI 3.14159265358979323846 #define TO_RADIANS(degrees) ((degrees * M_PI) / 180.0) #define TO_DEGREES(radians) ((radians * 180.0) / M_PI) -#define LINMATH_H_DEFINE_VEC(n) \ - typedef float vec##n[n]; \ - static inline void vec##n##_add(vec##n r, vec##n const a, vec##n const b) \ - { \ - int i; \ - for(i=0; i 1e-4) { - vec3_norm(u, u); - mat4 T; - mat4_from_vec3_mul_outer(T, u, u); - - mat4 S = { - { 0, u[2], -u[1], 0}, - {-u[2], 0, u[0], 0}, - { u[1], -u[0], 0, 0}, - { 0, 0, 0, 0} - }; - mat4_scale(S, S, s); - - mat4 C; - mat4_identity(C); - mat4_sub(C, C, T); - - mat4_scale(C, C, c); - - mat4_add(T, T, C); - mat4_add(T, T, S); - - T[3][3] = 1.; - mat4_mul(R, M, T); - } else { - mat4_dup(R, M); - } -} -static inline void mat4_rotate_X(mat4 Q, mat4 M, float angle) -{ - float s = sinf(angle); - float c = cosf(angle); - mat4 R = { - {1.f, 0.f, 0.f, 0.f}, - {0.f, c, s, 0.f}, - {0.f, -s, c, 0.f}, - {0.f, 0.f, 0.f, 1.f} - }; - mat4_mul(Q, M, R); -} -static inline void mat4_rotate_Y(mat4 Q, mat4 M, float angle) -{ - float s = sinf(angle); - float c = cosf(angle); - mat4 R = { - { c, 0.f, s, 0.f}, - { 0.f, 1.f, 0.f, 0.f}, - { -s, 0.f, c, 0.f}, - { 0.f, 0.f, 0.f, 1.f} - }; - mat4_mul(Q, M, R); -} -static inline void mat4_rotate_Z(mat4 Q, mat4 M, float angle) -{ - float s = sinf(angle); - float c = cosf(angle); - mat4 R = { - { c, s, 0.f, 0.f}, - { -s, c, 0.f, 0.f}, - { 0.f, 0.f, 1.f, 0.f}, - { 0.f, 0.f, 0.f, 1.f} - }; - mat4_mul(Q, M, R); -} -static inline void mat4_invert(mat4 T, mat4 M) -{ - float s[6]; - float c[6]; - s[0] = M[0][0]*M[1][1] - M[1][0]*M[0][1]; - s[1] = M[0][0]*M[1][2] - M[1][0]*M[0][2]; - s[2] = M[0][0]*M[1][3] - M[1][0]*M[0][3]; - s[3] = M[0][1]*M[1][2] - M[1][1]*M[0][2]; - s[4] = M[0][1]*M[1][3] - M[1][1]*M[0][3]; - s[5] = M[0][2]*M[1][3] - M[1][2]*M[0][3]; - - c[0] = M[2][0]*M[3][1] - M[3][0]*M[2][1]; - c[1] = M[2][0]*M[3][2] - M[3][0]*M[2][2]; - c[2] = M[2][0]*M[3][3] - M[3][0]*M[2][3]; - c[3] = M[2][1]*M[3][2] - M[3][1]*M[2][2]; - c[4] = M[2][1]*M[3][3] - M[3][1]*M[2][3]; - c[5] = M[2][2]*M[3][3] - M[3][2]*M[2][3]; +/* #define LINMATH_H_DEFINE_VEC(n) \ */ +/* typedef float vec##n[n]; \ */ +/* static inline void vec##n##_add(vec##n r, vec##n const a, vec##n const b) \ */ +/* { \ */ +/* int i; \ */ +/* for(i=0; i 1e-4) { */ +/* vec3_norm(u, u); */ +/* mat4 T; */ +/* mat4_from_vec3_mul_outer(T, u, u); */ + +/* mat4 S = { */ +/* { 0, u[2], -u[1], 0}, */ +/* {-u[2], 0, u[0], 0}, */ +/* { u[1], -u[0], 0, 0}, */ +/* { 0, 0, 0, 0} */ +/* }; */ +/* mat4_scale(S, S, s); */ + +/* mat4 C; */ +/* mat4_identity(C); */ +/* mat4_sub(C, C, T); */ + +/* mat4_scale(C, C, c); */ + +/* mat4_add(T, T, C); */ +/* mat4_add(T, T, S); */ + +/* T[3][3] = 1.; */ +/* mat4_mul(R, M, T); */ +/* } else { */ +/* mat4_dup(R, M); */ +/* } */ +/* } */ +/* static inline void mat4_rotate_X(mat4 Q, mat4 M, float angle) */ +/* { */ +/* float s = sinf(angle); */ +/* float c = cosf(angle); */ +/* mat4 R = { */ +/* {1.f, 0.f, 0.f, 0.f}, */ +/* {0.f, c, s, 0.f}, */ +/* {0.f, -s, c, 0.f}, */ +/* {0.f, 0.f, 0.f, 1.f} */ +/* }; */ +/* mat4_mul(Q, M, R); */ +/* } */ +/* static inline void mat4_rotate_Y(mat4 Q, mat4 M, float angle) */ +/* { */ +/* float s = sinf(angle); */ +/* float c = cosf(angle); */ +/* mat4 R = { */ +/* { c, 0.f, s, 0.f}, */ +/* { 0.f, 1.f, 0.f, 0.f}, */ +/* { -s, 0.f, c, 0.f}, */ +/* { 0.f, 0.f, 0.f, 1.f} */ +/* }; */ +/* mat4_mul(Q, M, R); */ +/* } */ +/* static inline void mat4_rotate_Z(mat4 Q, mat4 M, float angle) */ +/* { */ +/* float s = sinf(angle); */ +/* float c = cosf(angle); */ +/* mat4 R = { */ +/* { c, s, 0.f, 0.f}, */ +/* { -s, c, 0.f, 0.f}, */ +/* { 0.f, 0.f, 1.f, 0.f}, */ +/* { 0.f, 0.f, 0.f, 1.f} */ +/* }; */ +/* mat4_mul(Q, M, R); */ +/* } */ +/* static inline void mat4_invert(mat4 T, mat4 M) */ +/* { */ +/* float s[6]; */ +/* float c[6]; */ +/* s[0] = M[0][0]*M[1][1] - M[1][0]*M[0][1]; */ +/* s[1] = M[0][0]*M[1][2] - M[1][0]*M[0][2]; */ +/* s[2] = M[0][0]*M[1][3] - M[1][0]*M[0][3]; */ +/* s[3] = M[0][1]*M[1][2] - M[1][1]*M[0][2]; */ +/* s[4] = M[0][1]*M[1][3] - M[1][1]*M[0][3]; */ +/* s[5] = M[0][2]*M[1][3] - M[1][2]*M[0][3]; */ + +/* c[0] = M[2][0]*M[3][1] - M[3][0]*M[2][1]; */ +/* c[1] = M[2][0]*M[3][2] - M[3][0]*M[2][2]; */ +/* c[2] = M[2][0]*M[3][3] - M[3][0]*M[2][3]; */ +/* c[3] = M[2][1]*M[3][2] - M[3][1]*M[2][2]; */ +/* c[4] = M[2][1]*M[3][3] - M[3][1]*M[2][3]; */ +/* c[5] = M[2][2]*M[3][3] - M[3][2]*M[2][3]; */ - /* Assumes it is invertible */ - float idet = 1.0f/( s[0]*c[5]-s[1]*c[4]+s[2]*c[3]+s[3]*c[2]-s[4]*c[1]+s[5]*c[0] ); +/* /\* Assumes it is invertible *\/ */ +/* float idet = 1.0f/( s[0]*c[5]-s[1]*c[4]+s[2]*c[3]+s[3]*c[2]-s[4]*c[1]+s[5]*c[0] ); */ - T[0][0] = ( M[1][1] * c[5] - M[1][2] * c[4] + M[1][3] * c[3]) * idet; - T[0][1] = (-M[0][1] * c[5] + M[0][2] * c[4] - M[0][3] * c[3]) * idet; - T[0][2] = ( M[3][1] * s[5] - M[3][2] * s[4] + M[3][3] * s[3]) * idet; - T[0][3] = (-M[2][1] * s[5] + M[2][2] * s[4] - M[2][3] * s[3]) * idet; - - T[1][0] = (-M[1][0] * c[5] + M[1][2] * c[2] - M[1][3] * c[1]) * idet; - T[1][1] = ( M[0][0] * c[5] - M[0][2] * c[2] + M[0][3] * c[1]) * idet; - T[1][2] = (-M[3][0] * s[5] + M[3][2] * s[2] - M[3][3] * s[1]) * idet; - T[1][3] = ( M[2][0] * s[5] - M[2][2] * s[2] + M[2][3] * s[1]) * idet; - - T[2][0] = ( M[1][0] * c[4] - M[1][1] * c[2] + M[1][3] * c[0]) * idet; - T[2][1] = (-M[0][0] * c[4] + M[0][1] * c[2] - M[0][3] * c[0]) * idet; - T[2][2] = ( M[3][0] * s[4] - M[3][1] * s[2] + M[3][3] * s[0]) * idet; - T[2][3] = (-M[2][0] * s[4] + M[2][1] * s[2] - M[2][3] * s[0]) * idet; - - T[3][0] = (-M[1][0] * c[3] + M[1][1] * c[1] - M[1][2] * c[0]) * idet; - T[3][1] = ( M[0][0] * c[3] - M[0][1] * c[1] + M[0][2] * c[0]) * idet; - T[3][2] = (-M[3][0] * s[3] + M[3][1] * s[1] - M[3][2] * s[0]) * idet; - T[3][3] = ( M[2][0] * s[3] - M[2][1] * s[1] + M[2][2] * s[0]) * idet; -} -static inline void mat4_orthonormalize(mat4 R, mat4 M) -{ - mat4_dup(R, M); - float s = 1.; - vec3 h; - - vec3_norm(R[2], R[2]); +/* T[0][0] = ( M[1][1] * c[5] - M[1][2] * c[4] + M[1][3] * c[3]) * idet; */ +/* T[0][1] = (-M[0][1] * c[5] + M[0][2] * c[4] - M[0][3] * c[3]) * idet; */ +/* T[0][2] = ( M[3][1] * s[5] - M[3][2] * s[4] + M[3][3] * s[3]) * idet; */ +/* T[0][3] = (-M[2][1] * s[5] + M[2][2] * s[4] - M[2][3] * s[3]) * idet; */ + +/* T[1][0] = (-M[1][0] * c[5] + M[1][2] * c[2] - M[1][3] * c[1]) * idet; */ +/* T[1][1] = ( M[0][0] * c[5] - M[0][2] * c[2] + M[0][3] * c[1]) * idet; */ +/* T[1][2] = (-M[3][0] * s[5] + M[3][2] * s[2] - M[3][3] * s[1]) * idet; */ +/* T[1][3] = ( M[2][0] * s[5] - M[2][2] * s[2] + M[2][3] * s[1]) * idet; */ + +/* T[2][0] = ( M[1][0] * c[4] - M[1][1] * c[2] + M[1][3] * c[0]) * idet; */ +/* T[2][1] = (-M[0][0] * c[4] + M[0][1] * c[2] - M[0][3] * c[0]) * idet; */ +/* T[2][2] = ( M[3][0] * s[4] - M[3][1] * s[2] + M[3][3] * s[0]) * idet; */ +/* T[2][3] = (-M[2][0] * s[4] + M[2][1] * s[2] - M[2][3] * s[0]) * idet; */ + +/* T[3][0] = (-M[1][0] * c[3] + M[1][1] * c[1] - M[1][2] * c[0]) * idet; */ +/* T[3][1] = ( M[0][0] * c[3] - M[0][1] * c[1] + M[0][2] * c[0]) * idet; */ +/* T[3][2] = (-M[3][0] * s[3] + M[3][1] * s[1] - M[3][2] * s[0]) * idet; */ +/* T[3][3] = ( M[2][0] * s[3] - M[2][1] * s[1] + M[2][2] * s[0]) * idet; */ +/* } */ +/* static inline void mat4_orthonormalize(mat4 R, mat4 M) */ +/* { */ +/* mat4_dup(R, M); */ +/* float s = 1.; */ +/* vec3 h; */ + +/* vec3_norm(R[2], R[2]); */ - s = vec3_mul_inner(R[1], R[2]); - vec3_scale(h, R[2], s); - vec3_sub(R[1], R[1], h); - vec3_norm(R[2], R[2]); - - s = vec3_mul_inner(R[1], R[2]); - vec3_scale(h, R[2], s); - vec3_sub(R[1], R[1], h); - vec3_norm(R[1], R[1]); - - s = vec3_mul_inner(R[0], R[1]); - vec3_scale(h, R[1], s); - vec3_sub(R[0], R[0], h); - vec3_norm(R[0], R[0]); -} - -static inline void mat4_frustum(mat4 M, float l, float r, float b, float t, float n, float f) -{ - M[0][0] = 2.f*n/(r-l); - M[0][1] = M[0][2] = M[0][3] = 0.f; +/* s = vec3_mul_inner(R[1], R[2]); */ +/* vec3_scale(h, R[2], s); */ +/* vec3_sub(R[1], R[1], h); */ +/* vec3_norm(R[2], R[2]); */ + +/* s = vec3_mul_inner(R[1], R[2]); */ +/* vec3_scale(h, R[2], s); */ +/* vec3_sub(R[1], R[1], h); */ +/* vec3_norm(R[1], R[1]); */ + +/* s = vec3_mul_inner(R[0], R[1]); */ +/* vec3_scale(h, R[1], s); */ +/* vec3_sub(R[0], R[0], h); */ +/* vec3_norm(R[0], R[0]); */ +/* } */ + +/* static inline void mat4_frustum(mat4 M, float l, float r, float b, float t, float n, float f) */ +/* { */ +/* M[0][0] = 2.f*n/(r-l); */ +/* M[0][1] = M[0][2] = M[0][3] = 0.f; */ + +/* M[1][1] = 2.*n/(t-b); */ +/* M[1][0] = M[1][2] = M[1][3] = 0.f; */ + +/* M[2][0] = (r+l)/(r-l); */ +/* M[2][1] = (t+b)/(t-b); */ +/* M[2][2] = -(f+n)/(f-n); */ +/* M[2][3] = -1.f; */ - M[1][1] = 2.*n/(t-b); - M[1][0] = M[1][2] = M[1][3] = 0.f; +/* M[3][2] = -2.f*(f*n)/(f-n); */ +/* M[3][0] = M[3][1] = M[3][3] = 0.f; */ +/* } */ +/* static inline void mat4_ortho(mat4 M, float l, float r, float b, float t, float n, float f) */ +/* { */ +/* M[0][0] = 2.f/(r-l); */ +/* M[0][1] = M[0][2] = M[0][3] = 0.f; */ + +/* M[1][1] = 2.f/(t-b); */ +/* M[1][0] = M[1][2] = M[1][3] = 0.f; */ + +/* M[2][2] = -2.f/(f-n); */ +/* M[2][0] = M[2][1] = M[2][3] = 0.f; */ + +/* M[3][0] = -(r+l)/(r-l); */ +/* M[3][1] = -(t+b)/(t-b); */ +/* M[3][2] = -(f+n)/(f-n); */ +/* M[3][3] = 1.f; */ +/* } */ +/* static inline void mat4_perspective(mat4 m, float y_fov, float aspect, float n, float f) */ +/* { */ +/* /\* NOTE: Degrees are an unhandy unit to work with. */ +/* * linmath.h uses radians for everything! *\/ */ +/* float const a = 1.f / tan(y_fov / 2.f); */ + +/* m[0][0] = a / aspect; */ +/* m[0][1] = 0.f; */ +/* m[0][2] = 0.f; */ +/* m[0][3] = 0.f; */ + +/* m[1][0] = 0.f; */ +/* m[1][1] = a; */ +/* m[1][2] = 0.f; */ +/* m[1][3] = 0.f; */ + +/* m[2][0] = 0.f; */ +/* m[2][1] = 0.f; */ +/* m[2][2] = -((f + n) / (f - n)); */ +/* m[2][3] = -1.f; */ + +/* m[3][0] = 0.f; */ +/* m[3][1] = 0.f; */ +/* m[3][2] = -((2.f * f * n) / (f - n)); */ +/* m[3][3] = 0.f; */ +/* } */ +/* static inline void mat4_look_at(mat4 m, vec3 eye, vec3 lookat, vec3 up) */ +/* { */ +/* /\* Adapted from Android's OpenGL Matrix.java. *\/ */ +/* /\* See the OpenGL GLUT documentation for gluLookAt for a description *\/ */ +/* /\* of the algorithm. We implement it in a straightforward way: *\/ */ + +/* /\* TODO: The negation of of can be spared by swapping the order of */ +/* * operands in the following cross products in the right way. *\/ */ +/* vec3 f; */ +/* vec3_sub(f, lookat, eye); */ +/* vec3_norm(f, f); */ + +/* vec3 s; */ +/* vec3_mul_cross(s, f, up); */ +/* vec3_norm(s, s); */ + +/* vec3 t; */ +/* vec3_mul_cross(t, s, f); */ - M[2][0] = (r+l)/(r-l); - M[2][1] = (t+b)/(t-b); - M[2][2] = -(f+n)/(f-n); - M[2][3] = -1.f; +/* m[0][0] = s[0]; */ +/* m[1][0] = s[1]; */ +/* m[2][0] = s[2]; */ - M[3][2] = -2.f*(f*n)/(f-n); - M[3][0] = M[3][1] = M[3][3] = 0.f; -} -static inline void mat4_ortho(mat4 M, float l, float r, float b, float t, float n, float f) -{ - M[0][0] = 2.f/(r-l); - M[0][1] = M[0][2] = M[0][3] = 0.f; - - M[1][1] = 2.f/(t-b); - M[1][0] = M[1][2] = M[1][3] = 0.f; - - M[2][2] = -2.f/(f-n); - M[2][0] = M[2][1] = M[2][3] = 0.f; +/* m[0][1] = t[0]; */ +/* m[1][1] = t[1]; */ +/* m[2][1] = t[2]; */ - M[3][0] = -(r+l)/(r-l); - M[3][1] = -(t+b)/(t-b); - M[3][2] = -(f+n)/(f-n); - M[3][3] = 1.f; -} -static inline void mat4_perspective(mat4 m, float y_fov, float aspect, float n, float f) -{ - /* NOTE: Degrees are an unhandy unit to work with. - * linmath.h uses radians for everything! */ - float const a = 1.f / tan(y_fov / 2.f); - - m[0][0] = a / aspect; - m[0][1] = 0.f; - m[0][2] = 0.f; - m[0][3] = 0.f; - - m[1][0] = 0.f; - m[1][1] = a; - m[1][2] = 0.f; - m[1][3] = 0.f; - - m[2][0] = 0.f; - m[2][1] = 0.f; - m[2][2] = -((f + n) / (f - n)); - m[2][3] = -1.f; - - m[3][0] = 0.f; - m[3][1] = 0.f; - m[3][2] = -((2.f * f * n) / (f - n)); - m[3][3] = 0.f; -} -static inline void mat4_look_at(mat4 m, vec3 eye, vec3 lookat, vec3 up) -{ - /* Adapted from Android's OpenGL Matrix.java. */ - /* See the OpenGL GLUT documentation for gluLookAt for a description */ - /* of the algorithm. We implement it in a straightforward way: */ - - /* TODO: The negation of of can be spared by swapping the order of - * operands in the following cross products in the right way. */ - vec3 f; - vec3_sub(f, lookat, eye); - vec3_norm(f, f); +/* m[0][2] = -f[0]; */ +/* m[1][2] = -f[1]; */ +/* m[2][2] = -f[2]; */ - vec3 s; - vec3_mul_cross(s, f, up); - vec3_norm(s, s); - - vec3 t; - vec3_mul_cross(t, s, f); - - m[0][0] = s[0]; - m[0][1] = t[0]; - m[0][2] = -f[0]; - m[0][3] = 0.f; - - m[1][0] = s[1]; - m[1][1] = t[1]; - m[1][2] = -f[1]; - m[1][3] = 0.f; - - m[2][0] = s[2]; - m[2][1] = t[2]; - m[2][2] = -f[2]; - m[2][3] = 0.f; - - m[3][0] = 0.f; - m[3][1] = 0.f; - m[3][2] = 0.f; - m[3][3] = 1.f; - - mat4_translate_in_place(m, -eye[0], -eye[1], -eye[2]); -} - -typedef float quat[4]; -static inline void quat_identity(quat q) -{ - q[0] = q[1] = q[2] = 0.f; - q[3] = 1.f; -} -static inline void quat_add(quat r, quat a, quat b) -{ - int i; - for(i=0; i<4; ++i) - r[i] = a[i] + b[i]; -} -static inline void quat_sub(quat r, quat a, quat b) -{ - int i; - for(i=0; i<4; ++i) - r[i] = a[i] - b[i]; -} -static inline void quat_mul(quat r, quat p, quat q) -{ - /* vec3 w; */ - /* vec3_mul_cross(r, p, q); */ - /* vec3_scale(w, p, q[3]); */ - /* vec3_add(r, r, w); */ - /* vec3_scale(w, q, p[3]); */ - /* vec3_add(r, r, w); */ - /* r[3] = p[3]*q[3] - vec3_mul_inner(p, q); */ - - r[0] = p[3] * q[0] + p[0] * q[3] + p[1] * q[2] - p[2] * q[1]; - r[1] = p[3] * q[1] + p[1] * q[3] + p[2] * q[0] - p[0] * q[2]; - r[2] = p[3] * q[2] + p[2] * q[3] + p[0] * q[1] - p[1] * q[0]; - r[3] = p[3] * q[3] - p[0] * q[0] - p[1] * q[1] - p[2] * q[2]; -} -static inline void quat_scale(quat r, quat v, float s) -{ - int i; - for(i=0; i<4; ++i) - r[i] = v[i] * s; -} -static inline float quat_inner_product(quat a, quat b) -{ - float p = 0.f; - int i; - for(i=0; i<4; ++i) - p += b[i]*a[i]; - return p; -} -static inline void quat_conj(quat r, quat q) -{ - int i; - for(i=0; i<3; ++i) - r[i] = -q[i]; - r[3] = q[3]; -} -static inline void quat_rotate(quat r, float angle, vec3 axis) { - vec3 v; - vec3_scale(v, axis, sinf(angle / 2.f)); - int i; - for(i=0; i<3; ++i) - r[i] = v[i]; - r[3] = cosf(angle / 2.f); -} -#define quat_norm vec4_norm -static inline void quat_mul_vec3(vec3 r, quat q, vec3 v) -{ -/* - * Method by Fabian 'ryg' Giessen (of Farbrausch) -t = 2 * cross(q.xyz, v) -v' = v + q.w * t + cross(q.xyz, t) - */ - vec3 t = {q[0], q[1], q[2]}; - vec3 u = {q[0], q[1], q[2]}; - - vec3_mul_cross(t, t, v); - vec3_scale(t, t, 2); - - vec3_mul_cross(u, u, t); - vec3_scale(t, t, q[3]); - - vec3_add(r, v, t); - vec3_add(r, r, u); -} -static inline float quat_pitch(quat q) -{ - float result = atan2(2 * (q[1] * q[2] + q[3] * q[0]), q[3] * q[3] - q[0] * q[0] - q[1] * q[1] + q[2] * q[2]); - return result; -} - -static inline float quat_yaw(quat q) -{ - float result = asin(-2 * (q[0] * q[2] - q[3] * q[1])); - return result; -} -static inline float quat_roll(quat q) -{ - float result = atan2(2 * (q[0] * q[1] + q[3] * q[2]), q[3] * q[3] + q[0] * q[0] - q[1] * q[1] - q[2] * q[2]); - return result; -} -static inline void mat4_from_quat(mat4 M, quat q) -{ - /* float a = q[3]; */ - /* float b = q[0]; */ - /* float c = q[1]; */ - /* float d = q[2]; */ - /* float a2 = a*a; */ - /* float b2 = b*b; */ - /* float c2 = c*c; */ - /* float d2 = d*d; */ +/* m[0][3] = 0.f; */ +/* m[1][3] = 0.f; */ +/* m[2][3] = 0.f; */ + +/* m[3][0] = -vec3_mul_inner(s, eye); */ +/* m[3][1] = -vec3_mul_inner(t, eye); */ +/* m[3][2] = vec3_mul_inner(f, eye); */ +/* m[3][3] = 1.f; */ + +/* //mat4_translate_in_place(m, -eye[0], -eye[1], -eye[2]); */ +/* } */ + +/* typedef float quat[4]; */ +/* static inline void quat_identity(quat q) */ +/* { */ +/* q[0] = q[1] = q[2] = 0.f; */ +/* q[3] = 1.f; */ +/* } */ +/* static inline void quat_add(quat r, quat a, quat b) */ +/* { */ +/* int i; */ +/* for(i=0; i<4; ++i) */ +/* r[i] = a[i] + b[i]; */ +/* } */ +/* static inline void quat_sub(quat r, quat a, quat b) */ +/* { */ +/* int i; */ +/* for(i=0; i<4; ++i) */ +/* r[i] = a[i] - b[i]; */ +/* } */ +/* static inline void quat_mul(quat r, quat p, quat q) */ +/* { */ +/* /\* vec3 w; *\/ */ +/* /\* vec3_mul_cross(r, p, q); *\/ */ +/* /\* vec3_scale(w, p, q[3]); *\/ */ +/* /\* vec3_add(r, r, w); *\/ */ +/* /\* vec3_scale(w, q, p[3]); *\/ */ +/* /\* vec3_add(r, r, w); *\/ */ +/* /\* r[3] = p[3]*q[3] - vec3_mul_inner(p, q); *\/ */ + +/* r[0] = (p[3] * q[0]) + (p[0] * q[3]) + (p[1] * q[2]) - (p[2] * q[1]); */ +/* r[1] = (p[3] * q[1]) + (p[1] * q[3]) + (p[2] * q[0]) - (p[0] * q[2]); */ +/* r[2] = (p[3] * q[2]) + (p[2] * q[3]) + (p[0] * q[1]) - (p[1] * q[0]); */ +/* r[3] = (p[3] * q[3]) - (p[0] * q[0]) - (p[1] * q[1]) - (p[2] * q[2]); */ +/* } */ +/* static inline void quat_scale(quat r, quat v, float s) */ +/* { */ +/* int i; */ +/* for(i=0; i<4; ++i) */ +/* r[i] = v[i] * s; */ +/* } */ +/* static inline float quat_inner_product(quat a, quat b) */ +/* { */ +/* float p = 0.f; */ +/* int i; */ +/* for(i=0; i<4; ++i) */ +/* p += b[i]*a[i]; */ +/* return p; */ +/* } */ +/* static inline void quat_conj(quat r, quat q) */ +/* { */ +/* int i; */ +/* for(i=0; i<3; ++i) */ +/* r[i] = -q[i]; */ +/* r[3] = q[3]; */ +/* } */ +/* static inline void quat_rotate(quat r, float angle, vec3 axis) { */ +/* vec3 v; */ +/* vec3_scale(v, axis, sinf(angle / 2.f)); */ +/* int i; */ +/* for(i=0; i<3; ++i) */ +/* r[i] = v[i]; */ +/* r[3] = cosf(angle / 2.f); */ +/* } */ +/* #define quat_norm vec4_norm */ +/* static inline void quat_mul_vec3(vec3 r, quat q, vec3 v) */ +/* { */ +/* /\* */ +/* * Method by Fabian 'ryg' Giessen (of Farbrausch) */ +/* t = 2 * cross(q.xyz, v) */ +/* v' = v + q.w * t + cross(q.xyz, t) */ +/* *\/ */ +/* vec3 t = {q[0], q[1], q[2]}; */ +/* vec3 u = {q[0], q[1], q[2]}; */ + +/* vec3_mul_cross(t, t, v); */ +/* vec3_scale(t, t, 2.f); */ + +/* vec3_mul_cross(u, u, t); */ +/* vec3_scale(t, t, q[3]); */ + +/* vec3_add(r, v, t); */ +/* vec3_add(r, r, u); */ +/* } */ +/* static inline float quat_pitch(quat q) */ +/* { */ +/* float result = atan2(2 * (q[1] * q[2] + q[3] * q[0]), q[3] * q[3] - q[0] * q[0] - q[1] * q[1] + q[2] * q[2]); */ +/* return result; */ +/* } */ + +/* static inline float quat_yaw(quat q) */ +/* { */ +/* float result = asin(-2 * (q[0] * q[2] - q[3] * q[1])); */ +/* return result; */ +/* } */ +/* static inline float quat_roll(quat q) */ +/* { */ +/* float result = atan2(2 * (q[0] * q[1] + q[3] * q[2]), q[3] * q[3] + q[0] * q[0] - q[1] * q[1] - q[2] * q[2]); */ +/* return result; */ +/* } */ +/* static inline void mat4_from_quat(mat4 M, quat q) */ +/* { */ +/* /\* float a = q[3]; *\/ */ +/* /\* float b = q[0]; *\/ */ +/* /\* float c = q[1]; *\/ */ +/* /\* float d = q[2]; *\/ */ +/* /\* float a2 = a*a; *\/ */ +/* /\* float b2 = b*b; *\/ */ +/* /\* float c2 = c*c; *\/ */ +/* /\* float d2 = d*d; *\/ */ - /* M[0][0] = a2 + b2 - c2 - d2; */ - /* M[0][1] = 2.f*(b*c + a*d); */ - /* M[0][2] = 2.f*(b*d - a*c); */ - /* M[0][3] = 0.f; */ - - /* M[1][0] = 2*(b*c - a*d); */ - /* M[1][1] = a2 - b2 + c2 - d2; */ - /* M[1][2] = 2.f*(c*d + a*b); */ - /* M[1][3] = 0.f; */ - - /* M[2][0] = 2.f*(b*d + a*c); */ - /* M[2][1] = 2.f*(c*d - a*b); */ - /* M[2][2] = a2 - b2 - c2 + d2; */ - /* M[2][3] = 0.f; */ - - /* M[3][0] = M[3][1] = M[3][2] = 0.f; */ - /* M[3][3] = 1.f; */ - - float xx = q[0] * q[0]; - float xy = q[0] * q[1]; - float xz = q[0] * q[2]; - float xw = q[0] * q[3]; - - float yy = q[1] * q[1]; - float yz = q[1] * q[2]; - float yw = q[1] * q[3]; - - float zz = q[2] * q[2]; - float zw = q[2] * q[3]; - - M[0][0] = 1 - 2 * (yy + zz); - M[0][1] = 2 * (xy + zw); - M[0][2] = 2 * (xz - yw); - M[0][3] = 0; - - M[1][0] = 2 * (xy - zw); - M[1][1] = 1 - 2 * (xx + zz); - M[1][2] = 2 * (yz + xw); - M[1][3] = 0.0; - - M[2][0] = 2 * (xz + yw); - M[2][1] = 2 * (yz - xw); - M[2][2] = 1 - 2 * (xx + yy); - M[2][3] = 0.0; +/* /\* M[0][0] = a2 + b2 - c2 - d2; *\/ */ +/* /\* M[0][1] = 2.f*(b*c + a*d); *\/ */ +/* /\* M[0][2] = 2.f*(b*d - a*c); *\/ */ +/* /\* M[0][3] = 0.f; *\/ */ + +/* /\* M[1][0] = 2*(b*c - a*d); *\/ */ +/* /\* M[1][1] = a2 - b2 + c2 - d2; *\/ */ +/* /\* M[1][2] = 2.f*(c*d + a*b); *\/ */ +/* /\* M[1][3] = 0.f; *\/ */ + +/* /\* M[2][0] = 2.f*(b*d + a*c); *\/ */ +/* /\* M[2][1] = 2.f*(c*d - a*b); *\/ */ +/* /\* M[2][2] = a2 - b2 - c2 + d2; *\/ */ +/* /\* M[2][3] = 0.f; *\/ */ + +/* /\* M[3][0] = M[3][1] = M[3][2] = 0.f; *\/ */ +/* /\* M[3][3] = 1.f; *\/ */ + +/* float xx = q[0] * q[0]; */ +/* float xy = q[0] * q[1]; */ +/* float xz = q[0] * q[2]; */ + +/* float yy = q[1] * q[1]; */ +/* float yz = q[1] * q[2]; */ + +/* float zz = q[2] * q[2]; */ +/* float wz = q[3] * q[2]; */ +/* float wy = q[3] * q[1]; */ +/* float wx = q[3] * q[0]; */ + +/* M[0][0] = 1 - 2 * (yy + zz); */ +/* M[0][1] = 2 * (xy + wz); */ +/* M[0][2] = 2 * (xz - wy); */ +/* M[0][3] = 0; */ + +/* M[1][0] = 2 * (xy - wz); */ +/* M[1][1] = 1 - 2 * (xx + zz); */ +/* M[1][2] = 2 * (yz + wx); */ +/* M[1][3] = 0.0; */ + +/* M[2][0] = 2 * (xz + wy); */ +/* M[2][1] = 2 * (yz - wx); */ +/* M[2][2] = 1 - 2 * (xx + yy); */ +/* M[2][3] = 0.0; */ - M[3][0] = M[3][1] = M[3][2] = 0.f; - M[3][3] = 1.f; -} - -static inline void mat4o_mul_quat(mat4 R, mat4 M, quat q) -{ -/* XXX: The way this is written only works for othogonal matrices. */ -/* TODO: Take care of non-orthogonal case. */ - quat_mul_vec3(R[0], q, M[0]); - quat_mul_vec3(R[1], q, M[1]); - quat_mul_vec3(R[2], q, M[2]); - - R[3][0] = R[3][1] = R[3][2] = 0.f; - R[3][3] = 1.f; -} -static inline void quat_from_mat4(quat q, mat4 M) -{ - float r=0.f; - int i; - - int perm[] = { 0, 1, 2, 0, 1 }; - int *p = perm; - - for(i = 0; i<3; i++) { - float m = M[i][i]; - if( m < r ) - continue; - m = r; - p = &perm[i]; - } - - r = sqrtf(1.f + M[p[0]][p[0]] - M[p[1]][p[1]] - M[p[2]][p[2]] ); - - if(r < 1e-6) { - q[0] = 1.f; - q[1] = q[2] = q[3] = 0.f; - return; - } - - q[0] = r/2.f; - q[1] = (M[p[0]][p[1]] - M[p[1]][p[0]])/(2.f*r); - q[2] = (M[p[2]][p[0]] - M[p[0]][p[2]])/(2.f*r); - q[3] = (M[p[2]][p[1]] - M[p[1]][p[2]])/(2.f*r); -} +/* M[3][0] = M[3][1] = M[3][2] = 0.f; */ +/* M[3][3] = 1.f; */ +/* } */ + +/* static inline void mat4o_mul_quat(mat4 R, mat4 M, quat q) */ +/* { */ +/* /\* XXX: The way this is written only works for othogonal matrices. *\/ */ +/* /\* TODO: Take care of non-orthogonal case. *\/ */ +/* quat_mul_vec3(R[0], q, M[0]); */ +/* quat_mul_vec3(R[1], q, M[1]); */ +/* quat_mul_vec3(R[2], q, M[2]); */ + +/* R[3][0] = R[3][1] = R[3][2] = 0.f; */ +/* R[3][3] = 1.f; */ +/* } */ +/* static inline void quat_from_mat4(quat q, mat4 M) */ +/* { */ +/* float r=0.f; */ +/* int i; */ + +/* int perm[] = { 0, 1, 2, 0, 1 }; */ +/* int *p = perm; */ + +/* for(i = 0; i<3; i++) { */ +/* float m = M[i][i]; */ +/* if( m < r ) */ +/* continue; */ +/* m = r; */ +/* p = &perm[i]; */ +/* } */ + +/* r = sqrtf(1.f + M[p[0]][p[0]] - M[p[1]][p[1]] - M[p[2]][p[2]] ); */ + +/* if(r < 1e-6) { */ +/* q[0] = 1.f; */ +/* q[1] = q[2] = q[3] = 0.f; */ +/* return; */ +/* } */ + +/* q[0] = r/2.f; */ +/* q[1] = (M[p[0]][p[1]] - M[p[1]][p[0]])/(2.f*r); */ +/* q[2] = (M[p[2]][p[0]] - M[p[0]][p[2]])/(2.f*r); */ +/* q[3] = (M[p[2]][p[1]] - M[p[1]][p[2]])/(2.f*r); */ +/* } */ #endif diff --git a/src/model.c b/src/model.c index 5bd4411..7b8ee6e 100644 --- a/src/model.c +++ b/src/model.c @@ -50,6 +50,7 @@ int model_create(int node, const char* geo_name) new_model->node = node; new_model->geometry_index = geo_index; new_model->shader = 0; /* Temporary, for test run only till materials are added */ + vec4_fill(&new_model->color, 0.7f, 0.7f, 0.5f, 1.f); } else { @@ -94,13 +95,12 @@ void model_render_all(struct Camera* camera) struct Model* model = &model_list[i]; struct Entity* entity = entity_get(model->node); struct Transform* transform = entity_component_get(entity, C_TRANSFORM); - mat4_identity(mvp); + mat4_identity(&mvp); shader_bind(model->shader); - mat4_mul(mvp, camera->view_proj_mat, transform->trans_mat); - shader_set_uniform_mat4(model->shader, "mvp", mvp); - vec4 color = {0.7f, 0.7f, 0.5f, 1}; - shader_set_uniform_vec4(model->shader, "color", color); + mat4_mul(&mvp, &camera->view_proj_mat, &transform->trans_mat); + shader_set_uniform_mat4(model->shader, "mvp", &mvp); + shader_set_uniform_vec4(model->shader, "color", &model->color); geom_render(model->geometry_index); shader_unbind(); } diff --git a/src/model.h b/src/model.h index 87f73b8..0eed075 100644 --- a/src/model.h +++ b/src/model.h @@ -1,6 +1,8 @@ #ifndef model_H #define model_H +#include "linmath.h" + struct Camera; struct Model @@ -8,6 +10,7 @@ struct Model int node; int geometry_index; int shader; /* Temporary, replace with material */ + vec4 color; }; struct Model* model_get(int index); diff --git a/src/renderer.c b/src/renderer.c index e717e86..e28d91d 100644 --- a/src/renderer.c +++ b/src/renderer.c @@ -10,6 +10,7 @@ void on_framebuffer_size_change(GLFWwindow* window, int width, int height); void renderer_init(GLFWwindow* window) { glClearColor(0.3f, 0.6f, 0.9f, 1.0f); + glEnable(GL_DEPTH_TEST); glfwSetFramebufferSizeCallback(window, on_framebuffer_size_change); } diff --git a/src/shader.c b/src/shader.c index 04e4bd0..c9bdfd4 100644 --- a/src/shader.c +++ b/src/shader.c @@ -258,32 +258,32 @@ void shader_set_uniform_float(const int shader_index, const char* name, const fl glUniform1f(location, value); } -void shader_set_uniform_vec2(const int shader_index, const char* name, const vec2 value) +void shader_set_uniform_vec2(const int shader_index, const char* name, const vec2* value) { GLint location = shader_get_uniform_location(shader_index, name); if(location >= 0) - glUniform2fv(location, 1, value); + glUniform2fv(location, 1, &value->x); } -void shader_set_uniform_vec3(const int shader_index, const char* name, const vec3 value) +void shader_set_uniform_vec3(const int shader_index, const char* name, const vec3* value) { GLint location = shader_get_uniform_location(shader_index, name); if(location >= 0) - glUniform3fv(location, 1, value); + glUniform3fv(location, 1, &value->x); } -void shader_set_uniform_vec4(const int shader_index, const char* name, const vec4 value) +void shader_set_uniform_vec4(const int shader_index, const char* name, const vec4* value) { GLint location = shader_get_uniform_location(shader_index, name); if(location >= 0) - glUniform4fv(location, 1, value); + glUniform4fv(location, 1, &value->x); } -void shader_set_uniform_mat4(const int shader_index, const char* name, const mat4 value) +void shader_set_uniform_mat4(const int shader_index, const char* name, const mat4* value) { GLint location = shader_get_uniform_location(shader_index, name); if(location >= 0) - glUniformMatrix4fv(location, 1, GL_FALSE, *value); + glUniformMatrix4fv(location, 1, GL_FALSE, &value->mat[0]); } void shader_remove(const int shader_index) diff --git a/src/shader.h b/src/shader.h index 8f1a0c2..6c91ffd 100644 --- a/src/shader.h +++ b/src/shader.h @@ -10,10 +10,10 @@ void shader_remove(const int shader_index); void shader_unbind(void); void shader_set_uniform_int(const int shaderIndex, const char* name, const int value); void shader_set_uniform_float(const int shaderIndex, const char* name, const float value); -void shader_set_uniform_vec2(const int shaderIndex, const char* name, const vec2 value); -void shader_set_uniform_vec3(const int shaderIndex, const char* name, const vec3 value); -void shader_set_uniform_vec4(const int shaderIndex, const char* name, const vec4 value); -void shader_set_uniform_mat4(const int shaderIndex, const char* name, const mat4 value); +void shader_set_uniform_vec2(const int shaderIndex, const char* name, const vec2* value); +void shader_set_uniform_vec3(const int shaderIndex, const char* name, const vec3* value); +void shader_set_uniform_vec4(const int shaderIndex, const char* name, const vec4* value); +void shader_set_uniform_mat4(const int shaderIndex, const char* name, const mat4* value); void shader_cleanup(void); int shader_uniform_location_get(const int shader_index, const char* name); diff --git a/src/transform.c b/src/transform.c index 89cc450..e786e25 100644 --- a/src/transform.c +++ b/src/transform.c @@ -2,6 +2,7 @@ #include "log.h" #include "array.h" #include "entity.h" +#include "utils.h" #include static struct Transform* transform_list; @@ -37,138 +38,116 @@ int transform_create(int node) index = array_len(transform_list) - 1; } new_transform->node = node; - new_transform->position[0] = new_transform->position[1] = new_transform->position[2] = 0; - new_transform->scale[0] = new_transform->scale[1] = new_transform->scale[2] = 1; - //mat4_identity(new_transform->rotation); - quat_identity(new_transform->rotq); + vec3_fill(&new_transform->position, 0.f, 0.f, 0.f); + vec3_fill(&new_transform->scale, 1.f, 1.f, 1.f); + quat_identity(&new_transform->rotation); transform_update_transmat(new_transform); } return index; } -void transform_translate(struct Transform* transform, vec3 amount, enum Transform_Space space) +void transform_translate(struct Transform* transform, vec3* amount, enum Transform_Space space) { if(space == TS_LOCAL) { - mat4 temp; - mat4_identity(temp); - mat4_from_quat(temp, transform->rotq); - mat4_mul_vec3(amount, temp, amount); - //mat4_mul_vec3(amount, transform->rotation, amount); - //quat_mul_vec3(amount, transform->rotq, amount); + quat_mul_vec3(amount, &transform->rotation, amount); } - if(space == TS_PARENT) + else if(space == TS_PARENT) { struct Entity* parent = entity_get_parent(transform->node); struct Transform* parent_tran = entity_component_get(parent, C_TRANSFORM); - //mat4_mul_vec3(amount, parent_tran->rotation, amount); - quat_mul_vec3(amount, parent_tran->rotq, amount); + quat_mul_vec3(amount, &parent_tran->rotation, amount); } - vec3_add(transform->position, transform->position, amount); + vec3_add(&transform->position, &transform->position, amount); transform_update_transmat(transform); } void transform_rotate(struct Transform* transform, - vec3 axis, + vec3* axis, float angle, enum Transform_Space space) { - //mat4 new_rot; - quat new_rotq; - /* mat4_identity(new_rot); */ - /* mat4_rotate(new_rot, new_rot, axis[0], axis[1], axis[2], TO_RADIANS(angle)); */ - quat_identity(new_rotq); - quat_rotate(new_rotq, TO_RADIANS(angle), axis); - + quat new_rot; + quat_identity(&new_rot); + quat_axis_angle(&new_rot, axis, TO_RADIANS(angle)); + if(space == TS_LOCAL) - quat_mul(transform->rotq, transform->rotq, new_rotq); - else if(space == TS_WORLD) - quat_mul(transform->rotq, new_rotq, transform->rotq); - quat_norm(transform->rotq, transform->rotq); + quat_mul(&transform->rotation, &transform->rotation, &new_rot); + else + quat_mul(&transform->rotation, &new_rot, &transform->rotation); transform_update_transmat(transform); } -void transform_scale(struct Transform* transform, vec3 scale) +void transform_scale(struct Transform* transform, vec3* scale) { - transform->scale[0] = scale[0]; - transform->scale[1] = scale[1]; - transform->scale[2] = scale[2]; + vec3_assign(&transform->scale, scale); transform_update_transmat(transform); } -void transform_get_forward(struct Transform* transform, vec3 res) +void transform_get_forward(struct Transform* transform, vec3* res) { - res[0] = 0; res[1] = 0; res[2] = -1; - //mat4_mul_vec3(res, transform->rotation, res); - mat4 temp; - mat4_identity(temp); - mat4_from_quat(temp, transform->rotq); - mat4_mul_vec3(res, temp, res); - //quat_mul_vec3(res, transform->rotq, res); + vec3_fill(res, 0.f, 0.f, -1.f); + quat_get_forward_rh(res, &transform->rotation); } -void transform_get_lookat(struct Transform* transform, vec3 res) +void transform_get_lookat(struct Transform* transform, vec3* res) { transform_get_forward(transform, res); - vec3_mul_cross(res, transform->position, res); + vec3_add(res, &transform->position, res); } -void transform_get_absolute_forward(struct Transform* transform, vec3 res) +void transform_get_absolute_forward(struct Transform* transform, vec3* res) { - res[0] = 0.f; res[0] = 0.f; res[0] = -1.f; - //mat4_mul_vec3(res, transform->trans_mat, res); - quat_mul_vec3(res, transform->rotq, res); - vec3_norm(res, res); + vec3_fill(res, 0.f, 0.f, -1.f); + vec3_transform_norm(res, res, &transform->trans_mat); } -void transform_get_absolute_lookat(struct Transform* transform, vec3 res) +void transform_get_absolute_lookat(struct Transform* transform, vec3* res) { - vec3 abs_position = {0.f}; - transform_get_absolute_pos(transform, abs_position); + vec3 abs_position = {0.f, 0.f, 0.f}; + transform_get_absolute_pos(transform, &abs_position); transform_get_absolute_forward(transform, res); - vec3_add(res, abs_position, res); + vec3_add(res, &abs_position, res); +} + +void transform_get_up(struct Transform* transform, vec3* res) +{ + vec3_fill(res, 0.f, 1.f, 0.f); + quat_get_up(res, &transform->rotation); } -void transform_get_up(struct Transform* transform, vec3 res) +void transform_get_absolute_up(struct Transform* transform, vec3* res) { - res[0] = 0; res[1] = 1; res[2] = 0; - //mat4_mul_vec3(res, transform->rotation, res); - mat4 temp; - mat4_identity(temp); - mat4_from_quat(temp, transform->rotq); - mat4_mul_vec3(res, temp, res); - //quat_mul_vec3(res, transform->rotq, res); + vec3_fill(res, 0.f, 1.f, 0.f); + vec3_transform_norm(res, res, &transform->trans_mat); } -void transform_get_right(struct Transform* transform, vec3 res) +void transform_get_right(struct Transform* transform, vec3* res) { - res[0] = 1; res[1] = 0; res[2] = 0; - //mat4_mul_vec3(res, transform->rotation, res); - quat_mul_vec3(res, transform->rotq, res); + vec3_fill(res, 1.f, 0.f, 0.f); + quat_get_right(res, &transform->rotation); } void transform_update_transmat(struct Transform* transform) { - static mat4 scale, translation, rot; - mat4_identity(scale); - mat4_identity(translation); - mat4_identity(rot); - mat4_identity(transform->trans_mat); - mat4_scale_aniso(scale, scale, transform->scale[0], transform->scale[1], transform->scale[2]); - mat4_translate(translation, transform->position[0], transform->position[1], transform->position[2]); - mat4_from_quat(rot, transform->rotq); - - mat4_mul(transform->trans_mat, transform->trans_mat, translation); - //mat4_mul(transform->trans_mat, transform->trans_mat, transform->rotation); - mat4_mul(transform->trans_mat, transform->trans_mat, rot); - mat4_mul(transform->trans_mat, transform->trans_mat, scale); + static mat4 scale, translation, rotation; + mat4_identity(&scale); + mat4_identity(&translation); + mat4_identity(&rotation); + mat4_identity(&transform->trans_mat); + mat4_scale(&scale, transform->scale.x, transform->scale.y, transform->scale.z); + mat4_translate(&translation, transform->position.x, transform->position.y, transform->position.z); + mat4_from_quat(&rotation, &transform->rotation); + + mat4_mul(&transform->trans_mat, &transform->trans_mat, &translation); + mat4_mul(&transform->trans_mat, &transform->trans_mat, &rotation); + mat4_mul(&transform->trans_mat, &transform->trans_mat, &scale); struct Entity* entity = entity_get(transform->node); struct Entity* parent = entity_get(entity->parent); if(parent) { struct Transform* parent_tran = entity_component_get(parent, C_TRANSFORM); - mat4_mul(transform->trans_mat, transform->trans_mat, parent_tran->trans_mat); - //mat4_mul(transform->trans_mat, parent_tran->trans_mat, transform->trans_mat); + mat4_mul(&transform->trans_mat, &transform->trans_mat, &parent_tran->trans_mat); } /* Update all children */ @@ -198,14 +177,13 @@ void transform_remove(int index) array_push(empty_indices, index, int); } -void transform_set_position(struct Transform* transform, vec3 new_position) +void transform_set_position(struct Transform* transform, vec3* new_position) { - for(int i = 0; i < 3; i++) - transform->position[i] = new_position[i]; + vec3_assign(&transform->position, new_position); transform_update_transmat(transform); } -void transform_get_absolute_pos(struct Transform* transform, vec3 res) +void transform_get_absolute_pos(struct Transform* transform, vec3* res) { struct Entity* entity = entity_get(transform->node); struct Entity* parent = entity_get(entity->parent); @@ -214,5 +192,5 @@ void transform_get_absolute_pos(struct Transform* transform, vec3 res) struct Transform* parent_tran = entity_component_get(parent, C_TRANSFORM); transform_get_absolute_pos(parent_tran, res); } - vec3_add(res, res, transform->position); + vec3_add(res, res, &transform->position); } diff --git a/src/transform.h b/src/transform.h index c4a6bb4..4941da9 100644 --- a/src/transform.h +++ b/src/transform.h @@ -10,9 +10,8 @@ struct Transform int node; vec3 position; vec3 scale; - //mat4 rotation; + quat rotation; mat4 trans_mat; - quat rotq; }; struct Transform* transform_get(int index); @@ -20,19 +19,20 @@ void transform_remove(int index); void transform_init(void); void transform_cleanup(void); int transform_create(int node); -void transform_translate(struct Transform* transform, vec3 amount, enum Transform_Space space); +void transform_translate(struct Transform* transform, vec3* amount, enum Transform_Space space); void transform_rotate(struct Transform* transform, - vec3 axis, + vec3* axis, float angle, enum Transform_Space space); -void transform_scale(struct Transform* transform, vec3 scale); -void transform_set_position(struct Transform* transform, vec3 new_position); -void transform_get_forward(struct Transform* transform, vec3 res); -void transform_get_lookat(struct Transform* transform, vec3 res); -void transform_get_up(struct Transform* transform, vec3 res); -void transform_get_right(struct Transform* transform, vec3 res); +void transform_scale(struct Transform* transform, vec3* scale); +void transform_set_position(struct Transform* transform, vec3* new_position); +void transform_get_forward(struct Transform* transform, vec3* res); +void transform_get_lookat(struct Transform* transform, vec3* res); +void transform_get_up(struct Transform* transform, vec3* res); +void transform_get_right(struct Transform* transform, vec3* res); void transform_update_transmat(struct Transform* transform); -void transform_get_absolute_pos(struct Transform* transform, vec3 res); -void transform_get_absolute_lookat(struct Transform* transform, vec3 res); +void transform_get_absolute_pos(struct Transform* transform, vec3* res); +void transform_get_absolute_lookat(struct Transform* transform, vec3* res); +void transform_get_absolute_up(struct Transform* transform, vec3* res); #endif diff --git a/src/utils.c b/src/utils.c new file mode 100644 index 0000000..e435fbd --- /dev/null +++ b/src/utils.c @@ -0,0 +1,27 @@ +#include "utils.h" +#include +#include + +#define BUFF_SIZE 64 +static char str_buff[BUFF_SIZE]; + +const char* tostr_vec3(vec3* v) +{ + memset(str_buff, '\0', BUFF_SIZE); + snprintf(str_buff, BUFF_SIZE, "(%.3f, %.3f, %.3f)", v->x, v->y, v->z); + return str_buff; +} + +const char* tostr_vec4(vec4* v) +{ + memset(str_buff, '\0', BUFF_SIZE); + snprintf(str_buff, BUFF_SIZE, "(%.3f, %.3f, %.3f, %.3f)", v->x, v->y, v->z, v->w); + return str_buff; +} + +const char* tostr_quat(quat* q) +{ + memset(str_buff, '\0', BUFF_SIZE); + snprintf(str_buff, BUFF_SIZE, "(%.3f, %.3f, %.3f, %.3f)", q->x, q->y, q->z, q->w); + return str_buff; +} diff --git a/src/utils.h b/src/utils.h new file mode 100644 index 0000000..53ceb8e --- /dev/null +++ b/src/utils.h @@ -0,0 +1,10 @@ +#ifndef utils_H +#define utils_H + +#include "linmath.h" + +const char* tostr_vec3(vec3* v); +const char* tostr_vec4(vec4* v); +const char* tostr_quat(quat* q); + +#endif