From 820fd6880e145f0f86abdae332c283eb0b341d41 Mon Sep 17 00:00:00 2001 From: Shariq Shah Date: Thu, 20 Aug 2015 13:38:52 +0500 Subject: [PATCH] Fixed rotation issues by using matrix for rotation instead of quaternion(temporarily) --- orgfile.org | 1 + src/camera.c | 3 ++ src/game.c | 83 +++++++++++++++++++++++++++++++++++++++++++++---- src/linmath.h | 29 +++++++++++++---- src/transform.c | 39 +++++++++++++---------- src/transform.h | 3 +- 6 files changed, 129 insertions(+), 29 deletions(-) diff --git a/orgfile.org b/orgfile.org index b4bbf0e..6638eb6 100644 --- a/orgfile.org +++ b/orgfile.org @@ -45,6 +45,7 @@ while using as few libraries as possible. ** TODO Bounding Boxes ** TODO Materials ** TODO Mesh/Model +** TODO Add modifiers to input maps to enable combinations for example, c-x, m-k etc ** TODO Heirarchical Transforms ** TODO 2d drawing routines ** TODO Gui diff --git a/src/camera.c b/src/camera.c index fdaf370..37c5dd4 100644 --- a/src/camera.c +++ b/src/camera.c @@ -58,6 +58,9 @@ int camera_create(int node, int width, int height) new_camera->fov = TO_RADIANS(60.f); new_camera->aspect_ratio = ((float)width / (float)height) <= 0.f ? (4.f / 3.f) : ((float)width / (float)height); new_camera->ortho = 0; + 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); diff --git a/src/game.c b/src/game.c index e407015..8ac0b40 100644 --- a/src/game.c +++ b/src/game.c @@ -44,19 +44,47 @@ void game_init(void) int down_keys[2] = {'S', GLFW_KEY_DOWN}; int left_keys[2] = {'A', GLFW_KEY_LEFT}; int right_keys[2] = {'D', GLFW_KEY_RIGHT}; + int turn_right_keys[1] = {'L'}; + int turn_left_keys[1] = {'J'}; + int turn_up_keys[1] = {'I'}; + int turn_down_keys[1] = {'K'}; input_map_create("Move_Up", up_keys, 2); input_map_create("Move_Down", down_keys, 2); input_map_create("Move_Left", left_keys, 2); input_map_create("Move_Right", right_keys, 2); + input_map_create("Turn_Right", turn_right_keys, 1); + input_map_create("Turn_Left", turn_left_keys, 1); + input_map_create("Turn_Up", turn_up_keys, 1); + input_map_create("Turn_Down", turn_down_keys, 1); int shader = shader_create("unshaded.vert", "unshaded.frag"); entity = entity_create("Test", "None"); active_camera = entity_component_add(entity, C_CAMERA, 800, 600); + vec3 viewer_pos = {0, 0, 10}; + struct Transform* viewer_tran = entity_component_get(entity, C_TRANSFORM); + transform_set_position(viewer_tran, viewer_pos); + struct Entity* new_ent = entity_create("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"); + 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, 5}; + transform_scale(model_tran, scale); + + struct Entity* suz = entity_create("Suzanne", NULL); + 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); + + vec4 temp = {1, 0, 0, 1}; + mat4 mat; + mat4_identity(mat); + mat4_mul_vec4(temp, mat, temp); run(); } @@ -64,22 +92,65 @@ void game_init(void) void debug(float dt) { struct Transform* transform = entity_component_get(entity, C_TRANSFORM); - float speed = 5.f; + float move_speed = 5.f, turn_speed = 50.f; vec3 offset = {0, 0, 0}; - if(input_map_state_get("Move_Up", GLFW_PRESS)) offset[2] -= speed; - if(input_map_state_get("Move_Down", GLFW_PRESS)) offset[2] += speed; - if(input_map_state_get("Move_Left", GLFW_PRESS)) offset[0] -= speed; - if(input_map_state_get("Move_Right", GLFW_PRESS)) offset[0] += speed; + float turn_up_down = 0.f; + float turn_left_right = 0.f; + float max_up_down = 60.f; + static float total_up_down_rot = 0.f; + vec3 rot_axis_up_down = {-1, 0, 0}; + vec3 rot_axis_left_right = {0, 1, 0}; + + /* Look around */ + if(input_map_state_get("Turn_Up", GLFW_PRESS)) turn_up_down += turn_speed; + if(input_map_state_get("Turn_Down", GLFW_PRESS)) turn_up_down -= turn_speed; + if(input_map_state_get("Turn_Right", GLFW_PRESS)) turn_left_right += turn_speed; + if(input_map_state_get("Turn_Left", GLFW_PRESS)) turn_left_right -= turn_speed; + + if(turn_up_down != 0.f) + { + total_up_down_rot += turn_up_down; + if(total_up_down_rot >= max_up_down) + { + total_up_down_rot = max_up_down; + turn_left_right = 0.f; + } + else if(total_up_down_rot <= -max_up_down) + { + total_up_down_rot = -max_up_down; + turn_left_right = 0.f; + } + + if(turn_up_down != 0.f) + transform_rotate(transform, rot_axis_up_down, turn_up_down * dt, TS_LOCAL); + } + + if(turn_left_right != 0.f) + transform_rotate(transform, rot_axis_left_right, turn_left_right * dt, TS_WORLD); + + /* Movement */ + if(input_map_state_get("Move_Up", GLFW_PRESS)) offset[2] -= move_speed; + if(input_map_state_get("Move_Down", 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; vec3_scale(offset, offset, dt); if(offset[0] != 0 || offset[2] != 0) { - transform_translate(transform, offset, TS_WORLD); + transform_translate(transform, offset, TS_LOCAL); log_message("Position : %.3f, %.3f, %.3f", transform->position[0], transform->position[1], transform->position[2]); } + + if(input_key_state_get(GLFW_KEY_SPACE, GLFW_PRESS)) + { + struct Entity* model = entity_get(1); + 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_WORLD); + } } void run(void) diff --git a/src/linmath.h b/src/linmath.h index c7ba05d..b4b7424 100644 --- a/src/linmath.h +++ b/src/linmath.h @@ -156,12 +156,29 @@ static inline void mat4_mul(mat4 M, mat4 a, mat4 b) } static inline void mat4_mul_vec4(vec4 r, mat4 M, vec4 v) { - int i, j; - for(j=0; j<4; ++j) { - r[j] = 0.f; - for(i=0; i<4; ++i) - r[j] += M[i][j] * v[i]; - } + /* int i, j; */ + /* for(j=0; j<4; ++j) { */ + /* r[j] = 0.f; */ + /* for(i=0; i<4; ++i) */ + /* r[j] += M[i][j] * v[i]; */ + /* } */ + r[0] = (M[0][0] * v[0]) + (M[0][1] * v[1]) + (M[0][2] * v[2]) + (M[0][3] * v[3]); + r[1] = (M[1][0] * v[0]) + (M[1][1] * v[1]) + (M[1][2] * v[2]) + (M[1][3] * v[3]); + r[2] = (M[2][0] * v[0]) + (M[2][1] * v[1]) + (M[2][2] * v[2]) + (M[2][3] * v[3]); + r[3] = (M[3][0] * v[0]) + (M[3][1] * v[1]) + (M[3][2] * v[2]) + (M[3][3] * v[3]); +} +static inline void mat4_mul_vec3(vec3 r, mat4 M, vec3 v) +{ + /* vec4 temp; */ + /* for(int i = 0; i < 3; i++) */ + /* temp[i] = v[i]; */ + /* temp[3] = 1.f; */ + /* mat4_mul_vec4(temp, M, temp); */ + /* for(int i = 0; i < 3; i++) */ + /* r[i] = temp[i]; */ + r[0] = (M[0][0] * v[0]) + (M[0][1] * v[1]) + (M[0][2] * v[2]) + (M[0][3]); + r[1] = (M[1][0] * v[0]) + (M[1][1] * v[1]) + (M[1][2] * v[2]) + (M[1][3]); + r[2] = (M[2][0] * v[0]) + (M[2][1] * v[1]) + (M[2][2] * v[2]) + (M[2][3]); } static inline void mat4_translate(mat4 T, float x, float y, float z) { diff --git a/src/transform.c b/src/transform.c index 36ee50b..4f8afa5 100644 --- a/src/transform.c +++ b/src/transform.c @@ -1,4 +1,5 @@ #include "transform.h" +#include "log.h" #include "array.h" #include "entity.h" #include @@ -38,7 +39,7 @@ int transform_create(int node) 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; - quat_identity(new_transform->rotation); + mat4_identity(new_transform->rotation); transform_update_transmat(new_transform); } return index; @@ -47,7 +48,7 @@ int transform_create(int node) void transform_translate(struct Transform* transform, vec3 amount, enum Transform_Space space) { if(space == TS_LOCAL) - quat_mul_vec3(amount, transform->rotation, amount); + mat4_mul_vec3(amount, transform->rotation, amount); vec3_add(transform->position, transform->position, amount); transform_update_transmat(transform); } @@ -56,14 +57,13 @@ void transform_rotate(struct Transform* transform, float angle, enum Transform_Space space) { - quat new_rot; - quat_identity(new_rot); - quat_rotate(new_rot, angle, axis); - quat_norm(new_rot, new_rot); + mat4 new_rot; + mat4_identity(new_rot); + mat4_rotate(new_rot, new_rot, axis[0], axis[1], axis[2], TO_RADIANS(angle)); if(space == TS_LOCAL) - quat_mul(transform->rotation, transform->rotation, new_rot); + mat4_mul(transform->rotation, transform->rotation, new_rot); else if(space == TS_WORLD) - quat_mul(transform->rotation, new_rot, transform->rotation); + mat4_mul(transform->rotation, new_rot, transform->rotation); transform_update_transmat(transform); } void transform_scale(struct Transform* transform, vec3 scale) @@ -77,7 +77,7 @@ void transform_scale(struct Transform* transform, vec3 scale) void transform_get_forward(struct Transform* transform, vec3 res) { res[0] = 0; res[1] = 0; res[2] = -1; - quat_mul_vec3(res, transform->rotation, res); + mat4_mul_vec3(res, transform->rotation, res); } void transform_get_lookat(struct Transform* transform, vec3 res) @@ -89,29 +89,29 @@ void transform_get_lookat(struct Transform* transform, vec3 res) void transform_get_up(struct Transform* transform, vec3 res) { res[0] = 0; res[1] = 1; res[2] = 0; - quat_mul_vec3(res, transform->rotation, res); + mat4_mul_vec3(res, transform->rotation, res); } void transform_get_right(struct Transform* transform, vec3 res) { res[0] = 1; res[1] = 0; res[2] = 0; - quat_mul_vec3(res, transform->rotation, res); + mat4_mul_vec3(res, transform->rotation, res); } void transform_update_transmat(struct Transform* transform) { - mat4 scale, rot, tran; + static mat4 scale, tran; mat4_identity(scale); - mat4_identity(rot); mat4_identity(tran); mat4_identity(transform->trans_mat); mat4_scale_aniso(scale, scale, transform->scale[0], transform->scale[1], transform->scale[2]); - mat4_from_quat(rot, transform->rotation); mat4_translate(tran, transform->position[0], transform->position[1], transform->position[2]); - mat4_mul(transform->trans_mat, transform->trans_mat, scale); - mat4_mul(transform->trans_mat, transform->trans_mat, rot); + mat4_mul(transform->trans_mat, transform->trans_mat, tran); + mat4_mul(transform->trans_mat, transform->trans_mat, transform->rotation); + mat4_mul(transform->trans_mat, transform->trans_mat, scale); + struct Entity* entity = entity_get(transform->node); entity_sync_components(entity); } @@ -128,3 +128,10 @@ void transform_remove(int index) transform_list[index].node = -1; array_push(empty_indices, index, int); } + +void transform_set_position(struct Transform* transform, vec3 new_position) +{ + for(int i = 0; i < 3; i++) + transform->position[i] = new_position[i]; + transform_update_transmat(transform); +} diff --git a/src/transform.h b/src/transform.h index e0d7b4f..8af6794 100644 --- a/src/transform.h +++ b/src/transform.h @@ -10,7 +10,7 @@ struct Transform int node; vec3 position; vec3 scale; - quat rotation; + mat4 rotation; mat4 trans_mat; }; @@ -25,6 +25,7 @@ void transform_rotate(struct Transform* transform, 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);