Added finding bounding box normal from intersection point and ray

dev
Shariq Shah 6 years ago
parent eb91c66d36
commit ae1364d2cd
  1. 2
      src/common/version.h
  2. 20
      src/game/bounding_volumes.c
  3. 1
      src/game/bounding_volumes.h
  4. 73
      src/game/player.c
  5. 5
      src/game/scene.c
  6. 3
      todo.txt

@ -4,7 +4,7 @@
/* Auto generated version file. DO NOT MODIFY */ /* Auto generated version file. DO NOT MODIFY */
#define SYMMETRY_VERSION_MAJOR 0 #define SYMMETRY_VERSION_MAJOR 0
#define SYMMETRY_VERSION_MINOR 1 #define SYMMETRY_VERSION_MINOR 1
#define SYMMETRY_VERSION_REVISION 307 #define SYMMETRY_VERSION_REVISION 308
#define SYMMETRY_VERSION_BRANCH "dev" #define SYMMETRY_VERSION_BRANCH "dev"
#endif #endif

@ -391,3 +391,23 @@ bool bv_point_inside_bounding_box(struct Bounding_Box* box, vec3 point)
else else
return true; return true;
} }
vec3 bv_bounding_box_normal_from_intersection_point(struct Bounding_Box* box, struct Ray* ray, vec3 intersection_point)
{
vec3 center = { (box->max.x + box->min.x) * 0.5f,
(box->max.y + box->min.y) * 0.5f,
(box->max.z + box->min.z) * 0.5f };
vec3 local_point = { 0.f, 0.f, 0.f };
vec3_sub(&local_point, &intersection_point, &center);
vec3 d = { (box->min.x - box->max.x) * 0.5f,
(box->min.y - box->max.y) * 0.5f,
(box->min.z - box->max.z) * 0.5f };
float bias = 1.000001f;
vec3 normal = { (int)(local_point.x / fabsf(d.x) * bias),
(int)(local_point.y / fabsf(d.y) * bias),
(int)(local_point.z / fabsf(d.z) * bias) };
vec3_norm(&normal, &normal);
return normal;
}

@ -61,5 +61,6 @@ float bv_distance_ray_plane(struct Ray* ray, Plane* plane);
void bv_bounding_box_vertices_get(struct Bounding_Box* box, vec3 out_vertices[8]); void bv_bounding_box_vertices_get(struct Bounding_Box* box, vec3 out_vertices[8]);
void bv_bounding_box_vertices_get_line_visualization(struct Bounding_Box* bounding_box, vec3 out_vertices[24]); void bv_bounding_box_vertices_get_line_visualization(struct Bounding_Box* bounding_box, vec3 out_vertices[24]);
float bv_distance_ray_bounding_box(struct Ray* ray, struct Bounding_Box* box); float bv_distance_ray_bounding_box(struct Ray* ray, struct Bounding_Box* box);
vec3 bv_bounding_box_normal_from_intersection_point(struct Bounding_Box* box, struct Ray* ray, vec3 intersection_point);
#endif #endif

