Merge remote-tracking branch 'origin/main' into CameraIntegration
This commit is contained in:
commit
212e1e7c1f
|
@ -21,6 +21,8 @@
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
|
|
||||||
|
#include "Serialization/SHSerialization.h"
|
||||||
|
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -171,6 +173,10 @@ namespace SHADE
|
||||||
editor->selectedEntities.clear();
|
editor->selectedEntities.clear();
|
||||||
editor->selectedEntities.push_back(eid);
|
editor->selectedEntities.push_back(eid);
|
||||||
}
|
}
|
||||||
|
if(ImGui::Selectable("Copy"))
|
||||||
|
{
|
||||||
|
SHLOG_INFO(SHSerialization::SerializeEntitiesToString(editor->selectedEntities))
|
||||||
|
}
|
||||||
if(ImGui::Selectable(std::format("{} Delete", ICON_MD_DELETE).data()))
|
if(ImGui::Selectable(std::format("{} Delete", ICON_MD_DELETE).data()))
|
||||||
{
|
{
|
||||||
SHEntityManager::DestroyEntity(eid);
|
SHEntityManager::DestroyEntity(eid);
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
#include <imgui_internal.h>
|
#include <imgui_internal.h>
|
||||||
#include <rttr/type>
|
#include <rttr/type>
|
||||||
|
|
||||||
|
#include "Serialization/SHSerialization.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
constexpr ImGuiWindowFlags editorMenuBarFlags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse |
|
constexpr ImGuiWindowFlags editorMenuBarFlags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse |
|
||||||
|
@ -73,7 +75,14 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
if (ImGui::BeginMenu("File"))
|
if (ImGui::BeginMenu("File"))
|
||||||
{
|
{
|
||||||
|
if(ImGui::Selectable("Save"))
|
||||||
|
{
|
||||||
|
SHSerialization::SerializeSceneToFile("../../Assets/Scenes/Test.SHADE");
|
||||||
|
}
|
||||||
|
if(ImGui::Selectable("Load"))
|
||||||
|
{
|
||||||
|
SHSerialization::DeserializeSceneFromFile("../../Assets/Scenes/Test.SHADE");
|
||||||
|
}
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
if(ImGui::BeginMenu("Edit"))
|
if(ImGui::BeginMenu("Edit"))
|
||||||
|
|
|
@ -67,6 +67,11 @@ namespace SHADE
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SHEditorUI::IsItemHovered()
|
||||||
|
{
|
||||||
|
return ImGui::IsItemHovered();
|
||||||
|
}
|
||||||
|
|
||||||
bool SHEditorUI::BeginMenu(const std::string& label)
|
bool SHEditorUI::BeginMenu(const std::string& label)
|
||||||
{
|
{
|
||||||
return ImGui::BeginMenu(label.data());
|
return ImGui::BeginMenu(label.data());
|
||||||
|
@ -82,6 +87,16 @@ namespace SHADE
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHEditorUI::BeginTooltip()
|
||||||
|
{
|
||||||
|
ImGui::BeginTooltip();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHEditorUI::EndTooltip()
|
||||||
|
{
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* ImGui Wrapper Functions - Pop Ups */
|
/* ImGui Wrapper Functions - Pop Ups */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
@ -135,24 +150,30 @@ namespace SHADE
|
||||||
return ImGui::Selectable(std::format("{} {}", icon, label).data());
|
return ImGui::Selectable(std::format("{} {}", icon, label).data());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SHEditorUI::InputCheckbox(const std::string& label, bool& value)
|
bool SHEditorUI::InputCheckbox(const std::string& label, bool& value, bool* isHovered)
|
||||||
{
|
{
|
||||||
ImGui::Text(label.c_str());
|
ImGui::Text(label.c_str());
|
||||||
|
if (isHovered)
|
||||||
|
*isHovered = ImGui::IsItemHovered();
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
return ImGui::Checkbox("#", &value);
|
return ImGui::Checkbox("#", &value);
|
||||||
}
|
}
|
||||||
bool SHEditorUI::InputInt(const std::string& label, int& value)
|
bool SHEditorUI::InputInt(const std::string& label, int& value, bool* isHovered)
|
||||||
{
|
{
|
||||||
ImGui::Text(label.c_str());
|
ImGui::Text(label.c_str());
|
||||||
|
if (isHovered)
|
||||||
|
*isHovered = ImGui::IsItemHovered();
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
return ImGui::InputInt("#", &value,
|
return ImGui::InputInt("#", &value,
|
||||||
1, 10,
|
1, 10,
|
||||||
ImGuiInputTextFlags_EnterReturnsTrue);
|
ImGuiInputTextFlags_EnterReturnsTrue);
|
||||||
}
|
}
|
||||||
bool SHEditorUI::InputUnsignedInt(const std::string& label, unsigned int& value)
|
bool SHEditorUI::InputUnsignedInt(const std::string& label, unsigned int& value, bool* isHovered)
|
||||||
{
|
{
|
||||||
int signedVal = static_cast<int>(value);
|
int signedVal = static_cast<int>(value);
|
||||||
ImGui::Text(label.c_str());
|
ImGui::Text(label.c_str());
|
||||||
|
if (isHovered)
|
||||||
|
*isHovered = ImGui::IsItemHovered();
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
const bool CHANGED = InputInt("#", signedVal);
|
const bool CHANGED = InputInt("#", signedVal);
|
||||||
if (CHANGED)
|
if (CHANGED)
|
||||||
|
@ -162,64 +183,101 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
return CHANGED;
|
return CHANGED;
|
||||||
}
|
}
|
||||||
bool SHEditorUI::InputFloat(const std::string& label, float& value)
|
bool SHEditorUI::InputFloat(const std::string& label, float& value, bool* isHovered)
|
||||||
{
|
{
|
||||||
ImGui::Text(label.c_str());
|
ImGui::Text(label.c_str());
|
||||||
|
if (isHovered)
|
||||||
|
*isHovered = ImGui::IsItemHovered();
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
return ImGui::InputFloat("#", &value,
|
return ImGui::InputFloat("#", &value,
|
||||||
0.1f, 1.0f, "%.3f",
|
0.1f, 1.0f, "%.3f",
|
||||||
ImGuiInputTextFlags_EnterReturnsTrue);
|
ImGuiInputTextFlags_EnterReturnsTrue);
|
||||||
}
|
}
|
||||||
bool SHEditorUI::InputDouble(const std::string& label, double& value)
|
bool SHEditorUI::InputDouble(const std::string& label, double& value, bool* isHovered)
|
||||||
{
|
{
|
||||||
ImGui::Text(label.c_str());
|
ImGui::Text(label.c_str());
|
||||||
|
if (isHovered)
|
||||||
|
*isHovered = ImGui::IsItemHovered();
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
return ImGui::InputDouble("#", &value,
|
return ImGui::InputDouble("#", &value,
|
||||||
0.1, 1.0, "%.3f",
|
0.1, 1.0, "%.3f",
|
||||||
ImGuiInputTextFlags_EnterReturnsTrue);
|
ImGuiInputTextFlags_EnterReturnsTrue);
|
||||||
}
|
}
|
||||||
bool SHEditorUI::InputAngle(const std::string& label, double& value)
|
bool SHEditorUI::InputAngle(const std::string& label, double& value, bool* isHovered)
|
||||||
{
|
{
|
||||||
ImGui::Text(label.c_str());
|
ImGui::Text(label.c_str());
|
||||||
|
if (isHovered)
|
||||||
|
*isHovered = ImGui::IsItemHovered();
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
return ImGui::InputDouble("#", &value,
|
return ImGui::InputDouble("#", &value,
|
||||||
1.0, 45.0, "%.3f",
|
1.0, 45.0, "%.3f",
|
||||||
ImGuiInputTextFlags_EnterReturnsTrue);
|
ImGuiInputTextFlags_EnterReturnsTrue);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SHEditorUI::InputSlider(const std::string& label, double min, double max, double& value)
|
bool SHEditorUI::InputSlider(const std::string& label, int min, int max, int& value, bool* isHovered /*= nullptr*/)
|
||||||
{
|
{
|
||||||
float val = static_cast<float>(value);
|
|
||||||
ImGui::Text(label.c_str());
|
ImGui::Text(label.c_str());
|
||||||
|
if (isHovered)
|
||||||
|
*isHovered = ImGui::IsItemHovered();
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
const bool CHANGED = ImGui::SliderFloat("#", &val,
|
return ImGui::SliderInt("##", &value,
|
||||||
static_cast<float>(min), static_cast<float>(max), "%.3f",
|
static_cast<float>(min), static_cast<float>(max), "%d",
|
||||||
ImGuiInputTextFlags_EnterReturnsTrue);
|
ImGuiInputTextFlags_EnterReturnsTrue);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHEditorUI::InputSlider(const std::string& label, unsigned int min, unsigned int max, unsigned int& value, bool* isHovered /*= nullptr*/)
|
||||||
|
{
|
||||||
|
int val = static_cast<int>(value);
|
||||||
|
const bool CHANGED = InputSlider(label, min, max, val, isHovered);
|
||||||
if (CHANGED)
|
if (CHANGED)
|
||||||
{
|
{
|
||||||
value = val;
|
value = static_cast<int>(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
return CHANGED;
|
return CHANGED;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SHEditorUI::InputVec2(const std::string& label, SHVec2& value)
|
bool SHEditorUI::InputSlider(const std::string& label, float min, float max, float& value, bool* isHovered)
|
||||||
{
|
{
|
||||||
static const std::vector<std::string> COMPONENT_LABELS = { "X", "Y" };
|
ImGui::Text(label.c_str());
|
||||||
return SHEditorWidgets::DragN<float, 2>(label, COMPONENT_LABELS, { &value.x, &value.y });
|
if (isHovered)
|
||||||
}
|
*isHovered = ImGui::IsItemHovered();
|
||||||
bool SHEditorUI::InputVec3(const std::string& label, SHVec3& value, float speed)
|
ImGui::SameLine();
|
||||||
{
|
return ImGui::SliderFloat("##", &value,
|
||||||
static const std::vector<std::string> COMPONENT_LABELS = { "X", "Y", "Z"};
|
static_cast<float>(min), static_cast<float>(max), "%.3f",
|
||||||
return SHEditorWidgets::DragN<float, 3>(label, COMPONENT_LABELS, { &value.x, &value.y, &value.z }, speed, "%.3f");
|
ImGuiInputTextFlags_EnterReturnsTrue);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SHEditorUI::InputTextField(const std::string& label, std::string& value)
|
bool SHEditorUI::InputSlider(const std::string& label, double min, double max, double& value, bool* isHovered /*= nullptr*/)
|
||||||
|
{
|
||||||
|
float val = static_cast<float>(value);
|
||||||
|
const bool CHANGED = InputSlider(label, min, max, val, isHovered);
|
||||||
|
if (CHANGED)
|
||||||
|
{
|
||||||
|
value = static_cast<double>(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
return CHANGED;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHEditorUI::InputVec2(const std::string& label, SHVec2& value, bool* isHovered)
|
||||||
|
{
|
||||||
|
static const std::vector<std::string> COMPONENT_LABELS = { "X", "Y" };
|
||||||
|
return SHEditorWidgets::DragN<float, 2>(label, COMPONENT_LABELS, { &value.x, &value.y }, 0.1f, "%.3f", float{}, float{}, 0, isHovered);
|
||||||
|
}
|
||||||
|
bool SHEditorUI::InputVec3(const std::string& label, SHVec3& value, bool* isHovered, float speed)
|
||||||
|
{
|
||||||
|
static const std::vector<std::string> COMPONENT_LABELS = { "X", "Y", "Z"};
|
||||||
|
return SHEditorWidgets::DragN<float, 3>(label, COMPONENT_LABELS, { &value.x, &value.y, &value.z }, speed, "%.3f", float{}, float{}, 0, isHovered);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHEditorUI::InputTextField(const std::string& label, std::string& value, bool* isHovered)
|
||||||
{
|
{
|
||||||
std::array<char, TEXT_FIELD_MAX_LENGTH> buffer = { '\0' };
|
std::array<char, TEXT_FIELD_MAX_LENGTH> buffer = { '\0' };
|
||||||
strcpy_s(buffer.data(), TEXT_FIELD_MAX_LENGTH, value.c_str());
|
strcpy_s(buffer.data(), TEXT_FIELD_MAX_LENGTH, value.c_str());
|
||||||
ImGui::Text(label.c_str());
|
ImGui::Text(label.c_str());
|
||||||
|
if (isHovered)
|
||||||
|
*isHovered = ImGui::IsItemHovered();
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
const bool CHANGED = ImGui::InputText("#", &buffer[0], TEXT_FIELD_MAX_LENGTH);
|
const bool CHANGED = ImGui::InputText("#", &buffer[0], TEXT_FIELD_MAX_LENGTH);
|
||||||
if (CHANGED)
|
if (CHANGED)
|
||||||
|
@ -229,13 +287,15 @@ namespace SHADE
|
||||||
return CHANGED;
|
return CHANGED;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SHEditorUI::InputEnumCombo(const std::string& label, int& v, const std::vector<std::string>& enumNames)
|
bool SHEditorUI::InputEnumCombo(const std::string& label, int& v, const std::vector<std::string>& enumNames, bool* isHovered)
|
||||||
{
|
{
|
||||||
// Clamp input value
|
// Clamp input value
|
||||||
const std::string& INITIAL_NAME = v >= static_cast<int>(enumNames.size()) ? "Unknown" : enumNames[v];
|
const std::string& INITIAL_NAME = v >= static_cast<int>(enumNames.size()) ? "Unknown" : enumNames[v];
|
||||||
bool b = false;
|
bool b = false;
|
||||||
|
|
||||||
ImGui::Text(label.c_str());
|
ImGui::Text(label.c_str());
|
||||||
|
if (isHovered)
|
||||||
|
*isHovered = ImGui::IsItemHovered();
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::BeginCombo("#", INITIAL_NAME.c_str(), ImGuiComboFlags_None))
|
if (ImGui::BeginCombo("#", INITIAL_NAME.c_str(), ImGuiComboFlags_None))
|
||||||
{
|
{
|
||||||
|
|
|
@ -90,12 +90,19 @@ namespace SHADE
|
||||||
static void SameLine();
|
static void SameLine();
|
||||||
static void Separator();
|
static void Separator();
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* ImGui Wrapper Functions - Queries */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
static bool IsItemHovered();
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* ImGui Wrapper Functions - Menu */
|
/* ImGui Wrapper Functions - Menu */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
static bool BeginMenu(const std::string& label);
|
static bool BeginMenu(const std::string& label);
|
||||||
static bool BeginMenu(const std::string& label, const char* icon);
|
static bool BeginMenu(const std::string& label, const char* icon);
|
||||||
static void EndMenu();
|
static void EndMenu();
|
||||||
|
static void BeginTooltip();
|
||||||
|
static void EndTooltip();
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* ImGui Wrapper Functions - Pop Ups */
|
/* ImGui Wrapper Functions - Pop Ups */
|
||||||
|
@ -165,8 +172,9 @@ namespace SHADE
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="label">Label used to identify this widget.</param>
|
/// <param name="label">Label used to identify this widget.</param>
|
||||||
/// <param name="value">Reference to the variable to store the result.</param>
|
/// <param name="value">Reference to the variable to store the result.</param>
|
||||||
|
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
|
||||||
/// <returns>True if the value was changed.</returns>
|
/// <returns>True if the value was changed.</returns>
|
||||||
static bool InputCheckbox(const std::string& label, bool& value);
|
static bool InputCheckbox(const std::string& label, bool& value, bool* isHovered = nullptr);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a integer field widget for integer input.
|
/// Creates a integer field widget for integer input.
|
||||||
/// <br/>
|
/// <br/>
|
||||||
|
@ -174,8 +182,9 @@ namespace SHADE
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="label">Label used to identify this widget.</param>
|
/// <param name="label">Label used to identify this widget.</param>
|
||||||
/// <param name="value">Reference to the variable to store the result.</param>
|
/// <param name="value">Reference to the variable to store the result.</param>
|
||||||
|
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
|
||||||
/// <returns>True if the value was changed.</returns>
|
/// <returns>True if the value was changed.</returns>
|
||||||
static bool InputInt(const std::string& label, int& value);
|
static bool InputInt(const std::string& label, int& value, bool* isHovered = nullptr);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a integer field widget for unsigned integer input.
|
/// Creates a integer field widget for unsigned integer input.
|
||||||
/// <br/>
|
/// <br/>
|
||||||
|
@ -186,8 +195,9 @@ namespace SHADE
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="label">Label used to identify this widget.</param>
|
/// <param name="label">Label used to identify this widget.</param>
|
||||||
/// <param name="value">Reference to the variable to store the result.</param>
|
/// <param name="value">Reference to the variable to store the result.</param>
|
||||||
|
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
|
||||||
/// <returns>True if the value was changed.</returns>
|
/// <returns>True if the value was changed.</returns>
|
||||||
static bool InputUnsignedInt(const std::string& label, unsigned int& value);
|
static bool InputUnsignedInt(const std::string& label, unsigned int& value, bool* isHovered = nullptr);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a decimal field widget for single precision float input.
|
/// Creates a decimal field widget for single precision float input.
|
||||||
/// <br/>
|
/// <br/>
|
||||||
|
@ -195,8 +205,9 @@ namespace SHADE
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="label">Label used to identify this widget.</param>
|
/// <param name="label">Label used to identify this widget.</param>
|
||||||
/// <param name="value">Reference to the variable to store the result.</param>
|
/// <param name="value">Reference to the variable to store the result.</param>
|
||||||
|
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
|
||||||
/// <returns>True if the value was changed.</returns>
|
/// <returns>True if the value was changed.</returns>
|
||||||
static bool InputFloat(const std::string& label, float& value);
|
static bool InputFloat(const std::string& label, float& value, bool* isHovered = nullptr);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a decimal field widget for double precision float input.
|
/// Creates a decimal field widget for double precision float input.
|
||||||
/// <br/>
|
/// <br/>
|
||||||
|
@ -204,8 +215,9 @@ namespace SHADE
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="label">Label used to identify this widget.</param>
|
/// <param name="label">Label used to identify this widget.</param>
|
||||||
/// <param name="value">Reference to the variable to store the result.</param>
|
/// <param name="value">Reference to the variable to store the result.</param>
|
||||||
|
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
|
||||||
/// <returns>True if the value was changed.</returns>
|
/// <returns>True if the value was changed.</returns>
|
||||||
static bool InputDouble(const std::string& label, double& value);
|
static bool InputDouble(const std::string& label, double& value, bool* isHovered = nullptr);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a decimal field widget for double input with increments of higher
|
/// Creates a decimal field widget for double input with increments of higher
|
||||||
/// steps meant for angle variables.
|
/// steps meant for angle variables.
|
||||||
|
@ -214,19 +226,57 @@ namespace SHADE
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="label">Label used to identify this widget.</param>
|
/// <param name="label">Label used to identify this widget.</param>
|
||||||
/// <param name="value">Reference to the variable to store the result.</param>
|
/// <param name="value">Reference to the variable to store the result.</param>
|
||||||
|
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
|
||||||
/// <returns>True if the value was changed.</returns>
|
/// <returns>True if the value was changed.</returns>
|
||||||
static bool InputAngle(const std::string& label, double& value);
|
static bool InputAngle(const std::string& label, double& value, bool* isHovered = nullptr);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a double slider field widget for double input.
|
/// Creates an int slider field widget for double input.
|
||||||
/// <br/>
|
/// <br/>
|
||||||
/// Wraps up ImGui::InputSliderFloat().
|
/// Wraps up ImGui::SliderInt().
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="label">Label used to identify this widget.</param>
|
/// <param name="label">Label used to identify this widget.</param>
|
||||||
/// <param name="min">Minimum value of the slider.</param>
|
/// <param name="min">Minimum value of the slider.</param>
|
||||||
/// <param name="max">Maximum value of the slider.</param>
|
/// <param name="max">Maximum value of the slider.</param>
|
||||||
/// <param name="value">Reference to the variable to store the result.</param>
|
/// <param name="value">Reference to the variable to store the result.</param>
|
||||||
|
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
|
||||||
/// <returns>True if the value was changed.</returns>
|
/// <returns>True if the value was changed.</returns>
|
||||||
static bool InputSlider(const std::string& label, double min, double max, double& value);
|
static bool InputSlider(const std::string& label, int min, int max, int& value, bool* isHovered = nullptr);
|
||||||
|
/// <summary>
|
||||||
|
/// Creates an unsigned int slider field widget for double input.
|
||||||
|
/// <br/>
|
||||||
|
/// Wraps up ImGui::SliderInt().
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="label">Label used to identify this widget.</param>
|
||||||
|
/// <param name="min">Minimum value of the slider.</param>
|
||||||
|
/// <param name="max">Maximum value of the slider.</param>
|
||||||
|
/// <param name="value">Reference to the variable to store the result.</param>
|
||||||
|
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
|
||||||
|
/// <returns>True if the value was changed.</returns>
|
||||||
|
static bool InputSlider(const std::string& label, unsigned int min, unsigned int max, unsigned int& value, bool* isHovered = nullptr);
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a float slider field widget for double input.
|
||||||
|
/// <br/>
|
||||||
|
/// Wraps up ImGui::SliderFloat().
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="label">Label used to identify this widget.</param>
|
||||||
|
/// <param name="min">Minimum value of the slider.</param>
|
||||||
|
/// <param name="max">Maximum value of the slider.</param>
|
||||||
|
/// <param name="value">Reference to the variable to store the result.</param>
|
||||||
|
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
|
||||||
|
/// <returns>True if the value was changed.</returns>
|
||||||
|
static bool InputSlider(const std::string& label, float min, float max, float& value, bool* isHovered = nullptr);
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a double slider field widget for double input.
|
||||||
|
/// <br/>
|
||||||
|
/// Wraps up ImGui::SliderFloat().
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="label">Label used to identify this widget.</param>
|
||||||
|
/// <param name="min">Minimum value of the slider.</param>
|
||||||
|
/// <param name="max">Maximum value of the slider.</param>
|
||||||
|
/// <param name="value">Reference to the variable to store the result.</param>
|
||||||
|
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
|
||||||
|
/// <returns>True if the value was changed.</returns>
|
||||||
|
static bool InputSlider(const std::string& label, double min, double max, double& value, bool* isHovered = nullptr);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a 2x double field widget for Vector2 input.
|
/// Creates a 2x double field widget for Vector2 input.
|
||||||
/// <br/>
|
/// <br/>
|
||||||
|
@ -234,8 +284,9 @@ namespace SHADE
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="label">Label used to identify this widget.</param>
|
/// <param name="label">Label used to identify this widget.</param>
|
||||||
/// <param name="value">Reference to the variable to store the result.</param>
|
/// <param name="value">Reference to the variable to store the result.</param>
|
||||||
|
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
|
||||||
/// <returns>True if the value was changed.</returns>
|
/// <returns>True if the value was changed.</returns>
|
||||||
static bool InputVec2(const std::string& label, SHVec2& value);
|
static bool InputVec2(const std::string& label, SHVec2& value, bool* isHovered = nullptr);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a 3x double field widget for Vector3 input.
|
/// Creates a 3x double field widget for Vector3 input.
|
||||||
/// <br/>
|
/// <br/>
|
||||||
|
@ -243,8 +294,9 @@ namespace SHADE
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="label">Label used to identify this widget.</param>
|
/// <param name="label">Label used to identify this widget.</param>
|
||||||
/// <param name="value">Reference to the variable to store the result.</param>
|
/// <param name="value">Reference to the variable to store the result.</param>
|
||||||
|
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
|
||||||
/// <returns>True if the value was changed.</returns>
|
/// <returns>True if the value was changed.</returns>
|
||||||
static bool InputVec3(const std::string& label, SHVec3& value, float speed = 0.1f);
|
static bool InputVec3(const std::string& label, SHVec3& value, bool* isHovered = nullptr, float speed = 0.1f);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a text field widget for string input.
|
/// Creates a text field widget for string input.
|
||||||
/// <br/>
|
/// <br/>
|
||||||
|
@ -252,8 +304,9 @@ namespace SHADE
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="label">Label used to identify this widget.</param>
|
/// <param name="label">Label used to identify this widget.</param>
|
||||||
/// <param name="value">Reference to the variable to store the result.</param>
|
/// <param name="value">Reference to the variable to store the result.</param>
|
||||||
|
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
|
||||||
/// <returns>True if the value was changed.</returns>
|
/// <returns>True if the value was changed.</returns>
|
||||||
static bool InputTextField(const std::string& label, std::string& value);
|
static bool InputTextField(const std::string& label, std::string& value, bool* isHovered = nullptr);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a combo box for enumeration input.
|
/// Creates a combo box for enumeration input.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -264,17 +317,19 @@ namespace SHADE
|
||||||
/// <param name="toStrFn">
|
/// <param name="toStrFn">
|
||||||
/// Conversion function from the type of enum to C-style string.
|
/// Conversion function from the type of enum to C-style string.
|
||||||
/// </param>
|
/// </param>
|
||||||
|
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
|
||||||
/// <returns>Whether the value was modified.</returns>
|
/// <returns>Whether the value was modified.</returns>
|
||||||
template<typename Enum>
|
template<typename Enum>
|
||||||
static bool InputEnumCombo(const std::string& label, Enum& v, int maxVal, std::function<const char*(Enum)> toStrFn);
|
static bool InputEnumCombo(const std::string& label, Enum& v, int maxVal, std::function<const char*(Enum)> toStrFn, bool* isHovered = nullptr);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a combo box for enumeration input using a specified list of names.
|
/// Creates a combo box for enumeration input using a specified list of names.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="label">The name of the input.</param>
|
/// <param name="label">The name of the input.</param>
|
||||||
/// <param name="v">The reference to the value to modify.</param>
|
/// <param name="v">The reference to the value to modify.</param>
|
||||||
/// <param name="enumNames">Vector of names for each enumeration value.</param>
|
/// <param name="enumNames">Vector of names for each enumeration value.</param>
|
||||||
|
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
|
||||||
/// <returns>Whether the value was modified.</returns>
|
/// <returns>Whether the value was modified.</returns>
|
||||||
static bool InputEnumCombo(const std::string& label, int& v, const std::vector<std::string>& enumNames);
|
static bool InputEnumCombo(const std::string& label, int& v, const std::vector<std::string>& enumNames, bool* isHovered = nullptr);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -16,11 +16,11 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* ImGui Wrapper Functions - Widgets */
|
/* ImGui Wrapper Functions - Widgets */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
template<typename Enum>
|
template<typename Enum>
|
||||||
inline bool SHEditorUI::InputEnumCombo(const std::string& label, Enum& v, int maxVal, std::function<const char* (Enum)> toStrFn)
|
inline bool SHEditorUI::InputEnumCombo(const std::string& label, Enum& v, int maxVal, std::function<const char* (Enum)> toStrFn, bool* isHovered)
|
||||||
{
|
{
|
||||||
std::vector<Enum> values;
|
std::vector<Enum> values;
|
||||||
for (int i = 0; i <= maxVal; ++i)
|
for (int i = 0; i <= maxVal; ++i)
|
||||||
|
@ -28,6 +28,11 @@ namespace SHADE
|
||||||
values.emplace_back(static_cast<Enum>(i));
|
values.emplace_back(static_cast<Enum>(i));
|
||||||
}
|
}
|
||||||
bool b = false;
|
bool b = false;
|
||||||
|
|
||||||
|
ImGui::Text(label.c_str());
|
||||||
|
if (isHovered)
|
||||||
|
*isHovered = ImGui::IsItemHovered();
|
||||||
|
ImGui::SameLine();
|
||||||
if (ImGui::BeginCombo(label.c_str(), toStrFn(v), ImGuiComboFlags_None))
|
if (ImGui::BeginCombo(label.c_str(), toStrFn(v), ImGuiComboFlags_None))
|
||||||
{
|
{
|
||||||
for (int i = 0; i <= maxVal; ++i)
|
for (int i = 0; i <= maxVal; ++i)
|
||||||
|
|
|
@ -160,7 +160,7 @@ namespace SHADE
|
||||||
template <typename T, std::size_t N>
|
template <typename T, std::size_t N>
|
||||||
static bool DragN(const std::string& fieldLabel, std::vector<std::string>const& componentLabels,
|
static bool DragN(const std::string& fieldLabel, std::vector<std::string>const& componentLabels,
|
||||||
std::vector<T*> values, float speed = 0.1f, const char* displayFormat = "", T valueMin = T(), T valueMax = T(),
|
std::vector<T*> values, float speed = 0.1f, const char* displayFormat = "", T valueMin = T(), T valueMax = T(),
|
||||||
ImGuiSliderFlags flags = 0)
|
ImGuiSliderFlags flags = 0, bool* isHovered = nullptr)
|
||||||
{
|
{
|
||||||
const ImGuiWindow* const window = ImGui::GetCurrentWindow();
|
const ImGuiWindow* const window = ImGui::GetCurrentWindow();
|
||||||
if (window->SkipItems)
|
if (window->SkipItems)
|
||||||
|
@ -174,6 +174,8 @@ namespace SHADE
|
||||||
ImGui::BeginColumns("DragVecCol", 2, ImGuiOldColumnFlags_NoBorder | ImGuiOldColumnFlags_NoResize);
|
ImGui::BeginColumns("DragVecCol", 2, ImGuiOldColumnFlags_NoBorder | ImGuiOldColumnFlags_NoResize);
|
||||||
ImGui::SetColumnWidth(-1, 80.0f);
|
ImGui::SetColumnWidth(-1, 80.0f);
|
||||||
ImGui::Text(fieldLabel.c_str());
|
ImGui::Text(fieldLabel.c_str());
|
||||||
|
if (isHovered)
|
||||||
|
*isHovered = ImGui::IsItemHovered();
|
||||||
ImGui::NextColumn();
|
ImGui::NextColumn();
|
||||||
for (std::size_t i = 0; i < N; ++i)
|
for (std::size_t i = 0; i < N; ++i)
|
||||||
{
|
{
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include "Tools/SHLogger.h"
|
|
||||||
#include "SH_API.h"
|
#include "SH_API.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
|
|
|
@ -115,7 +115,7 @@ namespace SHADE
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Script Serialisation Functions */
|
/* Script Serialisation Functions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
std::string SHScriptEngine::SerialiseScripts(const SHEntity& entity) const
|
std::string SHScriptEngine::SerialiseScripts(EntityID entity) const
|
||||||
{
|
{
|
||||||
// Create buffer needed to store serialised script data
|
// Create buffer needed to store serialised script data
|
||||||
constexpr int BUFFER_SIZE = 10240;
|
constexpr int BUFFER_SIZE = 10240;
|
||||||
|
@ -124,7 +124,7 @@ namespace SHADE
|
||||||
|
|
||||||
// Attempt to serialise the script
|
// Attempt to serialise the script
|
||||||
std::string result;
|
std::string result;
|
||||||
if (csScriptsSerialise(entity.GetEID(), buffer.get(), BUFFER_SIZE))
|
if (csScriptsSerialise(entity, buffer.get(), BUFFER_SIZE))
|
||||||
{
|
{
|
||||||
result = std::string(buffer.get());
|
result = std::string(buffer.get());
|
||||||
}
|
}
|
||||||
|
@ -140,9 +140,9 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* Script Serialisation Functions */
|
/* Script Serialisation Functions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
void SHScriptEngine::DeserialiseScript(const SHEntity& entity, const std::string& yaml) const
|
void SHScriptEngine::DeserialiseScript(EntityID entity, const std::string& yaml) const
|
||||||
{
|
{
|
||||||
csScriptDeserialise(entity.GetEID(), yaml.c_str());
|
csScriptDeserialise(entity, yaml.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -148,7 +148,7 @@ namespace SHADE
|
||||||
/// <returns>
|
/// <returns>
|
||||||
/// String that represents the set of scripts attached to the specified Entity.
|
/// String that represents the set of scripts attached to the specified Entity.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
std::string SerialiseScripts(const SHEntity& entity) const;
|
std::string SerialiseScripts(EntityID entity) const;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Loads the specified JSON string and creates a Script for the specified Entity
|
/// Loads the specified JSON string and creates a Script for the specified Entity
|
||||||
/// based on the specified JSON string.
|
/// based on the specified JSON string.
|
||||||
|
@ -157,7 +157,7 @@ namespace SHADE
|
||||||
/// <param name="yaml">
|
/// <param name="yaml">
|
||||||
/// The YAML string that represents the Script to load into the Entity.
|
/// The YAML string that represents the Script to load into the Entity.
|
||||||
/// </param>
|
/// </param>
|
||||||
void DeserialiseScript(const SHEntity& entity, const std::string& yaml) const;
|
void DeserialiseScript(EntityID entity, const std::string& yaml) const;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Script Editor Functions */
|
/* Script Editor Functions */
|
||||||
|
|
|
@ -0,0 +1,220 @@
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHSerializationHelper.hpp"
|
||||||
|
#include "SHSerialization.h"
|
||||||
|
|
||||||
|
#include <yaml-cpp/yaml.h>
|
||||||
|
|
||||||
|
#include "ECS_Base/Managers/SHEntityManager.h"
|
||||||
|
#include "Scene/SHSceneManager.h"
|
||||||
|
#include "Tools/SHException.h"
|
||||||
|
#include "Assets/SHAssetManager.h"
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
||||||
|
#include "Math/Transform/SHTransformComponent.h"
|
||||||
|
#include "Physics/Components/SHRigidBodyComponent.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
void SHSerialization::SerializeSceneToFile(std::filesystem::path const& path)
|
||||||
|
{
|
||||||
|
YAML::Emitter out;
|
||||||
|
SerializeSceneToEmitter(out);
|
||||||
|
std::ofstream file(path.c_str());
|
||||||
|
if (file.good())
|
||||||
|
{
|
||||||
|
file << out.c_str();
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string SHSerialization::SerializeSceneToString()
|
||||||
|
{
|
||||||
|
YAML::Emitter out;
|
||||||
|
SerializeSceneToEmitter(out);
|
||||||
|
return std::basic_string<char>(out.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHSerialization::SerializeSceneToEmitter(YAML::Emitter& out)
|
||||||
|
{
|
||||||
|
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
||||||
|
auto root = sceneGraph.GetRoot();
|
||||||
|
|
||||||
|
SHASSERT(root != nullptr, "Root is null. Failed to serialize scene to node.");
|
||||||
|
|
||||||
|
auto const& children = root->GetChildren();
|
||||||
|
out << YAML::BeginSeq;
|
||||||
|
|
||||||
|
auto pred = [&out](SHSceneNode* node) {out << SerializeEntityToNode(node); };
|
||||||
|
sceneGraph.Traverse(pred);
|
||||||
|
//out << SerializeEntityToNode(child);
|
||||||
|
|
||||||
|
out << YAML::EndSeq;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DeserializeEntity(YAML::iterator& it, YAML::Node const& node, std::vector<EntityID>& createdEntities, EntityID parentEID = MAX_EID)
|
||||||
|
{
|
||||||
|
if (!node[EIDNode])
|
||||||
|
return;
|
||||||
|
EntityID eid = node[EIDNode].as<EntityID>();
|
||||||
|
std::string name = "Default";
|
||||||
|
if (node[EntityNameNode])
|
||||||
|
name = node[EntityNameNode].as<std::string>();
|
||||||
|
//Compile component IDs
|
||||||
|
const auto componentIDList = SHSerialization::GetComponentIDList(node[ComponentsNode]);
|
||||||
|
eid = SHEntityManager::CreateEntity(componentIDList, eid, name, parentEID);
|
||||||
|
createdEntities.push_back(eid);
|
||||||
|
if (node[NumberOfChildrenNode])
|
||||||
|
{
|
||||||
|
if(const int numOfChildren = node[NumberOfChildrenNode].as<int>(); numOfChildren > 0)
|
||||||
|
{
|
||||||
|
++it;
|
||||||
|
for (int i = 0; i < numOfChildren; ++i)
|
||||||
|
{
|
||||||
|
DeserializeEntity(it, (*it), createdEntities, eid);
|
||||||
|
if((i + 1) < numOfChildren)
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHSerialization::DeserializeSceneFromFile(std::filesystem::path const& path)
|
||||||
|
{
|
||||||
|
//TODO:Shift to using XQ's FileIO
|
||||||
|
std::ifstream iFile;
|
||||||
|
iFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
||||||
|
std::string fileContent = "";
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Open file
|
||||||
|
// Read file's buffer contents into streams
|
||||||
|
iFile.open(path);
|
||||||
|
std::stringstream fileStream;
|
||||||
|
fileStream << iFile.rdbuf();
|
||||||
|
|
||||||
|
fileContent = fileStream.str();
|
||||||
|
|
||||||
|
// Close file handler
|
||||||
|
iFile.close();
|
||||||
|
}
|
||||||
|
catch (std::ifstream::failure e)
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Could not read file");
|
||||||
|
}
|
||||||
|
YAML::Node entities = YAML::Load(fileContent);
|
||||||
|
std::vector<EntityID> createdEntities{};
|
||||||
|
|
||||||
|
//Create Entities
|
||||||
|
for (auto it = entities.begin(); it != entities.end(); ++it)
|
||||||
|
{
|
||||||
|
DeserializeEntity(it, (*it), createdEntities);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Initialize Entity
|
||||||
|
auto entityVecIt = createdEntities.begin();
|
||||||
|
for (auto it = entities.begin(); it != entities.end(); ++it)
|
||||||
|
{
|
||||||
|
InitializeEntity(*it, *entityVecIt++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHSerialization::EmitEntity(SHSceneNode* entityNode, YAML::Emitter& out)
|
||||||
|
{
|
||||||
|
out << SerializeEntityToNode(entityNode);
|
||||||
|
auto const& children = entityNode->GetChildren();
|
||||||
|
for(auto const& child : children)
|
||||||
|
{
|
||||||
|
EmitEntity(child, out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string SHSerialization::SerializeEntitiesToString(std::vector<EntityID> const& entities)
|
||||||
|
{
|
||||||
|
YAML::Emitter out;
|
||||||
|
YAML::Node node;
|
||||||
|
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
||||||
|
for (auto const& eid : entities)
|
||||||
|
{
|
||||||
|
auto entityNode = sceneGraph.GetNode(eid);
|
||||||
|
EmitEntity(entityNode, out);
|
||||||
|
}
|
||||||
|
return std::basic_string<char>(out.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHSerialization::SerializeEntityToFile(std::filesystem::path const& path)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
YAML::Node SHSerialization::SerializeEntityToNode(SHSceneNode* sceneNode)
|
||||||
|
{
|
||||||
|
YAML::Node node;
|
||||||
|
auto eid = sceneNode->GetEntityID();
|
||||||
|
auto entity = SHEntityManager::GetEntityByID(eid);
|
||||||
|
if (!sceneNode || !entity)
|
||||||
|
{
|
||||||
|
node = YAML::Null;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
node.SetStyle(YAML::EmitterStyle::Block);
|
||||||
|
node[EIDNode] = eid;
|
||||||
|
node[EntityNameNode] = entity->name;
|
||||||
|
node[IsActiveNode] = sceneNode->IsActive();
|
||||||
|
auto const& children = sceneNode->GetChildren();
|
||||||
|
node[NumberOfChildrenNode] = children.size();
|
||||||
|
|
||||||
|
YAML::Node components;
|
||||||
|
|
||||||
|
if (const auto transform = SHComponentManager::GetComponent_s<SHTransformComponent>(eid))
|
||||||
|
{
|
||||||
|
components[rttr::type::get<SHTransformComponent>().get_name().data()] = SHSerializationHelper::SerializeComponentToNode(transform);
|
||||||
|
}
|
||||||
|
if (const auto renderable = SHComponentManager::GetComponent_s<SHRenderable>(eid))
|
||||||
|
{
|
||||||
|
components[rttr::type::get<SHRenderable>().get_name().data()] = SHSerializationHelper::SerializeComponentToNode(renderable);
|
||||||
|
}
|
||||||
|
if (const auto rigidbody = SHComponentManager::GetComponent_s<SHRigidBodyComponent>(eid))
|
||||||
|
{
|
||||||
|
components[rttr::type::get<SHRigidBodyComponent>().get_name().data()] = SHSerializationHelper::SerializeComponentToNode(rigidbody);
|
||||||
|
}
|
||||||
|
node[ComponentsNode] = components;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
||||||
|
std::optional<ComponentTypeID> GetComponentID(YAML::Node const& componentNode)
|
||||||
|
{
|
||||||
|
if (componentNode[rttr::type::get<ComponentType>().get_name().data()])
|
||||||
|
return { SHFamilyID<SHComponent>::GetID<ComponentType>() };
|
||||||
|
else
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<ComponentTypeID> SHSerialization::GetComponentIDList(YAML::Node const& componentsNode)
|
||||||
|
{
|
||||||
|
std::vector<ComponentTypeID> componentIDList;
|
||||||
|
|
||||||
|
auto id = GetComponentID<SHTransformComponent>(componentsNode);
|
||||||
|
if (id.has_value())
|
||||||
|
componentIDList.push_back(id.value());
|
||||||
|
|
||||||
|
id = GetComponentID<SHRenderable>(componentsNode);
|
||||||
|
if (id.has_value())
|
||||||
|
componentIDList.push_back(id.value());
|
||||||
|
|
||||||
|
id = GetComponentID<SHRigidBodyComponent>(componentsNode);
|
||||||
|
if (id.has_value())
|
||||||
|
componentIDList.push_back(id.value());
|
||||||
|
|
||||||
|
return componentIDList;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHSerialization::InitializeEntity(YAML::Node const& entityNode, EntityID const& eid)
|
||||||
|
{
|
||||||
|
auto const componentsNode = entityNode[ComponentsNode];
|
||||||
|
if (!componentsNode)
|
||||||
|
return;
|
||||||
|
SHSerializationHelper::InitializeComponentFromNode<SHTransformComponent>(componentsNode, eid);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "SH_API.h"
|
||||||
|
#include <string>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
|
#include <ECS_Base/Components/SHComponent.h>
|
||||||
|
|
||||||
|
namespace YAML
|
||||||
|
{
|
||||||
|
class Emitter;
|
||||||
|
class Node;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SHSceneNode;
|
||||||
|
|
||||||
|
constexpr const char* ComponentsNode = "Components";
|
||||||
|
constexpr const char* EntityNameNode = "Name";
|
||||||
|
constexpr const char* EIDNode = "EID";
|
||||||
|
constexpr const char* IsActiveNode = "IsActive";
|
||||||
|
constexpr const char* NumberOfChildrenNode = "NumberOfChildren";
|
||||||
|
|
||||||
|
struct SH_API SHSerialization
|
||||||
|
{
|
||||||
|
//TODO: change paths to resource ID
|
||||||
|
static void SerializeSceneToFile(std::filesystem::path const& path);
|
||||||
|
static std::string SerializeSceneToString();
|
||||||
|
static void SerializeSceneToEmitter(YAML::Emitter& out);
|
||||||
|
static void DeserializeSceneFromFile(std::filesystem::path const& path);
|
||||||
|
|
||||||
|
|
||||||
|
static void EmitEntity(SHSceneNode* entityNode, YAML::Emitter& out);
|
||||||
|
static std::string SerializeEntitiesToString(std::vector<EntityID> const& entities);
|
||||||
|
static void SerializeEntityToFile(std::filesystem::path const& path);
|
||||||
|
static YAML::Node SerializeEntityToNode(SHSceneNode* sceneNode);
|
||||||
|
|
||||||
|
static std::vector<ComponentTypeID> GetComponentIDList(YAML::Node const& componentsNode);
|
||||||
|
private:
|
||||||
|
static void InitializeEntity(YAML::Node const& entityNode, EntityID const& eid);
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,204 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ECS_Base/Components/SHComponent.h"
|
||||||
|
#include <yaml-cpp/yaml.h>
|
||||||
|
|
||||||
|
#include <rttr/registration>
|
||||||
|
|
||||||
|
#include "ECS_Base/Managers/SHComponentManager.h"
|
||||||
|
#include "Math/Vector/SHVec2.h"
|
||||||
|
#include "Math/Vector/SHVec3.h"
|
||||||
|
#include "Math/Vector/SHVec4.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
struct SHSerializationHelper
|
||||||
|
{
|
||||||
|
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
||||||
|
static std::string SerializeComponentToString(ComponentType* component)
|
||||||
|
{
|
||||||
|
return std::string();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
||||||
|
static void SerializeComponentToFile(ComponentType* component, std::filesystem::path const& path)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static YAML::Node RTTRToNode(const rttr::variant& var)
|
||||||
|
{
|
||||||
|
YAML::Node node;
|
||||||
|
auto varType = var.get_type();
|
||||||
|
if (varType == rttr::type::get<SHVec4>())
|
||||||
|
{
|
||||||
|
node.SetStyle(YAML::EmitterStyle::Flow);
|
||||||
|
node["X"] = var.convert<SHVec4>().x;
|
||||||
|
node["Y"] = var.convert<SHVec4>().y;
|
||||||
|
node["Z"] = var.convert<SHVec4>().z;
|
||||||
|
node["W"] = var.convert<SHVec4>().w;
|
||||||
|
}
|
||||||
|
else if (varType == rttr::type::get<SHVec3>())
|
||||||
|
{
|
||||||
|
node.SetStyle(YAML::EmitterStyle::Flow);
|
||||||
|
node["X"] = var.convert<SHVec3>().x;
|
||||||
|
node["Y"] = var.convert<SHVec3>().y;
|
||||||
|
node["Z"] = var.convert<SHVec3>().z;
|
||||||
|
}
|
||||||
|
else if (varType == rttr::type::get<SHVec2>())
|
||||||
|
{
|
||||||
|
node.SetStyle(YAML::EmitterStyle::Flow);
|
||||||
|
node["X"] = var.convert<SHVec3>().x;
|
||||||
|
node["Y"] = var.convert<SHVec3>().y;
|
||||||
|
}
|
||||||
|
else if (varType.is_arithmetic())
|
||||||
|
{
|
||||||
|
bool ok = false;
|
||||||
|
if (varType == rttr::type::get<bool>())
|
||||||
|
node = var.to_bool();
|
||||||
|
else if (varType == rttr::type::get<int8_t>())
|
||||||
|
node = var.to_int8(&ok);
|
||||||
|
else if (varType == rttr::type::get<int16_t>())
|
||||||
|
node = var.to_int16(&ok);
|
||||||
|
else if (varType == rttr::type::get<int32_t>())
|
||||||
|
node = var.to_int32(&ok);
|
||||||
|
else if (varType == rttr::type::get<int64_t>())
|
||||||
|
node = var.to_int64(&ok);
|
||||||
|
else if (varType == rttr::type::get<uint8_t>())
|
||||||
|
node = var.to_uint8(&ok);
|
||||||
|
else if (varType == rttr::type::get<uint16_t>())
|
||||||
|
node = var.to_uint16(&ok);
|
||||||
|
else if (varType == rttr::type::get<uint32_t>())
|
||||||
|
node = var.to_uint32(&ok);
|
||||||
|
else if (varType == rttr::type::get<uint64_t>())
|
||||||
|
node = var.to_uint64(&ok);
|
||||||
|
else if (varType == rttr::type::get<float>())
|
||||||
|
node = var.to_float(&ok);
|
||||||
|
else if (varType == rttr::type::get<double>())
|
||||||
|
node = var.to_double(&ok);
|
||||||
|
//else if (varType == rttr::type::get<char>()) //same as uint8_t
|
||||||
|
// node = var.to_uint8();
|
||||||
|
}
|
||||||
|
else if (varType.is_enumeration())
|
||||||
|
{
|
||||||
|
bool ok = false;
|
||||||
|
auto result = var.to_string(&ok);
|
||||||
|
if (ok)
|
||||||
|
{
|
||||||
|
node = var.to_string();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ok = false;
|
||||||
|
auto value = var.to_uint64(&ok);
|
||||||
|
if (ok)
|
||||||
|
node = value;
|
||||||
|
else
|
||||||
|
node = YAML::Null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto properties = var.get_type().get_properties();
|
||||||
|
for (auto property : properties)
|
||||||
|
{
|
||||||
|
node[property.get_name().data()] = RTTRToNode(property.get_value(var));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
||||||
|
static YAML::Node SerializeComponentToNode(ComponentType* component)
|
||||||
|
{
|
||||||
|
YAML::Node node{};
|
||||||
|
if (!component)
|
||||||
|
return node;
|
||||||
|
|
||||||
|
auto componentType = rttr::type::get<ComponentType>();
|
||||||
|
node = RTTRToNode(*component);
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
||||||
|
static void InitializeProperty(ComponentType* component, rttr::property const& prop, YAML::Node const& propertyNode)
|
||||||
|
{
|
||||||
|
auto propType = prop.get_type();
|
||||||
|
if (propType == rttr::type::get<SHVec4>())
|
||||||
|
{
|
||||||
|
SHVec4 vec{ propertyNode["X"].as<float>(), propertyNode["Y"].as<float>(), propertyNode["Z"].as<float>(), propertyNode["W"].as<float>() };
|
||||||
|
prop.set_value(component, vec);
|
||||||
|
}
|
||||||
|
else if (propType == rttr::type::get<SHVec3>())
|
||||||
|
{
|
||||||
|
SHVec3 vec{ propertyNode["X"].as<float>(), propertyNode["Y"].as<float>(), propertyNode["Z"].as<float>() };
|
||||||
|
prop.set_value(component, vec);
|
||||||
|
}
|
||||||
|
else if (propType == rttr::type::get<SHVec2>())
|
||||||
|
{
|
||||||
|
SHVec2 vec{ propertyNode["X"].as<float>(), propertyNode["Y"].as<float>() };
|
||||||
|
prop.set_value(component, vec);
|
||||||
|
}
|
||||||
|
else if (propType.is_arithmetic())
|
||||||
|
{
|
||||||
|
bool ok = false;
|
||||||
|
if (propType == rttr::type::get<bool>())
|
||||||
|
prop.set_value(component, propertyNode.as<bool>());
|
||||||
|
else if (propType == rttr::type::get<int8_t>())
|
||||||
|
prop.set_value(component, propertyNode.as<int8_t>());
|
||||||
|
else if (propType == rttr::type::get<int16_t>())
|
||||||
|
prop.set_value(component, propertyNode.as<int16_t>());
|
||||||
|
else if (propType == rttr::type::get<int32_t>())
|
||||||
|
prop.set_value(component, propertyNode.as<int32_t>());
|
||||||
|
else if (propType == rttr::type::get<int64_t>())
|
||||||
|
prop.set_value(component, propertyNode.as<int64_t>());
|
||||||
|
else if (propType == rttr::type::get<uint8_t>())
|
||||||
|
prop.set_value(component, propertyNode.as<uint8_t>());
|
||||||
|
else if (propType == rttr::type::get<uint16_t>())
|
||||||
|
prop.set_value(component, propertyNode.as<uint16_t>());
|
||||||
|
else if (propType == rttr::type::get<uint32_t>())
|
||||||
|
prop.set_value(component, propertyNode.as<uint32_t>());
|
||||||
|
else if (propType == rttr::type::get<uint64_t>())
|
||||||
|
prop.set_value(component, propertyNode.as<uint64_t>());
|
||||||
|
else if (propType == rttr::type::get<float>())
|
||||||
|
prop.set_value(component, propertyNode.as<float>());
|
||||||
|
else if (propType == rttr::type::get<double>())
|
||||||
|
prop.set_value(component, propertyNode.as<double>());
|
||||||
|
}
|
||||||
|
else if (propType.is_enumeration())
|
||||||
|
{
|
||||||
|
auto enumAlign = prop.get_enumeration();
|
||||||
|
prop.set_value(component, enumAlign.name_to_value(propertyNode.as<std::string>()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto properties = propType.get_properties();
|
||||||
|
for (auto property : properties)
|
||||||
|
{
|
||||||
|
InitializeProperty(component, property, propertyNode[property.get_name().data()]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
||||||
|
static void InitializeComponentFromNode(YAML::Node const& componentsNode, EntityID const& eid)
|
||||||
|
{
|
||||||
|
auto component = SHComponentManager::GetComponent_s<ComponentType>(eid);
|
||||||
|
if (componentsNode.IsNull() && !component)
|
||||||
|
return;
|
||||||
|
auto rttrType = rttr::type::get<ComponentType>();
|
||||||
|
auto componentNode = componentsNode[rttrType.get_name().data()];
|
||||||
|
if (componentsNode.IsNull())
|
||||||
|
return;
|
||||||
|
auto properties = rttrType.get_properties();
|
||||||
|
for (auto const& prop : properties)
|
||||||
|
{
|
||||||
|
if (componentNode[prop.get_name().data()])
|
||||||
|
{
|
||||||
|
InitializeProperty<ComponentType>(component, prop, componentNode[prop.get_name().data()]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
|
@ -29,6 +29,8 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
#include "Editor/IconsMaterialDesign.h"
|
#include "Editor/IconsMaterialDesign.h"
|
||||||
#include "Editor/Command/SHCommandManager.h"
|
#include "Editor/Command/SHCommandManager.h"
|
||||||
#include "Editor/Command/SHCommand.hpp"
|
#include "Editor/Command/SHCommand.hpp"
|
||||||
|
#include "TooltipAttribute.hxx"
|
||||||
|
#include "RangeAttribute.hxx"
|
||||||
|
|
||||||
// Using Directives
|
// Using Directives
|
||||||
using namespace System;
|
using namespace System;
|
||||||
|
@ -53,7 +55,44 @@ using namespace System::Collections::Generic;
|
||||||
{ \
|
{ \
|
||||||
NATIVE_TYPE val = safe_cast<NATIVE_TYPE>(field->GetValue(object)); \
|
NATIVE_TYPE val = safe_cast<NATIVE_TYPE>(field->GetValue(object)); \
|
||||||
NATIVE_TYPE oldVal = val; \
|
NATIVE_TYPE oldVal = val; \
|
||||||
if (SHEditorUI::FUNC(Convert::ToNative(field->Name), val)) \
|
if (SHEditorUI::FUNC(Convert::ToNative(field->Name), val, &isHovered))\
|
||||||
|
{ \
|
||||||
|
field->SetValue(object, val); \
|
||||||
|
registerUndoAction(object, field, val, oldVal); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
/// <summary>
|
||||||
|
/// Alternative to RENDER_FIELD that checks for RangeAttribute and switches to a slider
|
||||||
|
/// instead.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="MANAGED_TYPE">The managed type of the object to edit.</param>
|
||||||
|
/// <param name="NATIVE_TYPE">The native type of the object to edit.</param>
|
||||||
|
/// <param name="FUNC">The SHEditorUI:: function to use for editing.</param>
|
||||||
|
#define RENDER_FIELD_RANGE(MANAGED_TYPE, NATIVE_TYPE, FUNC) \
|
||||||
|
(field->FieldType == MANAGED_TYPE::typeid) \
|
||||||
|
{ \
|
||||||
|
NATIVE_TYPE val = safe_cast<NATIVE_TYPE>(field->GetValue(object)); \
|
||||||
|
NATIVE_TYPE oldVal = val; \
|
||||||
|
\
|
||||||
|
RangeAttribute^ rangeAttrib = hasAttribute<RangeAttribute^>(field); \
|
||||||
|
const std::string FIELD_NAME = Convert::ToNative(field->Name); \
|
||||||
|
bool changed = false; \
|
||||||
|
if (rangeAttrib) \
|
||||||
|
{ \
|
||||||
|
changed = SHEditorUI::InputSlider \
|
||||||
|
( \
|
||||||
|
FIELD_NAME, \
|
||||||
|
static_cast<NATIVE_TYPE>(rangeAttrib->Min), \
|
||||||
|
static_cast<NATIVE_TYPE>(rangeAttrib->Max), \
|
||||||
|
val, &isHovered \
|
||||||
|
); \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
changed = SHEditorUI::FUNC(FIELD_NAME, val, &isHovered); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
if (changed) \
|
||||||
{ \
|
{ \
|
||||||
field->SetValue(object, val); \
|
field->SetValue(object, val); \
|
||||||
registerUndoAction(object, field, val, oldVal); \
|
registerUndoAction(object, field, val, oldVal); \
|
||||||
|
@ -76,7 +115,8 @@ using namespace System::Collections::Generic;
|
||||||
{ \
|
{ \
|
||||||
NATIVE_TYPE val = Convert::ToNative(safe_cast<MANAGED_TYPE>(field->GetValue(object))); \
|
NATIVE_TYPE val = Convert::ToNative(safe_cast<MANAGED_TYPE>(field->GetValue(object))); \
|
||||||
NATIVE_TYPE oldVal = val; \
|
NATIVE_TYPE oldVal = val; \
|
||||||
if (SHEditorUI::FUNC(Convert::ToNative(field->Name), val)) \
|
\
|
||||||
|
if (SHEditorUI::FUNC(Convert::ToNative(field->Name), val, &isHovered)) \
|
||||||
{ \
|
{ \
|
||||||
field->SetValue(object, Convert::ToCLI(val)); \
|
field->SetValue(object, Convert::ToCLI(val)); \
|
||||||
registerUndoAction(object, field, Convert::ToCLI(val), Convert::ToCLI(oldVal)); \
|
registerUndoAction(object, field, Convert::ToCLI(val), Convert::ToCLI(oldVal)); \
|
||||||
|
@ -196,16 +236,18 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
void Editor::renderFieldInInspector(Reflection::FieldInfo^ field, Object^ object)
|
void Editor::renderFieldInInspector(Reflection::FieldInfo^ field, Object^ object)
|
||||||
{
|
{
|
||||||
if RENDER_FIELD (Int16, int, InputInt)
|
bool isHovered = false;
|
||||||
else if RENDER_FIELD (Int32, int, InputInt)
|
|
||||||
else if RENDER_FIELD (Int64, int, InputInt)
|
if RENDER_FIELD_RANGE (Int16, int, InputInt)
|
||||||
else if RENDER_FIELD (UInt16, unsigned int, InputUnsignedInt)
|
else if RENDER_FIELD_RANGE (Int32, int, InputInt)
|
||||||
else if RENDER_FIELD (UInt32, unsigned int, InputUnsignedInt)
|
else if RENDER_FIELD_RANGE (Int64, int, InputInt)
|
||||||
else if RENDER_FIELD (UInt64, unsigned int, InputUnsignedInt)
|
else if RENDER_FIELD_RANGE (UInt16, unsigned int, InputUnsignedInt)
|
||||||
else if RENDER_FIELD (Byte, int, InputInt)
|
else if RENDER_FIELD_RANGE (UInt32, unsigned int, InputUnsignedInt)
|
||||||
|
else if RENDER_FIELD_RANGE (UInt64, unsigned int, InputUnsignedInt)
|
||||||
|
else if RENDER_FIELD_RANGE (Byte, int, InputInt)
|
||||||
else if RENDER_FIELD (bool, bool, InputCheckbox)
|
else if RENDER_FIELD (bool, bool, InputCheckbox)
|
||||||
else if RENDER_FIELD (float, float, InputFloat)
|
else if RENDER_FIELD_RANGE (float, float, InputFloat)
|
||||||
else if RENDER_FIELD (double, double, InputDouble)
|
else if RENDER_FIELD_RANGE (double, double, InputDouble)
|
||||||
else if (field->FieldType->IsSubclassOf(Enum::typeid))
|
else if (field->FieldType->IsSubclassOf(Enum::typeid))
|
||||||
{
|
{
|
||||||
// Get all the names of the enums
|
// Get all the names of the enums
|
||||||
|
@ -244,6 +286,15 @@ namespace SHADE
|
||||||
registerUndoAction(object, field, Convert::ToCLI(val), Convert::ToCLI(oldVal));
|
registerUndoAction(object, field, Convert::ToCLI(val), Convert::ToCLI(oldVal));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if the field has a specific attribute
|
||||||
|
TooltipAttribute^ toolTip = hasAttribute<TooltipAttribute^>(field);
|
||||||
|
if (toolTip && isHovered)
|
||||||
|
{
|
||||||
|
SHEditorUI::BeginTooltip();
|
||||||
|
SHEditorUI::Text(Convert::ToNative(toolTip->Description));
|
||||||
|
SHEditorUI::EndTooltip();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Editor::renderScriptContextMenu(Entity entity, Script^ script)
|
void Editor::renderScriptContextMenu(Entity entity, Script^ script)
|
||||||
|
@ -274,4 +325,24 @@ namespace SHADE
|
||||||
SHCommandManager::RegisterCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCLICommand>()));
|
SHCommandManager::RegisterCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCLICommand>()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
generic<typename Attribute>
|
||||||
|
Attribute Editor::hasAttribute(System::Reflection::FieldInfo^ field)
|
||||||
|
{
|
||||||
|
array<System::Object^>^ attributes = field->GetCustomAttributes(true);
|
||||||
|
for each (System::Object^ attrib in attributes)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Attribute attribute = safe_cast<Attribute>(attrib);
|
||||||
|
if (attribute != nullptr)
|
||||||
|
return attribute;
|
||||||
|
}
|
||||||
|
catch (System::InvalidCastException^)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Failed to find
|
||||||
|
return Attribute{};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ namespace SHADE
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Static class for Editor-related functions
|
/// Static class for Editor-related functions
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ref class Editor abstract sealed
|
private ref class Editor abstract sealed
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
@ -48,7 +48,13 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* UndoRedoStack Functions */
|
/* UndoRedoStack Functions */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/// <summary>
|
||||||
|
/// Undoes the last script inspector change if there is any.
|
||||||
|
/// </summary>
|
||||||
static void Undo();
|
static void Undo();
|
||||||
|
/// <summary>
|
||||||
|
/// Redoes the last script inspector change if there is any.
|
||||||
|
/// </summary>
|
||||||
static void Redo();
|
static void Redo();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -86,5 +92,7 @@ namespace SHADE
|
||||||
/// <param name="script">The Script to render the inspector for.</param>
|
/// <param name="script">The Script to render the inspector for.</param>
|
||||||
static void renderScriptContextMenu(Entity entity, Script^ script);
|
static void renderScriptContextMenu(Entity entity, Script^ script);
|
||||||
static void registerUndoAction(System::Object^ object, System::Reflection::FieldInfo^ field, System::Object^ newData, System::Object^ oldData);
|
static void registerUndoAction(System::Object^ object, System::Reflection::FieldInfo^ field, System::Object^ newData, System::Object^ oldData);
|
||||||
|
generic<typename Attribute> where Attribute : System::Attribute
|
||||||
|
static Attribute hasAttribute(System::Reflection::FieldInfo^ field);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
/************************************************************************************//*!
|
||||||
|
\file RangeAttribute.cxx
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\date Oct 18, 2022
|
||||||
|
\brief Contains the definition of the functions of the managed Range Attribute
|
||||||
|
class.
|
||||||
|
|
||||||
|
Note: This file is written in C++17/CLI.
|
||||||
|
|
||||||
|
Copyright (C) 2022 DigiPen Institute of Technology.
|
||||||
|
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||||
|
of DigiPen Institute of Technology is prohibited.
|
||||||
|
*//*************************************************************************************/
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "RangeAttribute.hxx"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Properties */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
float RangeAttribute::Min::get()
|
||||||
|
{
|
||||||
|
return minVal;
|
||||||
|
}
|
||||||
|
float RangeAttribute::Max::get()
|
||||||
|
{
|
||||||
|
return maxVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Constructors */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
RangeAttribute::RangeAttribute(float min, float max)
|
||||||
|
: minVal { min }
|
||||||
|
, maxVal { max }
|
||||||
|
{}
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
/************************************************************************************//*!
|
||||||
|
\file RangeAttribute.hxx
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\date Oct 18, 2022
|
||||||
|
\brief Contains the definition of the managed Range Attribute class with
|
||||||
|
the declaration of functions for working with it.
|
||||||
|
|
||||||
|
Note: This file is written in C++17/CLI.
|
||||||
|
|
||||||
|
Copyright (C) 2022 DigiPen Institute of Technology.
|
||||||
|
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||||
|
of DigiPen Institute of Technology is prohibited.
|
||||||
|
*//*************************************************************************************/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Simple attribute to constrain the range of values for a field on the editor.
|
||||||
|
/// </summary>
|
||||||
|
[System::AttributeUsage(System::AttributeTargets::Field)]
|
||||||
|
public ref class RangeAttribute : public System::Attribute
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* Properties */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/// <summary>
|
||||||
|
/// Minimum value for the Ranged field.
|
||||||
|
/// </summary>
|
||||||
|
property float Min
|
||||||
|
{
|
||||||
|
float get();
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Maximum value for the Ranged field.
|
||||||
|
/// </summary>
|
||||||
|
property float Max
|
||||||
|
{
|
||||||
|
float get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* Constructors */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/// <summary>
|
||||||
|
/// Constructor for a Tooltip attribute that fills in the description.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="description">Text to be shown when a field is hovered.</param>
|
||||||
|
RangeAttribute(float min, float max);
|
||||||
|
|
||||||
|
private:
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* Data Members */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
float minVal;
|
||||||
|
float maxVal;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
/************************************************************************************//*!
|
||||||
|
\file TooltipAttribute.cxx
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\date Oct 18, 2022
|
||||||
|
\brief Contains the definition of the functions of the managed Tooltip Attribute
|
||||||
|
class.
|
||||||
|
|
||||||
|
Note: This file is written in C++17/CLI.
|
||||||
|
|
||||||
|
Copyright (C) 2022 DigiPen Institute of Technology.
|
||||||
|
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||||
|
of DigiPen Institute of Technology is prohibited.
|
||||||
|
*//*************************************************************************************/
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "TooltipAttribute.hxx"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Properties */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
System::String^ TooltipAttribute::Description::get()
|
||||||
|
{
|
||||||
|
return desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Constructors */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
TooltipAttribute::TooltipAttribute(System::String^ description)
|
||||||
|
: desc { description }
|
||||||
|
{}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
/************************************************************************************//*!
|
||||||
|
\file TooltipAttribute.hxx
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\date Oct 18, 2022
|
||||||
|
\brief Contains the definition of the managed Tooltip Attribute class with
|
||||||
|
the declaration of functions for working with it.
|
||||||
|
|
||||||
|
Note: This file is written in C++17/CLI.
|
||||||
|
|
||||||
|
Copyright (C) 2022 DigiPen Institute of Technology.
|
||||||
|
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||||
|
of DigiPen Institute of Technology is prohibited.
|
||||||
|
*//*************************************************************************************/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Simple attribute to provide a field in a script with a tooltip.
|
||||||
|
/// </summary>
|
||||||
|
[System::AttributeUsage(System::AttributeTargets::Field)]
|
||||||
|
public ref class TooltipAttribute : public System::Attribute
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* Properties */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/// <summary>
|
||||||
|
/// Description that is to be shown in the Tooltip.
|
||||||
|
/// </summary>
|
||||||
|
property System::String^ Description
|
||||||
|
{
|
||||||
|
System::String^ get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* Constructors */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/// <summary>
|
||||||
|
/// Constructor for a Tooltip attribute that fills in the description.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="description">Text to be shown when a field is hovered.</param>
|
||||||
|
TooltipAttribute(System::String^ description);
|
||||||
|
|
||||||
|
private:
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* Data Members */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
System::String^ desc;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -1,27 +1,29 @@
|
||||||
/************************************************************************************//*!
|
/************************************************************************************//*!
|
||||||
\file SerializeFieldAttribute.cxx
|
\file Time.cxx
|
||||||
\author Tng Kah Wei, kahwei.tng, 390009620
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
\par email: kahwei.tng\@digipen.edu
|
\par email: kahwei.tng\@digipen.edu
|
||||||
\date Nov 5, 2021
|
\date Oct 19, 2022
|
||||||
\brief Contains the definition of the functions of the managed SerializeField
|
\brief This file is present so that the properties in Time.hxx would be compiled
|
||||||
Attribute class.
|
into the DLL.
|
||||||
|
|
||||||
Note: This file is written in C++17/CLI.
|
Note: This file is written in C++17/CLI.
|
||||||
|
|
||||||
Copyright (C) 2021 DigiPen Institute of Technology.
|
Copyright (C) 2022 DigiPen Institute of Technology.
|
||||||
Reproduction or disclosure of this file or its contents without the prior written consent
|
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||||
of DigiPen Institute of Technology is prohibited.
|
of DigiPen Institute of Technology is prohibited.
|
||||||
*//*************************************************************************************/
|
*//*************************************************************************************/
|
||||||
// Precompiled Headers
|
// Precompiled Headers
|
||||||
#include "SHpch.h"
|
#include "SHpch.h"
|
||||||
// Primary Header
|
// Primary Header
|
||||||
#include "SerializeFieldAttribute.hxx"
|
#include "Time.hxx"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Constructors */
|
/* Properties */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
SerializeField::SerializeField()
|
double Time::DeltaTime::get()
|
||||||
{}
|
{
|
||||||
|
return SHFrameRateController::GetRawDeltaTime();
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
/************************************************************************************//*!
|
||||||
|
\file Time.hxx
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\date Oct 19, 2022
|
||||||
|
\brief Contains the definition of the Time static class and the definition of
|
||||||
|
its properties.
|
||||||
|
|
||||||
|
Note: This file is written in C++17/CLI.
|
||||||
|
|
||||||
|
Copyright (C) 2022 DigiPen Institute of Technology.
|
||||||
|
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||||
|
of DigiPen Institute of Technology is prohibited.
|
||||||
|
*//*************************************************************************************/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "FRC/SHFramerateController.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Static class that contains the functions for working with time.
|
||||||
|
/// </summary>
|
||||||
|
public ref class Time abstract sealed
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* Properties */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/// <summary>
|
||||||
|
/// Time taken to process the previous frame.
|
||||||
|
/// Note, is affected by TimeScale. Use UnscaledDeltaTime if you wish to retrieve
|
||||||
|
/// real world time. This is also affected by MaxDeltaTime clamping that
|
||||||
|
/// UnscaledDeltaTime is subject to.
|
||||||
|
/// </summary>
|
||||||
|
static property double DeltaTime
|
||||||
|
{
|
||||||
|
double get();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
|
@ -21,15 +21,6 @@ namespace SHADE
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[System::AttributeUsage(System::AttributeTargets::Field)]
|
[System::AttributeUsage(System::AttributeTargets::Field)]
|
||||||
public ref class SerializeField : public System::Attribute
|
public ref class SerializeField : public System::Attribute
|
||||||
{
|
{};
|
||||||
public:
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
|
||||||
/* Constructors */
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
|
||||||
/// <summary>
|
|
||||||
/// Default Constructor
|
|
||||||
/// </summary>
|
|
||||||
SerializeField();
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,16 @@ using System;
|
||||||
|
|
||||||
public class RaccoonShowcase : Script
|
public class RaccoonShowcase : Script
|
||||||
{
|
{
|
||||||
public double RotateSpeed = 1.0;
|
[SerializeField]
|
||||||
public Vector3 ScaleSpeed = new Vector3(1.0, 1.0, 0.0);
|
[Tooltip("Speed of the rotation in radians per second.")]
|
||||||
|
[Range(-1.0f, 2.0f)]
|
||||||
|
private double RotateSpeed = 1.0;
|
||||||
|
//[SerializeField]
|
||||||
|
//[Range(-5, 20)]
|
||||||
|
//private int test = 5;
|
||||||
|
[SerializeField]
|
||||||
|
[Tooltip("Speed of the scaling in radians per second around each axis.")]
|
||||||
|
private Vector3 ScaleSpeed = new Vector3(1.0, 1.0, 0.0);
|
||||||
private Transform Transform;
|
private Transform Transform;
|
||||||
private double rotation = 0.0;
|
private double rotation = 0.0;
|
||||||
private Vector3 scale = Vector3.Zero;
|
private Vector3 scale = Vector3.Zero;
|
||||||
|
|
|
@ -3,7 +3,9 @@ using System;
|
||||||
|
|
||||||
public class RaccoonSpin : Script
|
public class RaccoonSpin : Script
|
||||||
{
|
{
|
||||||
public double RotateSpeed = 1.0;
|
[SerializeField]
|
||||||
|
[Tooltip("Speed of the rotation in radians per second.")]
|
||||||
|
private double RotateSpeed = 1.0;
|
||||||
private double rotation = 0.0;
|
private double rotation = 0.0;
|
||||||
private Transform Transform;
|
private Transform Transform;
|
||||||
public RaccoonSpin(GameObject gameObj) : base(gameObj) { }
|
public RaccoonSpin(GameObject gameObj) : base(gameObj) { }
|
||||||
|
|
Loading…
Reference in New Issue