|
|
|
@ -12,13 +12,14 @@
|
|
|
|
|
#include "Editor/IconsMaterialDesign.h"
|
|
|
|
|
#include "ECS_Base/Components/SHComponent.h"
|
|
|
|
|
#include "Editor/SHEditorWidgets.hpp"
|
|
|
|
|
#include "Physics/Components/SHColliderComponent.h"
|
|
|
|
|
#include "Reflection/SHReflectionMetadata.h"
|
|
|
|
|
namespace SHADE
|
|
|
|
|
{
|
|
|
|
|
template<typename T, std::enable_if_t<std::is_base_of<SHComponent, T>::value, bool> = true>
|
|
|
|
|
static void DrawContextMenu(T* component)
|
|
|
|
|
{
|
|
|
|
|
if(!component)
|
|
|
|
|
if (!component)
|
|
|
|
|
return;
|
|
|
|
|
rttr::string_view componentName = rttr::type::get<T>().get_name();
|
|
|
|
|
|
|
|
|
@ -45,7 +46,7 @@ namespace SHADE
|
|
|
|
|
{
|
|
|
|
|
if (!component)
|
|
|
|
|
return;
|
|
|
|
|
auto componentType = rttr::type::get(*component);
|
|
|
|
|
const auto componentType = rttr::type::get(*component);
|
|
|
|
|
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; });
|
|
|
|
|
ImGui::SameLine();
|
|
|
|
|
if (ImGui::CollapsingHeader(componentType.get_name().data()))
|
|
|
|
@ -56,14 +57,14 @@ namespace SHADE
|
|
|
|
|
{
|
|
|
|
|
auto const& type = property.get_type();
|
|
|
|
|
|
|
|
|
|
if(type.is_enumeration())
|
|
|
|
|
if (type.is_enumeration())
|
|
|
|
|
{
|
|
|
|
|
auto enumAlign = type.get_enumeration();
|
|
|
|
|
auto names = enumAlign.get_names();
|
|
|
|
|
std::vector<const char*> list;
|
|
|
|
|
for(auto const& name : names)
|
|
|
|
|
for (auto const& name : names)
|
|
|
|
|
list.push_back(name.data());
|
|
|
|
|
SHEditorWidgets::ComboBox(property.get_name().data(), list, [component, property]{return property.get_value(component).to_int();}, [component, property](int const& idx)
|
|
|
|
|
SHEditorWidgets::ComboBox(property.get_name().data(), list, [component, property] {return property.get_value(component).to_int(); }, [component, property](int const& idx)
|
|
|
|
|
{
|
|
|
|
|
auto enumAlign = property.get_enumeration();
|
|
|
|
|
auto values = enumAlign.get_values();
|
|
|
|
@ -71,11 +72,11 @@ namespace SHADE
|
|
|
|
|
property.set_value(component, *it);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
else if(type.is_arithmetic())
|
|
|
|
|
else if (type.is_arithmetic())
|
|
|
|
|
{
|
|
|
|
|
if (type == rttr::type::get<bool>())
|
|
|
|
|
{
|
|
|
|
|
SHEditorWidgets::CheckBox(property.get_name().data(), [component, property]{return property.get_value(component).to_bool();}, [component, property](bool const& result){property.set_value(component, result);});
|
|
|
|
|
SHEditorWidgets::CheckBox(property.get_name().data(), [component, property] {return property.get_value(component).to_bool(); }, [component, property](bool const& result) {property.set_value(component, result); });
|
|
|
|
|
}
|
|
|
|
|
//else if (type == rttr::type::get<char>())
|
|
|
|
|
//{
|
|
|
|
@ -85,39 +86,39 @@ namespace SHADE
|
|
|
|
|
{
|
|
|
|
|
auto metaMin = property.get_metadata(META::min);
|
|
|
|
|
auto metaMax = property.get_metadata(META::max);
|
|
|
|
|
if(metaMin && metaMax)
|
|
|
|
|
if (metaMin && metaMax)
|
|
|
|
|
{
|
|
|
|
|
SHEditorWidgets::SliderInt(property.get_name().data(), metaMin.template get_value<int>(), metaMin.template get_value<int>(), [component, property]{return property.get_value(component).to_int();}, [component, property](int const& result){property.set_value(component, result);});
|
|
|
|
|
SHEditorWidgets::SliderInt(property.get_name().data(), metaMin.template get_value<int>(), metaMin.template get_value<int>(), [component, property] {return property.get_value(component).to_int(); }, [component, property](int const& result) {property.set_value(component, result); });
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
SHEditorWidgets::DragInt(property.get_name().data(), [component, property]{return property.get_value(component).to_int();}, [component, property](int const& result){property.set_value(component, result);});
|
|
|
|
|
SHEditorWidgets::DragInt(property.get_name().data(), [component, property] {return property.get_value(component).to_int(); }, [component, property](int const& result) {property.set_value(component, result); });
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (type == rttr::type::get<uint8_t>())
|
|
|
|
|
{
|
|
|
|
|
auto metaMin = property.get_metadata(META::min);
|
|
|
|
|
auto metaMax = property.get_metadata(META::max);
|
|
|
|
|
if(metaMin.is_valid() && metaMax.is_valid())
|
|
|
|
|
if (metaMin.is_valid() && metaMax.is_valid())
|
|
|
|
|
{
|
|
|
|
|
SHEditorWidgets::SliderScalar<uint8_t>(property.get_name().data(), ImGuiDataType_U8, metaMin.template get_value<uint8_t>(), metaMax.template get_value<uint8_t>(), [component, property]{return property.get_value(component).to_uint8();}, [component, property](uint8_t const& result){property.set_value(component, result);},"%zu");
|
|
|
|
|
SHEditorWidgets::SliderScalar<uint8_t>(property.get_name().data(), ImGuiDataType_U8, metaMin.template get_value<uint8_t>(), metaMax.template get_value<uint8_t>(), [component, property] {return property.get_value(component).to_uint8(); }, [component, property](uint8_t const& result) {property.set_value(component, result); }, "%zu");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
SHEditorWidgets::DragScalar<uint8_t>(property.get_name().data(), ImGuiDataType_U8, [component, property]{return property.get_value(component).to_uint8();}, [component, property](uint8_t const& result){property.set_value(component, result);},0.1f,0,0,"%zu");
|
|
|
|
|
SHEditorWidgets::DragScalar<uint8_t>(property.get_name().data(), ImGuiDataType_U8, [component, property] {return property.get_value(component).to_uint8(); }, [component, property](uint8_t const& result) {property.set_value(component, result); }, 0.1f, 0, 0, "%zu");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (type == rttr::type::get<uint16_t>())
|
|
|
|
|
{
|
|
|
|
|
auto metaMin = property.get_metadata(META::min);
|
|
|
|
|
auto metaMax = property.get_metadata(META::max);
|
|
|
|
|
if(metaMin.is_valid() && metaMax.is_valid())
|
|
|
|
|
if (metaMin.is_valid() && metaMax.is_valid())
|
|
|
|
|
{
|
|
|
|
|
SHEditorWidgets::SliderScalar<uint16_t>(property.get_name().data(), ImGuiDataType_U16, metaMin.template get_value<uint16_t>(), metaMin.template get_value<uint16_t>(), [component, property]{return property.get_value(component).to_uint16();}, [component, property](uint16_t const& result){property.set_value(component, result);},"%zu");
|
|
|
|
|
SHEditorWidgets::SliderScalar<uint16_t>(property.get_name().data(), ImGuiDataType_U16, metaMin.template get_value<uint16_t>(), metaMin.template get_value<uint16_t>(), [component, property] {return property.get_value(component).to_uint16(); }, [component, property](uint16_t const& result) {property.set_value(component, result); }, "%zu");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
SHEditorWidgets::DragScalar<uint16_t>(property.get_name().data(), ImGuiDataType_U16, [component, property]{return property.get_value(component).to_uint16();}, [component, property](uint16_t const& result){property.set_value(component, result);},0.1f,0,0,"%zu");
|
|
|
|
|
SHEditorWidgets::DragScalar<uint16_t>(property.get_name().data(), ImGuiDataType_U16, [component, property] {return property.get_value(component).to_uint16(); }, [component, property](uint16_t const& result) {property.set_value(component, result); }, 0.1f, 0, 0, "%zu");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (type == rttr::type::get<uint32_t>())
|
|
|
|
@ -126,50 +127,50 @@ namespace SHADE
|
|
|
|
|
auto metaMax = property.get_metadata(META::max);
|
|
|
|
|
if (metaMin.is_valid() && metaMax.is_valid())
|
|
|
|
|
{
|
|
|
|
|
SHEditorWidgets::SliderScalar<uint32_t>(property.get_name().data(), ImGuiDataType_U32, metaMin.template get_value<uint32_t>(), metaMin.template get_value<uint32_t>(), [component, property]{ return property.get_value(component).to_uint32(); }, [component, property](uint32_t const& result){property.set_value(component, result); },"%zu");
|
|
|
|
|
SHEditorWidgets::SliderScalar<uint32_t>(property.get_name().data(), ImGuiDataType_U32, metaMin.template get_value<uint32_t>(), metaMin.template get_value<uint32_t>(), [component, property] { return property.get_value(component).to_uint32(); }, [component, property](uint32_t const& result) {property.set_value(component, result); }, "%zu");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
SHEditorWidgets::DragScalar<uint32_t>(property.get_name().data(), ImGuiDataType_U32, [component, property]{ return property.get_value(component).to_uint32(); }, [component, property](uint32_t const& result){property.set_value(component, result); },0.1f,0,0,"%zu");
|
|
|
|
|
SHEditorWidgets::DragScalar<uint32_t>(property.get_name().data(), ImGuiDataType_U32, [component, property] { return property.get_value(component).to_uint32(); }, [component, property](uint32_t const& result) {property.set_value(component, result); }, 0.1f, 0, 0, "%zu");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (type == rttr::type::get<uint64_t>())
|
|
|
|
|
{
|
|
|
|
|
auto metaMin = property.get_metadata(META::min);
|
|
|
|
|
auto metaMax = property.get_metadata(META::max);
|
|
|
|
|
if(metaMin.is_valid() && metaMax.is_valid())
|
|
|
|
|
if (metaMin.is_valid() && metaMax.is_valid())
|
|
|
|
|
{
|
|
|
|
|
SHEditorWidgets::SliderScalar<uint64_t>(property.get_name().data(), ImGuiDataType_U64, metaMin.template get_value<uint64_t>(), metaMin.template get_value<uint64_t>(), [component, property]{return property.get_value(component).to_uint64();}, [component, property](uint64_t const& result){property.set_value(component, result);},"%zu");
|
|
|
|
|
SHEditorWidgets::SliderScalar<uint64_t>(property.get_name().data(), ImGuiDataType_U64, metaMin.template get_value<uint64_t>(), metaMin.template get_value<uint64_t>(), [component, property] {return property.get_value(component).to_uint64(); }, [component, property](uint64_t const& result) {property.set_value(component, result); }, "%zu");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
SHEditorWidgets::DragScalar<uint64_t>(property.get_name().data(), ImGuiDataType_U64, [component, property]{return property.get_value(component).to_uint64();}, [component, property](uint64_t const& result){property.set_value(component, result);},0.1f,0,0,"%zu");
|
|
|
|
|
SHEditorWidgets::DragScalar<uint64_t>(property.get_name().data(), ImGuiDataType_U64, [component, property] {return property.get_value(component).to_uint64(); }, [component, property](uint64_t const& result) {property.set_value(component, result); }, 0.1f, 0, 0, "%zu");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (type == rttr::type::get<float>())
|
|
|
|
|
{
|
|
|
|
|
auto metaMin = property.get_metadata(META::min);
|
|
|
|
|
auto metaMax = property.get_metadata(META::max);
|
|
|
|
|
if(metaMin.is_valid() && metaMax.is_valid())
|
|
|
|
|
if (metaMin.is_valid() && metaMax.is_valid())
|
|
|
|
|
{
|
|
|
|
|
SHEditorWidgets::SliderFloat(property.get_name().data(), metaMin.template get_value<float>(), metaMin.template get_value<float>(), [component, property]{return property.get_value(component).to_float();}, [component, property](float const& result){property.set_value(component, result);});
|
|
|
|
|
SHEditorWidgets::SliderFloat(property.get_name().data(), metaMin.template get_value<float>(), metaMin.template get_value<float>(), [component, property] {return property.get_value(component).to_float(); }, [component, property](float const& result) {property.set_value(component, result); });
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
SHEditorWidgets::DragFloat(property.get_name().data(), [component, property]{return property.get_value(component).to_float();}, [component, property](float const& result){property.set_value(component, result);});
|
|
|
|
|
SHEditorWidgets::DragFloat(property.get_name().data(), [component, property] {return property.get_value(component).to_float(); }, [component, property](float const& result) {property.set_value(component, result); });
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (type == rttr::type::get<double>())
|
|
|
|
|
{
|
|
|
|
|
auto metaMin = property.get_metadata(META::min);
|
|
|
|
|
auto metaMax = property.get_metadata(META::max);
|
|
|
|
|
if(metaMin.is_valid() && metaMax.is_valid())
|
|
|
|
|
if (metaMin.is_valid() && metaMax.is_valid())
|
|
|
|
|
{
|
|
|
|
|
SHEditorWidgets::SliderScalar<double>(property.get_name().data(), ImGuiDataType_Double, metaMin.template get_value<double>(), metaMin.template get_value<double>(), [component, property]{return property.get_value(component).to_double();}, [component, property](double const& result){property.set_value(component, result);});
|
|
|
|
|
SHEditorWidgets::SliderScalar<double>(property.get_name().data(), ImGuiDataType_Double, metaMin.template get_value<double>(), metaMin.template get_value<double>(), [component, property] {return property.get_value(component).to_double(); }, [component, property](double const& result) {property.set_value(component, result); });
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
SHEditorWidgets::DragScalar<double>(property.get_name().data(), ImGuiDataType_Double, [component, property]{return property.get_value(component).to_double();}, [component, property](double const& result){property.set_value(component, result);}, 0.1f);
|
|
|
|
|
SHEditorWidgets::DragScalar<double>(property.get_name().data(), ImGuiDataType_Double, [component, property] {return property.get_value(component).to_double(); }, [component, property](double const& result) {property.set_value(component, result); }, 0.1f);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -183,11 +184,76 @@ namespace SHADE
|
|
|
|
|
}
|
|
|
|
|
else if (type == rttr::type::get<SHVec2>())
|
|
|
|
|
{
|
|
|
|
|
SHEditorWidgets::DragVec2(property.get_name().data(), { "X", "Y"}, [component, property]() {return property.get_value(component).template convert<SHVec2>(); }, [component, property](SHVec2 vec) {return property.set_value(component, vec); });
|
|
|
|
|
SHEditorWidgets::DragVec2(property.get_name().data(), { "X", "Y" }, [component, property]() {return property.get_value(component).template convert<SHVec2>(); }, [component, property](SHVec2 vec) {return property.set_value(component, vec); });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else DrawContextMenu(component);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<>
|
|
|
|
|
static void DrawComponent(SHColliderComponent* component)
|
|
|
|
|
{
|
|
|
|
|
if (!component)
|
|
|
|
|
return;
|
|
|
|
|
const auto componentType = rttr::type::get(*component);
|
|
|
|
|
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; });
|
|
|
|
|
ImGui::SameLine();
|
|
|
|
|
if (ImGui::CollapsingHeader(componentType.get_name().data()))
|
|
|
|
|
{
|
|
|
|
|
DrawContextMenu(component);
|
|
|
|
|
|
|
|
|
|
auto& colliders = component->GetColliders();
|
|
|
|
|
int const size = static_cast<int>(colliders.size());
|
|
|
|
|
ImGui::BeginChild("Colliders", {0.0f, colliders.empty() ? 1.0f : 250.0f}, true);
|
|
|
|
|
for (int i{}; i < size; ++i)
|
|
|
|
|
{
|
|
|
|
|
SHCollider& collider = component->GetCollider(i);
|
|
|
|
|
auto cursorPos = ImGui::GetCursorPos();
|
|
|
|
|
|
|
|
|
|
if (collider.GetType() == SHCollider::Type::BOX)
|
|
|
|
|
{
|
|
|
|
|
SHEditorWidgets::BeginPanel( std::format("{} Box Collider #{}", ICON_MD_VIEW_IN_AR, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y });
|
|
|
|
|
auto box = reinterpret_cast<SHBoundingBox*>(collider.GetShape());
|
|
|
|
|
SHEditorWidgets::DragVec3("Half Extents", { "X", "Y", "Z" }, [box] {return box->GetHalfExtents(); }, [box](SHVec3 const& vec) {box->SetHalfExtents(vec);});
|
|
|
|
|
}
|
|
|
|
|
else if (collider.GetType() == SHCollider::Type::SPHERE)
|
|
|
|
|
{
|
|
|
|
|
SHEditorWidgets::BeginPanel(std::format("{} Sphere Collider #{}", ICON_MD_CIRCLE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y });
|
|
|
|
|
auto sphere = reinterpret_cast<SHBoundingSphere*>(collider.GetShape());
|
|
|
|
|
SHEditorWidgets::DragFloat("Radius", [sphere] {return sphere->GetRadius(); }, [sphere](float const& value) {sphere->SetRadius(value);});
|
|
|
|
|
}
|
|
|
|
|
else if (collider.GetType() == SHCollider::Type::CAPSULE)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
SHEditorWidgets::BeginPanel("Offset", { ImGui::GetContentRegionAvail().x, 30.0f });
|
|
|
|
|
SHEditorWidgets::DragVec3("Position", { "X", "Y", "Z" }, [&collider] {return collider.GetPositionOffset(); }, [&collider](SHVec3 const& vec) {collider.SetPositionOffset(vec); });
|
|
|
|
|
SHEditorWidgets::EndPanel();
|
|
|
|
|
}
|
|
|
|
|
if(ImGui::Button(std::format("{} Remove Collider #{}", ICON_MD_REMOVE, i).data()))
|
|
|
|
|
{
|
|
|
|
|
component->RemoveCollider(i);
|
|
|
|
|
}
|
|
|
|
|
SHEditorWidgets::EndPanel();
|
|
|
|
|
}
|
|
|
|
|
ImGui::EndChild();
|
|
|
|
|
|
|
|
|
|
if (ImGui::BeginMenu("Add Collider"))
|
|
|
|
|
{
|
|
|
|
|
if(ImGui::Selectable("Box Collider"))
|
|
|
|
|
{
|
|
|
|
|
component->AddBoundingBox();
|
|
|
|
|
}
|
|
|
|
|
if(ImGui::Selectable("Sphere Collider"))
|
|
|
|
|
{
|
|
|
|
|
component->AddBoundingSphere();
|
|
|
|
|
}
|
|
|
|
|
ImGui::EndMenu();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else DrawContextMenu(component);
|
|
|
|
|
}
|
|
|
|
|
}
|