Fixed vec4 and mat4 multiplication, Implemented screen coord to ray and ray-sphere collision

dev
Shariq Shah 7 years ago
parent ada2e0efe2
commit ad5b56b717
  1. 7
      README.md
  2. 2
      build/genie.lua
  3. 8
      src/common/linmath.c
  4. 62
      src/libsymmetry/bounding_volumes.c
  5. 11
      src/libsymmetry/bounding_volumes.h
  6. 62
      src/libsymmetry/camera.c
  7. 2
      src/libsymmetry/camera.h
  8. 238
      src/libsymmetry/console.c
  9. 20
      src/libsymmetry/game.c
  10. 6
      src/libsymmetry/geometry.c
  11. 99
      src/libsymmetry/player.c
  12. 90
      src/libsymmetry/scene.c
  13. 5
      src/libsymmetry/scene.h

@ -155,11 +155,13 @@
- ## TODO - ## TODO
- Improve bounding sphere calculation
- Screen mouse coordinates to world-coordinates for aiming
- Player projectiles and sounds
- Console commands - Console commands
- Console fix bug when enabled in editor mode - Console fix bug when enabled in editor mode
- Console command history - Console command history
- Console command help - Console command help
- Player projectiles and sounds
- NPR and cross-hatching - NPR and cross-hatching
- Move Gui_State and Editor_State into game_state and modify usage as needed - Move Gui_State and Editor_State into game_state and modify usage as needed
- Remove model and replace all usages with static mesh - Remove model and replace all usages with static mesh
@ -412,4 +414,5 @@
* In-game basis for scrollable console/log-viewer * In-game basis for scrollable console/log-viewer
* Console log output * Console log output
* Console error/warning output * Console error/warning output
* Implemented Auto scrolling to the bottom in console * Implemented Auto scrolling to the bottom in console
* Implemented screen coordinate to ray conversion and ray-sphere collision

@ -137,7 +137,7 @@ solution "Symmetry"
newaction { newaction {
trigger = "build_addon", 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 () 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"); 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) printf("Output of blender addon build : \n%s\n", output)

@ -269,10 +269,10 @@ void vec4_mul(vec4* res, vec4* v1, vec4* v4)
void vec4_mul_mat4(vec4* res, vec4* val, mat4* mat) void vec4_mul_mat4(vec4* res, vec4* val, mat4* mat)
{ {
vec4 v; vec4 v;
v.x = val->x * mat->mat[0] + val->y * mat->mat[4] + val->z * mat->mat[8] + mat->mat[12]; 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] + mat->mat[14]; 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] + mat->mat[14]; 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[2] + val->y * mat->mat[6] + val->w * mat->mat[10] + 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->x = v.x;
res->y = v.y; res->y = v.y;
res->z = v.z; res->z = v.z;

@ -81,3 +81,65 @@ bool bv_intersect_frustum_point(vec4* frustum, const vec3* point)
} }
return success; return success;
} }
bool bv_intersect_sphere_ray(struct Bounding_Sphere* sphere, vec3* sphere_abs_position, struct Ray* ray)
{
vec3 center = {0.f};
vec3_add(&center, &sphere->center, sphere_abs_position);
float squared_radius = sphere->radius * sphere->radius;
vec3 centered_origin;
vec3_sub(&centered_origin, &ray->origin, &center);
float centered_origin_len_sqrd = vec3_len(&centered_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(&centered_origin, &ray->direction);
float c = vec3_dot(&centered_origin, &centered_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(&centered_origin, &ray->direction);
//if(tca < 0.0) return false;
//float L_dot = vec3_dot(&centered_origin, &centered_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;
}

@ -34,8 +34,15 @@ enum Frustum_Planes
FP_NUM_PLANES FP_NUM_PLANES
}; };
int bv_intersect_frustum_box(vec4* frustum, struct Bounding_Box* box, vec3* box_abs_position, vec3* box_abs_scale); struct Ray
int bv_intersect_frustum_sphere(vec4* frustum, struct Bounding_Sphere* sphere, struct Transform* transform); {
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_frustum_point(vec4* frustum, const vec3* point);
bool bv_intersect_sphere_ray(struct Bounding_Sphere* sphere, vec3* sphere_abs_position, struct Ray* ray);
#endif #endif

@ -201,4 +201,66 @@ static void update_frustum(struct Camera* camera)
float length = fabsf(vec3_len(&plane_xyz)); float length = fabsf(vec3_len(&plane_xyz));
vec4_scale(&camera->frustum[i], &camera->frustum[i], (1.f / length)); 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;*/
} }

