389 lines
14 KiB
C++
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();
|
|
}
|
|
};
|