From 62dd36d7d60cbaaf49de9ac7a9e4ba144c7adf57 Mon Sep 17 00:00:00 2001 From: KP Date: Tue, 30 Jul 2024 21:19:10 -0500 Subject: [PATCH] Add ability to select multiple things in editor --- Data/resources/textures/.kp3d/banner.png | Bin 5420 -> 5470 bytes Data/sandbox-log.txt | 48 +++++++ KP3Dii/src/KP3D_Map.cpp | 13 +- KP3Dii/src/KP3D_Map.h | 2 +- Sandbox/src/Editor.cpp | 174 ++++++++++++++++------- Sandbox/src/Editor.h | 14 +- 6 files changed, 194 insertions(+), 57 deletions(-) diff --git a/Data/resources/textures/.kp3d/banner.png b/Data/resources/textures/.kp3d/banner.png index 970cf7c45da212bfcfdafa332acb8052c141a797..0a8f10e1a4e87aeb460b8bbb37691868c41f8ee0 100644 GIT binary patch delta 5446 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 delta 5396 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 diff --git a/Data/sandbox-log.txt b/Data/sandbox-log.txt index e69de29..4a20554 100644 --- a/Data/sandbox-log.txt +++ b/Data/sandbox-log.txt @@ -0,0 +1,48 @@ +[09:17:25 PM] Info: Starting... + + KP3D version 2 +=============================== + Copyright (C) kpworld.xyz 2018-2024 + Contact me! @kp_cftsz + +[09:17:25 PM] Info: Initializing SDL +[09:17:25 PM] Info: Initializing OpenGL +[09:17:25 PM] Info: OpenGL version: 4.6.0 NVIDIA 536.23 +[09:17:25 PM] Info: Initializing GLEW +[09:17:25 PM] Info: Initializing SDL_mixer +[09:17:25 PM] Info: Reticulating splines... +[09:17:25 PM] Info: Ready! +[09:17:25 PM] Info: Loading material resource: block.png +[09:17:25 PM] Info: Found normal map texture: materials/block_n.png +[09:17:25 PM] Info: Loading material resource: FLAT5_7.png +[09:17:25 PM] Info: Found normal map texture: materials/FLAT5_7_n.png +[09:17:25 PM] Info: Loading material resource: floor0.png +[09:17:25 PM] Info: Found normal map texture: materials/floor0_n.png +[09:17:25 PM] Info: Loading material resource: floor1.png +[09:17:25 PM] Info: Found normal map texture: materials/floor1_n.png +[09:17:25 PM] Info: Loading material resource: GRASS2.png +[09:17:25 PM] Info: Found normal map texture: materials/GRASS2_n.png +[09:17:25 PM] Info: Map init +[09:17:25 PM] Info: Finalized mesh with 45 batches +[09:17:30 PM] Info: Finalized mesh with 50 batches +[09:17:39 PM] Info: Finalized mesh with 50 batches +[09:17:42 PM] Info: Finalized mesh with 50 batches +[09:17:47 PM] Info: Finalized mesh with 50 batches +[09:17:53 PM] Info: Finalized mesh with 50 batches +[09:17:54 PM] Info: Finalized mesh with 50 batches +[09:18:05 PM] Info: Finalized mesh with 52 batches +[09:18:07 PM] Info: Finalized mesh with 56 batches +[09:18:07 PM] Info: Finalized mesh with 56 batches +[09:18:07 PM] Info: Finalized mesh with 56 batches +[09:18:07 PM] Info: Finalized mesh with 56 batches +[09:18:07 PM] Info: Finalized mesh with 56 batches +[09:18:07 PM] Info: Finalized mesh with 56 batches +[09:18:07 PM] Info: Finalized mesh with 56 batches +[09:18:07 PM] Info: Finalized mesh with 56 batches +[09:18:07 PM] Info: Finalized mesh with 56 batches +[09:18:07 PM] Info: Finalized mesh with 56 batches +[09:18:07 PM] Info: Finalized mesh with 56 batches +[09:18:07 PM] Info: Finalized mesh with 56 batches +[09:18:07 PM] Info: Finalized mesh with 56 batches +[09:18:07 PM] Info: Finalized mesh with 56 batches +[09:18:12 PM] Info: Finalized mesh with 56 batches diff --git a/KP3Dii/src/KP3D_Map.cpp b/KP3Dii/src/KP3D_Map.cpp index afb610a..37194fd 100644 --- a/KP3Dii/src/KP3D_Map.cpp +++ b/KP3Dii/src/KP3D_Map.cpp @@ -60,11 +60,16 @@ bool SectorContains(const kp3d::Sector& outer, const kp3d::Sector& inner, Sector // kind of ugly the way this works... kp3d::uint ShouldHighlight(const kp3d::RenderBatch3D& batch) { - if (!kp3d::editor_hovered_batch) + using namespace kp3d; + if (editor_hovered_batch.empty()) return 0xFFFFFFFF; - if (&batch != kp3d::editor_hovered_batch) + if (std::find(editor_hovered_batch.begin(), editor_hovered_batch.end(), &batch) == editor_hovered_batch.end()) return 0xFFFFFFFF; - kp3d::BatchSectorInfo info = std::any_cast(batch.userdata); + // if (!kp3d::editor_hovered_batch) + // return 0xFFFFFFFF; + // if (&batch != kp3d::editor_hovered_batch) + // return 0xFFFFFFFF; + BatchSectorInfo info = std::any_cast(batch.userdata); if (info.sector) return 0x5555FFFF; } @@ -73,7 +78,7 @@ kp3d::uint ShouldHighlight(const kp3d::RenderBatch3D& batch) namespace kp3d { -RenderBatch3D* editor_hovered_batch = nullptr; +std::vector editor_hovered_batch; Map::Map() { diff --git a/KP3Dii/src/KP3D_Map.h b/KP3Dii/src/KP3D_Map.h index 5b2faa5..132a6ef 100644 --- a/KP3Dii/src/KP3D_Map.h +++ b/KP3Dii/src/KP3D_Map.h @@ -173,6 +173,6 @@ private: }; -extern RenderBatch3D* editor_hovered_batch; // hack +extern std::vector editor_hovered_batch; // hack } diff --git a/Sandbox/src/Editor.cpp b/Sandbox/src/Editor.cpp index d0a0090..c2c722c 100644 --- a/Sandbox/src/Editor.cpp +++ b/Sandbox/src/Editor.cpp @@ -3,6 +3,7 @@ #include #include "KP3D_Renderer3D.h" +#include "KP3D_StaticMesh.h" #include "KP3D_Raycast.h" #include "KP3D_Math.h" #include "KP3D_Geometry.h" @@ -59,6 +60,9 @@ void Editor::Update() KEY_SHORTCUT(V, m_mode = MODE_BUILD); KEY_SHORTCUT(C, m_mode = MODE_SECTOR_EDIT); + if (anything_hovered) + return; + if (m_mode == MODE_BUILD) { UpdateModeBuild(); @@ -66,42 +70,77 @@ void Editor::Update() } // Raycast through everything on the map - using namespace kp3d; - struct Target + if (sandbox->IsMouseButtonDown(kp3d::MOUSE_BUTTON_LEFT)) { - Vec3 position; - float distance; - RenderBatch3D* b; - }; - std::vector targets; - for (RenderBatch3D& b: sandbox->map.GetMeshRef().GetBatchesRef()) - { - for (size_t i = 0; i < b.vertex_data.size(); i += 3) + using namespace kp3d; + struct Target { - Vec3 pos; - Triangle tri = {b.vertex_data[i].position, b.vertex_data[i + 1].position, b.vertex_data[i + 2].position}; - auto ray = GetRayFromCamera(sandbox->camera); - bool raycast = RayIntersectsTriangle(ray[0], ray[1], &tri, pos); - if (raycast) + Vec3 position; + float distance; + RenderBatch3D* b; + }; + std::vector targets; + for (RenderBatch3D& b : sandbox->map.GetMeshRef().GetBatchesRef()) + { + for (size_t i = 0; i < b.vertex_data.size(); i += 3) { - float dist = sqrtf( - pow(pos.x - sandbox->camera.position.x, 2) + - pow(pos.y - sandbox->camera.position.y, 2) + - pow(pos.z - sandbox->camera.position.z, 2) - ); - targets.push_back({pos, dist, &b}); + Vec3 pos; + Triangle tri = { b.vertex_data[i].position, b.vertex_data[i + 1].position, b.vertex_data[i + 2].position }; + auto ray = GetRayFromCamera(sandbox->camera); + bool raycast = RayIntersectsTriangle(ray[0], ray[1], &tri, pos); + if (raycast) + { + float dist = sqrtf( + pow(pos.x - sandbox->camera.position.x, 2) + + pow(pos.y - sandbox->camera.position.y, 2) + + pow(pos.z - sandbox->camera.position.z, 2) + ); + targets.push_back({ pos, dist, &b }); + } + } + if (!targets.empty()) + { + std::sort(targets.begin(), targets.end(), [&](const Target& a, const Target& b) { return a.distance > b.distance; }); + const Target& target = targets.back(); + if (editor_hovered_batch.empty()) + { + if (std::find(editor_hovered_batch.begin(), editor_hovered_batch.end(), target.b) == editor_hovered_batch.end()) + editor_hovered_batch.push_back(target.b); + } + else + { + try + { + const auto& info = std::any_cast(kp3d::editor_hovered_batch[0]->userdata); + const auto& target_info = std::any_cast(target.b->userdata); + if (info.wall && target_info.wall) + { + if (std::find(editor_hovered_batch.begin(), editor_hovered_batch.end(), target.b) == editor_hovered_batch.end()) + editor_hovered_batch.push_back(target.b); + } + else if (info.flat && target_info.flat) + { + if (std::find(editor_hovered_batch.begin(), editor_hovered_batch.end(), target.b) == editor_hovered_batch.end()) + editor_hovered_batch.push_back(target.b); + } + } + catch (std::bad_any_cast& e) + { + KP3D_LOG_ERROR("Bad any cast: {}", e.what()); + } + } + } + else + { + // editor_hovered_batch = nullptr; + if (!sandbox->IsKeyDown(kp3d::KEY_LSHIFT)) + { + editor_hovered_batch.clear(); + } } } - if (!targets.empty()) - { - std::sort(targets.begin(), targets.end(), [&](const Target& a, const Target& b) { return a.distance > b.distance; }); - const Target& target = targets.back(); - editor_hovered_batch = target.b; - } - else - editor_hovered_batch = nullptr; + sandbox->MouseButtonReset(kp3d::MOUSE_BUTTON_LEFT); } - } void Editor::RenderMap() @@ -292,11 +331,11 @@ void Editor::RenderUI() } else { - if (kp3d::editor_hovered_batch) + if (!kp3d::editor_hovered_batch.empty()) { try { - const auto& info = std::any_cast(kp3d::editor_hovered_batch->userdata); + const auto& info = std::any_cast(kp3d::editor_hovered_batch[0]->userdata); ImGui::SeparatorText("Type"); ImGui::Text(info.wall ? "Wall" : "Flat/Sector"); if (info.wall) @@ -309,9 +348,9 @@ void Editor::RenderUI() ImGui::CheckboxFlags("Double-sided", (unsigned*)&info.wall->user_flags, kp3d::Wall::UFLAG_DOUBLESIDED); ImGui::SeparatorText("Materials"); - RenderUIMaterialSelect("Middle", &info.wall->materials[kp3d::TEX_FRONT]); - RenderUIMaterialSelect("Upper", &info.wall->materials[kp3d::TEX_UPPER]); - RenderUIMaterialSelect("Lower", &info.wall->materials[kp3d::TEX_LOWER]); + RenderUIMaterialSelect("Middle", MAT_MIDDLE_TEX, &info.wall->materials[kp3d::TEX_FRONT]); + RenderUIMaterialSelect("Upper", MAT_UPPER_TEX, &info.wall->materials[kp3d::TEX_UPPER]); + RenderUIMaterialSelect("Lower", MAT_LOWER_TEX, &info.wall->materials[kp3d::TEX_LOWER]); } else if (info.sector) { @@ -331,8 +370,8 @@ void Editor::RenderUI() if (changed) sandbox->map.Rebuild(kp3d::GEN_NORMALS); ImGui::SeparatorText("Materials"); - RenderUIMaterialSelect("Floor", &info.sector->floor.material); - RenderUIMaterialSelect("Ceiling", &info.sector->ceiling.material); + RenderUIMaterialSelect("Floor", MAT_FLOOR_TEX, &info.sector->floor.material); + RenderUIMaterialSelect("Ceiling", MAT_CEILING_TEX, &info.sector->ceiling.material); } } catch (std::bad_any_cast& e) @@ -340,16 +379,20 @@ void Editor::RenderUI() KP3D_LOG_ERROR("Bad any cast: {}", e.what()); } } + else + { + ImGui::Text("No selection"); + } } ImGui::End(); } } - //ImGui::ShowDemoWindow(); - - if (m_material_to_update) + if (!m_materials_to_update.empty()) RenderUIMaterialModal(); + + anything_hovered = ImGui::IsWindowHovered(ImGuiHoveredFlags_AnyWindow) || ImGui::IsAnyItemHovered(); } void Editor::RenderUIInfo() @@ -403,15 +446,40 @@ void Editor::RenderUIAbout() } } -void Editor::RenderUIMaterialSelect(const char* name, const kp3d::Material** material) +void Editor::RenderUIMaterialSelect(const char* name, int type, const kp3d::Material** material) { ImGui::Text("%s:", name); if (material && *material) { - ImGui::PushID(material); // not safe, not ideal + ImGui::PushID(name + type); // not safe, not ideal if (ImGui::ImageButton((ImTextureID)(*material)->textures[kp3d::MAT_TEX_DIFFUSE].GetGLID(), {96, 96})) { - m_material_to_update = material; + //m_material_to_update = material; + // m_materials_to_update.push_back(material); + for (auto* batch: kp3d::editor_hovered_batch) + { + try + { + auto info = std::any_cast(batch->userdata); + if (info.wall) + { + switch (type) + { + case MAT_UPPER_TEX: m_materials_to_update.push_back(&info.wall->materials[kp3d::TEX_UPPER]); + case MAT_LOWER_TEX: m_materials_to_update.push_back(&info.wall->materials[kp3d::TEX_LOWER]); + case MAT_MIDDLE_TEX: m_materials_to_update.push_back(&info.wall->materials[kp3d::TEX_FRONT]); + } + } + else if (info.flat) + { + m_materials_to_update.push_back(&info.flat->material); + } + } + catch (std::bad_any_cast& e) + { + // ... + } + } should_show_material_modal = true; } ImGui::PopID(); @@ -496,7 +564,8 @@ void Editor::RenderUIMaterialModal() // Should we rebuild the map when we change stuff? I guess. if (should_remove_texture) { - *m_material_to_update = nullptr; + //*m_material_to_update = nullptr; + m_materials_to_update.clear(); ImGui::CloseCurrentPopup(); should_show_material_modal = false; sandbox->map.Rebuild(kp3d::GEN_NORMALS); @@ -511,7 +580,9 @@ void Editor::RenderUIMaterialModal() if (should_update_texture) { - *m_material_to_update = chosen_tex; + for (auto mats: m_materials_to_update) + *mats = chosen_tex; + m_materials_to_update.clear(); ImGui::CloseCurrentPopup(); should_show_material_modal = false; sandbox->map.Rebuild(kp3d::GEN_NORMALS); @@ -526,15 +597,18 @@ void Editor::OnScrollWheel(const kp3d::ScrollWheelEvent* e) { using namespace kp3d; - if (!editor_hovered_batch) + if (editor_hovered_batch.empty()) return; auto factor = (2.0f / 128.0f) * e->length; - auto info = std::any_cast(editor_hovered_batch->userdata); - if (info.flat) + for (auto* batch: editor_hovered_batch) { - info.flat->base_height += factor; - sandbox->map.Rebuild(GEN_NORMALS); + auto info = std::any_cast(batch->userdata); + if (info.flat) + { + info.flat->base_height += factor; + sandbox->map.Rebuild(GEN_NORMALS); + } } } diff --git a/Sandbox/src/Editor.h b/Sandbox/src/Editor.h index c0fe3d4..07b2a7c 100644 --- a/Sandbox/src/Editor.h +++ b/Sandbox/src/Editor.h @@ -12,6 +12,15 @@ enum EditMode MODE_SECTOR_EDIT }; +enum MaterialType +{ + MAT_FLOOR_TEX, + MAT_CEILING_TEX, + MAT_UPPER_TEX, + MAT_LOWER_TEX, + MAT_MIDDLE_TEX +}; + class Editor { public: @@ -31,7 +40,7 @@ public: void RenderUI(); void RenderUIInfo(); void RenderUIAbout(); - void RenderUIMaterialSelect(const char* name, const kp3d::Material** material); + void RenderUIMaterialSelect(const char* name, int type, const kp3d::Material** material); void RenderUIMaterialModal(); void OnScrollWheel(const kp3d::ScrollWheelEvent* e); @@ -52,6 +61,7 @@ private: bool show_about_view = false; bool should_show_material_modal = false; char m_tex_filter_buf[512]; - const kp3d::Material** m_material_to_update = nullptr; + bool anything_hovered = false; + std::vector m_materials_to_update; };