Commit 3bc33525 authored by stonecompass's avatar stonecompass
Browse files

Camera feature done.


Former-commit-id: 4a05fe3f
parent 39a38b8b
......@@ -4,8 +4,9 @@ namespace editor
{
editor_state->windows.show_hierarchy = true;
editor_state->windows.show_inspector = true;
editor_state->windows.show_scene_settings = true;
editor_state->windows.show_stats = true;
editor_state->windows.show_scene_settings = false;
editor_state->windows.show_stats = false;
editor_state->windows.show_resources = true;
}
static void _recursive_entity_item(scene::Entity& entity, scene::SceneManager *scene_manager)
......@@ -68,7 +69,7 @@ namespace editor
ImGui::PopID();
}
static void _render_hierarchy(scene::Scene &scene, EditorState *editor_state, r64 delta_time)
static void _render_hierarchy(scene::Scene &scene, EditorState *editor_state, InputController *input_controller, r64 delta_time)
{
if(!editor_state->windows.show_hierarchy)
return;
......@@ -78,7 +79,7 @@ namespace editor
ImGui::SetNextWindowSize(ImVec2(1000, 200), ImGuiCond_FirstUseEver);
ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_FirstUseEver);
if(ImGui::Begin("Hierarchy", &hierarchy_open, 0))
if(ImGui::Begin("Hierarchy", &hierarchy_open, ImGuiWindowFlags_NoFocusOnAppearing))
{
for (i32 i = 0; i < scene.entity_count; i++)
{
......@@ -91,6 +92,20 @@ namespace editor
_recursive_entity_item(entity, scene.handle.manager);
}
}
if(ImGui::IsWindowFocused())
{
if(KEY_DOWN(Key_Delete) || KEY_DOWN(Key_Backspace))
{
if(IS_ENTITY_HANDLE_VALID(scene.handle.manager->selected_entity))
{
delete_entity(scene.handle.manager->selected_entity, scene.handle.manager);
scene.handle.manager->selected_entity = { -1 };
scene.handle.manager->gizmos.active = false;
}
}
}
}
editor_state->windows.show_hierarchy = hierarchy_open ;
......@@ -164,7 +179,9 @@ namespace editor
}
}
ImGui::SameLine();
ImGui::PushID("tag_text");
ImGui::InputText("", tag_text, IM_ARRAYSIZE(tag_text));
ImGui::PopID();
}
if(ImGui::CollapsingHeader("Transform"))
......@@ -283,11 +300,10 @@ namespace editor
ImGui::SliderFloat3("Specular", specular->e, 0.0f, 1.0f);
}
}
if(ImGui::CollapsingHeader("Fields"))
if(entity.type_info.field_count > 0 && ImGui::CollapsingHeader("Fields"))
{
scene::EntityData *data_ptr = entity.entity_data;
for(i32 i = 0; i < entity.type_info.field_count; i++)
{
scene::Field &field = entity.type_info.fields[i];
......@@ -307,7 +323,10 @@ namespace editor
break;
case scene::FieldType::FLOAT:
{
ImGui::DragFloat(field.name, ((r32*)ptr), delta_time);
r32 *float_ptr = (r32*)ptr;
r32 value = *float_ptr;
ImGui::DragFloat(field.name, &value, delta_time);
*float_ptr = value;
}
break;
case scene::FieldType::VEC2:
......@@ -746,7 +765,7 @@ namespace editor
bool open = true;
if(ImGui::Begin("Scene settings", &open))
if(ImGui::Begin("Scene settings", &open, ImGuiWindowFlags_NoFocusOnAppearing))
{
scene::Settings& settings = scene::get_scene_settings(scene_manager->loaded_scene);
......@@ -831,6 +850,32 @@ namespace editor
if(editor_state->callbacks.on_custom_main_menu_bar)
editor_state->callbacks.on_custom_main_menu_bar();
if(scene_manager->scene_loaded)
{
ImGui::Spacing();
ImGui::Spacing();
ImGui::Spacing();
ImGui::Spacing();
scene::Scene &scene = scene::get_scene(scene_manager->loaded_scene);
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.0f, 1.0f, 0.35f, 1.0f));
ImGui::Text(scene.file_path);
ImGui::PopStyleColor();
}
if(scene_manager->camera_preview.show_camera_preview)
{
ImGui::Spacing();
ImGui::Spacing();
ImGui::Spacing();
ImGui::Spacing();
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 0.0f, 0.35f, 1.0f));
ImGui::Text("(PREVIEWING CAMERA)");
ImGui::PopStyleColor();
}
ImGui::EndMainMenuBar();
}
......@@ -839,8 +884,49 @@ namespace editor
scene::editor_save(scene_manager);
}
}
static void _render_stats(EditorState *editor_state, scene::SceneManager *scene_manager, InputController *input_controller, sound::SoundSystem *sound_system, r64 delta_time)
{
if(!editor_state->windows.show_stats)
return;
Renderer *renderer = scene_manager->renderer;
bool open = true;
if(ImGui::Begin("Stats", &open, ImGuiWindowFlags_AlwaysAutoResize))
{
if(scene_manager->scene_loaded)
{
scene::Scene &scene = scene::get_scene(scene_manager->loaded_scene);
ImGui::Text("Entities: %d", (i32)scene.entity_count);
}
ImGui::Text("Shaders: %d", (i32)renderer->render.shader_count);
ImGui::Text("Material instances: %d", (i32)renderer->render.material_instance_count);
ImGui::Text("FPS: %.3f", renderer->fps);
ImGui::Text("Delta: %.3f", delta_time * 1000.0f);
ImGui::Text("Resolution: %d x %d", renderer->window_width, renderer->window_height);
ImGui::Text("Master vol: %d", (i32)(sound_system->master_volume * 100.0f));
ImGui::Text("Sfx vol: %d", (i32)(sound_system->sfx_volume * 100.0f));
ImGui::Text("Music vol: %d", (i32)(sound_system->music_volume * 100.0f));
r32 mouse_x_in_ui_coords = rendering::to_ui(renderer, renderer->window_width, (r32)input_controller->mouse_x);
r32 mouse_y_in_ui_coords = rendering::to_ui(renderer, renderer->window_height, renderer->window_height - (r32)input_controller->mouse_y);
ImGui::Text("UI mouse x: %f", mouse_x_in_ui_coords);
ImGui::Text("UI mouse y: %f", mouse_y_in_ui_coords);
ImGui::Text("Mouse x: %f", (i32)input_controller->mouse_x);
ImGui::Text("Mouse y: %f", (i32)input_controller->mouse_y);
}
editor_state->windows.show_stats = open;
ImGui::End();
}
static void _render_resources(project::ProjectState *state, EditorState *editor_state, scene::SceneManager *scene_manager, r64 delta_time)
static void _render_resources(project::ProjectState *state, EditorState *editor_state, scene::SceneManager *scene_manager, r64 delta_time)
{
if(!editor_state->windows.show_resources)
return;
......@@ -856,6 +942,30 @@ namespace editor
ImGui::Text(current_structure.path);
ImGui::SameLine();
char *file_str = nullptr;
char *dir_str = nullptr;
if(current_structure.file_count == 1)
{
file_str = "file";
}
else
{
file_str = "files";
}
if(current_structure.dir_count == 1)
{
dir_str = "directory";
}
else
{
dir_str = "directories";
}
ImGui::Text("(%d %s, %d %s)", current_structure.file_count, file_str, current_structure.dir_count, dir_str);
ImGui::SameLine();
if(ImGui::Button("Reload"))
{
clear(&state->resources.arenas[state->resources.structure_count - 1]);
......@@ -918,8 +1028,9 @@ namespace editor
char full_path[64];
sprintf(full_path, "%s/%s", current_structure.path, current_structure.files[i].name);
Camera &camera = scene::get_editor_camera(scene_manager->loaded_scene);
place_entity_from_template(scene_manager->editor_camera_transform.transform.position + camera.forward * 15.0f, full_path, scene_manager->loaded_scene, true, true);
scene::TransformComponent &transform_comp = scene::get_transform_comp(scene_manager->editor_camera, scene_manager->loaded_scene);
place_entity_from_template(transform_comp.transform.position + transform_comp.transform.forward * 15.0f, full_path, scene_manager->loaded_scene, true, true);
}
else if(has_extension(current_structure.files[i].name, ".gsc"))
{
......
......@@ -48,9 +48,10 @@ namespace editor
// Internal functions
static void _init(EditorState *editor_state);
static void _recursive_entity_item(scene::Entity& entity, scene::SceneManager *scene_manager, r64 delta_time);
static void _render_hierarchy(scene::Scene &scene, EditorState *editor_state, r64 delta_time);
static void _render_hierarchy(scene::Scene &scene, EditorState *editor_state, InputController *input_controller, r64 delta_time);
static void _render_inspector(scene::Scene &scene, EditorState *editor_state, InputController *input_controller, r64 delta_time);
static void _render_resources(project::ProjectState *project_state, EditorState *editor_state, scene::SceneManager *scene_manager, r64 delta_time);
static void _render_stats(EditorState *editor_state, scene::SceneManager *scene_manager, InputController *input_controller, sound::SoundSystem *sound_system, r64 delta_time);
static void set_editor_mode(EditorMode mode, EditorState *state);
}
......
......@@ -1091,6 +1091,7 @@ int main(int argc, char **args)
#ifdef EDITOR
if(scene_manager->mode == scene::SceneMode::RUNNING)
{
editor::_render_stats(&editor_state, scene_manager, &input_controller, &sound_system, delta_time);
game.update(&game_memory);
}
else
......@@ -1101,9 +1102,11 @@ int main(int argc, char **args)
if(editor_state.mode == editor::EditorMode::BUILT_IN)
{
editor::_render_hierarchy(current_scene, &editor_state, delta_time);
editor::_render_hierarchy(current_scene, &editor_state, &input_controller, delta_time);
editor::_render_inspector(current_scene, &editor_state, &input_controller, delta_time);
editor::_render_resources(project_state, &editor_state, scene_manager, delta_time);
editor::_render_scene_settings(&editor_state, scene_manager, delta_time);
editor::_render_stats(&editor_state, scene_manager, &input_controller, &sound_system, delta_time);
}
}
#else
......@@ -1113,12 +1116,11 @@ int main(int argc, char **args)
if(scene_manager->scene_loaded) // Check again, since there could be a call to unload_current_scene() in game.update()
{
current_scene = scene::get_scene(scene_manager->loaded_scene);
scene::update_cameras(current_scene, scene_manager);
#ifdef EDITOR
update_scene_editor(scene_manager->loaded_scene, &input_controller, render_state, delta_time);
#endif
#endif
scene::Scene &scene = scene::get_scene(scene_manager->loaded_scene);
scene::update_animators(scene, renderer, delta_time);
scene::push_scene_for_rendering(scene, renderer);
......@@ -1129,7 +1131,6 @@ int main(int argc, char **args)
update_particle_systems(renderer, delta_time);
//tick_animation_controllers(renderer, &sound_system, &input_controller, timer_controller, delta_time);
tick_timers(timer_controller, delta_time);
if(sound_system.update)
......
......@@ -53,8 +53,6 @@ namespace project
sprintf(settings_ptr->resources_folder_path, "%s/%s", settings_ptr->project_root_path, folder);
printf("Resources path: %s\n", settings_ptr->resources_folder_path);
project_state->resources.resource_file_structures = push_array(&project_state->resources.file_structure_arena, 8, FileList);
project_state->resources.arenas = push_array(&project_state->resources.file_structure_arena, 8, MemoryArena);
......
......@@ -1021,12 +1021,6 @@ namespace rendering
pass.clipping_planes.plane = plane;
}
static void set_camera_for_render_pass(Camera &camera, RenderPassHandle render_pass_handle, Renderer *renderer)
{
renderer->render.passes[render_pass_handle.handle - 1].camera = camera;
renderer->render.passes[render_pass_handle.handle - 1].use_scene_camera = false;
}
static math::Vec2i get_texture_size(rendering::TextureHandle handle, Renderer *renderer)
{
Texture* texture = renderer->render.textures[handle.handle - 1];
......
......@@ -264,6 +264,12 @@ namespace scene
{
Scene &scene = get_scene(handle);
scene = {};
for(i32 i = 0; i < 32; i++)
{
scene.render_pass_cameras[i] = {0};
}
scene.handle = handle;
scene.memory_arena = {};
......@@ -502,7 +508,7 @@ namespace scene
return nullptr;
}
static void parse_scene_object(FILE *file, SceneHandle scene, const char *name)
static void parse_scene_object(FILE *file, SceneHandle scene, char *name)
{
EntityHandle handle = { -1 };
......@@ -785,16 +791,16 @@ namespace scene
char *val = buffer + strlen(name) + 2;
load_entity_field(name, val, entity_data, *type_info);
if(scene.manager->callbacks.on_loaded_entity_of_type)
{
scene.manager->callbacks.on_loaded_entity_of_type(handle, type_info->type_id, scene);
}
}
set_hide_in_ui(handle, hide_in_ui, scene);
}
if (entity_data && scene.manager->callbacks.on_loaded_entity_of_type)
{
scene.manager->callbacks.on_loaded_entity_of_type(handle, type_info->type_id, scene);
}
set_hide_in_ui(handle, hide_in_ui, scene);
if(!is_whitespace(name))
{
Scene &s = get_scene(scene);
......@@ -1177,8 +1183,10 @@ static Camera get_standard_camera(SceneManager& manager)
{
i32 width = scene.renderer->window_width;
i32 height = scene.renderer->window_height;
Camera &camera = scene.scene_manager->editor_camera;
TransformComponent &transform = scene.scene_manager->editor_camera_transform;
CameraComponent &camera_comp = _get_camera_comp(scene.scene_manager->editor_camera, scene);
TransformComponent &transform = _get_transform_comp(scene.scene_manager->editor_camera, scene);
Camera &camera = camera_comp.camera;
r32 x = (2.0f * mouse_x) / width - 1.0f;
r32 y = 1.0f - (2.0f * mouse_y) / height;
......@@ -1340,7 +1348,6 @@ static Camera get_standard_camera(SceneManager& manager)
if(aabb_ray_intersection(ray, box, &intersection_point))
{
printf("Hit: %s\n", ent.name);
// Look for selectable parents
if(!ent.selection_enabled)
{
......@@ -1367,6 +1374,8 @@ static Camera get_standard_camera(SceneManager& manager)
MemoryArena temp_arena = {};
TemporaryMemory temp_mem = begin_temporary_memory(&temp_arena);
TransformComponent &editor_camera_transform = _get_transform_comp(scene.scene_manager->editor_camera, scene);
for(i32 i = 0; i < entity_list.entity_count; i++)
{
Entity entity = get_entity(entity_list.handles[i], scene);
......@@ -1392,7 +1401,7 @@ static Camera get_standard_camera(SceneManager& manager)
if(triangle_ray_intersection(local_ray, v1.position, v2.position, v3.position, &intersection_point))
{
intersection_point = transform.model * intersection_point;
r32 new_dist = math::distance(scene.scene_manager->editor_camera_transform.transform.position, intersection_point);
r32 new_dist = math::distance(editor_camera_transform.transform.position, intersection_point);
if(new_dist < dist)
{
......@@ -1651,7 +1660,7 @@ static Camera get_standard_camera(SceneManager& manager)
return l;
}
static void update_transform(TransformComponent &transform, Camera &camera, SceneManager *manager, InputController *input_controller, r64 delta_time)
static void update_transform(TransformComponent &transform, SceneManager *manager, InputController *input_controller, r64 delta_time)
{
if(manager->dragging)
{
......@@ -1995,13 +2004,16 @@ static Camera get_standard_camera(SceneManager& manager)
{
CameraComponent &camera_comp = scene.camera_components[i];
TransformComponent &transform = get_transform_comp(camera_comp.entity, scene.handle);
update_camera(camera_comp.camera, transform, scene_manager);
}
}
/* camera = scene_manager->editor_camera;
camera.view_matrix = scene_manager->editor_camera_transform.transform.model;
camera.pos = scene_manager->editor_camera_transform.transform.position;*/
static void set_camera_for_render_pass(EntityHandle camera_entity, rendering::RenderPassHandle handle, SceneHandle scene_handle)
{
Scene &scene = get_scene(scene_handle);
scene.render_pass_cameras[handle.handle - 1] = camera_entity;
}
static void update_scene_settings(SceneHandle handle)
{
......@@ -2017,6 +2029,17 @@ static Camera get_standard_camera(SceneManager& manager)
update_shadow_framebuffer(handle);
}
static void _set_particle_systems_paused(b32 paused, scene::SceneManager *scene_manager)
{
scene::Scene& scene = scene::get_scene(scene_manager->loaded_scene);
for(i32 i = 0; i < scene.particle_system_component_count; i++)
{
scene::ParticleSystemComponent comp = scene.particle_system_components[i];
scene.renderer->particles.api->pause_particle_system(comp.handle, scene.renderer, paused);
}
}
static void update_scene_editor(SceneHandle handle, InputController *input_controller, RenderState &render_state, r64 delta_time)
{
Scene &scene = get_scene(handle);
......@@ -2034,18 +2057,22 @@ static Camera get_standard_camera(SceneManager& manager)
manager->renderer->api_functions.show_mouse_cursor(true, &render_state);
manager->mode = SceneMode::EDITING;
CameraComponent &main_camera = get_main_camera_comp(manager->loaded_scene);
TransformComponent &main_camera_transform = get_main_camera_transform(manager->loaded_scene);
manager->editor_camera = main_camera.camera;
manager->editor_camera_transform = main_camera_transform;
find_all_template_files(manager);
scene::reload_scene(manager->loaded_scene);
_set_particle_systems_paused(true, manager);
TransformComponent &main_cam_transform = get_main_camera_transform(manager->loaded_scene);
TransformComponent &editor_cam_transform = get_transform_comp(manager->editor_camera, manager->loaded_scene);
scene::set_position(editor_cam_transform, main_cam_transform.transform.position);
scene::set_rotation(editor_cam_transform, main_cam_transform.transform.euler_angles);
if(manager->callbacks.on_started_edit_mode)
manager->callbacks.on_started_edit_mode(handle);
}
else
{
scene::reload_scene(manager->loaded_scene);
manager->renderer->api_functions.show_mouse_cursor(false, &render_state);
// Disable wireframes
if(IS_ENTITY_HANDLE_VALID(manager->selected_entity))
......@@ -2068,14 +2095,14 @@ static Camera get_standard_camera(SceneManager& manager)
{
Scene &scene = get_scene(manager->loaded_scene);
Camera &camera = manager->editor_camera;
TransformComponent &camera_transform = get_transform_comp(manager->editor_camera, manager->loaded_scene);
if(IS_ENTITY_HANDLE_VALID(manager->selected_entity))
{
TransformComponent &t = get_transform_comp(manager->selected_entity, handle);
update_transform(t, camera, manager, input_controller, delta_time);
manager->gizmos.current_distance_to_camera = math::distance(manager->editor_camera_transform.transform.position, t.transform.position) * 0.1f;
update_transform(t, manager, input_controller, delta_time);
manager->gizmos.current_distance_to_camera = math::distance(camera_transform.transform.position, t.transform.position) * 0.1f;
if(KEY_DOWN(Key_F))
{
......@@ -2089,17 +2116,6 @@ static Camera get_standard_camera(SceneManager& manager)
deselect_everything(manager);
}
if(KEY_DOWN(Key_Delete) || KEY_DOWN(Key_Backspace))
{
if(IS_ENTITY_HANDLE_VALID(manager->selected_entity))
{
delete_entity(manager->selected_entity, manager);
manager->selected_entity = { -1 };
manager->gizmos.active = false;
}
}
if(KEY(Key_LeftCtrl) && KEY_DOWN(Key_D))
{
if(IS_ENTITY_HANDLE_VALID(manager->selected_entity))
......@@ -2256,8 +2272,9 @@ static Camera get_standard_camera(SceneManager& manager)
}
else
{
update_editor_camera(manager->editor_camera, manager->editor_camera_transform, scene, input_controller, delta_time);
update_camera(manager->editor_camera, manager->editor_camera_transform, manager);
CameraComponent& cam = get_camera_comp(manager->editor_camera, handle);
TransformComponent& trans = get_transform_comp(manager->editor_camera, handle);
update_editor_camera(cam.camera, trans, scene, input_controller, delta_time);
}
}
}
......@@ -2300,9 +2317,20 @@ static Camera get_standard_camera(SceneManager& manager)
if(!scene->loaded)
{
if(scene_manager->mode == SceneMode::EDITING)
{
scene_manager->editor_camera = register_entity(COMP_TRANSFORM | COMP_CAMERA, handle, false);
scene::set_hide_in_ui(scene_manager->editor_camera, true, handle);
scene::set_entity_name(scene_manager->editor_camera, "Editor Camera", handle);
}
if(scene_manager->callbacks.on_scene_will_load)
scene_manager->callbacks.on_scene_will_load(handle);
// @Robustness: This is not good behaviour...
// Make sure to reget the scene in case a scene was freed in the callback
scene = &get_scene(handle);
allocate_instance_buffers(*scene);
scene->loaded = true;
}
......@@ -3414,6 +3442,12 @@ static Camera get_standard_camera(SceneManager& manager)
strcpy(entity.name, name);
}
static inline void set_entity_name(EntityHandle handle, const char *name, SceneHandle scene_handle)
{
Scene &scene = get_scene(scene_handle);
_set_entity_name(handle, name, scene);
}
static inline void _set_entity_template_path(EntityHandle handle, const char *template_path, Scene& scene)
{
Entity &entity = scene.entities[scene._internal_handles[handle.handle - 1]];
......@@ -4019,7 +4053,7 @@ static Camera get_standard_camera(SceneManager& manager)
assert(entity.comp_flags & COMP_CAMERA);
CameraComponent& comp = scene.camera_components[entity.render_handle.handle];
CameraComponent& comp = scene.camera_components[entity.camera_handle.handle];
return(comp);
}
......@@ -4086,11 +4120,6 @@ static Camera get_standard_camera(SceneManager& manager)
return camera_comp.camera;
}
static Camera& get_editor_camera(SceneHandle handle)
{
return handle.manager->editor_camera;
}
static Camera& get_current_camera(SceneHandle handle)
{
if(handle.manager->mode == SceneMode::RUNNING)
......@@ -4105,7 +4134,44 @@ static Camera get_standard_camera(SceneManager& manager)
return component.camera;
}
else
return get_editor_camera(handle);
{
CameraComponent &component = get_camera_comp(handle.manager->editor_camera, handle);
return component.camera;
}
}
}
static TransformComponent &get_current_camera_transform(SceneHandle handle)
{
if(handle.manager->mode == SceneMode::RUNNING)
{
return get_main_camera_transform(handle);
}
else
{
if(handle.manager->camera_preview.show_camera_preview)
{
return get_transform_comp(handle.manager->camera_preview.handle, handle);
}
else
return get_transform_comp(handle.manager->editor_camera, handle);
}
}
static CameraComponent &get_current_camera_comp(SceneHandle handle)
{
if(handle.manager->mode == SceneMode::RUNNING)
{
return get_main_camera_comp(handle);
}
else
{
if(handle.manager->camera_preview.show_camera_preview)
{
return get_camera_comp(handle.manager->camera_preview.handle, handle);
}
else
return get_camera_comp(handle.manager->editor_camera, handle);
}
}