Add ability to select multiple things in editor
This commit is contained in:
parent
7cd5cb59d3
commit
62dd36d7d6
6 changed files with 194 additions and 57 deletions
Binary file not shown.
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.3 KiB |
|
@ -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
|
|
@ -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<kp3d::BatchSectorInfo>(batch.userdata);
|
||||
// if (!kp3d::editor_hovered_batch)
|
||||
// return 0xFFFFFFFF;
|
||||
// if (&batch != kp3d::editor_hovered_batch)
|
||||
// return 0xFFFFFFFF;
|
||||
BatchSectorInfo info = std::any_cast<BatchSectorInfo>(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<RenderBatch3D*> editor_hovered_batch;
|
||||
|
||||
Map::Map()
|
||||
{
|
||||
|
|
|
@ -173,6 +173,6 @@ private:
|
|||
|
||||
};
|
||||
|
||||
extern RenderBatch3D* editor_hovered_batch; // hack
|
||||
extern std::vector<RenderBatch3D*> editor_hovered_batch; // hack
|
||||
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <imgui.h>
|
||||
|
||||
#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<Target> 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<Target> 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::BatchSectorInfo>(kp3d::editor_hovered_batch[0]->userdata);
|
||||
const auto& target_info = std::any_cast<kp3d::BatchSectorInfo>(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::BatchSectorInfo>(kp3d::editor_hovered_batch->userdata);
|
||||
const auto& info = std::any_cast<kp3d::BatchSectorInfo>(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<kp3d::BatchSectorInfo>(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<BatchSectorInfo>(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<BatchSectorInfo>(batch->userdata);
|
||||
if (info.flat)
|
||||
{
|
||||
info.flat->base_height += factor;
|
||||
sandbox->map.Rebuild(GEN_NORMALS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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<const kp3d::Material**> m_materials_to_update;
|
||||
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue