From ad5b56b71770b3a9507cf6fdca35cb5bbfecd5c4 Mon Sep 17 00:00:00 2001 From: Shariq Shah Date: Sun, 3 Jun 2018 02:40:27 +1000 Subject: [PATCH] Fixed vec4 and mat4 multiplication, Implemented screen coord to ray and ray-sphere collision --- README.md | 7 +- build/genie.lua | 2 +- src/common/linmath.c | 8 +- src/libsymmetry/bounding_volumes.c | 62 ++++++++ src/libsymmetry/bounding_volumes.h | 11 +- src/libsymmetry/camera.c | 62 ++++++++ src/libsymmetry/camera.h | 2 + src/libsymmetry/console.c | 238 ++++++++++++++--------------- src/libsymmetry/game.c | 20 +++ src/libsymmetry/geometry.c | 6 +- src/libsymmetry/player.c | 99 ++++++------ src/libsymmetry/scene.c | 90 ++++++++--- src/libsymmetry/scene.h | 5 + 13 files changed, 415 insertions(+), 197 deletions(-) diff --git a/README.md b/README.md index e6430ab..398dcf4 100644 --- a/README.md +++ b/README.md @@ -155,11 +155,13 @@ - ## TODO + - Improve bounding sphere calculation + - Screen mouse coordinates to world-coordinates for aiming + - Player projectiles and sounds - Console commands - Console fix bug when enabled in editor mode - Console command history - Console command help - - Player projectiles and sounds - NPR and cross-hatching - Move Gui_State and Editor_State into game_state and modify usage as needed - Remove model and replace all usages with static mesh @@ -412,4 +414,5 @@ * In-game basis for scrollable console/log-viewer * Console log output * Console error/warning output - * Implemented Auto scrolling to the bottom in console \ No newline at end of file + * Implemented Auto scrolling to the bottom in console + * Implemented screen coordinate to ray conversion and ray-sphere collision \ No newline at end of file diff --git a/build/genie.lua b/build/genie.lua index b836085..58ba83a 100644 --- a/build/genie.lua +++ b/build/genie.lua @@ -137,7 +137,7 @@ solution "Symmetry" newaction { trigger = "build_addon", - description = "Build blender addon into zip file that can be loaded into blender, needs zip installed and available on PATH", + description = "Build blender addon into zip file that can be loaded into blender, needs zip installed and available on PATH(Only works on bash/nix-style shell for now)", execute = function () local output = os.outputof("cd ../blender_addon && zip -r io_symmetry_exp.zip io_symmetry_exp/__init__.py io_symmetry_exp/exporter.py && mv io_symmetry_exp.zip ../build"); printf("Output of blender addon build : \n%s\n", output) diff --git a/src/common/linmath.c b/src/common/linmath.c index 768dae1..16dcbaf 100644 --- a/src/common/linmath.c +++ b/src/common/linmath.c @@ -269,10 +269,10 @@ void vec4_mul(vec4* res, vec4* v1, vec4* v4) 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] + mat->mat[12]; - v.y = val->x * mat->mat[1] + val->y * mat->mat[5] + val->z * mat->mat[9] + mat->mat[14]; - v.z = val->x * mat->mat[2] + val->y * mat->mat[6] + val->z * mat->mat[10] + mat->mat[14]; - v.w = val->x * mat->mat[2] + val->y * mat->mat[6] + val->w * mat->mat[10] + mat->mat[14]; + 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; diff --git a/src/libsymmetry/bounding_volumes.c b/src/libsymmetry/bounding_volumes.c index c7b2128..73e59d0 100644 --- a/src/libsymmetry/bounding_volumes.c +++ b/src/libsymmetry/bounding_volumes.c @@ -81,3 +81,65 @@ bool bv_intersect_frustum_point(vec4* frustum, const vec3* point) } return success; } + +bool bv_intersect_sphere_ray(struct Bounding_Sphere* sphere, vec3* sphere_abs_position, struct Ray* ray) +{ + + vec3 center = {0.f}; + vec3_add(¢er, &sphere->center, sphere_abs_position); + float squared_radius = sphere->radius * sphere->radius; + + vec3 centered_origin; + vec3_sub(¢ered_origin, &ray->origin, ¢er); + float centered_origin_len_sqrd = vec3_len(¢ered_origin); + centered_origin_len_sqrd *= centered_origin_len_sqrd; + + //Check if ray originates inside the sphere + if(centered_origin_len_sqrd <= squared_radius) + return true; + + // Calculate the intersection by quatratic equation' + float a = vec3_dot(&ray->direction, &ray->direction); + float b = 2.f * vec3_dot(¢ered_origin, &ray->direction); + float c = vec3_dot(¢ered_origin, ¢ered_origin) - squared_radius; + float d = b * b - 4.f * a * c; + + //No solution + if(d < 0.f) + return false; + + //Get the near solution + float d_sqrt = sqrtf(d); + float dist = (-b - d_sqrt) / (2.f * a); + if(dist >= 0.f) + return true; + else + return true; + + //float tca = vec3_dot(¢ered_origin, &ray->direction); + //if(tca < 0.0) return false; + + //float L_dot = vec3_dot(¢ered_origin, ¢ered_origin); + //float d2 = L_dot - (tca); + //float radius_sqr = sphere->radius * sphere->radius; + + //if (d2 > radius_sqr) return false; + //float thc = sqrtf(radius_sqr - d2); + //float t0 = tca - thc; + //float t1 = tca + thc; + + //if(t0 > t1) + //{ + // float temp = t0; + // t0 = t1; + // t1 = temp; + //} + + //if(t0 < 0) + //{ + // t0 = t1; + // if(t0 < 0) return false; + //} + + //return true; +} \ No newline at end of file diff --git a/src/libsymmetry/bounding_volumes.h b/src/libsymmetry/bounding_volumes.h index 4c4377e..b5378ea 100644 --- a/src/libsymmetry/bounding_volumes.h +++ b/src/libsymmetry/bounding_volumes.h @@ -34,8 +34,15 @@ enum Frustum_Planes FP_NUM_PLANES }; -int bv_intersect_frustum_box(vec4* frustum, struct Bounding_Box* box, vec3* box_abs_position, vec3* box_abs_scale); -int bv_intersect_frustum_sphere(vec4* frustum, struct Bounding_Sphere* sphere, struct Transform* transform); +struct Ray +{ + vec3 direction; + vec3 origin; +}; + +int bv_intersect_frustum_box(vec4* frustum, struct Bounding_Box* box, vec3* box_abs_position, vec3* box_abs_scale); +int bv_intersect_frustum_sphere(vec4* frustum, struct Bounding_Sphere* sphere, vec3* sphere_abs_pos, vec3* sphere_abs_scale); bool bv_intersect_frustum_point(vec4* frustum, const vec3* point); +bool bv_intersect_sphere_ray(struct Bounding_Sphere* sphere, vec3* sphere_abs_position, struct Ray* ray); #endif diff --git a/src/libsymmetry/camera.c b/src/libsymmetry/camera.c index 56c8a6d..3a823c9 100644 --- a/src/libsymmetry/camera.c +++ b/src/libsymmetry/camera.c @@ -201,4 +201,66 @@ static void update_frustum(struct Camera* camera) float length = fabsf(vec3_len(&plane_xyz)); vec4_scale(&camera->frustum[i], &camera->frustum[i], (1.f / length)); } +} + +struct Ray camera_screen_coord_to_ray(struct Camera* camera, int mouse_x, int mouse_y) +{ + struct Ray ray; + + int win_width = 0, win_height = 0; + struct Game_State* game_state = game_state_get(); + platform->window.get_size(game_state->window, &win_width, &win_height); + + float normalized_x = (2.f * (float)mouse_x) / (float)win_width - 1.f; + float normalized_y = 1.f - (2.f * (float)mouse_y) / (float)win_height; + + vec3 near_point = {0.f}; + vec3 far_point = {0.f}; + + mat4 inverse_view_proj_mat; + mat4_identity(&inverse_view_proj_mat); + mat4_inverse(&inverse_view_proj_mat, &camera->view_proj_mat); + + //Project the near point + quat rot_near = {normalized_x, normalized_y, 0.f, 1.f}; + vec4_mul_mat4(&rot_near, &rot_near, &inverse_view_proj_mat); + near_point.x = rot_near.x / rot_near.w; + near_point.y = rot_near.y / rot_near.w; + near_point.z = rot_near.z / rot_near.w; + + //Project far point + quat rot_far = {normalized_x, normalized_y, 1.f, 1.f}; + vec4_mul_mat4(&rot_far, &rot_far, &inverse_view_proj_mat); + far_point.x = rot_far.x / rot_far.w; + far_point.y = rot_far.y / rot_far.w; + far_point.z = rot_far.z / rot_far.w; + + vec3_sub(&ray.direction, &far_point, &near_point); + vec3_norm(&ray.direction, &ray.direction); + + transform_get_absolute_position(&camera->base, &ray.origin); + + return ray; + + /*vec4 clip_coords = {normalized_x, normalized_y, -1.f, 1.f}; + vec4 ray_eye = {0.f}; + + mat4 inverse_proj_mat; + mat4_identity(&inverse_proj_mat); + mat4_inverse(&inverse_proj_mat, &camera->proj_mat); + vec4_mul_mat4(&ray_eye, &clip_coords, &inverse_proj_mat); + + ray_eye.z = -1.f; + ray_eye.w = 0.f; + + vec4 ray_world = {0.f}; + mat4 inverse_view_mat; + mat4_identity(&inverse_view_mat); + mat4_inverse(&inverse_view_mat, &camera->view_mat); + vec4_mul_mat4(&ray_world, &ray_eye, &inverse_view_mat); + + vec3 world_coords = {ray_world.x, ray_world.y, ray_world.z}; + vec3_norm(&world_coords, &world_coords); + + return world_coords;*/ } \ No newline at end of file diff --git a/src/libsymmetry/camera.h b/src/libsymmetry/camera.h index ea66a86..615655c 100644 --- a/src/libsymmetry/camera.h +++ b/src/libsymmetry/camera.h @@ -2,6 +2,7 @@ #define CAMERA_H #include "../common/num_types.h" +#include "../common/linmath.h" struct Camera; @@ -16,6 +17,7 @@ void camera_attach_fbo(struct Camera* camera, bool has_depth, bool has_color, bool resizeable); +struct Ray camera_screen_coord_to_ray(struct Camera* camera, int mouse_x, int mouse_y); /* void camera_resize_all(int width, int height); */ #endif diff --git a/src/libsymmetry/console.c b/src/libsymmetry/console.c index 6900fd3..c5b0684 100644 --- a/src/libsymmetry/console.c +++ b/src/libsymmetry/console.c @@ -1,102 +1,102 @@ -#include "console.h" -#include "gui.h" -#include "game.h" -#include "../common/log.h" -#include "../common/common.h" - -#include -#include -#include - -static struct nk_color console_message_color[CMT_MAX]; - -static int console_filter(const struct nk_text_edit *box, nk_rune unicode); - -void console_init(struct Console* console) -{ - assert(console); - - console_message_color[CMT_MESSAGE] = nk_rgb(255, 255, 255); - console_message_color[CMT_WARNING] = nk_rgb(255, 255, 0); - console_message_color[CMT_ERROR] = nk_rgb(255, 0, 0); - console_message_color[CMT_COMMAND] = nk_rgb(114, 173, 224); - console_message_color[CMT_NONE] = nk_rgb(255, 0, 255); - - console->visible = false; - console->scroll_to_bottom = true; - console->text_region_height = 22.f; - console->line_height = 20.f; - console->current_message_index = -1; - - memset(console->console_command_text, '\0', MAX_CONSOLE_MESSAGE_LEN); - for(int i = 0; i < MAX_CONSOLE_MESSAGES; i++) - { - memset(console->console_messages[i].message, '\0', MAX_CONSOLE_MESSAGE_LEN); - console->console_messages[i].type = CMT_NONE; - } -} - -void console_toggle(struct Console* console) -{ - if(!console->visible) console->scroll_to_bottom = true; - console->visible = !console->visible; -} - -void console_update(struct Console* console, struct Gui_State* gui_state, float dt) -{ - if(!console->visible) return; - - struct nk_context* context = &gui_state->context; - struct Game_State* game_state = game_state_get(); - +#include "console.h" +#include "gui.h" +#include "game.h" +#include "../common/log.h" +#include "../common/common.h" + +#include +#include +#include + +static struct nk_color console_message_color[CMT_MAX]; + +static int console_filter(const struct nk_text_edit *box, nk_rune unicode); + +void console_init(struct Console* console) +{ + assert(console); + + console_message_color[CMT_MESSAGE] = nk_rgb(255, 255, 255); + console_message_color[CMT_WARNING] = nk_rgb(255, 255, 0); + console_message_color[CMT_ERROR] = nk_rgb(255, 0, 0); + console_message_color[CMT_COMMAND] = nk_rgb(114, 173, 224); + console_message_color[CMT_NONE] = nk_rgb(255, 0, 255); + + console->visible = false; + console->scroll_to_bottom = true; + console->text_region_height = 22.f; + console->line_height = 20.f; + console->current_message_index = -1; + + memset(console->console_command_text, '\0', MAX_CONSOLE_MESSAGE_LEN); + for(int i = 0; i < MAX_CONSOLE_MESSAGES; i++) + { + memset(console->console_messages[i].message, '\0', MAX_CONSOLE_MESSAGE_LEN); + console->console_messages[i].type = CMT_NONE; + } +} + +void console_toggle(struct Console* console) +{ + if(!console->visible) console->scroll_to_bottom = true; + console->visible = !console->visible; +} + +void console_update(struct Console* console, struct Gui_State* gui_state, float dt) +{ + if(!console->visible) return; + + struct nk_context* context = &gui_state->context; + struct Game_State* game_state = game_state_get(); + int win_width = 0, win_height = 0; platform->window.get_drawable_size(game_state->window, &win_width, &win_height); - int half_height = win_height / 2; - - if(nk_begin_titled(context, "Console", "Console", nk_recti(0, 0, win_width, half_height), NK_WINDOW_SCROLL_AUTO_HIDE)) - { - nk_layout_row_dynamic(context, nk_window_get_height(context) - console->text_region_height * 2, 1); - if(nk_group_begin(context, "Log", NK_WINDOW_BORDER)) - { - for(int i = 0; i <= console->current_message_index; i++) - { - nk_layout_row_dynamic(context, console->line_height, 1); - nk_labelf_colored(context, NK_TEXT_ALIGN_LEFT | NK_TEXT_ALIGN_MIDDLE, console_message_color[console->console_messages[i].type], console->console_messages[i].message); - } - - if(console->scroll_to_bottom == true) // scroll console message area to the bottom if required - { - *context->current->layout->offset_y = context->current->layout->at_y; - console->scroll_to_bottom = false; - } - - nk_group_end(context); - } - - //Edit-string/Textfield for command - nk_layout_row_dynamic(context, console->text_region_height, 1); - int edit_flags = NK_EDIT_GOTO_END_ON_ACTIVATE | NK_EDIT_FIELD | NK_EDIT_SIG_ENTER; - nk_edit_focus(context, edit_flags); - int edit_state = nk_edit_string_zero_terminated(context, edit_flags, console->console_command_text, MAX_CONSOLE_MESSAGE_LEN, console_filter); - if(edit_state & NK_EDIT_COMMITED) - { - if(++console->current_message_index >= MAX_CONSOLE_MESSAGES) - console->current_message_index = 0; - + int half_height = win_height / 2; + + if(nk_begin_titled(context, "Console", "Console", nk_recti(0, 0, win_width, half_height), NK_WINDOW_SCROLL_AUTO_HIDE)) + { + nk_layout_row_dynamic(context, nk_window_get_height(context) - console->text_region_height * 2, 1); + if(nk_group_begin(context, "Log", NK_WINDOW_BORDER)) + { + for(int i = 0; i <= console->current_message_index; i++) + { + nk_layout_row_dynamic(context, console->line_height, 1); + nk_labelf_colored(context, NK_TEXT_ALIGN_LEFT | NK_TEXT_ALIGN_MIDDLE, console_message_color[console->console_messages[i].type], console->console_messages[i].message); + } + + if(console->scroll_to_bottom == true) // scroll console message area to the bottom if required + { + *context->current->layout->offset_y = context->current->layout->at_y; + console->scroll_to_bottom = false; + } + + nk_group_end(context); + } + + //Edit-string/Textfield for command + nk_layout_row_dynamic(context, console->text_region_height, 1); + int edit_flags = NK_EDIT_GOTO_END_ON_ACTIVATE | NK_EDIT_FIELD | NK_EDIT_SIG_ENTER; + nk_edit_focus(context, edit_flags); + int edit_state = nk_edit_string_zero_terminated(context, edit_flags, console->console_command_text, MAX_CONSOLE_MESSAGE_LEN, console_filter); + if(edit_state & NK_EDIT_COMMITED) + { + if(++console->current_message_index >= MAX_CONSOLE_MESSAGES) + console->current_message_index = 0; + snprintf(console->console_messages[console->current_message_index].message, MAX_CONSOLE_MESSAGE_LEN, "> %s", console->console_command_text); - console->console_messages[console->current_message_index].type = CMT_COMMAND; - memset(console->console_command_text, '\0', MAX_CONSOLE_MESSAGE_LEN); - console->scroll_to_bottom = true; - } - } - nk_end(context); -} - -void console_destroy(struct Console* console) -{ - -} - + console->console_messages[console->current_message_index].type = CMT_COMMAND; + memset(console->console_command_text, '\0', MAX_CONSOLE_MESSAGE_LEN); + console->scroll_to_bottom = true; + } + } + nk_end(context); +} + +void console_destroy(struct Console* console) +{ + +} + int console_filter(const struct nk_text_edit *box, nk_rune unicode) { NK_UNUSED(box); @@ -107,29 +107,29 @@ int console_filter(const struct nk_text_edit *box, nk_rune unicode) } void console_on_log_message(struct Console* console, const char* message, va_list args) -{ - if(++console->current_message_index >= MAX_CONSOLE_MESSAGES) - console->current_message_index = 0; +{ + if(++console->current_message_index >= MAX_CONSOLE_MESSAGES) + console->current_message_index = 0; vsnprintf(console->console_messages[console->current_message_index].message, MAX_CONSOLE_MESSAGE_LEN, message, args); console->console_messages[console->current_message_index].type = CMT_MESSAGE; console->scroll_to_bottom = true; -} - -void console_on_log_warning(struct Console* console, const char* warning_message, va_list args) -{ - if(++console->current_message_index >= MAX_CONSOLE_MESSAGES) - console->current_message_index = 0; - vsnprintf(console->console_messages[console->current_message_index].message, MAX_CONSOLE_MESSAGE_LEN, warning_message, args); - console->console_messages[console->current_message_index].type = CMT_WARNING; - console->scroll_to_bottom = true; -} - -void console_on_log_error(struct Console* console, const char* context, const char* error, va_list args) -{ - if(++console->current_message_index >= MAX_CONSOLE_MESSAGES) - console->current_message_index = 0; - int loc = snprintf(console->console_messages[console->current_message_index].message, MAX_CONSOLE_MESSAGE_LEN, "(%s)", context); - vsnprintf(console->console_messages[console->current_message_index].message + loc, MAX_CONSOLE_MESSAGE_LEN, error, args); - console->console_messages[console->current_message_index].type = CMT_ERROR; - console->scroll_to_bottom = true; -} +} + +void console_on_log_warning(struct Console* console, const char* warning_message, va_list args) +{ + if(++console->current_message_index >= MAX_CONSOLE_MESSAGES) + console->current_message_index = 0; + vsnprintf(console->console_messages[console->current_message_index].message, MAX_CONSOLE_MESSAGE_LEN, warning_message, args); + console->console_messages[console->current_message_index].type = CMT_WARNING; + console->scroll_to_bottom = true; +} + +void console_on_log_error(struct Console* console, const char* context, const char* error, va_list args) +{ + if(++console->current_message_index >= MAX_CONSOLE_MESSAGES) + console->current_message_index = 0; + int loc = snprintf(console->console_messages[console->current_message_index].message, MAX_CONSOLE_MESSAGE_LEN, "(%s)", context); + vsnprintf(console->console_messages[console->current_message_index].message + loc, MAX_CONSOLE_MESSAGE_LEN, error, args); + console->console_messages[console->current_message_index].type = CMT_ERROR; + console->scroll_to_bottom = true; +} diff --git a/src/libsymmetry/game.c b/src/libsymmetry/game.c index 3c6be22..060967e 100644 --- a/src/libsymmetry/game.c +++ b/src/libsymmetry/game.c @@ -292,6 +292,26 @@ void game_scene_setup(void) ground->model.material_params[MMP_SPECULAR_STRENGTH].val_float = 1.f; vec3_fill(&ground->model.material_params[MMP_DIFFUSE_COL].val_vec3, 1.f, 1.f, 1.f); + int num_suz = 50; + char suz_name[MAX_ENTITY_NAME_LEN]; + vec3 suz_pos = {0.f}; + for(int i = 0; i < num_suz; i++) + { + memset(&suz_name, '\0', MAX_ENTITY_NAME_LEN); + snprintf(&suz_name, MAX_ENTITY_NAME_LEN, "Suzanne_%d", i); + struct Static_Mesh* suzanne = scene_static_mesh_create(game_state->scene, suz_name, NULL, "sphere.symbres", MAT_BLINN); + suzanne->model.material_params[MMP_DIFFUSE_TEX].val_int = texture_create_from_file("white.tga", TU_DIFFUSE); + suzanne->model.material_params[MMP_DIFFUSE].val_float = 0.5f; + suzanne->model.material_params[MMP_SPECULAR].val_float = 1.f; + suzanne->model.material_params[MMP_SPECULAR_STRENGTH].val_float = 1.f; + vec3_fill(&suzanne->model.material_params[MMP_DIFFUSE_COL].val_vec3, 1.f, 0.f, 1.f); + suz_pos.x = i + 10.f; + suz_pos.y = 5.f; + suz_pos.z = i + 5.f; + transform_set_position(suzanne, &suz_pos); + + } + struct Light* light = scene_light_create(game_state->scene, "Test_Light", NULL, LT_POINT); light->color.x = 1.f; diff --git a/src/libsymmetry/geometry.c b/src/libsymmetry/geometry.c index eb5e8c8..3bf46a6 100644 --- a/src/libsymmetry/geometry.c +++ b/src/libsymmetry/geometry.c @@ -363,9 +363,13 @@ int geom_render_in_frustum(int index, struct Entity* entity, enum Geometry_Draw_Mode draw_mode) { + vec3 abs_pos, abs_scale; + transform_get_absolute_position(entity, &abs_pos); + transform_get_absolute_scale(entity, &abs_scale); + struct Geometry* geometry = &geometry_list[index]; int indices_rendered = 0; - int intersection = bv_intersect_frustum_sphere(frustum, &geometry->bounding_sphere, entity); + int intersection = bv_intersect_frustum_sphere(frustum, &geometry->bounding_sphere, &abs_pos, &abs_scale); if(intersection == IT_INTERSECT || intersection == IT_INSIDE) { geom_render(index, draw_mode); diff --git a/src/libsymmetry/player.c b/src/libsymmetry/player.c index bc81f93..c6d2381 100644 --- a/src/libsymmetry/player.c +++ b/src/libsymmetry/player.c @@ -1,56 +1,58 @@ -#include "player.h" -#include "scene.h" -#include "input.h" -#include "../common/utils.h" -#include "transform.h" -#include "../common/common.h" - -void player_init(struct Player* player, struct Scene* scene) -{ +#include "player.h" +#include "scene.h" +#include "input.h" +#include "../common/utils.h" +#include "transform.h" +#include "../common/common.h" +#include "camera.h" +#include "bounding_volumes.h" + +void player_init(struct Player* player, struct Scene* scene) +{ entity_init(player, "Player", &scene->root_entity); player->base.active = true; player->base.id = 1; - player->base.type = ET_PLAYER; - + player->base.type = ET_PLAYER; + struct Hashmap* config = platform->config.get(); - player->move_speed = hashmap_int_get(config, "player_move_speed"); - player->move_speed_multiplier = hashmap_int_get(config, "player_move_speed_multiplier"); - player->turn_speed = hashmap_int_get(config, "player_turn_speed"); - - player->mesh = scene_static_mesh_create(scene, "Player_Mesh", player, "sphere.symbres", MAT_BLINN); - + player->move_speed = hashmap_int_get(config, "player_move_speed"); + player->move_speed_multiplier = hashmap_int_get(config, "player_move_speed_multiplier"); + player->turn_speed = hashmap_int_get(config, "player_turn_speed"); + + player->mesh = scene_static_mesh_create(scene, "Player_Mesh", player, "sphere.symbres", MAT_BLINN); + struct Camera* player_camera = &scene->cameras[CAM_GAME]; entity_rename(player_camera, "Player_Camera"); player_camera->base.active = true; player_camera->clear_color.x = 0.6f; player_camera->clear_color.y = 0.6f; player_camera->clear_color.z = 0.9f; - player_camera->clear_color.w = 1.f; - player->camera_node = player_camera; - + player_camera->clear_color.w = 1.f; + player->camera_node = player_camera; + int render_width = hashmap_int_get(config, "render_width"); int render_height = hashmap_int_get(config, "render_height"); - camera_attach_fbo(player_camera, render_width, render_height, true, true, true); - transform_parent_set(player_camera, player, true); - - vec3 cam_translation = {0.f, 20.f, 2.f}; - transform_translate(player_camera, &cam_translation, TS_LOCAL); - - vec3 cam_axis = {-1.f, 0.f, 0.f}; - transform_rotate(player_camera, &cam_axis, 85.f, TS_LOCAL); -} - -void player_destroy(struct Player* player) -{ - entity_reset(player, player->base.id); - player->base.active = false; -} - -void player_update(struct Player* player, struct Scene* scene, float dt) -{ - float move_speed = player->move_speed; - vec3 offset = {0.f, 0.f, 0.f}; - + camera_attach_fbo(player_camera, render_width, render_height, true, true, true); + transform_parent_set(player_camera, player, true); + + vec3 cam_translation = {0.f, 20.f, 2.f}; + transform_translate(player_camera, &cam_translation, TS_LOCAL); + + vec3 cam_axis = {-1.f, 0.f, 0.f}; + transform_rotate(player_camera, &cam_axis, 85.f, TS_LOCAL); +} + +void player_destroy(struct Player* player) +{ + entity_reset(player, player->base.id); + player->base.active = false; +} + +void player_update(struct Player* player, struct Scene* scene, float dt) +{ + float move_speed = player->move_speed; + vec3 offset = {0.f, 0.f, 0.f}; + /* Movement */ if(input_map_state_get("Sprint", KS_PRESSED)) move_speed *= player->move_speed_multiplier; if(input_map_state_get("Move_Forward", KS_PRESSED)) offset.z -= move_speed; @@ -64,5 +66,16 @@ void player_update(struct Player* player, struct Scene* scene, float dt) if(offset.x != 0 || offset.y != 0 || offset.z != 0) { transform_translate(player, &offset, TS_LOCAL); - } -} + } + + /* Aiming and Projectiles*/ + if(input_mousebutton_state_get(MSB_RIGHT, KS_PRESSED)) + { + int mouse_x = 0, mouse_y = 0; + platform->mouse_position_get(&mouse_x, &mouse_y); + struct Ray ray = camera_screen_coord_to_ray(player->camera_node, mouse_x, mouse_y); + log_message("Ray: %.3f, %.3f, %.3f", ray.direction.x, ray.direction.y, ray.direction.z); + + scene_ray_intersect(scene, &ray); + } +} diff --git a/src/libsymmetry/scene.c b/src/libsymmetry/scene.c index f712a22..282dfa0 100644 --- a/src/libsymmetry/scene.c +++ b/src/libsymmetry/scene.c @@ -10,6 +10,8 @@ #include "light.h" #include "player.h" #include "game.h" +#include "bounding_volumes.h" +#include "geometry.h" #include #include @@ -69,11 +71,11 @@ void scene_destroy(struct Scene* scene) player_destroy(&scene->player); entity_reset(&scene->root_entity, 0); scene->root_entity.active = false; -} - -void scene_update(struct Scene* scene, float dt) -{ - if(game_state_get()->game_mode == GAME_MODE_GAME) player_update(&scene->player, scene, dt); +} + +void scene_update(struct Scene* scene, float dt) +{ + if(game_state_get()->game_mode == GAME_MODE_GAME) player_update(&scene->player, scene, dt); } void scene_post_update(struct Scene* scene) @@ -500,26 +502,26 @@ struct Sound_Source* scene_sound_source_find(struct Scene* scene, const char* na } return sound_source; -} - -struct Entity* scene_base_entity_get(struct Scene* scene, int id, int type) -{ - assert(scene && id != -1 && type < ET_MAX); - - struct Entity* entity = NULL; - - switch(type) - { - case ET_DEFAULT: entity = &scene->entities[id]; break; - case ET_CAMERA: entity = &scene->cameras[id]; break; - case ET_LIGHT: entity = &scene->lights[id]; break; - case ET_STATIC_MESH: entity = &scene->static_meshes[id]; break; - case ET_SOUND_SOURCE: entity = &scene->sound_sources[id]; break; - case ET_PLAYER: entity = &scene->player; break; - case ET_ROOT: entity = &scene->root_entity; break; - } - - return entity; +} + +struct Entity* scene_base_entity_get(struct Scene* scene, int id, int type) +{ + assert(scene && id != -1 && type < ET_MAX); + + struct Entity* entity = NULL; + + switch(type) + { + case ET_DEFAULT: entity = &scene->entities[id]; break; + case ET_CAMERA: entity = &scene->cameras[id]; break; + case ET_LIGHT: entity = &scene->lights[id]; break; + case ET_STATIC_MESH: entity = &scene->static_meshes[id]; break; + case ET_SOUND_SOURCE: entity = &scene->sound_sources[id]; break; + case ET_PLAYER: entity = &scene->player; break; + case ET_ROOT: entity = &scene->root_entity; break; + } + + return entity; } void* scene_find(struct Scene* scene, const char* name) @@ -553,6 +555,44 @@ void scene_entity_parent_set(struct Scene* scene, struct Entity* entity, struct transform_parent_set(entity, parent, true); } + +void scene_ray_intersect(struct Scene* scene, struct Ray* ray) +{ + for(int i = 0; i < MAX_STATIC_MESHES; i++) + { + struct Static_Mesh* mesh = &scene->static_meshes[i]; + if(!mesh->base.active) continue; + vec3 abs_pos = {0.f}; + transform_get_absolute_position(mesh, &abs_pos); + + struct Geometry* geometry = geom_get(mesh->model.geometry_index); + if(bv_intersect_sphere_ray(&geometry->bounding_sphere, &abs_pos, ray)) + { + log_message("Ray intersected with %s", &mesh->base.name); + } + } +} + + + + + + + + + + + + + + + + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool scene_load(const char* filename, int directory_type) { // FILE* entity_file = platform->file.open(directory_type, filename, "r"); diff --git a/src/libsymmetry/scene.h b/src/libsymmetry/scene.h index 4f2da35..2dc24d2 100644 --- a/src/libsymmetry/scene.h +++ b/src/libsymmetry/scene.h @@ -10,6 +10,9 @@ #define MAX_STATIC_MESHES 1024 #define MAX_SOUND_SOURCES 128 + +struct Ray; + struct Scene { struct Render_Settings renderer_profile; @@ -53,6 +56,8 @@ struct Entity* scene_base_entity_get(struct Scene* scene, int id, int type void scene_entity_parent_set(struct Scene* scene, struct Entity* entity, struct Entity* parent); void scene_entity_parent_reset(struct Scene* scene, struct Entity* entity); // Sets root entity as parent +void scene_ray_intersect(struct Scene* scene, struct Ray* ray); + // //void scene_init(void); //void scene_remove(struct Entity* entity);