added first selectable, and modyfiable assets to system, Mesh, Material, and Texture. Texture ist WIP, because no subassets are created jet, well technicaly everything is WIP bit nevermind XD
This commit is contained in:
@@ -1,12 +1,167 @@
|
||||
#include "ElementDrawer.hpp"
|
||||
#include "BehaviourScriptRegistry.hpp"
|
||||
#include "elements/ShaderRegistry.hpp"
|
||||
#include "elements/AssetLibrary.hpp"
|
||||
#include "BehaviourScripts/Camera.hpp"
|
||||
#include "windows/HirearchieView.hpp"
|
||||
#include "windows/PropertiesView.hpp"
|
||||
#include <algorithm>
|
||||
#include <any>
|
||||
#include <cctype>
|
||||
|
||||
namespace TSE::EDITOR
|
||||
{
|
||||
namespace
|
||||
{
|
||||
char assetPickerSearchBuffer[128] = "";
|
||||
|
||||
std::string ToLowerCopy(std::string value)
|
||||
{
|
||||
std::transform(value.begin(), value.end(), value.begin(), [](unsigned char c)
|
||||
{
|
||||
return static_cast<char>(std::tolower(c));
|
||||
});
|
||||
return value;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::vector<T*> GetAssetsOfType()
|
||||
{
|
||||
std::vector<T*> result;
|
||||
int count = AssetLibrary::GetValueCount();
|
||||
for(int i = 0; i < count; i++)
|
||||
{
|
||||
auto [ptr, type, id] = AssetLibrary::GetValueAt(i);
|
||||
if(type != typeid(T).name() && type != typeid(T*).name())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
result.push_back(std::any_cast<T*>(ptr));
|
||||
}
|
||||
catch(const std::bad_any_cast&)
|
||||
{
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T, typename NameGetter>
|
||||
T* DrawAssetPickerPopup(const char* popupId, const char* searchHint, const char* emptyText, NameGetter getName)
|
||||
{
|
||||
T* selectedAsset = nullptr;
|
||||
|
||||
ImGui::SetNextWindowSize({360.0f, 420.0f}, ImGuiCond_Appearing);
|
||||
if(ImGui::BeginPopup(popupId))
|
||||
{
|
||||
ImGui::PushItemWidth(-1.0f);
|
||||
ImGui::InputTextWithHint("##AssetPickerSearch", searchHint, assetPickerSearchBuffer, IM_ARRAYSIZE(assetPickerSearchBuffer));
|
||||
ImGui::PopItemWidth();
|
||||
ImGui::Separator();
|
||||
|
||||
std::string filterText = ToLowerCopy(assetPickerSearchBuffer);
|
||||
std::vector<T*> assets = GetAssetsOfType<T>();
|
||||
|
||||
if(ImGui::BeginChild("##AssetPickerList", {0.0f, 0.0f}, ImGuiChildFlags_None, ImGuiWindowFlags_AlwaysVerticalScrollbar))
|
||||
{
|
||||
int shownCount = 0;
|
||||
for(T* asset : assets)
|
||||
{
|
||||
if(asset == nullptr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string assetName = getName(asset);
|
||||
if(!filterText.empty() && ToLowerCopy(assetName).find(filterText) == std::string::npos)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ImGui::PushID(asset);
|
||||
if(ImGui::Selectable(assetName.c_str()))
|
||||
{
|
||||
selectedAsset = asset;
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
ImGui::PopID();
|
||||
shownCount++;
|
||||
}
|
||||
|
||||
if(shownCount == 0)
|
||||
{
|
||||
ImGui::TextDisabled("%s", emptyText);
|
||||
}
|
||||
}
|
||||
ImGui::EndChild();
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
return selectedAsset;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool BeginAssetField(T** element, const char* popupId)
|
||||
{
|
||||
if(element == nullptr)
|
||||
{
|
||||
ImGui::TextDisabled("No Asset Field");
|
||||
return false;
|
||||
}
|
||||
|
||||
ImGui::PushID(element);
|
||||
|
||||
float buttonWidth = ImGui::GetFrameHeight();
|
||||
float fieldHeight = std::max(36.0f, ImGui::GetFrameHeightWithSpacing() + ImGui::GetStyle().WindowPadding.y * 2.0f);
|
||||
|
||||
ImGui::BeginChild("##AssetField", {0.0f, fieldHeight}, ImGuiChildFlags_Borders, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse);
|
||||
if(ImGui::Button("+##SelectAsset", {buttonWidth, 0.0f}))
|
||||
{
|
||||
assetPickerSearchBuffer[0] = '\0';
|
||||
ImGui::OpenPopup(popupId);
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::BeginChild("##AssetFieldValue", {0.0f, 0.0f}, ImGuiChildFlags_None, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse);
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void EndAssetField()
|
||||
{
|
||||
ImGui::EndChild();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void OpenAssetPropertiesOnDoubleClick(T* asset)
|
||||
{
|
||||
if(asset == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left))
|
||||
{
|
||||
PropertiesView::SetInspectorElement(InspectableType::IAsset, static_cast<IAsset*>(asset));
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T, typename NameGetter>
|
||||
void AssetSelector(T** element, const char* popupId, const char* searchHint, const char* emptyText, NameGetter getName)
|
||||
{
|
||||
T* selectedAsset = DrawAssetPickerPopup<T>(popupId, searchHint, emptyText, getName);
|
||||
if(selectedAsset != nullptr)
|
||||
{
|
||||
*element = selectedAsset;
|
||||
}
|
||||
|
||||
ImGui::EndChild();
|
||||
ImGui::PopID();
|
||||
}
|
||||
}
|
||||
|
||||
#pragma region helper
|
||||
bool InputText(const char* label, std::string& str, size_t bufferSize = 256) {
|
||||
std::vector<char> buffer(bufferSize);
|
||||
@@ -222,15 +377,7 @@ namespace TSE::EDITOR
|
||||
void ElementDrawer::Draw(Renderable *element, const bool &debug)
|
||||
{
|
||||
ImGui::SeparatorText("Material");
|
||||
int height = 100;
|
||||
if(element->GetMaterial() == nullptr)
|
||||
{
|
||||
height = 35;
|
||||
}
|
||||
ImVec2 size(0, height);
|
||||
ImGui::BeginChild("MaterialViewer", size, ImGuiChildFlags_Borders);
|
||||
Draw(element->GetMaterial(), debug);
|
||||
ImGui::EndChild();
|
||||
DrawMaterialField(element->GetMaterialRef());
|
||||
}
|
||||
void ElementDrawer::Draw(MeshContainer *element, const bool &debug)
|
||||
{
|
||||
@@ -240,7 +387,7 @@ namespace TSE::EDITOR
|
||||
height = 35;
|
||||
}
|
||||
ImVec2 size(0, height);
|
||||
Draw(element->GetMesh(), debug, "Mesh", true);
|
||||
DrawMeshField(element->GetMeshRef());
|
||||
}
|
||||
void ElementDrawer::Draw(Image *element, const bool &debug)
|
||||
{
|
||||
@@ -444,7 +591,7 @@ namespace TSE::EDITOR
|
||||
Texture* value = element->GetValue<Texture*>(name);
|
||||
Draw(value, debug, name , true);
|
||||
}
|
||||
if (type == typeid(uint).name())
|
||||
else if (type == typeid(uint).name())
|
||||
{
|
||||
int value = element->GetValue<uint>(name);
|
||||
if(ImGui::InputInt(name.c_str(), &value))
|
||||
@@ -481,11 +628,6 @@ namespace TSE::EDITOR
|
||||
}
|
||||
void ElementDrawer::Draw(Mesh *element, const bool &debug, const std::string &label, const bool small)
|
||||
{
|
||||
if(element == nullptr)
|
||||
{
|
||||
ImGui::Text("No Mesh Set");
|
||||
return;
|
||||
}
|
||||
if(small) DrawMeshCompact(element, debug, label);
|
||||
else DrawMeshNormal(element, debug, label);
|
||||
}
|
||||
@@ -943,6 +1085,24 @@ namespace TSE::EDITOR
|
||||
ImGui::TextDisabled(("Chunk Count: " + std::to_string(element->GetChunkCount())).c_str());
|
||||
}
|
||||
}
|
||||
void ElementDrawer::Draw(IAsset *element, const bool &debug)
|
||||
{
|
||||
if (element->assetType() == "material")
|
||||
{
|
||||
Draw((Material*)element, debug);
|
||||
}
|
||||
else if (element->assetType() == "texture")
|
||||
{
|
||||
Draw((Texture*)element, debug);
|
||||
}
|
||||
else if (element->assetType() == "mesh")
|
||||
{
|
||||
Draw((Mesh*)element, debug);
|
||||
}
|
||||
|
||||
element->SaveAsset();
|
||||
}
|
||||
|
||||
void ElementDrawer::DrawAudioClipCompact(AudioClip *element, const bool &debug, const std::string &label)
|
||||
{
|
||||
float item_spacing = ImGui::GetStyle().ItemSpacing.x;
|
||||
@@ -1034,6 +1194,21 @@ namespace TSE::EDITOR
|
||||
}
|
||||
void ElementDrawer::DrawMeshCompact(Mesh *element, const bool &debug, const std::string &label)
|
||||
{
|
||||
|
||||
if(element == nullptr)
|
||||
{
|
||||
ImGui::Text("No Mesh Set");
|
||||
return;
|
||||
}
|
||||
ImGui::Text(element->name.c_str());
|
||||
}
|
||||
void ElementDrawer::DrawMeshNormal(Mesh *element, const bool &debug, const std::string &label)
|
||||
{
|
||||
if(element == nullptr)
|
||||
{
|
||||
ImGui::Text("No Mesh Set");
|
||||
return;
|
||||
}
|
||||
float item_spacing = ImGui::GetStyle().ItemSpacing.x;
|
||||
ImVec2 label_size = ImGui::CalcTextSize(label.c_str());
|
||||
|
||||
@@ -1060,54 +1235,6 @@ namespace TSE::EDITOR
|
||||
cursorCurrent.y += 2;
|
||||
ImGui::SetCursorPos(cursorCurrent);
|
||||
ImGui::TextUnformatted(label.c_str());
|
||||
}
|
||||
void ElementDrawer::DrawMeshNormal(Mesh *element, const bool &debug, const std::string &label)
|
||||
{
|
||||
ImGui::Text(("Name: " + element->name).c_str());
|
||||
if(debug)
|
||||
{
|
||||
//ImGui::TextDisabled(("ID: " + to_string(element->id)).c_str());
|
||||
}
|
||||
ImGui::Separator();
|
||||
ImGui::Text(("Vectex Count: " + std::to_string(element->vertecies.size())).c_str());
|
||||
ImGui::Text(("Index Count: " + std::to_string(element->indecies.size())).c_str());
|
||||
ImGui::Text(("UV Count: " + std::to_string(element->uvs.size())).c_str());
|
||||
ImGui::Indent(20.0f);
|
||||
if(ImGui::CollapsingHeader("Vertecies"))
|
||||
{
|
||||
ImGui::PushID("Verts");
|
||||
ImGui::BeginDisabled();
|
||||
for (int i = 0; i < element->vertecies.size(); i++)
|
||||
{
|
||||
ImGui::InputFloat3(std::to_string(i).c_str(), &element->vertecies[i].x);
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
ImGui::PopID();
|
||||
}
|
||||
if(ImGui::CollapsingHeader("Indecies"))
|
||||
{
|
||||
ImGui::PushID("Inds");
|
||||
ImGui::BeginDisabled();
|
||||
for (int i = 0; i < element->indecies.size(); i++)
|
||||
{
|
||||
int val = element->indecies[i];
|
||||
ImGui::InputInt(std::to_string(i).c_str(), &val);
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
ImGui::PopID();
|
||||
}
|
||||
if(ImGui::CollapsingHeader("UVs"))
|
||||
{
|
||||
ImGui::PushID("Uvs");
|
||||
ImGui::BeginDisabled();
|
||||
for (int i = 0; i < element->uvs.size(); i++)
|
||||
{
|
||||
ImGui::InputFloat2(std::to_string(i).c_str(), &element->uvs[i].x);
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
ImGui::PopID();
|
||||
}
|
||||
ImGui::Unindent(20.0f);
|
||||
|
||||
}
|
||||
void ElementDrawer::DrawSpriteCompact(Sprite *element, const bool &debug, const std::string &label)
|
||||
@@ -1215,6 +1342,98 @@ namespace TSE::EDITOR
|
||||
|
||||
ImVec2 texSize (available_width, (available_width) * ymultiplyer);
|
||||
ImGui::Image(element->GetTextureId(), texSize, {0,1}, {1,0});
|
||||
ImGui::Separator();
|
||||
ImGui::SeparatorText("Import Settings");
|
||||
|
||||
TextureImportSettings& settings = element->GetImportSettings();
|
||||
bool importSettingsChanged = false;
|
||||
|
||||
int importMode = static_cast<int>(settings.importMode);
|
||||
const char* importModes[] = { "Raw Texture", "Sprite", "Sprite Set", "Nine Tile" };
|
||||
if (ImGui::Combo("Import Mode", &importMode, importModes, IM_ARRAYSIZE(importModes)))
|
||||
{
|
||||
settings.importMode = static_cast<byte>(std::clamp(importMode, 0, IM_ARRAYSIZE(importModes) - 1));
|
||||
importSettingsChanged = true;
|
||||
}
|
||||
|
||||
int importCount[2] = {
|
||||
static_cast<int>(settings.importCount.x),
|
||||
static_cast<int>(settings.importCount.y)
|
||||
};
|
||||
if (ImGui::InputInt2("Import Count", importCount))
|
||||
{
|
||||
settings.importCount.x = static_cast<float>(std::max(1, importCount[0]));
|
||||
settings.importCount.y = static_cast<float>(std::max(1, importCount[1]));
|
||||
importSettingsChanged = true;
|
||||
}
|
||||
|
||||
int bpp = static_cast<int>(settings.bpp);
|
||||
if (ImGui::InputInt("BPP", &bpp))
|
||||
{
|
||||
settings.bpp = static_cast<uint>(std::max(0, bpp));
|
||||
importSettingsChanged = true;
|
||||
}
|
||||
|
||||
int chanels = static_cast<int>(settings.chanels);
|
||||
if (ImGui::InputInt("Chanels", &chanels))
|
||||
{
|
||||
settings.chanels = static_cast<byte>(std::clamp(chanels, 0, 255));
|
||||
importSettingsChanged = true;
|
||||
}
|
||||
|
||||
if (InputText("Import Name", settings.name))
|
||||
{
|
||||
importSettingsChanged = true;
|
||||
}
|
||||
|
||||
if (importSettingsChanged)
|
||||
{
|
||||
element->SaveAsset();
|
||||
}
|
||||
}
|
||||
|
||||
void ElementDrawer::DrawMaterialCompact(Material *element, const bool &debug, const std::string &label)
|
||||
{
|
||||
if(element == nullptr)
|
||||
{
|
||||
ImGui::Text("No Mesh Set");
|
||||
return;
|
||||
}
|
||||
ImGui::Text(element->GetName().c_str());
|
||||
}
|
||||
|
||||
void ElementDrawer::DrawMeshField(Mesh **element)
|
||||
{
|
||||
if(!BeginAssetField<Mesh>(element, "MeshAssetPicker"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DrawMeshCompact(*element, false, "");
|
||||
OpenAssetPropertiesOnDoubleClick(*element);
|
||||
EndAssetField<Mesh>();
|
||||
|
||||
AssetSelector<Mesh>(element, "MeshAssetPicker", "Search Mesh", "No meshes found", [](Mesh* mesh)
|
||||
{
|
||||
return mesh->name.empty() ? std::string("Unnamed Mesh") : mesh->name;
|
||||
});
|
||||
}
|
||||
|
||||
void ElementDrawer::DrawMaterialField(Material **element)
|
||||
{
|
||||
if(!BeginAssetField<Material>(element, "MaterialAssetPicker"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DrawMaterialCompact(*element, false, "");
|
||||
OpenAssetPropertiesOnDoubleClick(*element);
|
||||
EndAssetField<Material>();
|
||||
|
||||
AssetSelector<Material>(element, "MaterialAssetPicker", "Search Material", "No materials found", [](Material* mat)
|
||||
{
|
||||
return mat->GetName().empty() ? std::string("Unnamed Material") : mat->GetName();
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace TSE::EDITOR
|
||||
|
||||
Reference in New Issue
Block a user