Added bounding inside transforms of entities that are recomputed when the entity transforms

dev
Shariq Shah 6 years ago
parent 33e07e5a52
commit 4238c2b16f
  1. 26
      src/game/bounding_volumes.c
  2. 1
      src/game/bounding_volumes.h
  3. 2
      src/game/entity.h
  4. 12
      src/game/geometry.c
  5. 10
      src/game/renderer.c
  6. 2
      src/game/scene.c
  7. 31
      src/game/transform.c
  8. 1
      src/game/transform.h
  9. 5
      todo.txt

@ -2,6 +2,32 @@
#include <math.h> #include <math.h>
int bv_intersect_frustum_box_(vec4* frustum, struct Bounding_Box* box)
{
vec3 size, center, half_ext, half_size;
vec3_fill(&size, 0.f, 0.f, 0.f);
vec3_fill(&center, 0.f, 0.f, 0.f);
vec3_fill(&half_ext, 0.f, 0.f, 0.f);
vec3_fill(&half_size, 0.f, 0.f, 0.f);
vec3_sub(&size, &box->max, &box->min);
vec3_add(&center, &box->max, &box->min);
vec3_scale(&center, &center, 0.5f);
vec3_assign(&half_ext, &size);
vec3_scale(&half_size, &size, 0.5f);
for(int i = 0; i < 6; i++)
{
vec3 normal = {frustum[i].x, frustum[i].y, frustum[i].z};
float distance = frustum[i].w;
float d = vec3_dot(&normal, &center);
vec3 abs_normal = {fabsf(normal.x), fabsf(normal.y), fabsf(normal.z)};
float r = vec3_dot(&half_ext, &abs_normal);
if(d + r < -distance)
return IT_OUTSIDE;
}
return IT_INSIDE;
}
int bv_intersect_frustum_box(vec4* frustum, struct Bounding_Box* box, vec3* box_abs_position, vec3* box_abs_scale) int bv_intersect_frustum_box(vec4* frustum, struct Bounding_Box* box, vec3* box_abs_position, vec3* box_abs_scale)
{ {
vec3 min, max, size, center, half_ext, half_size; vec3 min, max, size, center, half_ext, half_size;

@ -50,6 +50,7 @@ struct Raycast_Result
}; };
int bv_intersect_frustum_box(vec4* frustum, struct Bounding_Box* box, vec3* box_abs_position, vec3* box_abs_scale); int bv_intersect_frustum_box(vec4* frustum, struct Bounding_Box* box, vec3* box_abs_position, vec3* box_abs_scale);
int bv_intersect_frustum_box_(vec4* frustum, struct Bounding_Box* box);
int bv_intersect_frustum_sphere(vec4* frustum, struct Bounding_Sphere* sphere, vec3* sphere_abs_pos, vec3* sphere_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); //bool bv_intersect_sphere_ray(struct Bounding_Sphere* sphere, vec3* sphere_abs_position, struct Ray* ray);

@ -5,6 +5,7 @@
#include "../common/num_types.h" #include "../common/num_types.h"
#include "../system/physics.h" #include "../system/physics.h"
#include "../system/sound.h" #include "../system/sound.h"
#include "bounding_volumes.h"
#include "material.h" #include "material.h"
#define MAX_ENTITY_NAME_LEN 128 #define MAX_ENTITY_NAME_LEN 128
@ -65,6 +66,7 @@ struct Transform
mat4 trans_mat; mat4 trans_mat;
bool is_modified; bool is_modified;
bool sync_physics; bool sync_physics;
struct Bounding_Box bounding_box;
struct Entity* parent; struct Entity* parent;
struct Entity** children; struct Entity** children;
}; };

