From 4a2b6e723c60092fbef25d6e9003cc07bca9f2ae Mon Sep 17 00:00:00 2001 From: Shariq Shah Date: Tue, 15 May 2018 01:37:31 +1000 Subject: [PATCH] Improved editor camera handling and reimplemented showing current entities in the editor --- README.md | 3 + src/libsymmetry/camera.c | 1 + src/libsymmetry/editor.c | 642 ++++++++++++++++++------------------ src/libsymmetry/entity.c | 10 +- src/libsymmetry/entity.h | 3 +- src/libsymmetry/game.c | 104 +----- src/libsymmetry/scene.c | 28 +- src/libsymmetry/scene.h | 1 + src/libsymmetry/transform.c | 2 +- 9 files changed, 365 insertions(+), 429 deletions(-) diff --git a/README.md b/README.md index a0671e9..346a890 100644 --- a/README.md +++ b/README.md @@ -156,6 +156,7 @@ - ## TODO - Remove model and replace all usages with static mesh + - Get editor camera speed and other settings from config file - Re-Implement player logic - Re-Implement saving/loading scene to/from files - Bring back functionality and complete overhaul @@ -394,3 +395,5 @@ * Converted IM_Vertex array to only be used as temporary storage for vertices between begin and end calls * Implemented Debug physics mesh drawing for box and sphere primitives * Completed Phase 1 of codebase refactoring + * Improved editor camera handling + * Re-implemented showing all the entities in the editor diff --git a/src/libsymmetry/camera.c b/src/libsymmetry/camera.c index 44ce2e3..56c8a6d 100644 --- a/src/libsymmetry/camera.c +++ b/src/libsymmetry/camera.c @@ -37,6 +37,7 @@ void camera_reset(struct Camera* camera) void camera_init(struct Camera* camera, int width, int height) { + camera->base.type = ET_CAMERA; camera->fbo = -1; camera->render_tex = -1; camera->depth_tex = -1; diff --git a/src/libsymmetry/editor.c b/src/libsymmetry/editor.c index 042522e..1292770 100644 --- a/src/libsymmetry/editor.c +++ b/src/libsymmetry/editor.c @@ -32,13 +32,13 @@ struct Editor_State { - bool enabled; - bool renderer_settings_window; - int selected_entity_id; - int top_panel_height; - float camera_turn_speed; - float camera_move_speed; - float camera_sprint_multiplier; + bool enabled; + bool renderer_settings_window; + struct Entity* selected_entity; + int top_panel_height; + float camera_turn_speed; + float camera_move_speed; + float camera_sprint_multiplier; }; struct Debug_Variable @@ -52,6 +52,7 @@ static struct Debug_Variable* debug_vars_list = NULL; static int* empty_indices = NULL; static void editor_camera_update(float dt); +static void editor_show_entity_in_list(struct nk_context* context, struct Scene* scene, struct Entity* entity); static void editor_widget_color_combov3(struct nk_context* context, vec3* color, int width, int height); static void editor_widget_color_combov4(struct nk_context* context, vec4* color, int width, int height); static bool editor_widget_v3(struct nk_context* context, @@ -69,30 +70,27 @@ void editor_init(void) { editor_state.enabled = true; editor_state.renderer_settings_window = false; - editor_state.selected_entity_id = -1; + editor_state.selected_entity = NULL; editor_state.top_panel_height = 20; editor_state.camera_turn_speed = 50.f; - editor_state.camera_move_speed = 10.f; + editor_state.camera_move_speed = 20.f; editor_state.camera_sprint_multiplier = 2.f; debug_vars_list = array_new(struct Debug_Variable); empty_indices = array_new(int); - struct Camera* editor_camera = &game_state_get()->scene->cameras[CAM_EDITOR]; - editor_camera->base.active = true; - vec3 cam_pos = {0.f, 15.f, -5.f}; - transform_translate(editor_camera, &cam_pos, TS_WORLD); - editor_camera->clear_color.x = 0.3f; - editor_camera->clear_color.y = 0.6f; - editor_camera->clear_color.z = 0.9f; - editor_camera->clear_color.w = 1.f; - - struct Hashmap* config = platform->config.get(); - int render_width = hashmap_int_get(config, "render_width"); - int render_height = hashmap_int_get(config, "render_height"); - camera_attach_fbo(editor_camera, render_width, render_height, true, true, true); - - vec3 axis = {1.f, 0.f, 0.f}; - transform_rotate(editor_camera, &axis, -25.f, TS_WORLD); + struct Camera* editor_camera = &game_state_get()->scene->cameras[CAM_EDITOR]; + entity_rename(editor_camera, "Editor_Camera"); + editor_camera->base.active = true; + editor_camera->clear_color.x = 0.3f; + editor_camera->clear_color.y = 0.6f; + editor_camera->clear_color.z = 0.9f; + editor_camera->clear_color.w = 1.f; + + + struct Hashmap* config = platform->config.get(); + int render_width = hashmap_int_get(config, "render_width"); + int render_height = hashmap_int_get(config, "render_height"); + camera_attach_fbo(editor_camera, render_width, render_height, true, true, true); } int editor_debugvar_slot_create(const char* name, int value_type) @@ -227,36 +225,20 @@ void editor_update(float dt) if(nk_group_begin(context, "Editor Left", NK_WINDOW_SCROLL_AUTO_HIDE)) { /* Entities List */ + struct Scene* scene = game_state_get()->scene; if(nk_tree_push(context, NK_TREE_TAB, "Entities", NK_MAXIMIZED)) { - /*nk_layout_row_dynamic(context, 250, 1); + nk_layout_row_dynamic(context, 250, 1); if(nk_group_begin(context, "Entity Name", NK_WINDOW_SCROLL_AUTO_HIDE)) { - struct Entity* entity_list = entity_get_all(); - for(int i = 0; i < array_len(entity_list); i++) - { - struct Entity* entity = &entity_list[i]; - nk_layout_row_dynamic(context, 20, 1); - if(nk_selectable_label(context, entity->name, NK_TEXT_ALIGN_LEFT, &entity->editor_selected)) - { - if(editor_state.selected_entity_id != -1) - { - struct Entity* currently_selected = entity_get(editor_state.selected_entity_id); - currently_selected->editor_selected = false; - } - - if(entity->editor_selected) - { - editor_state.selected_entity_id = entity->id; - } - else - { - editor_state.selected_entity_id = -1; - } - } - } + + for(int i = 0; i < MAX_ENTITIES; i++) editor_show_entity_in_list(context, scene, &scene->entities[i]); + for(int i = 0; i < MAX_CAMERAS; i++) editor_show_entity_in_list(context, scene, &scene->cameras[i]); + for(int i = 0; i < MAX_LIGHTS; i++) editor_show_entity_in_list(context, scene, &scene->lights[i]); + for(int i = 0; i < MAX_STATIC_MESHES; i++) editor_show_entity_in_list(context, scene, &scene->static_meshes[i]); + nk_group_end(context); - }*/ + } nk_tree_pop(context); } @@ -292,186 +274,185 @@ void editor_update(float dt) if(nk_group_begin(context, "Editor Right", NK_WINDOW_NO_SCROLLBAR)) { /* Entity Inspector */ - //if(nk_tree_push(context, NK_TREE_TAB, "Inspector", NK_MAXIMIZED)) - //{ - // const int row_height = 18; - // if(editor_state.selected_entity_id != -1) - // { - // struct Entity* entity = entity_get(editor_state.selected_entity_id); - // nk_layout_row_dynamic(context, row_height, 2); - // nk_label(context, "Name", NK_TEXT_ALIGN_LEFT); nk_label(context, entity->name, NK_TEXT_ALIGN_RIGHT); - // nk_layout_row_dynamic(context, row_height, 2); - // nk_label(context, "ID", NK_TEXT_ALIGN_LEFT); nk_labelf(context, NK_TEXT_ALIGN_RIGHT, "%d", entity->id); - // nk_layout_row_dynamic(context, row_height, 2); - // nk_label(context, "Entity Type", NK_TEXT_ALIGN_LEFT); nk_labelf(context, NK_TEXT_ALIGN_RIGHT, "%s", entity_type_name_get(entity)); - // nk_layout_row_dynamic(context, row_height, 2); - // struct Entity* parent_ent = entity_get(entity->transform.parent); - // nk_label(context, "Parent Name", NK_TEXT_ALIGN_LEFT); nk_label(context, parent_ent ? parent_ent->name : "NONE", NK_TEXT_ALIGN_RIGHT); - - // /* Transform */ - // { - // nk_layout_row_dynamic(context, row_height, 1); nk_label(context, "Position", NK_TEXT_ALIGN_CENTERED); - // vec3 abs_pos = {0.f, 0.f, 0.f}; - // transform_get_absolute_position(entity, &abs_pos); - // if(editor_widget_v3(context, &abs_pos, "Px", "Py", "Pz", -FLT_MAX, FLT_MAX, 5.f, 1.f, row_height)) transform_set_position(entity, &abs_pos); - - // nk_layout_row_dynamic(context, row_height, 1); nk_label(context, "Rotation", NK_TEXT_ALIGN_CENTERED); - // quat abs_rot = {0.f, 0.f, 0.f, 1.f}; - // transform_get_absolute_rot(entity, &abs_rot); - // vec3 rot_angles = {0.f, 0.f, 0.f}; - // rot_angles.x = TO_DEGREES(quat_get_pitch(&abs_rot)); - // rot_angles.y = TO_DEGREES(quat_get_yaw(&abs_rot)); - // rot_angles.z = TO_DEGREES(quat_get_roll(&abs_rot)); - // vec3 curr_rot = {rot_angles.x, rot_angles.y, rot_angles.z}; - - // nk_layout_row_dynamic(context, row_height, 1); nk_property_float(context, "Rx", -FLT_MAX, &curr_rot.x, FLT_MAX, 5.f, 1.f); - // nk_layout_row_dynamic(context, row_height, 1); nk_property_float(context, "Ry", -FLT_MAX, &curr_rot.y, FLT_MAX, 5.f, 1.f); - // nk_layout_row_dynamic(context, row_height, 1); nk_property_float(context, "Rz", -FLT_MAX, &curr_rot.z, FLT_MAX, 5.f, 1.f); - - // vec3 delta = {0.f, 0.f, 0.f}; - // vec3_sub(&delta, &rot_angles, &curr_rot); - - // vec3 AXIS_X = {1.f, 0.f, 0.f}; - // vec3 AXIS_Y = {0.f, 1.f, 0.f}; - // vec3 AXIS_Z = {0.f, 0.f, 1.f}; - - // const float epsilon = 0.0001f; - // if(fabsf(delta.x) > epsilon) transform_rotate(entity, &AXIS_X, delta.x, TS_WORLD); - // if(fabsf(delta.y) > epsilon) transform_rotate(entity, &AXIS_Y, delta.y, TS_WORLD); - // if(fabsf(delta.z) > epsilon) transform_rotate(entity, &AXIS_Z, delta.z, TS_WORLD); - - // nk_layout_row_dynamic(context, row_height, 1); nk_label(context, "Scale", NK_TEXT_ALIGN_CENTERED); - // vec3 abs_scale = {0.f, 0.f, 0.f}; - // transform_get_absolute_scale(entity, &abs_scale); - // if(editor_widget_v3(context, &abs_scale, "SX", "SY", "SZ", 0.1f, FLT_MAX, 1.f, 0.1f, row_height)) - // { - // entity->transform.scale = abs_scale; - // transform_update_transmat(entity); - // } - // } - - // /* Light */ - // if(entity->type == ET_LIGHT) - // { - // if(nk_tree_push(context, NK_TREE_TAB, "Light", NK_MAXIMIZED)) - // { - // struct Light* light = &entity->light; - // if(light->type > LT_POINT) - // { - // nk_layout_row_dynamic(context, row_height, 1); - // nk_label(context, "Invalid light type!", NK_TEXT_ALIGN_CENTERED); - // } - // else - // { - // static const char* light_types[] = {"Spot", "Directional", "Point"}; - // float combo_width = nk_widget_width(context), combo_height = row_height * (LT_MAX); - // - // nk_layout_row_dynamic(context, row_height, 2); - // nk_label(context, "Light Type", NK_TEXT_ALIGN_LEFT); - // nk_combobox(context, light_types, LT_MAX - 1, &light->type, row_height, nk_vec2(combo_width, combo_height)); - // - // nk_layout_row_dynamic(context, row_height, 1); nk_label(context, "Light Color", NK_TEXT_ALIGN_CENTERED); - // nk_layout_row_dynamic(context, row_height, 1); - // editor_widget_color_combov3(context, &light->color, 200, 300); - - // nk_layout_row_dynamic(context, row_height, 1); - // nk_property_float(context, "Intensity", 0.f, &light->intensity, 100.f, 0.1f, 0.05f); - - // if(light->type != LT_DIR) - // { - // nk_layout_row_dynamic(context, row_height, 1); - // light->outer_angle = TO_RADIANS(nk_propertyf(context, "Outer Angle", TO_DEGREES(light->inner_angle), TO_DEGREES(light->outer_angle), 360, 1.f, 0.5f)); - - // nk_layout_row_dynamic(context, row_height, 1); - // light->inner_angle = TO_RADIANS(nk_propertyf(context, "Inner Angle", 1.f, TO_DEGREES(light->inner_angle), TO_DEGREES(light->outer_angle), 1.f, 0.5f)); - - // nk_layout_row_dynamic(context, row_height, 1); - // nk_property_int(context, "Radius", 1, &light->radius, INT_MAX, 1, 1); - - // nk_layout_row_dynamic(context, row_height, 1); - // nk_property_float(context, "Falloff", 0.f, &light->falloff, 100.f, 0.1f, 0.05f); - // } - // } - // nk_tree_pop(context); - // } - // } - - // /* Camera */ - // if(entity->type == ET_CAMERA) - // { - // if(nk_tree_push(context, NK_TREE_TAB, "Camera", NK_MAXIMIZED)) - // { - // bool update = false; - // struct Camera* camera = &entity->camera; - // - // nk_layout_row_dynamic(context, row_height, 2); - // nk_label(context, "Orthographic", NK_TEXT_ALIGN_LEFT | NK_TEXT_ALIGN_MIDDLE); - // bool ortho = nk_checkbox_label(context, "", &camera->ortho); - // if(ortho != camera->ortho) - // { - // update = true; - // } - // - - // if(!camera->ortho) - // { - // nk_layout_row_dynamic(context, row_height, 1); - // float new_fov = nk_propertyf(context, "Fov", 30.f, camera->fov, 90.f, 0.1f, 1.f); - // if(new_fov != camera->fov) - // { - // camera->fov = new_fov; - // update = true; - // } - - // nk_layout_row_dynamic(context, row_height, 2); - // nk_label(context, "Aspect Ratio", NK_TEXT_ALIGN_LEFT); nk_labelf(context, NK_TEXT_ALIGN_RIGHT, "%.5f", camera->aspect_ratio); - // } - - // nk_layout_row_dynamic(context, row_height, 1); nk_label(context, "Clear Color", NK_TEXT_ALIGN_CENTERED); - // nk_layout_row_dynamic(context, row_height, 1); - // editor_widget_color_combov4(context, &camera->clear_color, 200, 300); - - // nk_layout_row_dynamic(context, row_height, 1); - // float new_zoom = nk_propertyf(context, "Zoom", 1.f, camera->zoom, FLT_MAX, 0.1f, 1.f); - // if(new_zoom != camera->zoom) - // { - // camera->zoom = new_zoom; - // update = true; - // } - - // nk_layout_row_dynamic(context, row_height, 1); - // float new_near_z = nk_propertyf(context, "NearZ", -FLT_MAX, camera->nearz, camera->farz, 0.1f, 1.f); - // if(new_near_z != camera->nearz) - // { - // camera->nearz = new_near_z; - // update = true; - // } - // - // nk_layout_row_dynamic(context, row_height, 1); - // float new_far_z = nk_propertyf(context, "FarZ", camera->nearz, camera->farz, FLT_MAX, 0.1f, 2.f); - // if(new_far_z != camera->farz) - // { - // camera->farz = new_far_z; - // update = true; - // } - - // if(update) - // { - // camera_update_view(entity); - // camera_update_proj(entity); - // } - - // nk_tree_pop(context); - // } - // } - // } - // else - // { - // nk_label(context, "No Entity Selected", NK_TEXT_ALIGN_CENTERED); - // } - // nk_tree_pop(context); - //} - // + if(nk_tree_push(context, NK_TREE_TAB, "Inspector", NK_MAXIMIZED)) + { + const int row_height = 18; + if(editor_state.selected_entity) + { + struct Scene* scene = game_state_get()->scene; + struct Entity* entity = editor_state.selected_entity; + + struct Entity* parent_ent = entity->transform.parent; + nk_layout_row_dynamic(context, row_height, 2); nk_label(context, "Name", NK_TEXT_ALIGN_LEFT); nk_label(context, entity->name, NK_TEXT_ALIGN_RIGHT); + nk_layout_row_dynamic(context, row_height, 2); nk_label(context, "ID", NK_TEXT_ALIGN_LEFT); nk_labelf(context, NK_TEXT_ALIGN_RIGHT, "%d", entity->id); + nk_layout_row_dynamic(context, row_height, 2); nk_label(context, "Selected", NK_TEXT_ALIGN_LEFT); nk_labelf(context, NK_TEXT_ALIGN_RIGHT, "%s", entity->editor_selected ? "True" : "False"); + nk_layout_row_dynamic(context, row_height, 2); nk_label(context, "Entity Type", NK_TEXT_ALIGN_LEFT); nk_labelf(context, NK_TEXT_ALIGN_RIGHT, "%s", entity_type_name_get(entity)); + nk_layout_row_dynamic(context, row_height, 2); nk_label(context, "Parent Name", NK_TEXT_ALIGN_LEFT); nk_label(context, parent_ent ? parent_ent->name : "NONE", NK_TEXT_ALIGN_RIGHT); + + /* Transform */ + { + nk_layout_row_dynamic(context, row_height, 1); nk_label(context, "Position", NK_TEXT_ALIGN_CENTERED); + vec3 abs_pos = {0.f, 0.f, 0.f}; + transform_get_absolute_position(entity, &abs_pos); + if(editor_widget_v3(context, &abs_pos, "Px", "Py", "Pz", -FLT_MAX, FLT_MAX, 5.f, 1.f, row_height)) transform_set_position(entity, &abs_pos); + + nk_layout_row_dynamic(context, row_height, 1); nk_label(context, "Rotation", NK_TEXT_ALIGN_CENTERED); + quat abs_rot = {0.f, 0.f, 0.f, 1.f}; + transform_get_absolute_rot(entity, &abs_rot); + vec3 rot_angles = {0.f, 0.f, 0.f}; + rot_angles.x = TO_DEGREES(quat_get_pitch(&abs_rot)); + rot_angles.y = TO_DEGREES(quat_get_yaw(&abs_rot)); + rot_angles.z = TO_DEGREES(quat_get_roll(&abs_rot)); + vec3 curr_rot = {rot_angles.x, rot_angles.y, rot_angles.z}; + + nk_layout_row_dynamic(context, row_height, 1); nk_property_float(context, "Rx", -FLT_MAX, &curr_rot.x, FLT_MAX, 5.f, 1.f); + nk_layout_row_dynamic(context, row_height, 1); nk_property_float(context, "Ry", -FLT_MAX, &curr_rot.y, FLT_MAX, 5.f, 1.f); + nk_layout_row_dynamic(context, row_height, 1); nk_property_float(context, "Rz", -FLT_MAX, &curr_rot.z, FLT_MAX, 5.f, 1.f); + + vec3 delta = {0.f, 0.f, 0.f}; + vec3_sub(&delta, &rot_angles, &curr_rot); + + vec3 AXIS_X = {1.f, 0.f, 0.f}; + vec3 AXIS_Y = {0.f, 1.f, 0.f}; + vec3 AXIS_Z = {0.f, 0.f, 1.f}; + + const float epsilon = 0.0001f; + if(fabsf(delta.x) > epsilon) transform_rotate(entity, &AXIS_X, delta.x, TS_WORLD); + if(fabsf(delta.y) > epsilon) transform_rotate(entity, &AXIS_Y, delta.y, TS_WORLD); + if(fabsf(delta.z) > epsilon) transform_rotate(entity, &AXIS_Z, delta.z, TS_WORLD); + + nk_layout_row_dynamic(context, row_height, 1); nk_label(context, "Scale", NK_TEXT_ALIGN_CENTERED); + vec3 abs_scale = {0.f, 0.f, 0.f}; + transform_get_absolute_scale(entity, &abs_scale); + if(editor_widget_v3(context, &abs_scale, "SX", "SY", "SZ", 0.1f, FLT_MAX, 1.f, 0.1f, row_height)) + { + entity->transform.scale = abs_scale; + transform_update_transmat(entity); + } + } + + /* Light */ + if(entity->type == ET_LIGHT) + { + if(nk_tree_push(context, NK_TREE_TAB, "Light", NK_MAXIMIZED)) + { + struct Light* light = (struct Light*)entity; + if(light->type > LT_POINT) + { + nk_layout_row_dynamic(context, row_height, 1); + nk_label(context, "Invalid light type!", NK_TEXT_ALIGN_CENTERED); + } + else + { + static const char* light_types[] = {"Spot", "Directional", "Point"}; + float combo_width = nk_widget_width(context), combo_height = row_height * (LT_MAX); + + nk_layout_row_dynamic(context, row_height, 2); + nk_label(context, "Light Type", NK_TEXT_ALIGN_LEFT); + nk_combobox(context, light_types, LT_MAX - 1, &light->type, row_height, nk_vec2(combo_width, combo_height)); + + nk_layout_row_dynamic(context, row_height, 1); nk_label(context, "Light Color", NK_TEXT_ALIGN_CENTERED); + nk_layout_row_dynamic(context, row_height, 1); + editor_widget_color_combov3(context, &light->color, 200, 300); + + nk_layout_row_dynamic(context, row_height, 1); + nk_property_float(context, "Intensity", 0.f, &light->intensity, 100.f, 0.1f, 0.05f); + + if(light->type != LT_DIR) + { + nk_layout_row_dynamic(context, row_height, 1); + light->outer_angle = TO_RADIANS(nk_propertyf(context, "Outer Angle", TO_DEGREES(light->inner_angle), TO_DEGREES(light->outer_angle), 360, 1.f, 0.5f)); + + nk_layout_row_dynamic(context, row_height, 1); + light->inner_angle = TO_RADIANS(nk_propertyf(context, "Inner Angle", 1.f, TO_DEGREES(light->inner_angle), TO_DEGREES(light->outer_angle), 1.f, 0.5f)); + + nk_layout_row_dynamic(context, row_height, 1); + nk_property_int(context, "Radius", 1, &light->radius, INT_MAX, 1, 1); + + nk_layout_row_dynamic(context, row_height, 1); + nk_property_float(context, "Falloff", 0.f, &light->falloff, 100.f, 0.1f, 0.05f); + } + } + nk_tree_pop(context); + } + } + + /* Camera */ + if(entity->type == ET_CAMERA) + { + if(nk_tree_push(context, NK_TREE_TAB, "Camera", NK_MAXIMIZED)) + { + bool update = false; + struct Camera* camera = (struct Camera*)entity; + + nk_layout_row_dynamic(context, row_height, 2); + nk_label(context, "Orthographic", NK_TEXT_ALIGN_LEFT | NK_TEXT_ALIGN_MIDDLE); + bool ortho = nk_checkbox_label(context, "", &camera->ortho); + if(ortho != camera->ortho) + { + update = true; + } + + + if(!camera->ortho) + { + nk_layout_row_dynamic(context, row_height, 1); + float new_fov = nk_propertyf(context, "Fov", 30.f, camera->fov, 90.f, 0.1f, 1.f); + if(new_fov != camera->fov) + { + camera->fov = new_fov; + update = true; + } + + nk_layout_row_dynamic(context, row_height, 2); + nk_label(context, "Aspect Ratio", NK_TEXT_ALIGN_LEFT); nk_labelf(context, NK_TEXT_ALIGN_RIGHT, "%.5f", camera->aspect_ratio); + } + + nk_layout_row_dynamic(context, row_height, 1); nk_label(context, "Clear Color", NK_TEXT_ALIGN_CENTERED); + nk_layout_row_dynamic(context, row_height, 1); + editor_widget_color_combov4(context, &camera->clear_color, 200, 300); + + nk_layout_row_dynamic(context, row_height, 1); + float new_zoom = nk_propertyf(context, "Zoom", 1.f, camera->zoom, FLT_MAX, 0.1f, 1.f); + if(new_zoom != camera->zoom) + { + camera->zoom = new_zoom; + update = true; + } + + nk_layout_row_dynamic(context, row_height, 1); + float new_near_z = nk_propertyf(context, "NearZ", -FLT_MAX, camera->nearz, camera->farz, 0.1f, 1.f); + if(new_near_z != camera->nearz) + { + camera->nearz = new_near_z; + update = true; + } + + nk_layout_row_dynamic(context, row_height, 1); + float new_far_z = nk_propertyf(context, "FarZ", camera->nearz, camera->farz, FLT_MAX, 0.1f, 2.f); + if(new_far_z != camera->farz) + { + camera->farz = new_far_z; + update = true; + } + + if(update) + { + camera_update_view(entity); + camera_update_proj(entity); + } + + nk_tree_pop(context); + } + } + } + else + { + nk_label(context, "No Entity Selected", NK_TEXT_ALIGN_CENTERED); + } + nk_tree_pop(context); + } + nk_group_end(context); } } @@ -566,101 +547,87 @@ void editor_toggle(void) editor_state.enabled = !editor_state.enabled; } -void editor_camera_update(float dt) -{ - struct Camera* editor_camera = &game_state_get()->scene->cameras[CAM_EDITOR]; - float move_speed = editor_state.camera_move_speed, turn_speed = editor_state.camera_turn_speed; - vec3 offset = {0, 0, 0}; - float turn_up_down = 0.f; - float turn_left_right = 0.f; - float max_up_down = 60.f; - static float total_up_down_rot = 0.f; - vec3 rot_axis_up_down = {1, 0, 0}; - vec3 rot_axis_left_right = {0, 1, 0}; - - /* Look around */ - if(input_map_state_get("Turn_Up", KS_PRESSED)) turn_up_down += turn_speed; - if(input_map_state_get("Turn_Down", KS_PRESSED)) turn_up_down -= turn_speed; - if(input_map_state_get("Turn_Right", KS_PRESSED)) turn_left_right += turn_speed; - if(input_map_state_get("Turn_Left", KS_PRESSED)) turn_left_right -= turn_speed; - - if(input_mousebutton_state_get(MSB_RIGHT, KS_PRESSED)) - { - const float scale = 0.1f; - int cursor_lr, cursor_ud; - input_mouse_delta_get(&cursor_lr, &cursor_ud); - if(input_mouse_mode_get() != MM_RELATIVE) - { - input_mouse_mode_set(MM_RELATIVE); - cursor_lr = cursor_ud = 0; - } - - turn_up_down = -cursor_ud * turn_speed * dt * scale; - turn_left_right = cursor_lr * turn_speed * dt * scale; - // log_message("ud : %d, lr : %d", cursor_ud, cursor_lr); - } - else - { - input_mouse_mode_set(MM_NORMAL); - // log_message("ud : %.3f, lr : %.3f", turn_up_down, turn_left_right); - turn_up_down *= dt; - turn_left_right *= dt; - } - - total_up_down_rot += turn_up_down; - if(total_up_down_rot >= max_up_down) - { - total_up_down_rot = max_up_down; - turn_up_down = 0.f; - } - else if(total_up_down_rot <= -max_up_down) - { - total_up_down_rot = -max_up_down; - turn_up_down = 0.f; - } - - if(turn_left_right != 0.f) - { - /*transform_rotate(player_entity, &rot_axis_left_right, -turn_left_right, TS_WORLD); - vec3 up = {0.f, 0.f, 0.f}; - vec3 forward = {0.f, 0.f, 0.f}; - vec3 lookat = {0.f, 0.f, 0.f}; - transform_get_up(player_entity, &up); - transform_get_forward(player_entity, &forward); - transform_get_lookat(player_entity, &lookat);*/ - /* log_message("Up : %s", tostr_vec3(&up)); */ - /* log_message("FR : %s", tostr_vec3(&forward)); */ - } - if(turn_up_down != 0.f) - { - /*transform_rotate(player_entity, &rot_axis_up_down, turn_up_down, TS_LOCAL); - vec3 up = {0.f, 0.f, 0.f}; - vec3 forward = {0.f, 0.f, 0.f}; - vec3 lookat = {0.f, 0.f, 0.f}; - transform_get_up(player_entity, &up); - transform_get_forward(player_entity, &forward); - transform_get_lookat(player_entity, &lookat);*/ - /* log_message("Up : %s", tostr_vec3(&up)); */ - /* log_message("FR : %s", tostr_vec3(&forward)); */ - } - - /* Movement */ - if(input_map_state_get("Sprint", KS_PRESSED)) move_speed *= editor_state.camera_sprint_multiplier; - if(input_map_state_get("Move_Forward", KS_PRESSED)) offset.z -= move_speed; - if(input_map_state_get("Move_Backward", KS_PRESSED)) offset.z += move_speed; - if(input_map_state_get("Move_Left", KS_PRESSED)) offset.x -= move_speed; - if(input_map_state_get("Move_Right", KS_PRESSED)) offset.x += move_speed; - if(input_map_state_get("Move_Up", KS_PRESSED)) offset.y += move_speed; - if(input_map_state_get("Move_Down", KS_PRESSED)) offset.y -= move_speed; - - vec3_scale(&offset, &offset, dt); - if(offset.x != 0 || offset.y != 0 || offset.z != 0) - { - transform_translate(editor_camera, &offset, TS_LOCAL); - //log_message("Position : %s", tostr_vec3(&transform->position)); - } -} - +void editor_camera_update(float dt) +{ + struct Camera* editor_camera = &game_state_get()->scene->cameras[CAM_EDITOR]; + float move_speed = editor_state.camera_move_speed, turn_speed = editor_state.camera_turn_speed; + vec3 offset = {0, 0, 0}; + float turn_up_down = 0.f; + float turn_left_right = 0.f; + float max_up_down = 60.f; + static float total_up_down_rot = 0.f; + vec3 rot_axis_up_down = {1, 0, 0}; + vec3 rot_axis_left_right = {0, 1, 0}; + + /* Look around */ + if(input_map_state_get("Turn_Up", KS_PRESSED)) turn_up_down += turn_speed; + if(input_map_state_get("Turn_Down", KS_PRESSED)) turn_up_down -= turn_speed; + if(input_map_state_get("Turn_Right", KS_PRESSED)) turn_left_right += turn_speed; + if(input_map_state_get("Turn_Left", KS_PRESSED)) turn_left_right -= turn_speed; + + if(input_mousebutton_state_get(MSB_RIGHT, KS_PRESSED)) + { + const float scale = 0.1f; + int cursor_lr, cursor_ud; + input_mouse_delta_get(&cursor_lr, &cursor_ud); + if(input_mouse_mode_get() != MM_RELATIVE) + { + input_mouse_mode_set(MM_RELATIVE); + cursor_lr = cursor_ud = 0; + } + + turn_up_down = -cursor_ud * turn_speed * dt * scale; + turn_left_right = cursor_lr * turn_speed * dt * scale; + //log_message("ud : %d, lr : %d", cursor_ud, cursor_lr); + } + else + { + input_mouse_mode_set(MM_NORMAL); + //log_message("ud : %.3f, lr : %.3f", turn_up_down, turn_left_right); + turn_up_down *= dt; + turn_left_right *= dt; + } + + total_up_down_rot += turn_up_down; + if(total_up_down_rot >= max_up_down) + { + total_up_down_rot = max_up_down; + turn_up_down = 0.f; + } + else if(total_up_down_rot <= -max_up_down) + { + total_up_down_rot = -max_up_down; + turn_up_down = 0.f; + } + + if(turn_left_right != 0.f) + { + transform_rotate(editor_camera, &rot_axis_left_right, -turn_left_right, TS_WORLD); + } + + if(turn_up_down != 0.f) + { + //transform_rotate(editor_camera, &rot_axis_up_down, turn_up_down, TS_LOCAL); + transform_rotate(editor_camera, &rot_axis_up_down, turn_up_down, TS_LOCAL); + } + + /* Movement */ + if(input_map_state_get("Sprint", KS_PRESSED)) move_speed *= editor_state.camera_sprint_multiplier; + if(input_map_state_get("Move_Forward", KS_PRESSED)) offset.z -= move_speed; + if(input_map_state_get("Move_Backward", KS_PRESSED)) offset.z += move_speed; + if(input_map_state_get("Move_Left", KS_PRESSED)) offset.x -= move_speed; + if(input_map_state_get("Move_Right", KS_PRESSED)) offset.x += move_speed; + if(input_map_state_get("Move_Up", KS_PRESSED)) offset.y += move_speed; + if(input_map_state_get("Move_Down", KS_PRESSED)) offset.y -= move_speed; + + vec3_scale(&offset, &offset, dt); + if(offset.x != 0 || offset.y != 0 || offset.z != 0) + { + transform_translate(editor_camera, &offset, TS_LOCAL); + //log_message("Position : %s", tostr_vec3(&transform->position)); + } +} + void editor_widget_color_combov3(struct nk_context* context, vec3* color, int width, int height) { struct nk_color temp_color = nk_rgba_f(color->x, color->y, color->z, 1.f); @@ -750,3 +717,28 @@ bool editor_widget_v3(struct nk_context* context, vec3* value, const char* name_ if(!vec3_equals(&val_copy, value)) changed = true; return changed; } + + +void editor_show_entity_in_list(struct nk_context* context, struct Scene* scene, struct Entity* entity) +{ + if(!entity->active) return; + + nk_layout_row_dynamic(context, 20, 1); + if(nk_selectable_label(context, entity->name, NK_TEXT_ALIGN_LEFT, &entity->editor_selected)) + { + if(editor_state.selected_entity && editor_state.selected_entity != entity) + { + editor_state.selected_entity->editor_selected = false; + editor_state.selected_entity = NULL; + } + else if(editor_state.selected_entity && editor_state.selected_entity == entity && !entity->editor_selected) + { + editor_state.selected_entity = NULL; + } + + if(entity->editor_selected) + { + editor_state.selected_entity = entity; + } + } +} \ No newline at end of file diff --git a/src/libsymmetry/entity.c b/src/libsymmetry/entity.c index 73762cb..c6e1972 100644 --- a/src/libsymmetry/entity.c +++ b/src/libsymmetry/entity.c @@ -507,12 +507,13 @@ const char* entity_type_name_get(struct Entity* entity) switch(entity->type) { case ET_NONE: typename = "None"; break; + case ET_DEFAULT: typename = "Default"; break; case ET_CAMERA: typename = "Camera"; break; case ET_LIGHT: typename = "Light"; break; case ET_PLAYER: typename = "Player"; break; case ET_ROOT: typename = "Root"; break; case ET_SOUND_SOURCE: typename = "Sound Source"; break; - case ET_STATIC_MODEL: typename = "Static Mesh"; break; + case ET_STATIC_MESH: typename = "Static Mesh"; break; default: typename = "Unknown"; break; }; return typename; @@ -616,3 +617,10 @@ void entity_collision_shape_set(struct Entity* entity, struct Collision* collisi collision->collision_shape = shape; platform->physics.cs_data_set(shape, entity); } + +void entity_rename(struct Entity* entity, const char* new_name) +{ + assert(entity); + memset(entity->name, '\0', MAX_ENTITY_NAME_LEN); + snprintf(entity->name, MAX_ENTITY_NAME_LEN, new_name); +} diff --git a/src/libsymmetry/entity.h b/src/libsymmetry/entity.h index 0665c89..acf6aba 100644 --- a/src/libsymmetry/entity.h +++ b/src/libsymmetry/entity.h @@ -24,7 +24,7 @@ enum Entity_Type ET_ROOT, ET_CAMERA, ET_LIGHT, - ET_STATIC_MODEL, + ET_STATIC_MESH, ET_SOUND_SOURCE, ET_MAX }; @@ -157,5 +157,6 @@ void entity_rigidbody_on_move(Rigidbody body); 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); #endif diff --git a/src/libsymmetry/game.c b/src/libsymmetry/game.c index fcb358c..5523553 100644 --- a/src/libsymmetry/game.c +++ b/src/libsymmetry/game.c @@ -33,10 +33,8 @@ #include "im_render.h" #define UNUSED(a) (void)a -#ifndef _MSC_VER -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) < (b) ? (b) : (a)) -#endif +#define MIN_NUM(a,b) ((a) < (b) ? (a) : (b)) +#define MAX_NUM(a,b) ((a) < (b) ? (b) : (a)) #define LEN(a) (sizeof(a)/sizeof(a)[0]) @@ -289,7 +287,7 @@ void scene_setup(void) struct Light* light = scene_light_create(game_state->scene, "Test_Light", NULL, LT_POINT); light->color.x = 1.f; - light->color.y = 0.f; + light->color.y = 1.f; light->color.z = 1.f; light->radius = 20.f; vec3 light_pos = {0.f, 5.f, 0.f}; @@ -298,98 +296,6 @@ void scene_setup(void) void debug(float dt) { - //struct Entity* entity = entity_get(player_node); - float move_speed = 5.f, move_scale = 3.f, turn_speed = 50.f; - vec3 offset = {0, 0, 0}; - float turn_up_down = 0.f; - float turn_left_right = 0.f; - float max_up_down = 60.f; - static float total_up_down_rot = 0.f; - vec3 rot_axis_up_down = {1, 0, 0}; - vec3 rot_axis_left_right = {0, 1, 0}; - - /* Look around */ - if(input_map_state_get("Turn_Up", KS_PRESSED)) turn_up_down += turn_speed; - if(input_map_state_get("Turn_Down", KS_PRESSED)) turn_up_down -= turn_speed; - if(input_map_state_get("Turn_Right", KS_PRESSED)) turn_left_right += turn_speed; - if(input_map_state_get("Turn_Left", KS_PRESSED)) turn_left_right -= turn_speed; - - if(input_mousebutton_state_get(MSB_RIGHT, KS_PRESSED)) - { - const float scale = 0.1f; - int cursor_lr, cursor_ud; - input_mouse_delta_get(&cursor_lr, &cursor_ud); - if(input_mouse_mode_get() != MM_RELATIVE) - { - input_mouse_mode_set(MM_RELATIVE); - cursor_lr = cursor_ud = 0; - } - - turn_up_down = -cursor_ud * turn_speed * dt * scale; - turn_left_right = cursor_lr * turn_speed * dt * scale; -// log_message("ud : %d, lr : %d", cursor_ud, cursor_lr); - } - else - { - input_mouse_mode_set(MM_NORMAL); -// log_message("ud : %.3f, lr : %.3f", turn_up_down, turn_left_right); - turn_up_down *= dt; - turn_left_right *= dt; - } - - total_up_down_rot += turn_up_down; - if(total_up_down_rot >= max_up_down) - { - total_up_down_rot = max_up_down; - turn_up_down = 0.f; - } - else if(total_up_down_rot <= -max_up_down) - { - total_up_down_rot = -max_up_down; - turn_up_down = 0.f; - } - - if(turn_left_right != 0.f) - { - /*transform_rotate(player_entity, &rot_axis_left_right, -turn_left_right, TS_WORLD); - vec3 up = {0.f, 0.f, 0.f}; - vec3 forward = {0.f, 0.f, 0.f}; - vec3 lookat = {0.f, 0.f, 0.f}; - transform_get_up(player_entity, &up); - transform_get_forward(player_entity, &forward); - transform_get_lookat(player_entity, &lookat);*/ - /* log_message("Up : %s", tostr_vec3(&up)); */ - /* log_message("FR : %s", tostr_vec3(&forward)); */ - } - if(turn_up_down != 0.f) - { - /*transform_rotate(player_entity, &rot_axis_up_down, turn_up_down, TS_LOCAL); - vec3 up = {0.f, 0.f, 0.f}; - vec3 forward = {0.f, 0.f, 0.f}; - vec3 lookat = {0.f, 0.f, 0.f}; - transform_get_up(player_entity, &up); - transform_get_forward(player_entity, &forward); - transform_get_lookat(player_entity, &lookat);*/ - /* log_message("Up : %s", tostr_vec3(&up)); */ - /* log_message("FR : %s", tostr_vec3(&forward)); */ - } - - /* Movement */ - if(input_map_state_get("Sprint", KS_PRESSED)) move_speed *= move_scale; - if(input_map_state_get("Move_Forward", KS_PRESSED)) offset.z -= move_speed; - if(input_map_state_get("Move_Backward", KS_PRESSED)) offset.z += move_speed; - if(input_map_state_get("Move_Left", KS_PRESSED)) offset.x -= move_speed; - if(input_map_state_get("Move_Right", KS_PRESSED)) offset.x += move_speed; - if(input_map_state_get("Move_Up", KS_PRESSED)) offset.y += move_speed; - if(input_map_state_get("Move_Down", KS_PRESSED)) offset.y -= move_speed; - - vec3_scale(&offset, &offset, dt); - if(offset.x != 0 || offset.y != 0 || offset.z != 0) - { - //transform_translate(player_entity, &offset, TS_LOCAL); - //log_message("Position : %s", tostr_vec3(&transform->position)); - } - if(input_is_key_pressed(KEY_SPACE)) { struct Entity* model = scene_find(game_state->scene, "Light_Ent"); @@ -491,7 +397,7 @@ void debug(float dt) im_color.y = 0.f; im_begin(im_position, im_rot, im_scale, im_color, GL_TRIANGLES); - float length = 200 * sin(dt); + float length = 200.f; //Front im_pos(0.f, 0.f, 0.f); @@ -1023,7 +929,7 @@ void debug_gui(float dt) if (nk_button_symbol(ctx, NK_SYMBOL_TRIANGLE_LEFT)) { if (sel_date.tm_mon == 0) { sel_date.tm_mon = 11; - sel_date.tm_year = MAX(0, sel_date.tm_year-1); + sel_date.tm_year = MAX_NUM(0, sel_date.tm_year-1); } else sel_date.tm_mon--; } nk_layout_row_push(ctx, 0.9f); diff --git a/src/libsymmetry/scene.c b/src/libsymmetry/scene.c index f292e26..d67ee1c 100644 --- a/src/libsymmetry/scene.c +++ b/src/libsymmetry/scene.c @@ -29,7 +29,11 @@ void scene_init(struct Scene* scene) scene->player.base.type = ET_PLAYER; for(int i = 0; i < MAX_ENTITIES; i++) entity_reset(&scene->entities[i], i); - for(int i = 0; i < MAX_LIGHTS; i++) entity_reset(&scene->lights[i], i); + for(int i = 0; i < MAX_LIGHTS; i++) + { + entity_reset(&scene->lights[i], i); + scene->lights[i].type = ET_LIGHT; + } for(int i = 0; i < MAX_STATIC_MESHES; i++) { entity_reset(&scene->static_meshes[i], i); @@ -288,7 +292,7 @@ struct Static_Model* scene_static_mesh_create(struct Scene* scene, const char* n if(new_static_mesh) { entity_init(&new_static_mesh->base, name, parent); - new_static_mesh->base.type = ET_STATIC_MODEL; + 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 } @@ -497,6 +501,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; } void* scene_find(struct Scene* scene, const char* name) diff --git a/src/libsymmetry/scene.h b/src/libsymmetry/scene.h index bb27bc7..fd4408e 100644 --- a/src/libsymmetry/scene.h +++ b/src/libsymmetry/scene.h @@ -48,6 +48,7 @@ struct Light* scene_light_find(struct Scene* scene, const char* name); struct Camera* scene_camera_find(struct Scene* scene, const char* name); struct Static_Mesh* scene_static_mesh_find(struct Scene* scene, const char* name); struct Sound_Source* scene_sound_source_find(struct Scene* scene, const char* name); +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 diff --git a/src/libsymmetry/transform.c b/src/libsymmetry/transform.c index 5f49425..88162b6 100644 --- a/src/libsymmetry/transform.c +++ b/src/libsymmetry/transform.c @@ -203,7 +203,7 @@ void transform_update_transmat(struct Entity* entity) transform_update_transmat(entity->transform.children[i]); } transform->is_modified = true; - if(entity->type == ET_STATIC_MODEL) entity->transform.sync_physics = true; // Find a better way to handle this + if(entity->type == ET_STATIC_MESH) entity->transform.sync_physics = true; // Find a better way to handle this } void transform_destroy(struct Entity* entity)