@ -2,6 +2,7 @@
#define CAMERA_H #define CAMERA_H
#include "../common/num_types.h" #include "../common/num_types.h"
#include "../common/linmath.h"
struct Camera; struct Camera;
@ -16,6 +17,7 @@ void camera_attach_fbo(struct Camera* camera,
bool has_depth, bool has_depth,
bool has_color, bool has_color,
bool resizeable); 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); */ /* void camera_resize_all(int width, int height); */
#endif #endif

@ -1,102 +1,102 @@
#include "console.h" #include "console.h"
#include "gui.h" #include "gui.h"
#include "game.h" #include "game.h"
#include "../common/log.h" #include "../common/log.h"
#include "../common/common.h" #include "../common/common.h"
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
#include <nuklear.h> #include <nuklear.h>
static struct nk_color console_message_color[CMT_MAX]; static struct nk_color console_message_color[CMT_MAX];
static int console_filter(const struct nk_text_edit *box, nk_rune unicode); static int console_filter(const struct nk_text_edit *box, nk_rune unicode);
void console_init(struct Console* console) void console_init(struct Console* console)
{ {
assert(console); assert(console);
console_message_color[CMT_MESSAGE] = nk_rgb(255, 255, 255); console_message_color[CMT_MESSAGE] = nk_rgb(255, 255, 255);
console_message_color[CMT_WARNING] = nk_rgb(255, 255, 0); console_message_color[CMT_WARNING] = nk_rgb(255, 255, 0);
console_message_color[CMT_ERROR] = nk_rgb(255, 0, 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_COMMAND] = nk_rgb(114, 173, 224);
console_message_color[CMT_NONE] = nk_rgb(255, 0, 255); console_message_color[CMT_NONE] = nk_rgb(255, 0, 255);
console->visible = false; console->visible = false;
console->scroll_to_bottom = true; console->scroll_to_bottom = true;
console->text_region_height = 22.f; console->text_region_height = 22.f;
console->line_height = 20.f; console->line_height = 20.f;
console->current_message_index = -1; console->current_message_index = -1;
memset(console->console_command_text, '\0', MAX_CONSOLE_MESSAGE_LEN); memset(console->console_command_text, '\0', MAX_CONSOLE_MESSAGE_LEN);
for(int i = 0; i < MAX_CONSOLE_MESSAGES; i++) for(int i = 0; i < MAX_CONSOLE_MESSAGES; i++)
{ {
memset(console->console_messages[i].message, '\0', MAX_CONSOLE_MESSAGE_LEN); memset(console->console_messages[i].message, '\0', MAX_CONSOLE_MESSAGE_LEN);
console->console_messages[i].type = CMT_NONE; console->console_messages[i].type = CMT_NONE;
} }
} }
void console_toggle(struct Console* console) void console_toggle(struct Console* console)
{ {
if(!console->visible) console->scroll_to_bottom = true; if(!console->visible) console->scroll_to_bottom = true;
console->visible = !console->visible; console->visible = !console->visible;
} }
void console_update(struct Console* console, struct Gui_State* gui_state, float dt) void console_update(struct Console* console, struct Gui_State* gui_state, float dt)
{ {
if(!console->visible) return; if(!console->visible) return;
struct nk_context* context = &gui_state->context; struct nk_context* context = &gui_state->context;
struct Game_State* game_state = game_state_get(); struct Game_State* game_state = game_state_get();
int win_width = 0, win_height = 0; int win_width = 0, win_height = 0;
platform->window.get_drawable_size(game_state->window, &win_width, &win_height); platform->window.get_drawable_size(game_state->window, &win_width, &win_height);
int half_height = win_height / 2; 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)) 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); 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)) if(nk_group_begin(context, "Log", NK_WINDOW_BORDER))
{ {
for(int i = 0; i <= console->current_message_index; i++) for(int i = 0; i <= console->current_message_index; i++)
{ {
nk_layout_row_dynamic(context, console->line_height, 1); 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); 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 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; *context->current->layout->offset_y = context->current->layout->at_y;
console->scroll_to_bottom = false; console->scroll_to_bottom = false;
} }
nk_group_end(context); nk_group_end(context);
} }
//Edit-string/Textfield for command //Edit-string/Textfield for command
nk_layout_row_dynamic(context, console->text_region_height, 1); 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; int edit_flags = NK_EDIT_GOTO_END_ON_ACTIVATE | NK_EDIT_FIELD | NK_EDIT_SIG_ENTER;
nk_edit_focus(context, edit_flags); 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); 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(edit_state & NK_EDIT_COMMITED)
{ {
if(++console->current_message_index >= MAX_CONSOLE_MESSAGES) if(++console->current_message_index >= MAX_CONSOLE_MESSAGES)
console->current_message_index = 0; console->current_message_index = 0;
snprintf(console->console_messages[console->current_message_index].message, MAX_CONSOLE_MESSAGE_LEN, "> %s", console->console_command_text); 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; console->console_messages[console->current_message_index].type = CMT_COMMAND;
memset(console->console_command_text, '\0', MAX_CONSOLE_MESSAGE_LEN); memset(console->console_command_text, '\0', MAX_CONSOLE_MESSAGE_LEN);
console->scroll_to_bottom = true; console->scroll_to_bottom = true;
} }
} }
nk_end(context); nk_end(context);
} }
void console_destroy(struct Console* console) void console_destroy(struct Console* console)
{ {
} }
int console_filter(const struct nk_text_edit *box, nk_rune unicode) int console_filter(const struct nk_text_edit *box, nk_rune unicode)
{ {
NK_UNUSED(box); 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) void console_on_log_message(struct Console* console, const char* message, va_list args)
{ {
if(++console->current_message_index >= MAX_CONSOLE_MESSAGES) if(++console->current_message_index >= MAX_CONSOLE_MESSAGES)
console->current_message_index = 0; console->current_message_index = 0;
vsnprintf(console->console_messages[console->current_message_index].message, MAX_CONSOLE_MESSAGE_LEN, message, args); 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->console_messages[console->current_message_index].type = CMT_MESSAGE;
console->scroll_to_bottom = true; console->scroll_to_bottom = true;
} }
void console_on_log_warning(struct Console* console, const char* warning_message, va_list args) void console_on_log_warning(struct Console* console, const char* warning_message, va_list args)
{ {
if(++console->current_message_index >= MAX_CONSOLE_MESSAGES) if(++console->current_message_index >= MAX_CONSOLE_MESSAGES)
console->current_message_index = 0; console->current_message_index = 0;
vsnprintf(console->console_messages[console->current_message_index].message, MAX_CONSOLE_MESSAGE_LEN, warning_message, args); 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->console_messages[console->current_message_index].type = CMT_WARNING;
console->scroll_to_bottom = true; console->scroll_to_bottom = true;
} }
void console_on_log_error(struct Console* console, const char* context, const char* error, va_list args) 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) if(++console->current_message_index >= MAX_CONSOLE_MESSAGES)
console->current_message_index = 0; console->current_message_index = 0;
int loc = snprintf(console->console_messages[console->current_message_index].message, MAX_CONSOLE_MESSAGE_LEN, "(%s)", context); 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); 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->console_messages[console->current_message_index].type = CMT_ERROR;
console->scroll_to_bottom = true; console->scroll_to_bottom = true;
} }