@ -372,15 +372,15 @@ int geom_render_in_frustum(int index,
int indices_rendered = 0; int indices_rendered = 0;
int intersection = bv_intersect_frustum_sphere(frustum, &geometry->bounding_sphere, &abs_pos, &abs_scale); 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);
//indices_rendered = array_len(geometry->indices);
intersection = bv_intersect_frustum_box(frustum, &geometry->bounding_box, &abs_pos, &abs_scale);
if(intersection == IT_INTERSECT || intersection == IT_INSIDE)
{ {
geom_render(index, draw_mode); geom_render(index, draw_mode);
indices_rendered = array_len(geometry->indices); indices_rendered = array_len(geometry->indices);
/* intersection = bv_intersect_frustum_box(frustum, &geometry->bounding_box, entity); */ }
/* if(intersection == IT_INTERSECT || intersection == IT_INSIDE) */
/* { */
/* geom_render(index, draw_mode); */
/* rendered = array_len(geometry->indices); */
/* } */
} }
return indices_rendered; return indices_rendered;
} }

@ -266,10 +266,20 @@ void renderer_render(struct Renderer* renderer, struct Scene* scene)
continue; continue;
} }
else else
{
//intersection = bv_intersect_frustum_box(&camera->frustum, &geometry->bounding_box, &abs_pos, &abs_scale);
intersection = bv_intersect_frustum_box_(&camera->frustum, &mesh->base.transform.bounding_box);
if(intersection == IT_INSIDE || intersection == IT_INTERSECT)
{ {
renderer->num_indices += array_len(geometry->indices); renderer->num_indices += array_len(geometry->indices);
renderer->num_rendered++; renderer->num_rendered++;
} }
else
{
renderer->num_culled++;
continue;
}
}
/* set material params for the model */ /* set material params for the model */
for(int k = 0; k < MMP_MAX; k++) for(int k = 0; k < MMP_MAX; k++)

@ -548,6 +548,8 @@ struct Static_Mesh* scene_static_mesh_create(struct Scene* scene, const char* na
new_static_mesh->base.type = ET_STATIC_MESH; new_static_mesh->base.type = ET_STATIC_MESH;
model_init(&new_static_mesh->model, new_static_mesh, geometry_name, material_type); model_init(&new_static_mesh->model, new_static_mesh, geometry_name, material_type);
// TODO: handle creating collision mesh for the model at creation // TODO: handle creating collision mesh for the model at creation
vec3_assign(&new_static_mesh->base.transform.bounding_box.min, &geom_get(new_static_mesh->model.geometry_index)->bounding_box.min);
vec3_assign(&new_static_mesh->base.transform.bounding_box.max, &geom_get(new_static_mesh->model.geometry_index)->bounding_box.max);
} }
else else
{ {

@ -14,6 +14,8 @@ void transform_init(struct Entity* entity, struct Entity* parent)
vec3_fill(&transform->scale, 1.f, 1.f, 1.f); vec3_fill(&transform->scale, 1.f, 1.f, 1.f);
quat_identity(&transform->rotation); quat_identity(&transform->rotation);
mat4_identity(&transform->trans_mat); mat4_identity(&transform->trans_mat);
transform->bounding_box.min = (vec3){ 0.f, 0.f, 0.f };
transform->bounding_box.max = (vec3){ 1.f, 1.f, 1.f };
transform->children = array_new(struct Entity*); transform->children = array_new(struct Entity*);
transform->parent = NULL; transform->parent = NULL;
if(parent) if(parent)
@ -21,6 +23,33 @@ void transform_init(struct Entity* entity, struct Entity* parent)
transform_update_transmat(entity); transform_update_transmat(entity);
} }
void transform_update_bounding_box(struct Entity* entity)
{
struct Bounding_Box* bounding_box = &entity->transform.bounding_box;
vec3 transformed_points[8];
vec3_fill(&transformed_points[0], bounding_box->min.x, bounding_box->min.y, bounding_box->min.z);
vec3_fill(&transformed_points[1], bounding_box->max.x, bounding_box->min.y, bounding_box->min.z);
vec3_fill(&transformed_points[2], bounding_box->min.x, bounding_box->max.y, bounding_box->min.z);
vec3_fill(&transformed_points[3], bounding_box->min.x, bounding_box->min.y, bounding_box->max.z);
vec3_fill(&transformed_points[4], bounding_box->max.x, bounding_box->max.y, bounding_box->max.z);
vec3_fill(&transformed_points[5], bounding_box->min.x, bounding_box->max.y, bounding_box->max.z);
vec3_fill(&transformed_points[6], bounding_box->max.x, bounding_box->min.y, bounding_box->max.z);
vec3_fill(&transformed_points[7], bounding_box->max.x, bounding_box->max.y, bounding_box->min.z);
for(int i = 0; i < 8; i++)
{
vec3_mul_mat4(&transformed_points[i], &transformed_points[i], &entity->transform.trans_mat);
if(transformed_points[i].x < bounding_box->min.x) bounding_box->min.x = transformed_points[i].x;
if(transformed_points[i].y < bounding_box->min.y) bounding_box->min.y = transformed_points[i].y;
if(transformed_points[i].z < bounding_box->min.z) bounding_box->min.z = transformed_points[i].z;
if(transformed_points[i].x > bounding_box->max.x) bounding_box->max.x = transformed_points[i].x;
if(transformed_points[i].y > bounding_box->max.y) bounding_box->max.y = transformed_points[i].y;
if(transformed_points[i].z > bounding_box->max.z) bounding_box->max.z = transformed_points[i].z;
}
}
void transform_child_add(struct Entity* parent, struct Entity* child, bool update_transmat) void transform_child_add(struct Entity* parent, struct Entity* child, bool update_transmat)
{ {
struct Transform* parent_transform = &parent->transform; struct Transform* parent_transform = &parent->transform;
@ -225,6 +254,8 @@ void transform_update_transmat(struct Entity* entity)
mat4_mul(&transform->trans_mat, &parent_tran->trans_mat, &transform->trans_mat); mat4_mul(&transform->trans_mat, &parent_tran->trans_mat, &transform->trans_mat);
} }
transform_update_bounding_box(entity);
/* Update all children */ /* Update all children */
int children = array_len(transform->children); int children = array_len(transform->children);
if(children > 0) if(children > 0)

