Skip to content

Commit

Permalink
feat(tools): add palette editor plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
roby2014 committed Oct 21, 2023
1 parent 9d2a268 commit 5d90965
Show file tree
Hide file tree
Showing 8 changed files with 224 additions and 2 deletions.
1 change: 1 addition & 0 deletions engine/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ set(CUBOS_ENGINE_SOURCE
"src/cubos/engine/tools/entity_inspector/plugin.cpp"
"src/cubos/engine/tools/scene_editor/plugin.cpp"
"src/cubos/engine/tools/debug_camera/plugin.cpp"
"src/cubos/engine/tools/voxel_palette_editor/plugin.cpp"

"src/cubos/engine/transform/plugin.cpp"
"src/cubos/engine/transform/local_to_world.cpp"
Expand Down
22 changes: 22 additions & 0 deletions engine/include/cubos/engine/tools/voxel_palette_editor/plugin.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/// @dir
/// @brief @ref voxel-palette-editor-tool-plugin plugin directory.

/// @file
/// @brief Plugin entry point.
/// @ingroup voxel-palette-editor-tool-plugin

#pragma once

#include <cubos/engine/cubos.hpp>

namespace cubos::engine::tools
{
/// @defgroup voxel-palette-editor-tool-plugin Palette editor
/// @ingroup tool-plugins
/// @brief Allows the user to open and inspect/edit a palette asset.

/// @brief Plugin entry function.
/// @param cubos @b CUBOS. main class
/// @ingroup voxel-palette-editor-tool-plugin
void voxelPaletteEditorPlugin(Cubos& cubos);
} // namespace cubos::engine::tools
190 changes: 190 additions & 0 deletions engine/src/cubos/engine/tools/voxel_palette_editor/plugin.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
// todo: voxelpaletteeditor rename

#include <imgui.h>

#include <cubos/core/data/old/debug_serializer.hpp>
#include <cubos/core/log.hpp>

#include <cubos/engine/imgui/plugin.hpp>
#include <cubos/engine/renderer/plugin.hpp>
#include <cubos/engine/tools/asset_explorer/plugin.hpp>
#include <cubos/engine/tools/voxel_palette_editor/plugin.hpp>
#include <cubos/engine/voxels/plugin.hpp>

using cubos::core::data::old::Debug;
using cubos::core::ecs::EventReader;
using cubos::core::ecs::Read;
using cubos::core::ecs::Write;

using namespace cubos::engine;

using tools::AssetSelectedEvent;

struct SelectedPaletteInfo
{
Asset<VoxelPalette> asset;
VoxelPalette paletteCopy;
bool modified;
Asset<VoxelPalette> next;
};

static void savePaletteUiGuard(Write<Assets> assets, Write<SelectedPaletteInfo> selectedPalette)
{
// The popup only shows when we've already opened a palette and want to show another one.
// Thus if we haven't set the next asset variable we can just stop here.
if (selectedPalette->next.isNull())
{
return;
}

ImVec2 center = ImGui::GetMainViewport()->GetCenter();
ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5F, 0.5F));

if (ImGui::BeginPopupModal("Save Palette?", nullptr, ImGuiWindowFlags_AlwaysAutoResize))
{
bool optionSelected = false;

ImGui::Text("Do you want to save the modified palette?");
ImGui::Separator();

if (ImGui::Button("Yes", ImVec2(80, 0)))
{
CUBOS_INFO("Saving palette asset {} modificaations", Debug(selectedPalette->next));
assets->store(selectedPalette->asset, selectedPalette->paletteCopy);
assets->save(selectedPalette->asset);
optionSelected = true;
}

ImGui::SetItemDefaultFocus();
ImGui::SameLine();

if (ImGui::Button("No", ImVec2(80, 0)))
{
CUBOS_DEBUG("Discarding palette asset {} modifications", Debug(selectedPalette->next));
optionSelected = true;
}

ImGui::SameLine();

if (ImGui::Button("Cancel", ImVec2(80, 0)))
{
ImGui::CloseCurrentPopup();
}

if (optionSelected)
{
selectedPalette->asset = assets->load(selectedPalette->next);
selectedPalette->paletteCopy = assets->read(selectedPalette->asset).get();
selectedPalette->modified = false;
ImGui::CloseCurrentPopup();
}

ImGui::EndPopup();
}
}

static void checkAssetEventSystem(EventReader<AssetSelectedEvent> reader, Write<Assets> assets,
Write<SelectedPaletteInfo> selectedPalette)
{
for (const auto& event : reader)
{
if (assets->type(event.asset) == typeid(VoxelPalette))
{
CUBOS_INFO("Opening palette asset {}", Debug(event.asset));
if (!selectedPalette->asset.isNull() && selectedPalette->modified)
{
CUBOS_DEBUG("Opening save palette UI guard");
ImGui::OpenPopup("Save Palette?");
selectedPalette->next = event.asset;
}
else
{
selectedPalette->asset = assets->load(event.asset);
selectedPalette->paletteCopy = assets->read(selectedPalette->asset).get();
}
}
}

// When the 'Save Palette?' option is opened using ImGui::OpenPopup, this will be displayed.
savePaletteUiGuard(assets, selectedPalette);
}

