Files
WickedEngine/Editor/VoxelGridWindow.cpp
T
Turánszki János fea9d9f702 Pathfinding (#805)
2024-02-25 18:40:50 +01:00

240 lines
8.1 KiB
C++

#include "stdafx.h"
#include "VoxelGridWindow.h"
using namespace wi::ecs;
using namespace wi::scene;
void VoxelGridWindow::Create(EditorComponent* _editor)
{
editor = _editor;
wi::gui::Window::Create(ICON_VOXELGRID " VoxelGrid", wi::gui::Window::WindowControls::COLLAPSE | wi::gui::Window::WindowControls::CLOSE);
SetSize(XMFLOAT2(520, 400));
closeButton.SetTooltip("Delete VoxelGrid");
OnClose([=](wi::gui::EventArgs args) {
wi::Archive& archive = editor->AdvanceHistory();
archive << EditorComponent::HISTORYOP_COMPONENT_DATA;
editor->RecordEntity(archive, entity);
editor->GetCurrentScene().voxel_grids.Remove(entity);
editor->RecordEntity(archive, entity);
editor->optionsWnd.RefreshEntityTree();
});
float x = 80;
float y = 0;
float hei = 18;
float wid = 200;
float step = hei + 4;
infoLabel.Create("");
infoLabel.SetSize(XMFLOAT2(100, 150));
AddWidget(&infoLabel);
dimXInput.Create("DimX");
dimXInput.SetSize(XMFLOAT2(100, hei));
dimXInput.SetDescription("Dimension X: ");
dimXInput.OnInputAccepted([=](wi::gui::EventArgs args) {
Scene& scene = editor->GetCurrentScene();
wi::VoxelGrid* voxelgrid = scene.voxel_grids.GetComponent(entity);
if (voxelgrid == nullptr)
return;
voxelgrid->init(uint32_t(std::max(1, args.iValue)), voxelgrid->resolution.y, voxelgrid->resolution.z);
});
AddWidget(&dimXInput);
dimYInput.Create("DimY");
dimYInput.SetSize(XMFLOAT2(100, hei));
dimYInput.SetDescription("Y: ");
dimYInput.OnInputAccepted([=](wi::gui::EventArgs args) {
Scene& scene = editor->GetCurrentScene();
wi::VoxelGrid* voxelgrid = scene.voxel_grids.GetComponent(entity);
if (voxelgrid == nullptr)
return;
voxelgrid->init(voxelgrid->resolution.x, uint32_t(std::max(1, args.iValue)), voxelgrid->resolution.z);
});
AddWidget(&dimYInput);
dimZInput.Create("DimZ");
dimZInput.SetSize(XMFLOAT2(100, hei));
dimZInput.SetDescription("Z: ");
dimZInput.OnInputAccepted([=](wi::gui::EventArgs args) {
Scene& scene = editor->GetCurrentScene();
wi::VoxelGrid* voxelgrid = scene.voxel_grids.GetComponent(entity);
if (voxelgrid == nullptr)
return;
voxelgrid->init(voxelgrid->resolution.x, voxelgrid->resolution.y, uint32_t(std::max(1, args.iValue)));
});
AddWidget(&dimZInput);
clearButton.Create("Clear voxels " ICON_CLEARVOXELS);
clearButton.SetSize(XMFLOAT2(100, hei));
clearButton.OnClick([=](wi::gui::EventArgs args) {
Scene& scene = editor->GetCurrentScene();
wi::VoxelGrid* voxelgrid = scene.voxel_grids.GetComponent(entity);
if (voxelgrid == nullptr)
return;
voxelgrid->cleardata();
});
AddWidget(&clearButton);
voxelizeObjectsButton.Create("Voxelize objects " ICON_VOXELIZE);
voxelizeObjectsButton.SetTooltip("Generate navigation grid including all meshes.");
voxelizeObjectsButton.SetSize(XMFLOAT2(100, hei));
voxelizeObjectsButton.OnClick([=](wi::gui::EventArgs args) {
Scene& scene = editor->GetCurrentScene();
wi::VoxelGrid* voxelgrid = scene.voxel_grids.GetComponent(entity);
if (voxelgrid == nullptr)
return;
scene.VoxelizeScene(*voxelgrid, subtractCheckBox.GetCheck(), wi::enums::FILTER_OBJECT_ALL);
});
AddWidget(&voxelizeObjectsButton);
voxelizeNavigationButton.Create("Voxelize navigation " ICON_VOXELIZE);
voxelizeNavigationButton.SetTooltip("Generate navigation grid including all navmeshes (object tagged as navmesh).");
voxelizeNavigationButton.SetSize(XMFLOAT2(100, hei));
voxelizeNavigationButton.OnClick([=](wi::gui::EventArgs args) {
Scene& scene = editor->GetCurrentScene();
wi::VoxelGrid* voxelgrid = scene.voxel_grids.GetComponent(entity);
if (voxelgrid == nullptr)
return;
scene.VoxelizeScene(*voxelgrid, subtractCheckBox.GetCheck(), wi::enums::FILTER_NAVIGATION_MESH);
});
AddWidget(&voxelizeNavigationButton);
voxelizeCollidersButton.Create("Voxelize CPU colliders " ICON_VOXELIZE);
voxelizeCollidersButton.SetTooltip("Generate navigation grid including all CPU colliders.");
voxelizeCollidersButton.SetSize(XMFLOAT2(100, hei));
voxelizeCollidersButton.OnClick([=](wi::gui::EventArgs args) {
Scene& scene = editor->GetCurrentScene();
wi::VoxelGrid* voxelgrid = scene.voxel_grids.GetComponent(entity);
if (voxelgrid == nullptr)
return;
scene.VoxelizeScene(*voxelgrid, subtractCheckBox.GetCheck(), wi::enums::FILTER_COLLIDER);
});
AddWidget(&voxelizeCollidersButton);
fitToSceneButton.Create("Fit bounds to scene " ICON_VOXELBOUNDS);
fitToSceneButton.SetTooltip("Fit the bounds of the voxel grid onto the whole scene.");
fitToSceneButton.SetSize(XMFLOAT2(100, hei));
fitToSceneButton.OnClick([=](wi::gui::EventArgs args) {
Scene& scene = editor->GetCurrentScene();
if (scene.bounds.getArea() < 0)
return;
wi::VoxelGrid* voxelgrid = scene.voxel_grids.GetComponent(entity);
if (voxelgrid == nullptr)
return;
voxelgrid->from_aabb(scene.bounds);
TransformComponent* transform = scene.transforms.GetComponent(entity);
if (transform != nullptr)
{
// feed back to transform component if it exists:
transform->translation_local = voxelgrid->center;
transform->scale_local = voxelgrid->voxelSize;
transform->SetDirty();
}
});
AddWidget(&fitToSceneButton);
subtractCheckBox.Create("Subtraction mode: ");
subtractCheckBox.SetTooltip("If enabled, voxelization will be subtractive, so it will remove voxels instead of add.");
subtractCheckBox.SetSize(XMFLOAT2(hei, hei));
AddWidget(&subtractCheckBox);
debugAllCheckBox.Create("Debug draw all: ");
debugAllCheckBox.SetTooltip("Draw all voxel grids, whether they are selected or not.");
debugAllCheckBox.SetSize(XMFLOAT2(hei, hei));
AddWidget(&debugAllCheckBox);
SetMinimized(true);
SetVisible(false);
}
void VoxelGridWindow::SetEntity(Entity entity)
{
bool changed = this->entity != entity;
this->entity = entity;
Scene& scene = editor->GetCurrentScene();
wi::VoxelGrid* voxelgrid = scene.voxel_grids.GetComponent(entity);
if (voxelgrid != nullptr)
{
std::string infotext = "Voxel grid can be used for navigation. By voxelizing the scene into the grid, path finding can be used on the resulting voxel grid.";
infotext += "\n\nMemory usage: ";
infotext += wi::helper::GetMemorySizeText(voxelgrid->get_memory_size());
infoLabel.SetText(infotext);
dimXInput.SetValue((int)voxelgrid->resolution.x);
dimYInput.SetValue((int)voxelgrid->resolution.y);
dimZInput.SetValue((int)voxelgrid->resolution.z);
}
}
void VoxelGridWindow::ResizeLayout()
{
wi::gui::Window::ResizeLayout();
const float padding = 4;
const float width = GetWidgetAreaSize().x;
float y = padding;
float jump = 20;
const float margin_left = 90;
const float margin_right = 40;
auto add = [&](wi::gui::Widget& widget) {
if (!widget.IsVisible())
return;
widget.SetPos(XMFLOAT2(margin_left, y));
widget.SetSize(XMFLOAT2(width - margin_left - margin_right, widget.GetScale().y));
y += widget.GetSize().y;
y += padding;
};
auto add_right = [&](wi::gui::Widget& widget) {
if (!widget.IsVisible())
return;
const float margin_right = padding;
widget.SetPos(XMFLOAT2(width - margin_right - widget.GetSize().x, y));
y += widget.GetSize().y;
y += padding;
};
auto add_fullwidth = [&](wi::gui::Widget& widget) {
if (!widget.IsVisible())
return;
const float margin_left = padding;
const float margin_right = padding;
widget.SetPos(XMFLOAT2(margin_left, y));
widget.SetSize(XMFLOAT2(width - margin_left - margin_right, widget.GetScale().y));
y += widget.GetSize().y;
y += padding;
};
add_fullwidth(infoLabel);
const float padding2 = 20;
const float l = 95;
const float r = width;
float w = ((r - l) - padding2 * 2) / 3.0f;
dimXInput.SetSize(XMFLOAT2(w, dimXInput.GetSize().y));
dimYInput.SetSize(XMFLOAT2(w, dimYInput.GetSize().y));
dimZInput.SetSize(XMFLOAT2(w, dimZInput.GetSize().y));
dimXInput.SetPos(XMFLOAT2(margin_left, y));
dimYInput.SetPos(XMFLOAT2(dimXInput.GetPos().x + w + padding2, y));
dimZInput.SetPos(XMFLOAT2(dimYInput.GetPos().x + w + padding2, y));
y += dimZInput.GetSize().y;
y += padding;
add_fullwidth(clearButton);
add_fullwidth(voxelizeObjectsButton);
add_fullwidth(voxelizeCollidersButton);
add_fullwidth(voxelizeNavigationButton);
add_fullwidth(fitToSceneButton);
add_right(subtractCheckBox);
add_right(debugAllCheckBox);
}