@ -34,5 +34,6 @@ void transform_child_add(struct Entity* entity, struct Entity* child, bool updat
bool transform_child_remove(struct Entity* entity, struct Entity* child); bool transform_child_remove(struct Entity* entity, struct Entity* child);
void transform_parent_set(struct Entity* entity, struct Entity* parent, bool update_transmat); void transform_parent_set(struct Entity* entity, struct Entity* parent, bool update_transmat);
void transform_copy(struct Entity* copy_to, struct Entity* copy_from, bool copy_parent); void transform_copy(struct Entity* copy_to, struct Entity* copy_from, bool copy_parent);
void transform_update_bounding_box(struct Entity* entity);
#endif #endif

@ -1,9 +1,11 @@
Todo: Todo:
- Implement bounding box visualization
- Implement ray-bounding box picking and determine whether that is enough for our needs or do we need to implement OBB
- 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
- Re-write/Overhaul bounding volumes and ray intersection - Re-write/Overhaul bounding volumes and ray intersection
- Reduce the opacity of wireframe around selected entity in editor - Reduce the opacity of wireframe around selected entity in editor
- Release mouse when window loses focus and limit fps
- Allow picking and selecting other entity types in editor i.e. the ones that don't have meshes - Allow picking and selecting other entity types in editor i.e. the ones that don't have meshes
? Save transformation information when saving entity archetypes
? When saving a scene entity entry, save the changed properties as well, that way when the scene is loaded, we load the base properties from archetype and the ones we changed per entry are saved when we saved the entity ? When saving a scene entity entry, save the changed properties as well, that way when the scene is loaded, we load the base properties from archetype and the ones we changed per entry are saved when we saved the entity
this will prevent us from having needless amount of entities with only minor changes from one another this will prevent us from having needless amount of entities with only minor changes from one another
? Split up material declarations into their own separate files. Materials have a base material like Blinn or Unshaded and in the file we save an instance with modified properties. ? Split up material declarations into their own separate files. Materials have a base material like Blinn or Unshaded and in the file we save an instance with modified properties.
@ -397,3 +399,4 @@ Done:
* Add uv tiling parameter to materials that can be serialized along with entities * Add uv tiling parameter to materials that can be serialized along with entities
* Implement resetting complete transform or just rotation, translation * Implement resetting complete transform or just rotation, translation
or scale for selected entity or scale for selected entity
* Save transformation information when saving entity archetypes
Loading…
Cancel
Save