@ -13,6 +13,9 @@
#include "game.h" #include "game.h"
#include "debug_vars.h" #include "debug_vars.h"
#include "geometry.h" #include "geometry.h"
#include "im_render.h"
#include <float.h>
void player_init(struct Player* player, struct Scene* scene) void player_init(struct Player* player, struct Scene* scene)
{ {
@ -176,10 +179,14 @@ void player_update(struct Player* player, struct Scene* scene, float dt)
/* Check for collisions ahead */ /* Check for collisions ahead */
int mouse_x = 0, mouse_y = 0; int mouse_x = 0, mouse_y = 0;
platform_mouse_position_get(&mouse_x, &mouse_y); platform_mouse_position_get(&mouse_x, &mouse_y);
struct Ray forward_ray = camera_screen_coord_to_ray(player->camera_node, mouse_x, mouse_y); //struct Ray forward_ray = camera_screen_coord_to_ray(player->camera_node, 0, 0);
float min_collision_distance = 2.0f; struct Ray forward_ray = { 0 };
transform_get_absolute_position(player, &forward_ray.origin);
transform_get_absolute_forward(player->camera_node, &forward_ray.direction);
// Get all the entities that intersect then check the distance if it is less than // Get all the entities that intersect then check the distance if it is less than
// or equal to min_collision_distance then we are colliding // or equal to min_collision_distance then we are colliding
float min_collision_distance = 5.0f;
struct Raycast_Result ray_result; struct Raycast_Result ray_result;
scene_ray_intersect(scene, &forward_ray, &ray_result, ERM_STATIC_MESH); scene_ray_intersect(scene, &forward_ray, &ray_result, ERM_STATIC_MESH);
debug_vars_show_int("Colliding Entities", ray_result.num_entities_intersected); debug_vars_show_int("Colliding Entities", ray_result.num_entities_intersected);
@ -192,8 +199,24 @@ void player_update(struct Player* player, struct Scene* scene, float dt)
debug_vars_show_float("Collision ahead", distance); debug_vars_show_float("Collision ahead", distance);
if(distance > 0.f && distance <= min_collision_distance && colliding_entity != player->mesh) if(distance > 0.f && distance <= min_collision_distance && colliding_entity != player->mesh)
{ {
velocity.x = 0.f; vec3 intersection_point = forward_ray.direction;
velocity.z = 0.f; vec3_scale(&intersection_point, &intersection_point, distance);
vec3_add(&intersection_point, &intersection_point, &forward_ray.origin);
struct Bounding_Box* box = &colliding_entity->derived_bounding_box;
vec3 normal = bv_bounding_box_normal_from_intersection_point(box, &forward_ray, intersection_point);
struct Ray normal_ray;
normal_ray.origin = intersection_point;
normal_ray.direction = normal;
im_ray(&normal_ray, 5.f, (vec4) { 1.f, 0.f, 0.f, 1.f }, 3);
float dot = (vec3_dot(&velocity, &normal));
vec3 norm_scaled = { 0.f };
vec3_scale(&norm_scaled, &normal, dot);
vec3_sub(&velocity, &velocity, &norm_scaled);
debug_vars_show_vec3("Normal", &normal);
debug_vars_show_float("Dot", dot);
} }
} }
} }
@ -210,9 +233,11 @@ void player_update(struct Player* player, struct Scene* scene, float dt)
for(int i = 0; i < down_ray_result.num_entities_intersected; i++) for(int i = 0; i < down_ray_result.num_entities_intersected; i++)
{ {
struct Entity* colliding_entity = down_ray_result.entities_intersected[i]; struct Entity* colliding_entity = down_ray_result.entities_intersected[i];
if(colliding_entity == player->mesh)
continue;
float distance = bv_distance_ray_bounding_box(&downward_ray, &colliding_entity->derived_bounding_box); float distance = bv_distance_ray_bounding_box(&downward_ray, &colliding_entity->derived_bounding_box);
debug_vars_show_float("Collision below", distance); debug_vars_show_float("Collision below", distance);
if(distance > 0.f && distance <= min_downward_distance && colliding_entity != player->mesh && !jumping) if(distance > 0.f && distance <= min_downward_distance && !jumping)
{ {
velocity.y = 0.f; velocity.y = 0.f;
player->grounded = true; player->grounded = true;
@ -220,9 +245,19 @@ void player_update(struct Player* player, struct Scene* scene, float dt)
} }
} }
vec3 offset = {0.f, 0.f, 0.f}; float min_velocity = 0.0001f;
float fract_part = 0.f;
double int_part = 0.f;
double int_part2 = 0.f;
fract_part = modf(velocity.x, &int_part);
if(fabsf(fract_part) < min_velocity) velocity.x = 0.f;
fract_part = modf(velocity.z, &int_part2);
if(fabsf(fract_part) < min_velocity) velocity.z = 0.f;
debug_vars_show_vec3("velocity", &velocity); debug_vars_show_vec3("velocity", &velocity);
debug_vars_show_bool("Grounded", player->grounded); debug_vars_show_bool("Grounded", player->grounded);
vec3 offset = {0.f, 0.f, 0.f};
vec3_assign(&offset, &velocity); vec3_assign(&offset, &velocity);
vec3_scale(&offset, &offset, dt); vec3_scale(&offset, &offset, dt);
if(offset.x != 0 || offset.z != 0) if(offset.x != 0 || offset.z != 0)
@ -239,12 +274,32 @@ void player_update(struct Player* player, struct Scene* scene, float dt)
/* Aiming and Projectiles*/ /* Aiming and Projectiles*/
if(input_mousebutton_state_get(MSB_RIGHT, KS_PRESSED)) if(input_mousebutton_state_get(MSB_RIGHT, KS_PRESSED))
{ {
log_message("Right Click");
int mouse_x = 0, mouse_y = 0; int mouse_x = 0, mouse_y = 0;
platform_mouse_position_get(&mouse_x, &mouse_y); platform_mouse_position_get(&mouse_x, &mouse_y);
struct Ray bullet_ray = camera_screen_coord_to_ray(player->camera_node, mouse_x, mouse_y); struct Ray bullet_ray = camera_screen_coord_to_ray(player->camera_node, mouse_x, mouse_y);
log_message("Ray: %.3f, %.3f, %.3f", bullet_ray.direction.x, bullet_ray.direction.y, bullet_ray.direction.z);
struct Raycast_Result ray_result; struct Raycast_Result bullet_ray_result;
scene_ray_intersect(scene, &bullet_ray, &ray_result, ERM_ALL); scene_ray_intersect(scene, &bullet_ray, &bullet_ray_result, ERM_STATIC_MESH);
if(bullet_ray_result.num_entities_intersected > 0)
{
for(int i = 0; i < bullet_ray_result.num_entities_intersected; i++)
{
struct Entity* colliding_entity = bullet_ray_result.entities_intersected[i];
if(colliding_entity == player->mesh)
continue;
float distance = bv_distance_ray_bounding_box(&bullet_ray, &colliding_entity->derived_bounding_box);
if(distance > 0.f)
{
vec3 collision_point = bullet_ray.direction;
vec3_scale(&collision_point, &collision_point, distance);
vec3_add(&collision_point, &collision_point, &bullet_ray.origin);
struct Static_Mesh* bullet = scene_static_mesh_create(game_state_get()->scene, "bullet", NULL, "cube.symbres", MAT_UNSHADED);
transform_set_position(bullet, &collision_point);
}
}
}
} }
debug_vars_show_float("Frame Time", dt * 100000.f);
} }

@ -868,6 +868,11 @@ void scene_ray_intersect(struct Scene* scene, struct Ray* ray, struct Raycast_Re
{ {
out_results->entities_intersected[out_results->num_entities_intersected] = entity; out_results->entities_intersected[out_results->num_entities_intersected] = entity;
out_results->num_entities_intersected++; out_results->num_entities_intersected++;
if(out_results->num_entities_intersected >= MAX_RAYCAST_ENTITIES_INTERSECT)
{
log_warning("Reached Max raycast limit");
return;
}
} }
} }

@ -1,4 +1,7 @@
Todo: Todo:
- Improve player collision by impelenting sliding along collision plane in case of collision
- Check if running in a lower frame rate affects movement
- Move player movement related variables from function to player struct and load them from config file
? Write entity flags to scene file or when saving entity to file? ? Write entity flags to scene file or when saving entity to file?
? Add scene init/de-init function hashmap that maps a function that should be called when scene is loaded and unloaded. Save this to file for every scene or map functions based on the name of the scene? ? Add scene init/de-init function hashmap that maps a function that should be called when scene is loaded and unloaded. Save this to file for every scene or map functions based on the name of the scene?
- Command to create a placeholder entity of a particular type in a file - Command to create a placeholder entity of a particular type in a file

Loading…
Cancel
Save