@ -292,6 +292,26 @@ void game_scene_setup(void)
ground->model.material_params[MMP_SPECULAR_STRENGTH].val_float = 1.f; 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); 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); struct Light* light = scene_light_create(game_state->scene, "Test_Light", NULL, LT_POINT);
light->color.x = 1.f; light->color.x = 1.f;

@ -363,9 +363,13 @@ int geom_render_in_frustum(int index,
struct Entity* entity, struct Entity* entity,
enum Geometry_Draw_Mode draw_mode) 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]; struct Geometry* geometry = &geometry_list[index];
int indices_rendered = 0; 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) if(intersection == IT_INTERSECT || intersection == IT_INSIDE)
{ {
geom_render(index, draw_mode); geom_render(index, draw_mode);

@ -1,56 +1,58 @@
#include "player.h" #include "player.h"
#include "scene.h" #include "scene.h"
#include "input.h" #include "input.h"
#include "../common/utils.h" #include "../common/utils.h"
#include "transform.h" #include "transform.h"
#include "../common/common.h" #include "../common/common.h"
#include "camera.h"
void player_init(struct Player* player, struct Scene* scene) #include "bounding_volumes.h"
{
void player_init(struct Player* player, struct Scene* scene)
{
entity_init(player, "Player", &scene->root_entity); entity_init(player, "Player", &scene->root_entity);
player->base.active = true; player->base.active = true;
player->base.id = 1; player->base.id = 1;
player->base.type = ET_PLAYER; player->base.type = ET_PLAYER;
struct Hashmap* config = platform->config.get(); struct Hashmap* config = platform->config.get();
player->move_speed = hashmap_int_get(config, "player_move_speed"); player->move_speed = hashmap_int_get(config, "player_move_speed");
player->move_speed_multiplier = hashmap_int_get(config, "player_move_speed_multiplier"); player->move_speed_multiplier = hashmap_int_get(config, "player_move_speed_multiplier");
player->turn_speed = hashmap_int_get(config, "player_turn_speed"); 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->mesh = scene_static_mesh_create(scene, "Player_Mesh", player, "sphere.symbres", MAT_BLINN);
struct Camera* player_camera = &scene->cameras[CAM_GAME]; struct Camera* player_camera = &scene->cameras[CAM_GAME];
entity_rename(player_camera, "Player_Camera"); entity_rename(player_camera, "Player_Camera");
player_camera->base.active = true; player_camera->base.active = true;
player_camera->clear_color.x = 0.6f; player_camera->clear_color.x = 0.6f;
player_camera->clear_color.y = 0.6f; player_camera->clear_color.y = 0.6f;
player_camera->clear_color.z = 0.9f; player_camera->clear_color.z = 0.9f;
player_camera->clear_color.w = 1.f; player_camera->clear_color.w = 1.f;
player->camera_node = player_camera; player->camera_node = player_camera;
int render_width = hashmap_int_get(config, "render_width"); int render_width = hashmap_int_get(config, "render_width");
int render_height = hashmap_int_get(config, "render_height"); int render_height = hashmap_int_get(config, "render_height");
camera_attach_fbo(player_camera, render_width, render_height, true, true, true); camera_attach_fbo(player_camera, render_width, render_height, true, true, true);
transform_parent_set(player_camera, player, true); transform_parent_set(player_camera, player, true);
vec3 cam_translation = {0.f, 20.f, 2.f}; vec3 cam_translation = {0.f, 20.f, 2.f};
transform_translate(player_camera, &cam_translation, TS_LOCAL); transform_translate(player_camera, &cam_translation, TS_LOCAL);
vec3 cam_axis = {-1.f, 0.f, 0.f}; vec3 cam_axis = {-1.f, 0.f, 0.f};
transform_rotate(player_camera, &cam_axis, 85.f, TS_LOCAL); transform_rotate(player_camera, &cam_axis, 85.f, TS_LOCAL);
} }
void player_destroy(struct Player* player) void player_destroy(struct Player* player)
{ {
entity_reset(player, player->base.id); entity_reset(player, player->base.id);
player->base.active = false; player->base.active = false;
} }
void player_update(struct Player* player, struct Scene* scene, float dt) void player_update(struct Player* player, struct Scene* scene, float dt)
{ {
float move_speed = player->move_speed; float move_speed = player->move_speed;
vec3 offset = {0.f, 0.f, 0.f}; vec3 offset = {0.f, 0.f, 0.f};
/* Movement */ /* Movement */
if(input_map_state_get("Sprint", KS_PRESSED)) move_speed *= player->move_speed_multiplier; 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; 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) if(offset.x != 0 || offset.y != 0 || offset.z != 0)
{ {
transform_translate(player, &offset, TS_LOCAL); 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);
}
}

@ -10,6 +10,8 @@
#include "light.h" #include "light.h"
#include "player.h" #include "player.h"
#include "game.h" #include "game.h"
#include "bounding_volumes.h"
#include "geometry.h"
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
@ -69,11 +71,11 @@ void scene_destroy(struct Scene* scene)
player_destroy(&scene->player); player_destroy(&scene->player);
entity_reset(&scene->root_entity, 0); entity_reset(&scene->root_entity, 0);
scene->root_entity.active = false; scene->root_entity.active = false;
} }
void scene_update(struct Scene* scene, float dt) void scene_update(struct Scene* scene, float dt)
{ {
if(game_state_get()->game_mode == GAME_MODE_GAME) player_update(&scene->player, scene, dt); if(game_state_get()->game_mode == GAME_MODE_GAME) player_update(&scene->player, scene, dt);
} }
void scene_post_update(struct Scene* scene) 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; return sound_source;
} }
struct Entity* scene_base_entity_get(struct Scene* scene, int id, int type) struct Entity* scene_base_entity_get(struct Scene* scene, int id, int type)
{ {
assert(scene && id != -1 && type < ET_MAX); assert(scene && id != -1 && type < ET_MAX);
struct Entity* entity = NULL; struct Entity* entity = NULL;
switch(type) switch(type)
{ {
case ET_DEFAULT: entity = &scene->entities[id]; break; case ET_DEFAULT: entity = &scene->entities[id]; break;
case ET_CAMERA: entity = &scene->cameras[id]; break; case ET_CAMERA: entity = &scene->cameras[id]; break;
case ET_LIGHT: entity = &scene->lights[id]; break; case ET_LIGHT: entity = &scene->lights[id]; break;
case ET_STATIC_MESH: entity = &scene->static_meshes[id]; break; case ET_STATIC_MESH: entity = &scene->static_meshes[id]; break;
case ET_SOUND_SOURCE: entity = &scene->sound_sources[id]; break; case ET_SOUND_SOURCE: entity = &scene->sound_sources[id]; break;
case ET_PLAYER: entity = &scene->player; break; case ET_PLAYER: entity = &scene->player; break;
case ET_ROOT: entity = &scene->root_entity; break; case ET_ROOT: entity = &scene->root_entity; break;
} }
return entity; return entity;
} }
void* scene_find(struct Scene* scene, const char* name) 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); 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) bool scene_load(const char* filename, int directory_type)
{ {
// FILE* entity_file = platform->file.open(directory_type, filename, "r"); // FILE* entity_file = platform->file.open(directory_type, filename, "r");

@ -10,6 +10,9 @@
#define MAX_STATIC_MESHES 1024 #define MAX_STATIC_MESHES 1024
#define MAX_SOUND_SOURCES 128 #define MAX_SOUND_SOURCES 128
struct Ray;
struct Scene struct Scene
{ {
struct Render_Settings renderer_profile; 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_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_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_init(void);
//void scene_remove(struct Entity* entity); //void scene_remove(struct Entity* entity);

Loading…
Cancel
Save