diff --git a/src/game/editor.c b/src/game/editor.c index 68c9117..6a318eb 100755 --- a/src/game/editor.c +++ b/src/game/editor.c @@ -172,7 +172,7 @@ void editor_init_camera(struct Editor* editor, struct Hashmap* cvars) { struct Camera* editor_camera = &game_state_get()->scene->cameras[CAM_EDITOR]; entity_rename(editor_camera, "Editor_Camera"); - editor_camera->base.flags |= EF_ACTIVE | EF_TRANSIENT; + editor_camera->base.flags |= EF_ACTIVE | EF_TRANSIENT | EF_IGNORE_RAYCAST; editor_camera->clear_color.x = 0.3f; editor_camera->clear_color.y = 0.6f; editor_camera->clear_color.z = 0.9f; @@ -250,7 +250,7 @@ void editor_render(struct Editor* editor, struct Camera * active_camera) /* Draw bounding box for selected entity */ static vec3 vertices[24]; - bv_bounding_box_vertices_get_line_visualization(&editor->selected_entity->transform.bounding_box, vertices); + bv_bounding_box_vertices_get_line_visualization(&editor->selected_entity->derived_bounding_box, vertices); for(int i = 0; i <= 22; i += 2) im_line(vertices[i], vertices[i + 1], (vec3) { 0.f, 0.f, 0.f }, (quat) { 0.f, 0.f, 0.f, 1.f }, editor->cursor_entity_color, 3); @@ -876,7 +876,7 @@ void editor_on_mousebutton_release(const struct Event* event) struct Ray ray = camera_screen_coord_to_ray(editor_camera, mouse_x, mouse_y); struct Scene* scene = game_state_get()->scene; - struct Entity* intersected_entity = scene_ray_intersect_closest(scene, &ray); + struct Entity* intersected_entity = scene_ray_intersect_closest(scene, &ray, ERM_ALL); if(intersected_entity) { if(intersected_entity != editor->selected_entity) @@ -954,7 +954,7 @@ void editor_on_mousebutton_press(const struct Event* event) int mouse_x = 0, mouse_y = 0; platform_mouse_position_get(&mouse_x, &mouse_y); struct Ray ray = camera_screen_coord_to_ray(editor_camera, mouse_x, mouse_y); - struct Entity* intersected_entity = scene_ray_intersect_closest(scene, &ray); + struct Entity* intersected_entity = scene_ray_intersect_closest(scene, &ray, ERM_ALL); bool start_rotation = true; if(intersected_entity) @@ -1159,21 +1159,7 @@ void editor_on_mousemotion(const struct Event* event) struct Scene* scene = game_state->scene; struct Camera* editor_camera = &scene->cameras[CAM_EDITOR]; struct Ray ray = camera_screen_coord_to_ray(editor_camera, event->mousemotion.x, event->mousemotion.y); - //struct Raycast_Result ray_result; - //scene_ray_intersect(scene, &ray, &ray_result); - - //if(ray_result.num_entities_intersected > 0) - //{ - // struct Entity* intersected_entity = ray_result.entities_intersected[0]; - // if(intersected_entity && intersected_entity != editor->hovered_entity) - // editor->hovered_entity = intersected_entity; - //} - //else - //{ - // if(editor->hovered_entity) - // editor->hovered_entity = NULL; - //} - struct Entity* intersected_entity = scene_ray_intersect_closest(scene, &ray); + struct Entity* intersected_entity = scene_ray_intersect_closest(scene, &ray, ERM_ALL); if(intersected_entity) { if(intersected_entity != editor->hovered_entity) @@ -1877,6 +1863,35 @@ void editor_window_property_inspector(struct nk_context* context, struct Editor* entity->transform.scale = abs_scale; transform_update_transmat(entity); } + + if(nk_tree_push(context, NK_TREE_TAB, "Bounding Box", NK_MINIMIZED)) + { + nk_layout_row_dynamic(context, row_height, 1); + nk_label(context, "Base", NK_TEXT_ALIGN_MIDDLE | NK_TEXT_ALIGN_CENTERED); + + nk_label(context, "Min", NK_TEXT_ALIGN_MIDDLE | NK_TEXT_ALIGN_CENTERED); + if(editor_widget_v3(context, &entity->bounding_box.min, "#X", "#Y", "#Z", -FLT_MAX, FLT_MAX, 0.5f, 0.5f, row_height)) entity_update_derived_bounding_box(entity); + + nk_layout_row_dynamic(context, row_height, 1); + nk_label(context, "Max", NK_TEXT_ALIGN_MIDDLE | NK_TEXT_ALIGN_CENTERED); + if(editor_widget_v3(context, &entity->bounding_box.max, "#X", "#Y", "#Z", -FLT_MAX, FLT_MAX, 0.5f, 0.5f, row_height)) entity_update_derived_bounding_box(entity); + + struct Bounding_Box* derived_box = &entity->derived_bounding_box; + nk_layout_row_dynamic(context, row_height, 1); + nk_label(context, "Derived", NK_TEXT_ALIGN_MIDDLE | NK_TEXT_ALIGN_CENTERED); + + nk_layout_row_dynamic(context, row_height, 2); + nk_label(context, "Min", NK_TEXT_ALIGN_MIDDLE | NK_TEXT_ALIGN_LEFT); + nk_labelf(context, NK_TEXT_ALIGN_MIDDLE | NK_TEXT_ALIGN_RIGHT, "%.1f %.1f %.1f", derived_box->min.x, derived_box->min.y, derived_box->min.z); + nk_label(context, "Max", NK_TEXT_ALIGN_MIDDLE | NK_TEXT_ALIGN_LEFT); + nk_labelf(context, NK_TEXT_ALIGN_MIDDLE | NK_TEXT_ALIGN_RIGHT, "%.1f %.1f %.1f", derived_box->max.x, derived_box->max.y, derived_box->max.z); + + nk_layout_row_dynamic(context, row_height, 1); + if(nk_button_label(context, "Reset to Default")) + entity_bounding_box_reset(entity, true); + + nk_tree_pop(context); + } } /* Light */ diff --git a/src/game/entity.c b/src/game/entity.c index 24dd923..e44760e 100755 --- a/src/game/entity.c +++ b/src/game/entity.c @@ -24,6 +24,7 @@ #include #include #include +#include #define MAX_ENTITY_PROP_NAME_LEN 128 #define MAX_ENTITY_PROP_LEN 256 @@ -35,22 +36,68 @@ void entity_init(struct Entity* entity, const char* name, struct Entity* parent) strncpy(entity->name, name ? name : "DEFAULT_ENTITY_NAME", MAX_ENTITY_NAME_LEN); entity->name[MAX_ENTITY_NAME_LEN - 1] = '\0'; - entity->type = ET_DEFAULT; - entity->archetype_index = -1; - entity->flags = EF_ACTIVE; + entity->type = ET_DEFAULT; + entity->archetype_index = -1; + entity->flags = EF_ACTIVE; + entity_bounding_box_reset(entity, false); + entity->derived_bounding_box.min = (vec3){ -0.5f, -0.5f, -0.5f }; + entity->derived_bounding_box.max = (vec3){ 0.5f, 0.5f, 0.5f }; transform_init(entity, parent); } -void entity_reset(struct Entity * entity, int id) +void entity_reset(struct Entity* entity, int id) { assert(entity); - entity->id = id; - entity->type = ET_DEFAULT; - entity->archetype_index = -1; - entity->flags = EF_NONE; + entity->id = id; + entity->type = ET_DEFAULT; + entity->archetype_index = -1; + entity->flags = EF_NONE; + entity_bounding_box_reset(entity, false); + entity->derived_bounding_box.min = (vec3){ -0.5f, -0.5f, -0.5f }; + entity->derived_bounding_box.max = (vec3){ 0.5f, 0.5f, 0.5f }; memset(entity->name, '\0', MAX_ENTITY_NAME_LEN); } +void entity_update_derived_bounding_box(struct Entity* entity) +{ + struct Bounding_Box* derived_box = &entity->derived_bounding_box; + vec3_fill(&derived_box->min, FLT_MAX, FLT_MAX, FLT_MAX); + vec3_fill(&derived_box->max, -FLT_MAX, -FLT_MAX, -FLT_MAX); + vec3 box_vertices[8]; + bv_bounding_box_vertices_get(&entity->bounding_box, box_vertices); + + for(int i = 0; i < 8; i++) + { + vec3 transformed_vertex = { 0.f, 0.f, 0.f }; + vec3_mul_mat4(&transformed_vertex, &box_vertices[i], &entity->transform.trans_mat); + if(transformed_vertex.x < derived_box->min.x) derived_box->min.x = transformed_vertex.x; + if(transformed_vertex.y < derived_box->min.y) derived_box->min.y = transformed_vertex.y; + if(transformed_vertex.z < derived_box->min.z) derived_box->min.z = transformed_vertex.z; + + if(transformed_vertex.x > derived_box->max.x) derived_box->max.x = transformed_vertex.x; + if(transformed_vertex.y > derived_box->max.y) derived_box->max.y = transformed_vertex.y; + if(transformed_vertex.z > derived_box->max.z) derived_box->max.z = transformed_vertex.z; + } +} + +void entity_bounding_box_reset(struct Entity* entity, bool update_derived) +{ + if(entity->type == ET_STATIC_MESH) + { + struct Static_Mesh* mesh = (struct Static_Mesh*)entity; + struct Geometry* geom = geom_get(mesh->model.geometry_index); + vec3_assign(&entity->bounding_box.min, &geom->bounding_box.min); + vec3_assign(&entity->bounding_box.max, &geom->bounding_box.max); + } + else + { + vec3_fill(&entity->bounding_box.min, -0.5f, -0.5f, -0.5f); + vec3_fill(&entity->bounding_box.max, 0.5f, 0.5f, 0.5f); + } + if(update_derived) entity_update_derived_bounding_box(entity); + +} + bool entity_write(struct Entity* entity, struct Parser_Object* object, bool write_transform) { if(!object) diff --git a/src/game/entity.h b/src/game/entity.h index fdf5fe7..84a53c5 100755 --- a/src/game/entity.h +++ b/src/game/entity.h @@ -58,6 +58,18 @@ enum Entity_Flags EF_IGNORE_RAYCAST = 1 << 6 }; +enum Entity_Ray_Mask +{ + ERM_NONE = 0, + ERM_DEFAULT = 1 << 0, + ERM_PLAYER = 1 << 1, + ERM_CAMERA = 1 << 2, + ERM_LIGHT = 1 << 3, + ERM_STATIC_MESH = 1 << 4, + ERM_SOUND_SOURCE = 1 << 5, + ERM_ALL = ERM_DEFAULT | ERM_PLAYER | ERM_CAMERA | ERM_LIGHT | ERM_STATIC_MESH | ERM_SOUND_SOURCE +}; + struct Transform { vec3 position; @@ -66,19 +78,20 @@ struct Transform mat4 trans_mat; bool is_modified; bool sync_physics; - struct Bounding_Box bounding_box; struct Entity* parent; struct Entity** children; }; struct Entity { - int id; - int type; - int archetype_index; - uchar flags; - char name[MAX_ENTITY_NAME_LEN]; - struct Transform transform; + int id; + int type; + int archetype_index; + uchar flags; + char name[MAX_ENTITY_NAME_LEN]; + struct Bounding_Box bounding_box; + struct Bounding_Box derived_bounding_box; + struct Transform transform; }; struct Model @@ -176,5 +189,7 @@ void entity_rigidbody_on_collision(Rigidbody body_A, Rigidbody body_B) void entity_rigidbody_set(struct Entity* entity, struct Collision* collision, Rigidbody body); void entity_collision_shape_set(struct Entity* entity, struct Collision* collision, Collision_Shape shape); // Only used for collision shapes like plane which can't have a rigidbody attached to collision shape void entity_rename(struct Entity* entity, const char* new_name); +void entity_update_derived_bounding_box(struct Entity* entity); +void entity_bounding_box_reset(struct Entity* entity, bool update_derived); #endif diff --git a/src/game/player.c b/src/game/player.c index 83d6cd9..5f7c282 100755 --- a/src/game/player.c +++ b/src/game/player.c @@ -141,15 +141,15 @@ void player_update(struct Player* player, struct Scene* scene, float dt) log_message("Ray: %.3f, %.3f, %.3f", ray.direction.x, ray.direction.y, ray.direction.z); struct Raycast_Result ray_result; - scene_ray_intersect(scene, &ray, &ray_result); + scene_ray_intersect(scene, &ray, &ray_result, ERM_ALL); } vec3 mesh_abs = { 0.f, 0.f, 0.f }; transform_get_absolute_position(player->mesh, &mesh_abs); debug_vars_show_vec3("Player Position", &player->base.transform.position); debug_vars_show_vec3("Mesh Position", &mesh_abs); - debug_vars_show_vec3("Min", &player->mesh->base.transform.bounding_box.min); - debug_vars_show_vec3("Max", &player->mesh->base.transform.bounding_box.max); + debug_vars_show_vec3("Min", &player->mesh->base.derived_bounding_box.min); + debug_vars_show_vec3("Max", &player->mesh->base.derived_bounding_box.max); struct Geometry* geom = geom_get(player->mesh->model.geometry_index); debug_vars_show_vec3("Geom Min", &geom->bounding_box.min); debug_vars_show_vec3("Geom Max", &geom->bounding_box.max); diff --git a/src/game/renderer.c b/src/game/renderer.c index ded3129..b050e79 100755 --- a/src/game/renderer.c +++ b/src/game/renderer.c @@ -257,7 +257,7 @@ void renderer_render(struct Renderer* renderer, struct Scene* scene) /* Check if model is in frustum */ - int intersection = bv_intersect_frustum_box(&camera->frustum, &mesh->base.transform.bounding_box); + int intersection = bv_intersect_frustum_box(&camera->frustum, &mesh->base.derived_bounding_box); if(intersection == IT_INSIDE || intersection == IT_INTERSECT) { renderer->num_indices += array_len(geometry->indices); diff --git a/src/game/scene.c b/src/game/scene.c index 3e39117..566047b 100755 --- a/src/game/scene.c +++ b/src/game/scene.c @@ -548,9 +548,9 @@ struct Static_Mesh* scene_static_mesh_create(struct Scene* scene, const char* na entity_init(&new_static_mesh->base, name, parent ? parent : &scene->root_entity); new_static_mesh->base.type = ET_STATIC_MESH; model_init(&new_static_mesh->model, new_static_mesh, geometry_name, material_type); - // 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); + vec3_assign(&new_static_mesh->base.bounding_box.min, &geom_get(new_static_mesh->model.geometry_index)->bounding_box.min); + vec3_assign(&new_static_mesh->base.bounding_box.max, &geom_get(new_static_mesh->model.geometry_index)->bounding_box.max); + entity_update_derived_bounding_box(new_static_mesh); } else { @@ -804,65 +804,161 @@ 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, struct Raycast_Result* out_results) +void scene_ray_intersect(struct Scene* scene, struct Ray* ray, struct Raycast_Result* out_results, int ray_mask) { assert(out_results); memset(&out_results[0], '\0', sizeof(struct Entity*) * MAX_RAYCAST_ENTITIES_INTERSECT); out_results->num_entities_intersected = 0; - for(int i = 0; i < MAX_STATIC_MESHES; i++) + for(int i = 0; i < ET_MAX; i++) { - struct Static_Mesh* mesh = &scene->static_meshes[i]; - if(!(mesh->base.flags & EF_ACTIVE) || (mesh->base.flags & EF_IGNORE_RAYCAST)) continue; - vec3 abs_pos = { 0.f, 0.f, 0.f }; - vec3 abs_scale = { 1.f, 1.f, 1.f }; - transform_get_absolute_position(mesh, &abs_pos); - transform_get_absolute_scale(mesh, &abs_scale); - - struct Geometry* geometry = geom_get(mesh->model.geometry_index); - if(bv_intersect_bounding_box_ray(&mesh->base.transform.bounding_box, ray) == IT_INTERSECT) + int max_length = 0; + size_t stride = 0; + struct Entity* entity = NULL; + + switch(i) { - out_results->entities_intersected[out_results->num_entities_intersected] = &mesh->base; - out_results->num_entities_intersected++; + case ET_DEFAULT: + if(!(ray_mask & ERM_DEFAULT)) continue; + max_length = MAX_ENTITIES; + entity = &scene->entities[0]; + stride = sizeof(struct Entity); + break; + case ET_LIGHT: + if(!(ray_mask & ERM_LIGHT)) continue; + max_length = MAX_LIGHTS; + entity = &scene->lights[0].base; + stride = sizeof(struct Light); + break; + case ET_STATIC_MESH: + if(!(ray_mask & ERM_STATIC_MESH)) continue; + max_length = MAX_STATIC_MESHES; + entity = &scene->static_meshes[0].base; + stride = sizeof(struct Static_Mesh); + break; + case ET_CAMERA: + if(!(ray_mask & ERM_CAMERA)) continue; + max_length = MAX_CAMERAS; + entity = &scene->cameras[0].base; + stride = sizeof(struct Camera); + break; + case ET_SOUND_SOURCE: + if(!(ray_mask & ERM_SOUND_SOURCE)) continue; + max_length = MAX_SOUND_SOURCES; + entity = &scene->sound_sources[0].base; + stride = sizeof(struct Sound_Source); + break; + case ET_PLAYER: + if(!(ray_mask & ERM_PLAYER)) continue; + max_length = 1; + entity = &scene->player; + stride = sizeof(struct Player); + break; + default: continue; + } + + size_t count = 0; + while(count < max_length) + { + if(entity->flags & EF_ACTIVE && !(entity->flags & EF_IGNORE_RAYCAST)) + { + int result = bv_intersect_bounding_box_ray(&entity->derived_bounding_box, ray); + if(result == IT_INTERSECT || result == IT_INSIDE) + { + out_results->entities_intersected[out_results->num_entities_intersected] = &entity; + out_results->num_entities_intersected++; + } + } + + count++; + ((char*)entity) += stride; } } } -struct Entity* scene_ray_intersect_closest(struct Scene* scene, struct Ray* ray) +struct Entity* scene_ray_intersect_closest(struct Scene* scene, struct Ray* ray, int ray_mask) { struct Entity* closest = NULL; float current_closest = 0.f; - for(int i = 0; i < MAX_STATIC_MESHES; i++) + for(int i = 0; i < ET_MAX; i++) { - struct Static_Mesh* mesh = &scene->static_meshes[i]; - if(!(mesh->base.flags & EF_ACTIVE) || (mesh->base.flags & EF_IGNORE_RAYCAST)) continue; - vec3 abs_pos = { 0.f, 0.f, 0.f }; - vec3 abs_scale = { 1.f, 1.f, 1.f }; - transform_get_absolute_position(mesh, &abs_pos); - transform_get_absolute_scale(mesh, &abs_scale); - - struct Geometry* geometry = geom_get(mesh->model.geometry_index); - float distance = bv_distance_ray_bounding_box(ray, &mesh->base.transform.bounding_box); - if(distance != INFINITY && distance >= 0.f) + int max_length = 0; + size_t stride = 0; + struct Entity* entity = NULL; + + switch(i) + { + case ET_DEFAULT: + if(!(ray_mask & ERM_DEFAULT)) continue; + max_length = MAX_ENTITIES; + entity = &scene->entities[0]; + stride = sizeof(struct Entity); + break; + case ET_LIGHT: + if(!(ray_mask & ERM_LIGHT)) continue; + max_length = MAX_LIGHTS; + entity = &scene->lights[0].base; + stride = sizeof(struct Light); + break; + case ET_STATIC_MESH: + if(!(ray_mask & ERM_STATIC_MESH)) continue; + max_length = MAX_STATIC_MESHES; + entity = &scene->static_meshes[0].base; + stride = sizeof(struct Static_Mesh); + break; + case ET_CAMERA: + if(!(ray_mask & ERM_CAMERA)) continue; + max_length = MAX_CAMERAS; + entity = &scene->cameras[0].base; + stride = sizeof(struct Camera); + break; + case ET_SOUND_SOURCE: + if(!(ray_mask & ERM_SOUND_SOURCE)) continue; + max_length = MAX_SOUND_SOURCES; + entity = &scene->sound_sources[0].base; + stride = sizeof(struct Sound_Source); + break; + case ET_PLAYER: + if(!(ray_mask & ERM_PLAYER)) continue; + max_length = 1; + entity = &scene->player; + stride = sizeof(struct Player); + break; + default: continue; + } + + size_t count = 0; + while(count < max_length) { - bool assign = false; - if(closest == NULL) - assign = true; - else if(distance > current_closest && - bv_intersect_bounding_box_ray(&mesh->base.transform.bounding_box, ray) == IT_INSIDE && - bv_intersect_bounding_boxes(&mesh->base.transform.bounding_box, &closest->transform.bounding_box) != IT_INSIDE) - assign = true; - else if(distance < current_closest) - assign = true; - - if(assign) + if(entity->flags & EF_ACTIVE && !(entity->flags & EF_IGNORE_RAYCAST)) { - current_closest = distance; - closest = &mesh->base; + float distance = bv_distance_ray_bounding_box(ray, &entity->derived_bounding_box); + if(distance != INFINITY && distance >= 0.f) + { + bool assign = false; + if(closest == NULL) + assign = true; + else if(distance > current_closest&& + bv_intersect_bounding_box_ray(&entity->derived_bounding_box, ray) == IT_INSIDE && + bv_intersect_bounding_boxes(&entity->derived_bounding_box, &closest->derived_bounding_box) != IT_INSIDE) + assign = true; + else if(distance < current_closest) + assign = true; + + if(assign) + { + current_closest = distance; + closest = entity; + } + } } + + count++; + ((char*)entity) += stride; } } + return closest; } diff --git a/src/game/scene.h b/src/game/scene.h index 35c8433..cef4f88 100755 --- a/src/game/scene.h +++ b/src/game/scene.h @@ -60,24 +60,8 @@ void scene_entity_parent_set(struct Scene* scene, struct Entity* entity, struct void scene_entity_parent_reset(struct Scene* scene, struct Entity* entity); // Sets root entity as parent int scene_entity_archetype_add(struct Scene* scene, const char* filename); -void scene_ray_intersect(struct Scene* scene, struct Ray* ray, struct Raycast_Result* out_results); -struct Entity* scene_ray_intersect_closest(struct Scene* scene, struct Ray* ray); +void scene_ray_intersect(struct Scene* scene, struct Ray* ray, struct Raycast_Result* out_results, int ray_mask); +struct Entity* scene_ray_intersect_closest(struct Scene* scene, struct Ray* ray, int ray_mask); float scene_entity_distance(struct Scene* scene, struct Entity* entity1, struct Entity* entity2); -// -//void scene_init(void); -//void scene_remove(struct Entity* entity); -//void scene_reset_parent(struct Entity* entity, struct Entity* new_parent); -//void scene_cleanup(void); -//struct Entity* scene_add_new(const char* name, const int type); /* Add as child of Root */ -//struct Entity* scene_add_as_child(const char* name, const int type, int parent); -//struct Entity* scene_find(const char* name); -//struct Entity* scene_get_root(void); -//void scene_root_set(struct Entity* entity); -//struct Entity* scene_get_child_by_name(struct Entity* parent, const char* name); -//struct Entity* scene_get_parent(struct Entity* entity); -//bool scene_load(const char* filename, int directory_type); -//bool scene_save(const char* filename, int directory_type); - - #endif diff --git a/src/game/transform.c b/src/game/transform.c index 1da45f9..c1ebc92 100755 --- a/src/game/transform.c +++ b/src/game/transform.c @@ -18,45 +18,12 @@ void transform_init(struct Entity* entity, struct Entity* parent) vec3_fill(&transform->scale, 1.f, 1.f, 1.f); quat_identity(&transform->rotation); 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->parent = NULL; if(parent) transform_parent_set(entity, parent, false); transform_update_transmat(entity); -} - -void transform_update_bounding_box(struct Entity* entity) -{ - struct Bounding_Box* box = &entity->transform.bounding_box; - vec3_fill(&box->min, FLT_MAX, FLT_MAX, FLT_MAX); - vec3_fill(&box->max, -FLT_MAX, -FLT_MAX, -FLT_MAX); - vec3 box_vertices[8]; - if(entity->type == ET_STATIC_MESH) - { - struct Static_Mesh* mesh = (struct Static_Mesh*)entity; - struct Geometry* geometry = geom_get(mesh->model.geometry_index); - bv_bounding_box_vertices_get(&geometry->bounding_box, box_vertices); - } - else - { - bv_bounding_box_vertices_get(box, box_vertices); - } - - for(int i = 0; i < 8; i++) - { - vec3 transformed_vertex = { 0.f, 0.f, 0.f }; - vec3_mul_mat4(&transformed_vertex, &box_vertices[i], &entity->transform.trans_mat); - if(transformed_vertex.x < box->min.x) box->min.x = transformed_vertex.x; - if(transformed_vertex.y < box->min.y) box->min.y = transformed_vertex.y; - if(transformed_vertex.z < box->min.z) box->min.z = transformed_vertex.z; - - if(transformed_vertex.x > box->max.x) box->max.x = transformed_vertex.x; - if(transformed_vertex.y > box->max.y) box->max.y = transformed_vertex.y; - if(transformed_vertex.z > box->max.z) box->max.z = transformed_vertex.z; - } -} +} void transform_child_add(struct Entity* parent, struct Entity* child, bool update_transmat) { @@ -262,7 +229,7 @@ void transform_update_transmat(struct Entity* entity) mat4_mul(&transform->trans_mat, &parent_tran->trans_mat, &transform->trans_mat); } - transform_update_bounding_box(entity); + entity_update_derived_bounding_box(entity); /* Update all children */ int children = array_len(transform->children); diff --git a/src/game/transform.h b/src/game/transform.h index 95f8d0a..8b53e72 100755 --- a/src/game/transform.h +++ b/src/game/transform.h @@ -34,6 +34,5 @@ void transform_child_add(struct Entity* entity, struct Entity* child, bool updat 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_copy(struct Entity* copy_to, struct Entity* copy_from, bool copy_parent); -void transform_update_bounding_box(struct Entity* entity); #endif diff --git a/todo.txt b/todo.txt index cfe8956..884826b 100644 --- a/todo.txt +++ b/todo.txt @@ -1,8 +1,7 @@ Todo: - - Fix camera frustum creation/update - - Imlpement picking entities of all types in editor + - Save/Load base bounding boxes for entity types other than static mesh - Determine whether we should enable or disble picking when a tool is active within an editor - ? Only show bounding box for hovered entity + ? Only show bounding box for hovered entity instead of wireframe mesh - Fix crash where if an entity is hoverd in editor and deleted, the game crashes because the hovered variable in editor doesn't know that the entity was deleted ? 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? @@ -139,6 +138,7 @@ Bugs: - Fix crash if player's mesh is deleted in editor - Fix camera not rotating if the cursor overlaps any ui element - Fix hierarchichal transformations in the editor when the entity being transformed is a child entity of another entity + - Fix camera frustum creation/update Done: * Input @@ -397,4 +397,6 @@ Done: * Save transformation information when saving entity archetypes * Implement bounding box visualization * Fixed rotation gizmo for scaled meshes - * Implement ray-bounding box picking and determine whether that is enough for our needs or do we need to implement OBB \ No newline at end of file + * Implemented ray-bounding box picking and determine whether that is enough for our needs or do we need to implement OBB + * Implemented base and derived bounding boxes for all entity types + * Imlpemented picking entities of all types in editor \ No newline at end of file