Files
Nuake-custom/Editor/src/ComponentsPanel/NavMeshVolumePanel.h

389 lines
14 KiB
C++

#pragma once
#include "ComponentPanel.h"
#include <src/Scene/Entities/ImGuiHelper.h>
#include <src/Scene/Components/NavMeshVolumeComponent.h>
#include "src/AI/NavManager.h"
#include "src/Scene/Components/QuakeMap.h"
#include <src/Core/Maths.h>
#include <src/AI/RecastConfig.h>
class NavMeshVolumePanel
{
public:
static void Draw(Nuake::Entity& entity, entt::meta_any& componentInstance)
{
using namespace Nuake;
Nuake::NavMeshVolumeComponent* componentPtr = componentInstance.try_cast<Nuake::NavMeshVolumeComponent>();
if (componentPtr == nullptr)
{
return;
}
Nuake::NavMeshVolumeComponent& component = *componentPtr;
BeginComponentTable(NAVMESH VOLUME, NavMeshVolumeComponent);
{
{
CompononentPropertyName("Volume Bounds");
ImGui::TableNextColumn();
Vector3 volumeSize = component.VolumeSize;
ImGuiHelper::DrawVec3("VolumeSize", &volumeSize);
if (volumeSize.x > 0 && volumeSize.y > 0 && volumeSize.z > 0)
{
component.VolumeSize = volumeSize;
}
ImGui::TableNextColumn();
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1, 1, 1, 0));
std::string resetLabel = std::string(ICON_FA_UNDO) + "##ResetVolumeSize";
if (ImGui::Button(resetLabel.c_str()))
{
volumeSize = { 1.0, 1.0, 1.0 };
}
ImGui::PopStyleColor();
}
ImGui::TableNextColumn();
{
CompononentPropertyName("Only include map");
ImGui::TableNextColumn();
Vector3 volumeSize = component.VolumeSize;
UI::CheckBox("##onlyIncludeMapGeo", component.OnlyIncludeMapGeometry);
ImGui::TableNextColumn();
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1, 1, 1, 0));
std::string resetLabel = std::string(ICON_FA_UNDO) + "##ResetOnlyIncludeGeo";
if (ImGui::Button(resetLabel.c_str()))
{
component.OnlyIncludeMapGeometry = true;
}
ImGui::PopStyleColor();
}
ImGui::TableNextColumn();
{
CompononentPropertyName("Cell Size");
ImGui::TableNextColumn();
UI::FloatSlider("##cellsize", component.CellSize, 0.01f, 10.0f, 0.1f);
ImGui::TableNextColumn();
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1, 1, 1, 0));
std::string resetLabel = std::string(ICON_FA_UNDO) + "##resetcellsize";
if (ImGui::Button(resetLabel.c_str()))
{
component.CellSize = 0.2f;
}
ImGui::PopStyleColor();
}
ImGui::TableNextColumn();
{
CompononentPropertyName("Cell Height");
ImGui::TableNextColumn();
UI::FloatSlider("##cellHeight", component.CellHeight, 0.01f, 50.0f, 0.1f);
ImGui::TableNextColumn();
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1, 1, 1, 0));
std::string resetLabel = std::string(ICON_FA_UNDO) + "##resetcellheight";
if (ImGui::Button(resetLabel.c_str()))
{
component.CellHeight = 0.2f;
}
ImGui::PopStyleColor();
}
ImGui::TableNextColumn();
{
CompononentPropertyName("Tile Size");
ImGui::TableNextColumn();
UI::FloatSlider("##tilesize", component.TileSize, 0.01f, 50.0f, 0.1f);
ImGui::TableNextColumn();
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1, 1, 1, 0));
std::string resetLabel = std::string(ICON_FA_UNDO) + "##resettilesize";
if (ImGui::Button(resetLabel.c_str()))
{
component.TileSize = 10.0f;
}
ImGui::PopStyleColor();
}
ImGui::TableNextColumn();
{
CompononentPropertyName("Walkable Slope Angle");
ImGui::TableNextColumn();
UI::FloatSlider("##walkableslopeAngle", component.WalkableSlopeAngle, 1.0f, 90.0f, 0.1f);
ImGui::TableNextColumn();
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1, 1, 1, 0));
std::string resetLabel = std::string(ICON_FA_UNDO) + "##resetwalkableslopeangle";
if (ImGui::Button(resetLabel.c_str()))
{
component.WalkableSlopeAngle = 45.0f;
}
ImGui::PopStyleColor();
}
ImGui::TableNextColumn();
{
CompononentPropertyName("Walkable Height");
ImGui::TableNextColumn();
UI::FloatSlider("##WalkableHeight", component.WalkableHeight, 10.0f, 0.1f, 0.1f);
ImGui::TableNextColumn();
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1, 1, 1, 0));
std::string resetLabel = std::string(ICON_FA_UNDO) + "##resetWalkableHeight";
if (ImGui::Button(resetLabel.c_str()))
{
component.WalkableHeight = 1.0f;
}
ImGui::PopStyleColor();
}
ImGui::TableNextColumn();
{
CompononentPropertyName("Walkable Radius");
ImGui::TableNextColumn();
UI::FloatSlider("##WalkableRadius", component.WalkableRadius, 0.1f, 10.0f, 0.1f);
ImGui::TableNextColumn();
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1, 1, 1, 0));
std::string resetLabel = std::string(ICON_FA_UNDO) + "##resetWalkableRadius";
if (ImGui::Button(resetLabel.c_str()))
{
component.WalkableRadius = 1.0f;
}
ImGui::PopStyleColor();
}
ImGui::TableNextColumn();
{
CompononentPropertyName("Walkable Climb");
ImGui::TableNextColumn();
UI::FloatSlider("##WalkableClimb", component.WalkableClimb, 0.1f, 10.0f, 0.1f);
ImGui::TableNextColumn();
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1, 1, 1, 0));
std::string resetLabel = std::string(ICON_FA_UNDO) + "##resetWalkableClimb";
if (ImGui::Button(resetLabel.c_str()))
{
component.WalkableClimb = 1.0f;
}
ImGui::PopStyleColor();
}
ImGui::TableNextColumn();
{
CompononentPropertyName("Max Simplification Error");
ImGui::TableNextColumn();
UI::FloatSlider("##MaxSimplificationError", component.MaxSimplificationError, 0.1f, 10.0f, 0.1f);
ImGui::TableNextColumn();
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1, 1, 1, 0));
std::string resetLabel = std::string(ICON_FA_UNDO) + "##resetMaxSimplificationError";
if (ImGui::Button(resetLabel.c_str()))
{
component.MaxSimplificationError = 1.3f;
}
ImGui::PopStyleColor();
}
ImGui::TableNextColumn();
{
CompononentPropertyName("Min Region Area");
ImGui::TableNextColumn();
UI::FloatSlider("##MinRegionArea", component.MinRegionArea, 0.1f, 10.0f, 0.1f);
ImGui::TableNextColumn();
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1, 1, 1, 0));
std::string resetLabel = std::string(ICON_FA_UNDO) + "##resetMinRegionArea";
if (ImGui::Button(resetLabel.c_str()))
{
component.MinRegionArea = 4.f;
}
ImGui::PopStyleColor();
}
ImGui::TableNextColumn();
{
CompononentPropertyName("Merge Region Area");
ImGui::TableNextColumn();
UI::FloatSlider("##MergeRegionArea", component.MergeRegionArea, 0.1f, 25.0f, 0.1f);
ImGui::TableNextColumn();
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1, 1, 1, 0));
std::string resetLabel = std::string(ICON_FA_UNDO) + "##resetMergeRegionArea";
if (ImGui::Button(resetLabel.c_str()))
{
component.MergeRegionArea = 10.f;
}
ImGui::PopStyleColor();
}
ImGui::TableNextColumn();
{
CompononentPropertyName("Max Edge Length");
ImGui::TableNextColumn();
UI::FloatSlider("##MaxEdgeLength", component.MaxEdgeLength, 0.1f, 20.0f, 0.1f);
ImGui::TableNextColumn();
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1, 1, 1, 0));
std::string resetLabel = std::string(ICON_FA_UNDO) + "##resetMaxEdgeLength";
if (ImGui::Button(resetLabel.c_str()))
{
component.MaxEdgeLength = 12.f;
}
ImGui::PopStyleColor();
}
ImGui::TableNextColumn();
{
CompononentPropertyName("MaxVertsPerPoly");
ImGui::TableNextColumn();
UI::FloatSlider("##MaxVertsPerPoly", component.MaxVertsPerPoly, 3.f, 6.0f, 1.0f);
ImGui::TableNextColumn();
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1, 1, 1, 0));
std::string resetLabel = std::string(ICON_FA_UNDO) + "##resetMaxVertsPerPoly";
if (ImGui::Button(resetLabel.c_str()))
{
component.MaxVertsPerPoly = 6.f;
}
ImGui::PopStyleColor();
}
ImGui::TableNextColumn();
{
CompononentPropertyName("Detail Sample Distance");
ImGui::TableNextColumn();
UI::FloatSlider("##DetailSampleDistance", component.DetailSampleDistance, 0.1f, 10.0f , 0.1f);
ImGui::TableNextColumn();
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1, 1, 1, 0));
std::string resetLabel = std::string(ICON_FA_UNDO) + "##resetDetailSampleDistance";
if (ImGui::Button(resetLabel.c_str()))
{
component.DetailSampleDistance = 2.f;
}
ImGui::PopStyleColor();
}
ImGui::TableNextColumn();
{
CompononentPropertyName("Detail Sample Max Error");
ImGui::TableNextColumn();
UI::FloatSlider("##DetailsampleMaxError", component.DetailsampleMaxError, 0.1f, 10.0f, 0.1f);
ImGui::TableNextColumn();
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1, 1, 1, 0));
std::string resetLabel = std::string(ICON_FA_UNDO) + "##resetDetailsampleMaxError";
if (ImGui::Button(resetLabel.c_str()))
{
component.DetailsampleMaxError = 1.f;
}
ImGui::PopStyleColor();
}
ImGui::TableNextColumn();
{
CompononentPropertyName("Generate");
ImGui::TableNextColumn();
if (UI::SecondaryButton("Generate"))
{
if (component.OnlyIncludeMapGeometry)
{
auto& volumeTransformComponent = entity.GetComponent<TransformComponent>();
Matrix4 globalTransform = volumeTransformComponent.GetGlobalTransform();
Matrix4 offset = Matrix4(1.0f);
offset = glm::translate(offset, volumeTransformComponent.GetGlobalPosition());
auto view = Engine::GetCurrentScene()->m_Registry.view<TransformComponent, QuakeMapComponent>();
for (auto e : view)
{
auto [transform, map] = view.get<TransformComponent, QuakeMapComponent>(e);
for (auto& brush : map.m_Brushes)
{
if (!brush.HasComponent<ModelComponent>())
{
continue;
}
auto& transformComponent = brush.GetComponent<TransformComponent>();
auto& modelComponent = brush.GetComponent<ModelComponent>();
for (auto& mesh : modelComponent.ModelResource->GetMeshes())
{
Nuake::NavManager::Get().PushMesh(mesh, transformComponent.GetGlobalTransform());
}
}
}
auto recastConfig = RecastConfig(component);
recastConfig.Position = volumeTransformComponent.GetGlobalPosition();
component.NavMeshData = NavManager::Get().BuildNavMesh(std::move(recastConfig));
}
}
ImGui::TableNextColumn();
// No reset button
ImGui::TableNextColumn();
}
}
EndComponentTable();
}
};