static void voxelPaletteEditorSystem(Write<Assets> assets, Write<Renderer>, Write<SelectedPaletteInfo> selectedPalette,
Write<ActiveVoxelPalette> activePalette)
{
if (assets->status(selectedPalette->asset) != Assets::Status::Loaded)
{
return;
}

ImGui::Begin("Palette Editor");

bool wasMaterialModified = false;
std::pair<uint16_t, VoxelMaterial> modifiedMaterial;

for (uint16_t i = 0; i < selectedPalette->paletteCopy.size(); ++i)
{
const uint16_t materialIndex = i + 1;
auto& material = (VoxelMaterial&)selectedPalette->paletteCopy.get(materialIndex);

std::string label = "Material " + std::to_string(materialIndex);
if (ImGui::ColorEdit4(label.c_str(), &material.color.r))
{
CUBOS_DEBUG("Modified material");
modifiedMaterial = std::pair(materialIndex, material);
wasMaterialModified = true;
}
}

if (wasMaterialModified)
{
CUBOS_DEBUG("Storing as new asset because palette was modified");
auto [idx, material] = modifiedMaterial;
selectedPalette->paletteCopy.set(idx, material);
selectedPalette->modified = true;
}

// Add material / Make Active / Save

if (ImGui::Button("Add Material") || selectedPalette->paletteCopy.size() == 0)
{
selectedPalette->paletteCopy.push(VoxelMaterial{{1.0F, 0.0F, 1.0F, 1.0F}});
selectedPalette->modified = true;
}

ImGui::SameLine();

if (ImGui::Button("Make Active"))
{
activePalette->asset = selectedPalette->asset;
}

ImGui::SameLine();

if (ImGui::Button("Save"))
{
assets->store(selectedPalette->asset, selectedPalette->paletteCopy);
assets->save(selectedPalette->asset);
selectedPalette->modified = false;
}

if (activePalette->asset == selectedPalette->asset)
{
ImGui::TextColored({0, 255, 0, 255}, "This is your current active palette!");
}

ImGui::End();
}

void cubos::engine::tools::voxelPaletteEditorPlugin(Cubos& cubos)
{
cubos.addPlugin(rendererPlugin);
cubos.addPlugin(imguiPlugin);
cubos.addPlugin(assetExplorerPlugin);
cubos.addPlugin(voxelsPlugin);

cubos.addResource<SelectedPaletteInfo>();

cubos.system(checkAssetEventSystem).tagged("cubos.imgui");
cubos.system(voxelPaletteEditorSystem).tagged("cubos.imgui");
}
Binary file added tools/tesseratos/assets/main.pal
Binary file not shown.
3 changes: 3 additions & 0 deletions tools/tesseratos/assets/main.pal.meta
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"id": "6f42ae5a-59d1-5df3-8720-83b8df6dd536"
}
Binary file added tools/tesseratos/assets/main_copy.pal
Binary file not shown.
3 changes: 3 additions & 0 deletions tools/tesseratos/assets/main_copy.pal.meta
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"id": "1abc415a-abcd-15f1-0555-1242df6dabc6"
}
7 changes: 5 additions & 2 deletions tools/tesseratos/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <cubos/engine/tools/entity_inspector/plugin.hpp>
#include <cubos/engine/tools/scene_editor/plugin.hpp>
#include <cubos/engine/tools/settings_inspector/plugin.hpp>
#include <cubos/engine/tools/voxel_palette_editor/plugin.hpp>
#include <cubos/engine/tools/world_inspector/plugin.hpp>
#include <cubos/engine/transform/plugin.hpp>

Expand All @@ -23,8 +24,9 @@ static void mockCamera(Write<ActiveCameras> camera, Commands cmds)
.entity();
}

static void mockSettings(Write<Settings> settings)
static void setSettingsSystem(Write<Settings> settings)
{
settings->setBool("assets.io.readOnly", false);
settings->setString("assets.io.path", TESSERATOS_ASSETS_FOLDER);
}

Expand All @@ -35,11 +37,12 @@ int main(int argc, char** argv)
cubos.addPlugin(tools::sceneEditorPlugin);
cubos.addPlugin(tools::entityInspectorPlugin);
cubos.addPlugin(tools::worldInspectorPlugin);
cubos.addPlugin(tools::voxelPaletteEditorPlugin);
cubos.addPlugin(tools::assetExplorerPlugin);
cubos.addPlugin(tools::debugCameraPlugin);

cubos.startupSystem(mockCamera).tagged("setup");
cubos.startupSystem(mockSettings).tagged("setup");
cubos.startupSystem(setSettingsSystem).tagged("setup");

cubos.run();
}

0 comments on commit 5d90965

Please sign in to comment.