Archived
1
Fork 0

Reformat editor code

This commit is contained in:
Joshua Goins 2022-08-15 11:10:06 -04:00
parent c0928ea80c
commit 68d4512763
27 changed files with 1364 additions and 1323 deletions

View file

@ -1,14 +1,14 @@
set(CMAKE_FOLDER "Tools") set(CMAKE_FOLDER "Tools")
if(NOT NEEDS_HOSTED_SHADER_COMPILER) if (NOT NEEDS_HOSTED_SHADER_COMPILER)
add_subdirectory(shadercompiler) add_subdirectory(shadercompiler)
endif() endif ()
if(BUILD_TOOLS) if (BUILD_TOOLS)
add_subdirectory(common) add_subdirectory(common)
add_subdirectory(assetpipeline) add_subdirectory(assetpipeline)
add_subdirectory(fontcompiler) add_subdirectory(fontcompiler)
add_subdirectory(editor) add_subdirectory(editor)
add_subdirectory(modelcompiler) add_subdirectory(modelcompiler)
add_subdirectory(cutsceneeditor) add_subdirectory(cutsceneeditor)
endif() endif ()

View file

@ -1,5 +1,5 @@
#include <fmt/format.h>
#include <filesystem> #include <filesystem>
#include <fmt/format.h>
#include <vector> #include <vector>
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
@ -11,8 +11,8 @@ int main(int argc, char* argv[]) {
std::string gameDirectory = argv[2]; std::string gameDirectory = argv[2];
fmt::print("Game directory to output compiled assets in: {}\n", gameDirectory); fmt::print("Game directory to output compiled assets in: {}\n", gameDirectory);
for(auto const& dir_entry : std::filesystem::recursive_directory_iterator{dataDirectory}) { for (auto const& dir_entry : std::filesystem::recursive_directory_iterator{dataDirectory}) {
if(dir_entry.path().extension() == ".fbx") { if (dir_entry.path().extension() == ".fbx") {
fmt::print("Found fbx: {}\n", dir_entry.path().c_str()); fmt::print("Found fbx: {}\n", dir_entry.path().c_str());
@ -22,7 +22,7 @@ int main(int argc, char* argv[]) {
fmt::print("Equivalent file in the game directory: {}\n", new_game_path.c_str()); fmt::print("Equivalent file in the game directory: {}\n", new_game_path.c_str());
if(!exists(new_game_path)) { if (!exists(new_game_path)) {
fmt::print("Compiled version does not exist!\n"); fmt::print("Compiled version does not exist!\n");
std::vector<std::string> model_compiler_args; std::vector<std::string> model_compiler_args;
@ -34,7 +34,7 @@ int main(int argc, char* argv[]) {
model_compiler_args.emplace_back(new_game_path.c_str()); model_compiler_args.emplace_back(new_game_path.c_str());
std::string compiled_command; std::string compiled_command;
for(const auto& arg : model_compiler_args) { for (const auto& arg : model_compiler_args) {
compiled_command += arg + " "; compiled_command += arg + " ";
} }

View file

@ -1,16 +1,16 @@
set(SRC set(SRC
include/commoneditor.hpp include/commoneditor.hpp
include/debugpass.hpp include/debugpass.hpp
include/undostack.hpp include/undostack.hpp
src/commoneditor.cpp src/commoneditor.cpp
src/debugpass.cpp src/debugpass.cpp
src/undostack.cpp) src/undostack.cpp)
add_library(EditorCommon ${SRC}) add_library(EditorCommon ${SRC})
target_include_directories(EditorCommon PUBLIC include) target_include_directories(EditorCommon PUBLIC include)
target_link_libraries(EditorCommon PUBLIC target_link_libraries(EditorCommon PUBLIC
Renderer Renderer
imgui imgui
Core) Core)
set_engine_properties(EditorCommon) set_engine_properties(EditorCommon)

View file

@ -4,24 +4,24 @@
#include <vector> #include <vector>
#include "app.hpp" #include "app.hpp"
#include "assertions.hpp"
#include "asset.hpp"
#include "components.hpp"
#include "debugpass.hpp"
#include "engine.hpp"
#include "file.hpp"
#include "imgui_backend.hpp"
#include "log.hpp"
#include "math.hpp"
#include "object.hpp"
#include "platform.hpp"
#include "renderer.hpp"
#include "scene.hpp"
#include "undostack.hpp"
#include "utility.hpp" #include "utility.hpp"
#include <imgui.h> #include <imgui.h>
#include "math.hpp"
#include <imgui_stdlib.h>
#include <imgui_internal.h> #include <imgui_internal.h>
#include "platform.hpp" #include <imgui_stdlib.h>
#include "file.hpp"
#include "object.hpp"
#include "undostack.hpp"
#include "components.hpp"
#include "engine.hpp"
#include "debugpass.hpp"
#include "assertions.hpp"
#include "log.hpp"
#include "asset.hpp"
#include "scene.hpp"
#include "renderer.hpp"
#include "imgui_backend.hpp"
class TransformCommand : public Command { class TransformCommand : public Command {
public: public:
@ -69,7 +69,8 @@ public:
prism::Object new_parent; prism::Object new_parent;
std::string fetch_name() override { std::string fetch_name() override {
return "Change parent of " + engine->get_scene()->get(object).name + " to " + engine->get_scene()->get(new_parent).name; return "Change parent of " + engine->get_scene()->get(object).name + " to " +
engine->get_scene()->get(new_parent).name;
} }
void undo() override { void undo() override {
@ -89,15 +90,14 @@ enum class AssetType {
Scene Scene
}; };
template<typename T> template<typename T> AssetType get_asset_type() {
AssetType get_asset_type() { if constexpr (std::is_same<T, Mesh>::value) {
if constexpr(std::is_same<T, Mesh>::value) {
return AssetType::Mesh; return AssetType::Mesh;
} else if constexpr(std::is_same<T, Material>::value) { } else if constexpr (std::is_same<T, Material>::value) {
return AssetType::Material; return AssetType::Material;
} else if constexpr(std::is_same<T, Texture>::value) { } else if constexpr (std::is_same<T, Texture>::value) {
return AssetType::Texture; return AssetType::Texture;
} else if constexpr(std::is_same<T, Scene>::value) { } else if constexpr (std::is_same<T, Scene>::value) {
return AssetType::Scene; return AssetType::Scene;
} }
@ -108,16 +108,16 @@ constexpr int thumbnail_resolution = 256;
class CommonEditor : public prism::app { class CommonEditor : public prism::app {
public: public:
explicit CommonEditor(std::string_view id); explicit CommonEditor(std::string_view id);
void initialize_render() override; void initialize_render() override;
void prepare_quit() override; void prepare_quit() override;
bool should_quit() override; bool should_quit() override;
virtual void drawUI() {} virtual void drawUI() {}
void begin_frame() override; void begin_frame() override;
void update(float deltaTime) override; void update(float deltaTime) override;
@ -130,24 +130,30 @@ public:
virtual void updateEditor([[maybe_unused]] float deltaTime) {} virtual void updateEditor([[maybe_unused]] float deltaTime) {}
virtual void object_selected([[maybe_unused]] prism::Object object) {} virtual void object_selected([[maybe_unused]] prism::Object object) {}
virtual void asset_selected([[maybe_unused]] const std::filesystem::path& path, [[maybe_unused]] AssetType type) {} virtual void asset_selected([[maybe_unused]] const std::filesystem::path& path, [[maybe_unused]] AssetType type) {}
bool wants_no_scene_rendering() override { return true; } bool wants_no_scene_rendering() override {
bool is_multimodal() override { return true; } return true;
}
bool is_multimodal() override {
return true;
}
void createDockArea(); void createDockArea();
void drawViewport(Scene* scene); void drawViewport(Scene* scene);
void drawAssets(); void drawAssets();
// options // options
int getDefaultX() const; int getDefaultX() const;
int getDefaultY() const; int getDefaultY() const;
int getDefaultWidth() const; int getDefaultWidth() const;
int getDefaultHeight() const; int getDefaultHeight() const;
void addOpenedFile(std::string_view path); void addOpenedFile(std::string_view path);
void clearOpenedFiles(); void clearOpenedFiles();
std::vector<std::string> getOpenedFiles() const; std::vector<std::string> getOpenedFiles() const;
void drawOutline(); void drawOutline();
void drawPropertyEditor(); void drawPropertyEditor();
@ -162,26 +168,25 @@ public:
GFXTexture* get_texture_preview(Texture& texture); GFXTexture* get_texture_preview(Texture& texture);
GFXTexture* generate_common_preview(Scene& scene, prism::float3 camera_position); GFXTexture* generate_common_preview(Scene& scene, prism::float3 camera_position);
template<typename T> template<typename T> GFXTexture* get_asset_thumbnail(AssetPtr<T>& asset) {
GFXTexture* get_asset_thumbnail(AssetPtr<T>& asset) {
Expects(asset.handle != nullptr); Expects(asset.handle != nullptr);
if(asset_thumbnails.count(asset->path)) { if (asset_thumbnails.count(asset->path)) {
return asset_thumbnails[asset->path]; return asset_thumbnails[asset->path];
} else { } else {
if constexpr(std::is_same_v<T, Material>) { if constexpr (std::is_same_v<T, Material>) {
auto texture = get_material_preview(*asset.handle); auto texture = get_material_preview(*asset.handle);
asset_thumbnails[asset->path] = texture; asset_thumbnails[asset->path] = texture;
return texture; return texture;
} else if constexpr(std::is_same_v<T, Mesh>) { } else if constexpr (std::is_same_v<T, Mesh>) {
auto texture = get_mesh_preview(*asset.handle); auto texture = get_mesh_preview(*asset.handle);
asset_thumbnails[asset->path] = texture; asset_thumbnails[asset->path] = texture;
return texture; return texture;
} else if constexpr(std::is_same_v<T, Texture>) { } else if constexpr (std::is_same_v<T, Texture>) {
auto texture = get_texture_preview(*asset.handle); auto texture = get_texture_preview(*asset.handle);
asset_thumbnails[asset->path] = texture; asset_thumbnails[asset->path] = texture;
@ -194,27 +199,27 @@ public:
} }
GFXTexture* get_asset_thumbnail(const prism::path& path) { GFXTexture* get_asset_thumbnail(const prism::path& path) {
if(asset_thumbnails.count(path.string())) { if (asset_thumbnails.count(path.string())) {
return asset_thumbnails[path.string()]; return asset_thumbnails[path.string()];
} else { } else {
auto [asset, block] = assetm->load_asset_generic(path); auto [asset, block] = assetm->load_asset_generic(path);
// store as dummy texture, as to stop infinite reload because of failure (e.g. out of date model) // store as dummy texture, as to stop infinite reload because of failure (e.g. out of date model)
if(asset == nullptr) { if (asset == nullptr) {
asset_thumbnails[path.string()] = engine->get_renderer()->dummy_texture; asset_thumbnails[path.string()] = engine->get_renderer()->dummy_texture;
return engine->get_renderer()->dummy_texture; return engine->get_renderer()->dummy_texture;
} }
if(can_load_asset<Material>(path)) { if (can_load_asset<Material>(path)) {
auto ptr = AssetPtr<Material>(static_cast<Material*>(asset), block); auto ptr = AssetPtr<Material>(static_cast<Material*>(asset), block);
return get_asset_thumbnail(ptr); return get_asset_thumbnail(ptr);
} else if(can_load_asset<Mesh>(path)) { } else if (can_load_asset<Mesh>(path)) {
auto ptr = AssetPtr<Mesh>(static_cast<Mesh*>(asset), block); auto ptr = AssetPtr<Mesh>(static_cast<Mesh*>(asset), block);
return get_asset_thumbnail(ptr); return get_asset_thumbnail(ptr);
} else if(can_load_asset<Texture>(path)) { } else if (can_load_asset<Texture>(path)) {
auto ptr = AssetPtr<Texture>(static_cast<Texture*>(asset), block); auto ptr = AssetPtr<Texture>(static_cast<Texture*>(asset), block);
return get_asset_thumbnail(ptr); return get_asset_thumbnail(ptr);
@ -226,8 +231,7 @@ public:
bool has_asset_edit_changed = false; bool has_asset_edit_changed = false;
template<typename T> template<typename T> bool edit_asset(const char* name, AssetPtr<T>& asset) {
bool edit_asset(const char* name, AssetPtr<T>& asset) {
ImGui::PushID(&asset); ImGui::PushID(&asset);
auto draw_list = ImGui::GetWindowDrawList(); auto draw_list = ImGui::GetWindowDrawList();
@ -242,30 +246,46 @@ public:
const auto frame_color = ImGui::GetStyle().Colors[ImGuiCol_FrameBg]; const auto frame_color = ImGui::GetStyle().Colors[ImGuiCol_FrameBg];
const auto text_color = ImGui::GetStyle().Colors[ImGuiCol_Text]; const auto text_color = ImGui::GetStyle().Colors[ImGuiCol_Text];
const ImRect edit_rect = ImRect(window_pos, ImVec2(window_pos.x + thumbnail_size, window_pos.y + thumbnail_size)); const ImRect edit_rect =
ImRect(window_pos, ImVec2(window_pos.x + thumbnail_size, window_pos.y + thumbnail_size));
if(asset) if (asset)
draw_list->AddImageRounded(get_asset_thumbnail(asset), edit_rect.Min, edit_rect.Max, ImVec2(0, 0), ImVec2(1, 1), IM_COL32_WHITE, 3.0f); draw_list->AddImageRounded(
get_asset_thumbnail(asset),
edit_rect.Min,
edit_rect.Max,
ImVec2(0, 0),
ImVec2(1, 1),
IM_COL32_WHITE,
3.0f);
ImRect path_rect = ImRect(ImVec2(window_pos.x + thumbnail_size + 10.0f, window_pos.y), ImVec2(window_pos.x + item_width - inner_spacing, window_pos.y + 20.0f)); ImRect path_rect = ImRect(
ImVec2(window_pos.x + thumbnail_size + 10.0f, window_pos.y),
ImVec2(window_pos.x + item_width - inner_spacing, window_pos.y + 20.0f));
draw_list->AddText(ImVec2(window_pos.x + item_width, window_pos.y + (thumbnail_size / 2.0f) - (line_height / 2.0f)), ImColor(text_color), name); draw_list->AddText(
ImVec2(window_pos.x + item_width, window_pos.y + (thumbnail_size / 2.0f) - (line_height / 2.0f)),
ImColor(text_color),
name);
draw_list->AddRectFilled(path_rect.Min, path_rect.Max, ImColor(frame_color), 3.0f); draw_list->AddRectFilled(path_rect.Min, path_rect.Max, ImColor(frame_color), 3.0f);
ImRect clear_rect = ImRect(ImVec2(window_pos.x + thumbnail_size + 10.0f, window_pos.y + 20.0f), ImVec2(window_pos.x + thumbnail_size + 30.0f, window_pos.y + 40.0f)); ImRect clear_rect = ImRect(
ImVec2(window_pos.x + thumbnail_size + 10.0f, window_pos.y + 20.0f),
ImVec2(window_pos.x + thumbnail_size + 30.0f, window_pos.y + 40.0f));
draw_list->AddRectFilled(clear_rect.Min, clear_rect.Max, ImColor(255, 0, 0, 255), 3.0f); draw_list->AddRectFilled(clear_rect.Min, clear_rect.Max, ImColor(255, 0, 0, 255), 3.0f);
std::string path; std::string path;
if(asset) if (asset)
path = asset->path; path = asset->path;
else else
path = "None"; path = "None";
ImGui::PushClipRect(path_rect.Min, path_rect.Max, false); ImGui::PushClipRect(path_rect.Min, path_rect.Max, false);
draw_list->AddText(ImVec2(window_pos.x + thumbnail_size + 10.0f, window_pos.y), ImColor(text_color), path.c_str()); draw_list->AddText(
ImVec2(window_pos.x + thumbnail_size + 10.0f, window_pos.y), ImColor(text_color), path.c_str());
ImGui::Dummy(ImVec2(thumbnail_size, thumbnail_size + 10.0f)); ImGui::Dummy(ImVec2(thumbnail_size, thumbnail_size + 10.0f));
@ -273,7 +293,7 @@ public:
ImGui::PopClipRect(); ImGui::PopClipRect();
if(ImGui::IsItemClicked()) { if (ImGui::IsItemClicked()) {
current_asset_type = get_asset_type<T>(); current_asset_type = get_asset_type<T>();
open_asset_popup = true; open_asset_popup = true;
on_asset_select = [&asset, this](auto p) { on_asset_select = [&asset, this](auto p) {
@ -284,17 +304,17 @@ public:
ImGui::ItemAdd(edit_rect, ImGui::GetID("edit")); ImGui::ItemAdd(edit_rect, ImGui::GetID("edit"));
if(ImGui::IsItemClicked()) if (ImGui::IsItemClicked())
asset_selected(asset->path, get_asset_type<T>()); asset_selected(asset->path, get_asset_type<T>());
ImGui::ItemAdd(clear_rect, ImGui::GetID("clear")); ImGui::ItemAdd(clear_rect, ImGui::GetID("clear"));
if(ImGui::IsItemClicked()) if (ImGui::IsItemClicked())
asset.clear(); asset.clear();
ImGui::PopID(); ImGui::PopID();
if(has_asset_edit_changed) { if (has_asset_edit_changed) {
has_asset_edit_changed = false; has_asset_edit_changed = false;
return true; return true;
} else { } else {
@ -302,8 +322,7 @@ public:
} }
} }
template<class T> template<class T> void open_asset(const AssetType type, const std::function<void(prism::path)>& func_ptr) {
void open_asset(const AssetType type, const std::function<void(prism::path)>& func_ptr) {
current_asset_type = type; current_asset_type = type;
open_asset_popup = true; open_asset_popup = true;
on_asset_select = func_ptr; on_asset_select = func_ptr;
@ -328,7 +347,7 @@ private:
void load_thumbnail_cache(); void load_thumbnail_cache();
void save_thumbnail_cache(); void save_thumbnail_cache();
std::string id; std::string id;
std::string iniFileName; std::string iniFileName;
std::unordered_map<std::string, GFXTexture*> asset_thumbnails; std::unordered_map<std::string, GFXTexture*> asset_thumbnails;
@ -346,8 +365,8 @@ private:
UndoStack* current_stack = nullptr; UndoStack* current_stack = nullptr;
int defaultX, defaultY, defaultWidth, defaultHeight; int defaultX, defaultY, defaultWidth, defaultHeight;
std::vector<std::string> lastOpenedFiles; std::vector<std::string> lastOpenedFiles;
void walkObject(prism::Object object, prism::Object parentObject = prism::NullObject); void walkObject(prism::Object object, prism::Object parentObject = prism::NullObject);
@ -355,10 +374,14 @@ private:
void editRenderable(Renderable& mesh); void editRenderable(Renderable& mesh);
}; };
inline void editPath(const char* label, std::string& path, bool editable = true, const std::function<void()> on_selected = nullptr) { inline void editPath(
const char* label,
std::string& path,
bool editable = true,
const std::function<void()> on_selected = nullptr) {
ImGui::PushID(label); ImGui::PushID(label);
if(!editable) { if (!editable) {
ImGui::Text("%s: %s", label, path.c_str()); ImGui::Text("%s: %s", label, path.c_str());
} else { } else {
ImGui::InputText(label, &path); ImGui::InputText(label, &path);
@ -366,11 +389,11 @@ inline void editPath(const char* label, std::string& path, bool editable = true,
ImGui::SameLine(); ImGui::SameLine();
if(ImGui::Button("...")) { if (ImGui::Button("...")) {
engine->get_imgui().open_dialog(false, [&path, &on_selected](std::string p) { engine->get_imgui().open_dialog(false, [&path, &on_selected](std::string p) {
path = prism::get_relative_path(prism::domain::game, p).string(); path = prism::get_relative_path(prism::domain::game, p).string();
if(on_selected != nullptr) if (on_selected != nullptr)
on_selected(); on_selected();
}); });
} }

View file

@ -4,15 +4,15 @@
#include <functional> #include <functional>
#include <vector> #include <vector>
#include "pass.hpp" #include "assetptr.hpp"
#include "gfx_renderpass.hpp"
#include "gfx_pipeline.hpp"
#include "gfx_texture.hpp"
#include "gfx_buffer.hpp" #include "gfx_buffer.hpp"
#include "gfx_framebuffer.hpp" #include "gfx_framebuffer.hpp"
#include "gfx_pipeline.hpp"
#include "gfx_renderpass.hpp"
#include "gfx_texture.hpp"
#include "matrix.hpp" #include "matrix.hpp"
#include "object.hpp" #include "object.hpp"
#include "assetptr.hpp" #include "pass.hpp"
class Texture; class Texture;
class Mesh; class Mesh;
@ -47,13 +47,13 @@ public:
void create_render_target_resources(RenderTarget& target) override; void create_render_target_resources(RenderTarget& target) override;
void render_scene(Scene& scene, GFXCommandBuffer* commandBuffer) override; void render_scene(Scene& scene, GFXCommandBuffer* commandBuffer) override;
void get_selected_object(int x, int y, const std::function<void(SelectableObject)>& callback); void get_selected_object(int x, int y, const std::function<void(SelectableObject)>& callback);
void draw_arrow(GFXCommandBuffer* commandBuffer, prism::float3 color, Matrix4x4 model); void draw_arrow(GFXCommandBuffer* commandBuffer, prism::float3 color, Matrix4x4 model);
GFXTexture* get_requested_texture(PassTextureType type) override { GFXTexture* get_requested_texture(PassTextureType type) override {
if(type == PassTextureType::SelectionSobel) if (type == PassTextureType::SelectionSobel)
return sobelTexture; return sobelTexture;
return nullptr; return nullptr;

View file

@ -1,15 +1,15 @@
#pragma once #pragma once
#include <memory>
#include <string> #include <string>
#include <vector> #include <vector>
#include <memory>
class Command { class Command {
public: public:
std::string stored_name; std::string stored_name;
std::string get_name() { std::string get_name() {
if(stored_name.empty()) if (stored_name.empty())
stored_name = fetch_name(); stored_name = fetch_name();
return stored_name; return stored_name;
@ -23,11 +23,10 @@ public:
class UndoStack { class UndoStack {
public: public:
template<class T> template<class T> T& new_command() {
T& new_command() {
// if we are in the middle of the stack currently, wipe out everything and start fresh // if we are in the middle of the stack currently, wipe out everything and start fresh
// TODO: only do it up to the point we're modifing // TODO: only do it up to the point we're modifing
if(stack_position != (command_stack.size() - 1)) { if (stack_position != (command_stack.size() - 1)) {
command_stack.clear(); command_stack.clear();
stack_position = -1; stack_position = -1;
} }
@ -37,7 +36,7 @@ public:
return static_cast<T&>(*command_stack.emplace_back(std::make_unique<T>())); return static_cast<T&>(*command_stack.emplace_back(std::make_unique<T>()));
} }
//void push_command(Command* command); // void push_command(Command* command);
void undo(); void undo();
void redo(); void redo();

View file

@ -1,22 +1,22 @@
#include "commoneditor.hpp" #include "commoneditor.hpp"
#include <imgui.h>
#include <imgui_stdlib.h>
#include <imgui_internal.h>
#include <nlohmann/json.hpp>
#include <debug.hpp> #include <debug.hpp>
#include <imgui.h>
#include <imgui_internal.h>
#include <imgui_stdlib.h>
#include <nlohmann/json.hpp>
#include "engine.hpp" #include "engine.hpp"
#include "file.hpp" #include "file.hpp"
#include "platform.hpp"
#include "transform.hpp"
#include "log.hpp"
#include "shadowpass.hpp"
#include "gfx.hpp" #include "gfx.hpp"
#include "gfx_commandbuffer.hpp" #include "gfx_commandbuffer.hpp"
#include "imgui_utility.hpp" #include "imgui_utility.hpp"
#include "input.hpp" #include "input.hpp"
#include "log.hpp"
#include "platform.hpp"
#include "scenecapture.hpp" #include "scenecapture.hpp"
#include "shadowpass.hpp"
#include "transform.hpp"
const std::map<ImGuiKey, InputButton> imToPl = { const std::map<ImGuiKey, InputButton> imToPl = {
{ImGuiKey_Tab, InputButton::Tab}, {ImGuiKey_Tab, InputButton::Tab},
@ -39,8 +39,7 @@ const std::map<ImGuiKey, InputButton> imToPl = {
{ImGuiKey_V, InputButton::V}, {ImGuiKey_V, InputButton::V},
{ImGuiKey_X, InputButton::X}, {ImGuiKey_X, InputButton::X},
{ImGuiKey_Y, InputButton::Y}, {ImGuiKey_Y, InputButton::Y},
{ImGuiKey_Z, InputButton::Z} {ImGuiKey_Z, InputButton::Z}};
};
CommonEditor::CommonEditor(const std::string_view id) : id(id) { CommonEditor::CommonEditor(const std::string_view id) : id(id) {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
@ -87,15 +86,15 @@ static bool willCaptureMouse = false;
static float previous_intersect = 0.0; static float previous_intersect = 0.0;
void CommonEditor::update(float deltaTime) { void CommonEditor::update(float deltaTime) {
if(engine->get_scene() != nullptr) { if (engine->get_scene() != nullptr) {
prism::float3 offset; prism::float3 offset;
willCaptureMouse = engine->get_input()->is_repeating("cameraLook") && accepting_viewport_input; willCaptureMouse = engine->get_input()->is_repeating("cameraLook") && accepting_viewport_input;
platform::capture_mouse(willCaptureMouse); platform::capture_mouse(willCaptureMouse);
if(willCaptureMouse) { if (willCaptureMouse) {
if(engine->get_scene() != nullptr && !engine->get_scene()->get_all<Camera>().empty()) { if (engine->get_scene() != nullptr && !engine->get_scene()->get_all<Camera>().empty()) {
yaw += engine->get_input()->get_value("lookX") * 50.0f * deltaTime; yaw += engine->get_input()->get_value("lookX") * 50.0f * deltaTime;
pitch += engine->get_input()->get_value("lookY") * 50.0f * deltaTime; pitch += engine->get_input()->get_value("lookY") * 50.0f * deltaTime;
@ -103,7 +102,9 @@ void CommonEditor::update(float deltaTime) {
const float speed = 7.00f; const float speed = 7.00f;
prism::float3 forward, right; prism::float3 forward, right;
forward = normalize(angle_axis(yaw, prism::float3(0, 1, 0)) * angle_axis(pitch, prism::float3(1, 0, 0)) * prism::float3(0, 0, 1)); forward = normalize(
angle_axis(yaw, prism::float3(0, 1, 0)) * angle_axis(pitch, prism::float3(1, 0, 0)) *
prism::float3(0, 0, 1));
right = normalize(angle_axis(yaw, prism::float3(0, 1, 0)) * prism::float3(1, 0, 0)); right = normalize(angle_axis(yaw, prism::float3(0, 1, 0)) * prism::float3(1, 0, 0));
float movX = engine->get_input()->get_value("movementX"); float movX = engine->get_input()->get_value("movementX");
@ -114,21 +115,22 @@ void CommonEditor::update(float deltaTime) {
engine->get_scene()->get<Transform>(obj).position += right * movX * speed * deltaTime; engine->get_scene()->get<Transform>(obj).position += right * movX * speed * deltaTime;
engine->get_scene()->get<Transform>(obj).position += forward * -movY * speed * deltaTime; engine->get_scene()->get<Transform>(obj).position += forward * -movY * speed * deltaTime;
engine->get_scene()->get<Transform>(obj).rotation = angle_axis(yaw, prism::float3(0, 1, 0)) * angle_axis(pitch, prism::float3(1, 0, 0)); engine->get_scene()->get<Transform>(obj).rotation =
angle_axis(yaw, prism::float3(0, 1, 0)) * angle_axis(pitch, prism::float3(1, 0, 0));
} }
} }
doing_viewport_input = willCaptureMouse; doing_viewport_input = willCaptureMouse;
if(debugPass != nullptr) { if (debugPass != nullptr) {
if(engine->get_input()->is_pressed("cameraSelect") && accepting_viewport_input && !transforming_axis) { if (engine->get_input()->is_pressed("cameraSelect") && accepting_viewport_input && !transforming_axis) {
debugPass->get_selected_object(viewport_x, viewport_y, [this](SelectableObject object) { debugPass->get_selected_object(viewport_x, viewport_y, [this](SelectableObject object) {
if(object.object == prism::NullObject) { if (object.object == prism::NullObject) {
object_selected(prism::NullObject); object_selected(prism::NullObject);
return; return;
} }
if(object.type == SelectableObject::Type::Handle) { if (object.type == SelectableObject::Type::Handle) {
transforming_axis = true; transforming_axis = true;
axis = object.axis; axis = object.axis;
previous_intersect = 0.0; previous_intersect = 0.0;
@ -139,8 +141,8 @@ void CommonEditor::update(float deltaTime) {
}); });
} }
if(transforming_axis) { if (transforming_axis) {
if(!engine->get_input()->is_pressed("cameraSelect", true)) if (!engine->get_input()->is_pressed("cameraSelect", true))
transforming_axis = false; transforming_axis = false;
auto [obj, cam] = engine->get_scene()->get_all<Camera>()[0]; auto [obj, cam] = engine->get_scene()->get_all<Camera>()[0];
@ -148,8 +150,9 @@ void CommonEditor::update(float deltaTime) {
const auto width = viewport_width; const auto width = viewport_width;
const auto height = viewport_height; const auto height = viewport_height;
prism::float2 n = prism::float2(((viewport_x / (float)width) * 2) - 1, prism::float2 n = prism::float2(
((viewport_y / (float)height) * 2) - 1); // [-1, 1] mouse coordinates ((viewport_x / (float)width) * 2) - 1,
((viewport_y / (float)height) * 2) - 1); // [-1, 1] mouse coordinates
n.y = -n.y; n.y = -n.y;
n.x = std::clamp(n.x, -1.0f, 1.0f); n.x = std::clamp(n.x, -1.0f, 1.0f);
@ -174,7 +177,7 @@ void CommonEditor::update(float deltaTime) {
transform_ray.origin = last_object_position; transform_ray.origin = last_object_position;
transform_ray.t = std::numeric_limits<float>::max(); transform_ray.t = std::numeric_limits<float>::max();
switch(axis) { switch (axis) {
case SelectableObject::Axis::X: case SelectableObject::Axis::X:
transform_ray.direction = prism::float3(1, 0, 0); transform_ray.direction = prism::float3(1, 0, 0);
break; break;
@ -189,14 +192,14 @@ void CommonEditor::update(float deltaTime) {
prism::closest_distance_between_lines(camera_ray, transform_ray); prism::closest_distance_between_lines(camera_ray, transform_ray);
const float current_intersect = transform_ray.t; const float current_intersect = transform_ray.t;
if(previous_intersect == 0.0) if (previous_intersect == 0.0)
previous_intersect = current_intersect; previous_intersect = current_intersect;
const float delta = current_intersect - previous_intersect; const float delta = current_intersect - previous_intersect;
previous_intersect = current_intersect; previous_intersect = current_intersect;
switch(axis) { switch (axis) {
case SelectableObject::Axis::X: case SelectableObject::Axis::X:
transform.position.x -= delta; transform.position.x -= delta;
break; break;
@ -235,13 +238,13 @@ void cacheAssetFilesystem();
void CommonEditor::begin_frame() { void CommonEditor::begin_frame() {
drawUI(); drawUI();
if(open_asset_popup) { if (open_asset_popup) {
ImGui::OpenPopup("Select Asset"); ImGui::OpenPopup("Select Asset");
open_asset_popup = false; open_asset_popup = false;
} }
if(ImGui::BeginPopupModal("Select Asset", nullptr, ImGuiWindowFlags_NoMove)) { if (ImGui::BeginPopupModal("Select Asset", nullptr, ImGuiWindowFlags_NoMove)) {
if(!filesystem_cached) if (!filesystem_cached)
cacheAssetFilesystem(); cacheAssetFilesystem();
ImGui::SetWindowSize(ImVec2(500, 500)); ImGui::SetWindowSize(ImVec2(500, 500));
@ -249,9 +252,9 @@ void CommonEditor::begin_frame() {
ImGui::BeginChild("assetbox", ImVec2(-1, 400), true); ImGui::BeginChild("assetbox", ImVec2(-1, 400), true);
int column = 0; int column = 0;
for(auto& [p, a_type] : asset_files) { for (auto& [p, a_type] : asset_files) {
if(current_asset_type == a_type) { if (current_asset_type == a_type) {
if(ImGui::ImageButton(get_asset_thumbnail(prism::game_domain / p), ImVec2(64, 64))) { if (ImGui::ImageButton(get_asset_thumbnail(prism::game_domain / p), ImVec2(64, 64))) {
on_asset_select(p); on_asset_select(p);
ImGui::CloseCurrentPopup(); ImGui::CloseCurrentPopup();
} }
@ -264,7 +267,7 @@ void CommonEditor::begin_frame() {
column++; column++;
if(column != 5) if (column != 5)
ImGui::SameLine(); ImGui::SameLine();
else else
column = 0; column = 0;
@ -273,7 +276,7 @@ void CommonEditor::begin_frame() {
ImGui::EndChild(); ImGui::EndChild();
if(ImGui::Button("Cancel")) if (ImGui::Button("Cancel"))
ImGui::CloseCurrentPopup(); ImGui::CloseCurrentPopup();
ImGui::EndPopup(); ImGui::EndPopup();
@ -309,10 +312,11 @@ std::vector<std::string> CommonEditor::getOpenedFiles() const {
} }
void CommonEditor::walkObject(prism::Object object, prism::Object) { void CommonEditor::walkObject(prism::Object object, prism::Object) {
static ImGuiTreeNodeFlags base_flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_SpanAvailWidth; static ImGuiTreeNodeFlags base_flags =
ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_SpanAvailWidth;
auto& data = engine->get_scene()->get<Data>(object); auto& data = engine->get_scene()->get<Data>(object);
if(data.editor_object) if (data.editor_object)
return; return;
const auto text_color = ImGui::GetStyle().Colors[ImGuiCol_Text]; const auto text_color = ImGui::GetStyle().Colors[ImGuiCol_Text];
@ -322,8 +326,8 @@ void CommonEditor::walkObject(prism::Object object, prism::Object) {
bool is_open = ImGui::TreeNodeEx((void*)object, base_flags, "%s", data.name.c_str()); bool is_open = ImGui::TreeNodeEx((void*)object, base_flags, "%s", data.name.c_str());
if(ImGui::IsItemClicked()) { if (ImGui::IsItemClicked()) {
if(current_stack != nullptr) { if (current_stack != nullptr) {
auto& command = current_stack->new_command<SelectionCommand>(); auto& command = current_stack->new_command<SelectionCommand>();
command.editor = this; command.editor = this;
command.old_selection = selected_object; command.old_selection = selected_object;
@ -334,12 +338,12 @@ void CommonEditor::walkObject(prism::Object object, prism::Object) {
} }
if (ImGui::BeginPopupContextItem()) { if (ImGui::BeginPopupContextItem()) {
if(ImGui::Button("Delete")) { if (ImGui::Button("Delete")) {
engine->get_scene()->remove_object(object); engine->get_scene()->remove_object(object);
ImGui::CloseCurrentPopup(); ImGui::CloseCurrentPopup();
} }
if(ImGui::Button("Duplicate")) { if (ImGui::Button("Duplicate")) {
prism::Object obj = engine->get_scene()->duplicate_object(object); prism::Object obj = engine->get_scene()->duplicate_object(object);
engine->get_scene()->get(obj).name += "duplicate"; engine->get_scene()->get(obj).name += "duplicate";
@ -351,8 +355,8 @@ void CommonEditor::walkObject(prism::Object object, prism::Object) {
ImGui::EndPopup(); ImGui::EndPopup();
} }
if(is_open) { if (is_open) {
for(auto& child : engine->get_scene()->children_of(object)) for (auto& child : engine->get_scene()->children_of(object))
walkObject(child); walkObject(child);
ImGui::TreePop(); ImGui::TreePop();
@ -362,11 +366,11 @@ void CommonEditor::walkObject(prism::Object object, prism::Object) {
} }
void CommonEditor::drawOutline() { void CommonEditor::drawOutline() {
if(engine->get_scene() != nullptr) { if (engine->get_scene() != nullptr) {
ImGui::BeginChild("outlineinner", ImVec2(-1, -1), true); ImGui::BeginChild("outlineinner", ImVec2(-1, -1), true);
for(auto& object : engine->get_scene()->get_objects()) { for (auto& object : engine->get_scene()->get_objects()) {
if(engine->get_scene()->get(object).parent == prism::NullObject) if (engine->get_scene()->get(object).parent == prism::NullObject)
walkObject(object); walkObject(object);
} }
@ -381,7 +385,7 @@ Transform stored_transform;
bool IsItemActiveLastFrame() { bool IsItemActiveLastFrame() {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
// TODO: uh oh this is broken now :-( // TODO: uh oh this is broken now :-(
//if (g.ActiveIdPreviousFrame) // if (g.ActiveIdPreviousFrame)
// return g.ActiveIdPreviousFrame == g.CurrentWindow->DC.LastItemId; // return g.ActiveIdPreviousFrame == g.CurrentWindow->DC.LastItemId;
return false; return false;
@ -403,7 +407,7 @@ void CommonEditor::editTransform(prism::Object object, Transform transform) {
if (started_edit) if (started_edit)
stored_transform = transform; stored_transform = transform;
if(changed) if (changed)
engine->get_scene()->get<Transform>(object) = transform; engine->get_scene()->get<Transform>(object) = transform;
if (is_done_editing && current_stack != nullptr) { if (is_done_editing && current_stack != nullptr) {
@ -417,12 +421,12 @@ void CommonEditor::editTransform(prism::Object object, Transform transform) {
void CommonEditor::editRenderable(Renderable& mesh) { void CommonEditor::editRenderable(Renderable& mesh) {
edit_asset("Mesh", mesh.mesh); edit_asset("Mesh", mesh.mesh);
for(auto [i, material] : utility::enumerate(mesh.materials)) { for (auto [i, material] : utility::enumerate(mesh.materials)) {
std::string str = "Material " + std::to_string(i); std::string str = "Material " + std::to_string(i);
edit_asset(str.c_str(), material); edit_asset(str.c_str(), material);
} }
if(ImGui::Button("Add material")) if (ImGui::Button("Add material"))
mesh.materials.emplace_back(); mesh.materials.emplace_back();
} }
@ -433,7 +437,7 @@ void editLight(Light& light) {
ImGui::DragFloat("Size", &light.size, 0.1f, 0.0f, 1000.0f); ImGui::DragFloat("Size", &light.size, 0.1f, 0.0f, 1000.0f);
ImGui::DragFloat("Power", &light.power, 0.5f, 0.0f, 100.0f); ImGui::DragFloat("Power", &light.power, 0.5f, 0.0f, 100.0f);
if(light.type == Light::Type::Spot) if (light.type == Light::Type::Spot)
ImGui::DragFloat("Spot Size", &light.spot_size, 0.5f, 40.0f, 56.0f); ImGui::DragFloat("Spot Size", &light.spot_size, 0.5f, 40.0f, 56.0f);
ImGui::Checkbox("Enable shadows", &light.enable_shadows); ImGui::Checkbox("Enable shadows", &light.enable_shadows);
@ -449,7 +453,7 @@ void editCollision(Collision& collision) {
ImGui::Checkbox("Is Trigger", &collision.is_trigger); ImGui::Checkbox("Is Trigger", &collision.is_trigger);
if(collision.is_trigger) if (collision.is_trigger)
ImGui::InputText("Trigger ID", &collision.trigger_id); ImGui::InputText("Trigger ID", &collision.trigger_id);
} }
@ -459,7 +463,7 @@ void editRigidbody(Rigidbody& rigidbody) {
void editProbe(EnvironmentProbe& probe) { void editProbe(EnvironmentProbe& probe) {
ImGui::Checkbox("Is Sized", &probe.is_sized); ImGui::Checkbox("Is Sized", &probe.is_sized);
if(probe.is_sized) if (probe.is_sized)
ImGui::DragFloat3("Size", probe.size.ptr()); ImGui::DragFloat3("Size", probe.size.ptr());
ImGui::SliderFloat("Intensity", &probe.intensity, 0.0f, 1.0f); ImGui::SliderFloat("Intensity", &probe.intensity, 0.0f, 1.0f);
@ -467,7 +471,7 @@ void editProbe(EnvironmentProbe& probe) {
template<typename T> template<typename T>
bool componentHeader(Scene& scene, prism::Object& object, const char* name, const bool removable = true) { bool componentHeader(Scene& scene, prism::Object& object, const char* name, const bool removable = true) {
if(!scene.has<T>(object)) if (!scene.has<T>(object))
return false; return false;
const auto draw_list = ImGui::GetWindowDrawList(); const auto draw_list = ImGui::GetWindowDrawList();
@ -476,7 +480,7 @@ bool componentHeader(Scene& scene, prism::Object& object, const char* name, cons
const auto state_store = ImGui::GetStateStorage(); const auto state_store = ImGui::GetStateStorage();
auto is_open = state_store->GetBoolRef(ImGui::GetID((std::string(name) + "_open").c_str()), true); auto is_open = state_store->GetBoolRef(ImGui::GetID((std::string(name) + "_open").c_str()), true);
if(is_open == nullptr) if (is_open == nullptr)
return false; return false;
const auto window_padding = ImGui::GetStyle().WindowPadding; const auto window_padding = ImGui::GetStyle().WindowPadding;
@ -492,7 +496,10 @@ bool componentHeader(Scene& scene, prism::Object& object, const char* name, cons
const auto line_height = ImGui::GetTextLineHeight(); const auto line_height = ImGui::GetTextLineHeight();
draw_list->AddRectFilled(header_start, header_end, ImColor(widget_color), 5.0f); draw_list->AddRectFilled(header_start, header_end, ImColor(widget_color), 5.0f);
draw_list->AddText(ImVec2(header_start.x + frame_padding.x, header_start.y + (25.0f / 2.0f) - (line_height / 2.0f)), ImColor(text_color), name); draw_list->AddText(
ImVec2(header_start.x + frame_padding.x, header_start.y + (25.0f / 2.0f) - (line_height / 2.0f)),
ImColor(text_color),
name);
ImGui::Dummy(ImVec2(window_size.x - window_pos.x, 25)); ImGui::Dummy(ImVec2(window_size.x - window_pos.x, 25));
@ -502,8 +509,11 @@ bool componentHeader(Scene& scene, prism::Object& object, const char* name, cons
*is_open = !(*is_open); *is_open = !(*is_open);
} }
if(removable) { if (removable) {
draw_list->AddText(ImVec2(header_end.x - (button_size / 2.0f), header_start.y + (25.0f / 2.0f) - (line_height / 2.0f)), ImColor(text_color), "X"); draw_list->AddText(
ImVec2(header_end.x - (button_size / 2.0f), header_start.y + (25.0f / 2.0f) - (line_height / 2.0f)),
ImColor(text_color),
"X");
ImGui::ItemAdd(ImRect(ImVec2(header_end.x - button_size, header_start.y), header_end), ImGui::GetID(name)); ImGui::ItemAdd(ImRect(ImVec2(header_end.x - button_size, header_start.y), header_end), ImGui::GetID(name));
@ -519,14 +529,14 @@ bool componentHeader(Scene& scene, prism::Object& object, const char* name, cons
void CommonEditor::drawPropertyEditor() { void CommonEditor::drawPropertyEditor() {
auto scene = engine->get_scene(); auto scene = engine->get_scene();
if(scene != nullptr) { if (scene != nullptr) {
if(selected_object != prism::NullObject) { if (selected_object != prism::NullObject) {
if(!scene->has<Data>(selected_object)) { if (!scene->has<Data>(selected_object)) {
selected_object = prism::NullObject; selected_object = prism::NullObject;
return; return;
} }
if(scene->is_object_prefab(selected_object)) { if (scene->is_object_prefab(selected_object)) {
ImGui::TextDisabled("Cannot edit prefab, so certain data is uneditable."); ImGui::TextDisabled("Cannot edit prefab, so certain data is uneditable.");
} else { } else {
auto& data = scene->get(selected_object); auto& data = scene->get(selected_object);
@ -534,10 +544,10 @@ void CommonEditor::drawPropertyEditor() {
ImGui::InputText("Name", &data.name); ImGui::InputText("Name", &data.name);
static std::string stored_name; static std::string stored_name;
if(ImGui::IsItemActive() && !IsItemActiveLastFrame()) if (ImGui::IsItemActive() && !IsItemActiveLastFrame())
stored_name = data.name; stored_name = data.name;
if(ImGui::IsItemDeactivatedAfterEdit() && current_stack != nullptr) { if (ImGui::IsItemDeactivatedAfterEdit() && current_stack != nullptr) {
auto& command = current_stack->new_command<RenameCommand>(); auto& command = current_stack->new_command<RenameCommand>();
command.object = selected_object; command.object = selected_object;
command.new_name = data.name; command.new_name = data.name;
@ -545,7 +555,7 @@ void CommonEditor::drawPropertyEditor() {
} }
std::string preview_value = data.parent == prism::NullObject ? "None" : scene->get(data.parent).name; std::string preview_value = data.parent == prism::NullObject ? "None" : scene->get(data.parent).name;
if(ImGui::BeginCombo("Parent", preview_value.c_str())) { if (ImGui::BeginCombo("Parent", preview_value.c_str())) {
for (auto& object : scene->get_objects()) { for (auto& object : scene->get_objects()) {
// dont allow selecting a node to be the parent of itself // dont allow selecting a node to be the parent of itself
if (object == selected_object) if (object == selected_object)
@ -567,32 +577,32 @@ void CommonEditor::drawPropertyEditor() {
ImGui::OpenPopup("add_popup"); ImGui::OpenPopup("add_popup");
if (ImGui::BeginPopup("add_popup")) { if (ImGui::BeginPopup("add_popup")) {
if(ImGui::Selectable("Renderable")) { if (ImGui::Selectable("Renderable")) {
scene->add<Renderable>(selected_object); scene->add<Renderable>(selected_object);
ImGui::CloseCurrentPopup(); ImGui::CloseCurrentPopup();
} }
if(ImGui::Selectable("Light")) { if (ImGui::Selectable("Light")) {
scene->add<Light>(selected_object); scene->add<Light>(selected_object);
ImGui::CloseCurrentPopup(); ImGui::CloseCurrentPopup();
} }
if(ImGui::Selectable("Camera")) { if (ImGui::Selectable("Camera")) {
scene->add<Camera>(selected_object); scene->add<Camera>(selected_object);
ImGui::CloseCurrentPopup(); ImGui::CloseCurrentPopup();
} }
if(ImGui::Selectable("Collision")) { if (ImGui::Selectable("Collision")) {
scene->add<Collision>(selected_object); scene->add<Collision>(selected_object);
ImGui::CloseCurrentPopup(); ImGui::CloseCurrentPopup();
} }
if(ImGui::Selectable("Rigidbody")) { if (ImGui::Selectable("Rigidbody")) {
scene->add<Rigidbody>(selected_object); scene->add<Rigidbody>(selected_object);
ImGui::CloseCurrentPopup(); ImGui::CloseCurrentPopup();
} }
if(ImGui::Selectable("Environment Probe")) { if (ImGui::Selectable("Environment Probe")) {
scene->add<EnvironmentProbe>(selected_object); scene->add<EnvironmentProbe>(selected_object);
ImGui::CloseCurrentPopup(); ImGui::CloseCurrentPopup();
} }
@ -600,25 +610,25 @@ void CommonEditor::drawPropertyEditor() {
ImGui::EndPopup(); ImGui::EndPopup();
} }
if(componentHeader<Transform>(*scene, selected_object, "Transform", false)) if (componentHeader<Transform>(*scene, selected_object, "Transform", false))
editTransform(selected_object, scene->get<Transform>(selected_object)); editTransform(selected_object, scene->get<Transform>(selected_object));
if(componentHeader<Renderable>(*scene, selected_object, "Renderable")) if (componentHeader<Renderable>(*scene, selected_object, "Renderable"))
editRenderable(scene->get<Renderable>(selected_object)); editRenderable(scene->get<Renderable>(selected_object));
if(componentHeader<Light>(*scene, selected_object, "Light")) if (componentHeader<Light>(*scene, selected_object, "Light"))
editLight(scene->get<Light>(selected_object)); editLight(scene->get<Light>(selected_object));
if(componentHeader<Camera>(*scene, selected_object, "Camera")) if (componentHeader<Camera>(*scene, selected_object, "Camera"))
editCamera(scene->get<Camera>(selected_object)); editCamera(scene->get<Camera>(selected_object));
if(componentHeader<Collision>(*scene, selected_object, "Collision")) if (componentHeader<Collision>(*scene, selected_object, "Collision"))
editCollision(scene->get<Collision>(selected_object)); editCollision(scene->get<Collision>(selected_object));
if(componentHeader<Rigidbody>(*scene, selected_object, "Rigidbody")) if (componentHeader<Rigidbody>(*scene, selected_object, "Rigidbody"))
editRigidbody(scene->get<Rigidbody>(selected_object)); editRigidbody(scene->get<Rigidbody>(selected_object));
if(componentHeader<EnvironmentProbe>(*scene, selected_object, "Environment Probe")) if (componentHeader<EnvironmentProbe>(*scene, selected_object, "Environment Probe"))
editProbe(scene->get<EnvironmentProbe>(selected_object)); editProbe(scene->get<EnvironmentProbe>(selected_object));
} }
} else { } else {
@ -638,12 +648,9 @@ void CommonEditor::createDockArea() {
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f); ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
ImGuiWindowFlags window_flags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking | ImGuiWindowFlags window_flags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking |
ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse |
ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove |
ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus;
ImGuiWindowFlags_NoMove |
ImGuiWindowFlags_NoBringToFrontOnFocus |
ImGuiWindowFlags_NoNavFocus;
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f)); ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
ImGui::Begin("dockspace", nullptr, window_flags); ImGui::Begin("dockspace", nullptr, window_flags);
@ -656,15 +663,16 @@ void CommonEditor::createDockArea() {
void CommonEditor::drawViewport(Scene* scene) { void CommonEditor::drawViewport(Scene* scene) {
const auto size = ImGui::GetContentRegionAvail(); const auto size = ImGui::GetContentRegionAvail();
const auto real_size = ImVec2(static_cast<int>(size.x * platform::get_monitor_dpi()), static_cast<int>(size.y * platform::get_monitor_dpi())); const auto real_size = ImVec2(
static_cast<int>(size.x * platform::get_monitor_dpi()), static_cast<int>(size.y * platform::get_monitor_dpi()));
if(real_size.x <= 0 || real_size.y <= 0) if (real_size.x <= 0 || real_size.y <= 0)
return; return;
auto window = ImGui::GetCurrentWindowRead(); auto window = ImGui::GetCurrentWindowRead();
auto window_id = window->ID; auto window_id = window->ID;
if(!viewport_render_targets.count(window_id)) { if (!viewport_render_targets.count(window_id)) {
ViewportRenderTarget new_target; ViewportRenderTarget new_target;
new_target.target = engine->get_renderer()->allocate_render_target(real_size); new_target.target = engine->get_renderer()->allocate_render_target(real_size);
@ -673,7 +681,7 @@ void CommonEditor::drawViewport(Scene* scene) {
auto target = &viewport_render_targets[window_id]; auto target = &viewport_render_targets[window_id];
if(real_size.x != target->target->extent.width || real_size.y != target->target->extent.height) if (real_size.x != target->target->extent.width || real_size.y != target->target->extent.height)
engine->get_renderer()->resize_render_target(*target->target, real_size); engine->get_renderer()->resize_render_target(*target->target, real_size);
target->scene = scene; target->scene = scene;
@ -691,17 +699,17 @@ void CommonEditor::drawViewport(Scene* scene) {
accepting_viewport_input = ImGui::IsWindowHovered(); accepting_viewport_input = ImGui::IsWindowHovered();
if(doing_viewport_input) if (doing_viewport_input)
ImGui::SetWindowFocus(); ImGui::SetWindowFocus();
} }
void CommonEditor::set_undo_stack(UndoStack *stack) { void CommonEditor::set_undo_stack(UndoStack* stack) {
current_stack = stack; current_stack = stack;
} }
bool mesh_readable(const prism::path& path) { bool mesh_readable(const prism::path& path) {
auto file = prism::open_file(path); auto file = prism::open_file(path);
if(!file.has_value()) { if (!file.has_value()) {
prism::log("Failed to load mesh from {}!", path.string()); prism::log("Failed to load mesh from {}!", path.string());
return false; return false;
} }
@ -714,7 +722,7 @@ bool mesh_readable(const prism::path& path) {
bool material_readable(const prism::path& path) { bool material_readable(const prism::path& path) {
auto file = prism::open_file(path); auto file = prism::open_file(path);
if(!file.has_value()) { if (!file.has_value()) {
prism::log("Failed to load material from {}!", path.string()); prism::log("Failed to load material from {}!", path.string());
return false; return false;
} }
@ -729,17 +737,17 @@ void cacheAssetFilesystem() {
asset_files.clear(); asset_files.clear();
auto data_directory = "data"; auto data_directory = "data";
if(!std::filesystem::exists(data_directory)) if (!std::filesystem::exists(data_directory))
return; return;
for(auto& p : std::filesystem::recursive_directory_iterator(data_directory)) { for (auto& p : std::filesystem::recursive_directory_iterator(data_directory)) {
if(p.path().extension() == ".model" && mesh_readable(p.path())) { if (p.path().extension() == ".model" && mesh_readable(p.path())) {
asset_files[std::filesystem::relative(p, data_directory)] = AssetType::Mesh; asset_files[std::filesystem::relative(p, data_directory)] = AssetType::Mesh;
} else if(p.path().extension() == ".material" && material_readable(p.path())) { } else if (p.path().extension() == ".material" && material_readable(p.path())) {
asset_files[std::filesystem::relative(p, data_directory)] = AssetType::Material; asset_files[std::filesystem::relative(p, data_directory)] = AssetType::Material;
} else if(p.path().extension() == ".png") { } else if (p.path().extension() == ".png") {
asset_files[std::filesystem::relative(p, data_directory)] = AssetType::Texture; asset_files[std::filesystem::relative(p, data_directory)] = AssetType::Texture;
} else if(p.path().extension() == ".scene") { } else if (p.path().extension() == ".scene") {
asset_files[std::filesystem::relative(p, data_directory)] = AssetType::Scene; asset_files[std::filesystem::relative(p, data_directory)] = AssetType::Scene;
} }
} }
@ -748,7 +756,7 @@ void cacheAssetFilesystem() {
} }
void CommonEditor::drawAssets() { void CommonEditor::drawAssets() {
if(!filesystem_cached) if (!filesystem_cached)
cacheAssetFilesystem(); cacheAssetFilesystem();
const float window_width = ImGui::GetWindowWidth(); const float window_width = ImGui::GetWindowWidth();
@ -761,18 +769,18 @@ void CommonEditor::drawAssets() {
const int max_columns = std::floor((window_width - window_padding) / column_width); const int max_columns = std::floor((window_width - window_padding) / column_width);
int column = 0; int column = 0;
for(auto& [p, type] : asset_files) { for (auto& [p, type] : asset_files) {
ImGui::PushID(&p); ImGui::PushID(&p);
if(ImGui::ImageButton(get_asset_thumbnail(prism::game_domain / p), ImVec2(64, 64))) if (ImGui::ImageButton(get_asset_thumbnail(prism::game_domain / p), ImVec2(64, 64)))
asset_selected(prism::game_domain / p, type); asset_selected(prism::game_domain / p, type);
if(ImGui::BeginPopupContextItem()) { if (ImGui::BeginPopupContextItem()) {
ImGui::TextDisabled("%s", p.string().c_str()); ImGui::TextDisabled("%s", p.string().c_str());
ImGui::Separator(); ImGui::Separator();
if(ImGui::Button("Regenerate thumbnail")) { if (ImGui::Button("Regenerate thumbnail")) {
asset_thumbnails.erase(asset_thumbnails.find((prism::game_domain / p).string())); asset_thumbnails.erase(asset_thumbnails.find((prism::game_domain / p).string()));
} }
@ -781,7 +789,7 @@ void CommonEditor::drawAssets() {
column++; column++;
if(column >= max_columns) { if (column >= max_columns) {
column = 0; column = 0;
} else { } else {
ImGui::SameLine(); ImGui::SameLine();
@ -796,7 +804,8 @@ GFXTexture* CommonEditor::get_material_preview(Material& material) {
auto sphere = scene.add_object(); auto sphere = scene.add_object();
scene.add<Renderable>(sphere).mesh = assetm->get<Mesh>(prism::base_domain / "models" / "sphere.model"); scene.add<Renderable>(sphere).mesh = assetm->get<Mesh>(prism::base_domain / "models" / "sphere.model");
scene.get<Renderable>(sphere).materials.push_back(assetm->get<Material>(prism::game_domain / material.path)); // we throw away our material handle here :-( scene.get<Renderable>(sphere).materials.push_back(
assetm->get<Material>(prism::game_domain / material.path)); // we throw away our material handle here :-(
scene.get<Transform>(sphere).rotation = euler_to_quat(prism::float3(radians(90.0f), 0, 0)); scene.get<Transform>(sphere).rotation = euler_to_quat(prism::float3(radians(90.0f), 0, 0));
@ -810,10 +819,10 @@ GFXTexture* CommonEditor::get_mesh_preview(Mesh& mesh) {
scene.add<Renderable>(mesh_obj).mesh = assetm->get<Mesh>(prism::game_domain / mesh.path); scene.add<Renderable>(mesh_obj).mesh = assetm->get<Mesh>(prism::game_domain / mesh.path);
float biggest_component = 0.0f; float biggest_component = 0.0f;
for(const auto& part : scene.get<Renderable>(mesh_obj).mesh->parts) { for (const auto& part : scene.get<Renderable>(mesh_obj).mesh->parts) {
const auto find_biggest_component = [&biggest_component](const prism::float3 vec) { const auto find_biggest_component = [&biggest_component](const prism::float3 vec) {
for(auto& component : vec.data) { for (auto& component : vec.data) {
if(std::fabs(component) > biggest_component) if (std::fabs(component) > biggest_component)
biggest_component = component; biggest_component = component;
} }
}; };
@ -821,7 +830,8 @@ GFXTexture* CommonEditor::get_mesh_preview(Mesh& mesh) {
find_biggest_component(part.bounding_box.min); find_biggest_component(part.bounding_box.min);
find_biggest_component(part.bounding_box.max); find_biggest_component(part.bounding_box.max);
scene.get<Renderable>(mesh_obj).materials.push_back(assetm->get<Material>(prism::game_domain / "materials" / "Material.material")); scene.get<Renderable>(mesh_obj).materials.push_back(
assetm->get<Material>(prism::game_domain / "materials" / "Material.material"));
} }
return generate_common_preview(scene, prism::float3(biggest_component * 2.0f)); return generate_common_preview(scene, prism::float3(biggest_component * 2.0f));
@ -873,8 +883,13 @@ GFXTexture* CommonEditor::get_texture_preview(Texture& texture) {
prism::float4 viewport; prism::float4 viewport;
prism::float4 options; prism::float4 options;
} pc; } pc;
pc.options.w = 1.0; pc.options.w = 1.0;
pc.viewport = prism::float4(1.0 / (float)thumbnail_resolution, 1.0 / (float)thumbnail_resolution, thumbnail_resolution, thumbnail_resolution); pc.viewport = prism::float4(
1.0 / (float)thumbnail_resolution,
1.0 / (float)thumbnail_resolution,
thumbnail_resolution,
thumbnail_resolution);
command_buffer->set_push_constant(&pc, sizeof(PostPushConstants)); command_buffer->set_push_constant(&pc, sizeof(PostPushConstants));
@ -958,7 +973,7 @@ GFXTexture* CommonEditor::generate_common_preview(Scene& scene, const prism::flo
renderer->shadow_pass->render(command_buffer, scene); renderer->shadow_pass->render(command_buffer, scene);
if(render_options.enable_ibl) if (render_options.enable_ibl)
renderer->scene_capture->render(command_buffer, &scene); renderer->scene_capture->render(command_buffer, &scene);
GFXRenderPassBeginInfo begin_info = {}; GFXRenderPassBeginInfo begin_info = {};
@ -969,7 +984,8 @@ GFXTexture* CommonEditor::generate_common_preview(Scene& scene, const prism::flo
command_buffer->set_render_pass(begin_info); command_buffer->set_render_pass(begin_info);
prism::renderer::controller_continuity continuity; prism::renderer::controller_continuity continuity;
renderer->render_camera(command_buffer, scene, camera, scene.get<Camera>(camera), begin_info.render_area.extent, *target, continuity); renderer->render_camera(
command_buffer, scene, camera, scene.get<Camera>(camera), begin_info.render_area.extent, *target, continuity);
// render post // render post
begin_info.framebuffer = final_framebuffer; begin_info.framebuffer = final_framebuffer;
@ -994,8 +1010,13 @@ GFXTexture* CommonEditor::generate_common_preview(Scene& scene, const prism::flo
prism::float4 viewport; prism::float4 viewport;
prism::float4 options; prism::float4 options;
} pc; } pc;
pc.options.w = 1.0; pc.options.w = 1.0;
pc.viewport = prism::float4(1.0 / (float)thumbnail_resolution, 1.0 / (float)thumbnail_resolution, thumbnail_resolution, thumbnail_resolution); pc.viewport = prism::float4(
1.0 / (float)thumbnail_resolution,
1.0 / (float)thumbnail_resolution,
thumbnail_resolution,
thumbnail_resolution);
command_buffer->set_push_constant(&pc, sizeof(PostPushConstants)); command_buffer->set_push_constant(&pc, sizeof(PostPushConstants));
@ -1023,8 +1044,7 @@ void CommonEditor::load_options() {
for (auto& file : j["files"]) for (auto& file : j["files"])
lastOpenedFiles.push_back(file.get<std::string>()); lastOpenedFiles.push_back(file.get<std::string>());
} } else {
else {
defaultX = -1; defaultX = -1;
defaultY = -1; defaultY = -1;
defaultWidth = 1280; defaultWidth = 1280;
@ -1049,11 +1069,11 @@ void CommonEditor::save_options() {
void CommonEditor::load_thumbnail_cache() { void CommonEditor::load_thumbnail_cache() {
auto thumbnail_cache = prism::open_file("./thumbnail-cache"); auto thumbnail_cache = prism::open_file("./thumbnail-cache");
if(thumbnail_cache != std::nullopt) { if (thumbnail_cache != std::nullopt) {
int size; int size;
thumbnail_cache->read(&size); thumbnail_cache->read(&size);
for(int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
std::string filename; std::string filename;
thumbnail_cache->read_string(filename); thumbnail_cache->read_string(filename);
@ -1077,10 +1097,11 @@ void CommonEditor::load_thumbnail_cache() {
} }
void CommonEditor::save_thumbnail_cache() { void CommonEditor::save_thumbnail_cache() {
GFXBuffer* thumbnailBuffer = engine->get_gfx()->create_buffer(nullptr, thumbnail_resolution * thumbnail_resolution * 4, false, GFXBufferUsage::Storage); GFXBuffer* thumbnailBuffer = engine->get_gfx()->create_buffer(
nullptr, thumbnail_resolution * thumbnail_resolution * 4, false, GFXBufferUsage::Storage);
FILE* file = fopen("thumbnail-cache", "wb"); FILE* file = fopen("thumbnail-cache", "wb");
if(file == nullptr) { if (file == nullptr) {
prism::log("Failed to write thumbnail cache!"); prism::log("Failed to write thumbnail cache!");
return; return;
} }
@ -1088,7 +1109,7 @@ void CommonEditor::save_thumbnail_cache() {
int size = asset_thumbnails.size(); int size = asset_thumbnails.size();
fwrite(&size, sizeof(int), 1, file); fwrite(&size, sizeof(int), 1, file);
for(auto [p, thumbnail] : asset_thumbnails) { for (auto [p, thumbnail] : asset_thumbnails) {
unsigned int len = strlen(p.c_str()); unsigned int len = strlen(p.c_str());
fwrite(&len, sizeof(unsigned int), 1, file); fwrite(&len, sizeof(unsigned int), 1, file);

View file

@ -1,13 +1,13 @@
#include "debugpass.hpp" #include "debugpass.hpp"
#include "gfx_commandbuffer.hpp" #include "asset.hpp"
#include "engine.hpp" #include "engine.hpp"
#include "scene.hpp"
#include "transform.hpp"
#include "file.hpp" #include "file.hpp"
#include "gfx.hpp" #include "gfx.hpp"
#include "asset.hpp" #include "gfx_commandbuffer.hpp"
#include "renderer.hpp" #include "renderer.hpp"
#include "scene.hpp"
#include "transform.hpp"
struct BillPushConstant { struct BillPushConstant {
Matrix4x4 mvp; Matrix4x4 mvp;
@ -32,13 +32,9 @@ void DebugPass::initialize() {
createInfo.vertex_input.attributes.push_back(positionAttribute); createInfo.vertex_input.attributes.push_back(positionAttribute);
createInfo.shader_input.push_constants = { createInfo.shader_input.push_constants = {{sizeof(Matrix4x4) + sizeof(prism::float4), 0}};
{sizeof(Matrix4x4) + sizeof(prism::float4), 0}
};
createInfo.shader_input.bindings = { createInfo.shader_input.bindings = {{1, GFXBindingType::PushConstant}};
{1, GFXBindingType::PushConstant}
};
createInfo.render_pass = engine->get_renderer()->offscreen_render_pass; createInfo.render_pass = engine->get_renderer()->offscreen_render_pass;
createInfo.rasterization.polygon_type = GFXPolygonType::Line; createInfo.rasterization.polygon_type = GFXPolygonType::Line;
@ -80,13 +76,9 @@ void DebugPass::initialize() {
pipelineInfo.vertex_input.attributes.push_back(attribute); pipelineInfo.vertex_input.attributes.push_back(attribute);
pipelineInfo.shader_input.bindings = { pipelineInfo.shader_input.bindings = {{1, GFXBindingType::PushConstant}};
{1, GFXBindingType::PushConstant}
};
pipelineInfo.shader_input.push_constants = { pipelineInfo.shader_input.push_constants = {{sizeof(Matrix4x4) + sizeof(prism::float4), 0}};
{sizeof(Matrix4x4) + sizeof(prism::float4), 0}
};
pipelineInfo.render_pass = selectRenderPass; pipelineInfo.render_pass = selectRenderPass;
pipelineInfo.depth.depth_mode = GFXDepthMode::Less; pipelineInfo.depth.depth_mode = GFXDepthMode::Less;
@ -121,13 +113,9 @@ void DebugPass::initialize() {
pipelineInfo.vertex_input.attributes.push_back(attribute); pipelineInfo.vertex_input.attributes.push_back(attribute);
pipelineInfo.shader_input.bindings = { pipelineInfo.shader_input.bindings = {{1, GFXBindingType::PushConstant}};
{1, GFXBindingType::PushConstant}
};
pipelineInfo.shader_input.push_constants = { pipelineInfo.shader_input.push_constants = {{sizeof(Matrix4x4) + sizeof(prism::float4), 0}};
{sizeof(Matrix4x4) + sizeof(prism::float4), 0}
};
pipelineInfo.render_pass = sobelRenderPass; pipelineInfo.render_pass = sobelRenderPass;
@ -144,14 +132,9 @@ void DebugPass::initialize() {
pipelineInfo.shaders.fragment_src = ShaderSource(prism::path("billboard.frag")); pipelineInfo.shaders.fragment_src = ShaderSource(prism::path("billboard.frag"));
pipelineInfo.shader_input.bindings = { pipelineInfo.shader_input.bindings = {
{1, GFXBindingType::PushConstant}, {1, GFXBindingType::PushConstant}, {2, GFXBindingType::Texture}, {3, GFXBindingType::StorageBuffer}};
{2, GFXBindingType::Texture},
{3, GFXBindingType::StorageBuffer}
};
pipelineInfo.shader_input.push_constants = { pipelineInfo.shader_input.push_constants = {{sizeof(BillPushConstant), 0}};
{sizeof(BillPushConstant), 0}
};
pipelineInfo.depth.depth_mode = GFXDepthMode::Less; pipelineInfo.depth.depth_mode = GFXDepthMode::Less;
@ -198,7 +181,8 @@ void DebugPass::createOffscreenResources() {
selectFramebuffer = engine->get_gfx()->create_framebuffer(info); selectFramebuffer = engine->get_gfx()->create_framebuffer(info);
selectBuffer = engine->get_gfx()->create_buffer(nullptr, extent.width * extent.height * 4 * sizeof(uint8_t), false, GFXBufferUsage::Storage); selectBuffer = engine->get_gfx()->create_buffer(
nullptr, extent.width * extent.height * 4 * sizeof(uint8_t), false, GFXBufferUsage::Storage);
} }
// sobel // sobel
@ -226,6 +210,7 @@ void DebugPass::draw_arrow(GFXCommandBuffer* commandBuffer, prism::float3 color,
Matrix4x4 mvp; Matrix4x4 mvp;
prism::float4 color; prism::float4 color;
} pc; } pc;
pc.mvp = model; pc.mvp = model;
pc.color = color; pc.color = color;
@ -247,7 +232,7 @@ void DebugPass::render_scene(Scene& scene, GFXCommandBuffer* commandBuffer) {
Matrix4x4 vp = camera.perspective * camera.view; Matrix4x4 vp = camera.perspective * camera.view;
commandBuffer->set_graphics_pipeline(primitive_pipeline); commandBuffer->set_graphics_pipeline(primitive_pipeline);
struct DebugPrimitive { struct DebugPrimitive {
prism::float3 position, size; prism::float3 position, size;
@ -265,13 +250,13 @@ void DebugPass::render_scene(Scene& scene, GFXCommandBuffer* commandBuffer) {
std::vector<DebugBillboard> billboards; std::vector<DebugBillboard> billboards;
for(auto& obj : scene.get_objects()) { for (auto& obj : scene.get_objects()) {
if(scene.get(obj).editor_object) if (scene.get(obj).editor_object)
continue; continue;
auto& transform = scene.get<Transform>(obj); auto& transform = scene.get<Transform>(obj);
if(scene.has<Collision>(obj)) { if (scene.has<Collision>(obj)) {
auto& collision = scene.get<Collision>(obj); auto& collision = scene.get<Collision>(obj);
{ {
@ -285,12 +270,12 @@ void DebugPass::render_scene(Scene& scene, GFXCommandBuffer* commandBuffer) {
} }
} }
if(scene.has<Light>(obj)) { if (scene.has<Light>(obj)) {
DebugBillboard bill; DebugBillboard bill;
bill.position = transform.get_world_position(); bill.position = transform.get_world_position();
bill.color = prism::float4(scene.get<Light>(obj).color, 1.0f); bill.color = prism::float4(scene.get<Light>(obj).color, 1.0f);
switch(scene.get<Light>(obj).type) { switch (scene.get<Light>(obj).type) {
case Light::Type::Point: case Light::Type::Point:
bill.texture = pointTexture->handle; bill.texture = pointTexture->handle;
break; break;
@ -305,8 +290,8 @@ void DebugPass::render_scene(Scene& scene, GFXCommandBuffer* commandBuffer) {
billboards.push_back(bill); billboards.push_back(bill);
} }
if(scene.has<EnvironmentProbe>(obj)) { if (scene.has<EnvironmentProbe>(obj)) {
if(selected_object == obj) { if (selected_object == obj) {
auto& probe = scene.get<EnvironmentProbe>(obj); auto& probe = scene.get<EnvironmentProbe>(obj);
DebugPrimitive prim; DebugPrimitive prim;
@ -328,7 +313,7 @@ void DebugPass::render_scene(Scene& scene, GFXCommandBuffer* commandBuffer) {
} }
// draw primitives // draw primitives
for(auto& prim : primitives) { for (auto& prim : primitives) {
PushConstant pc; PushConstant pc;
Matrix4x4 m = prism::translate(Matrix4x4(), prim.position); Matrix4x4 m = prism::translate(Matrix4x4(), prim.position);
@ -351,7 +336,7 @@ void DebugPass::render_scene(Scene& scene, GFXCommandBuffer* commandBuffer) {
engine->get_gfx()->copy_buffer(scene_info_buffer, &camera.view, 0, sizeof(Matrix4x4)); engine->get_gfx()->copy_buffer(scene_info_buffer, &camera.view, 0, sizeof(Matrix4x4));
// draw primitives // draw primitives
for(auto& bill : billboards) { for (auto& bill : billboards) {
Matrix4x4 m = prism::translate(Matrix4x4(), bill.position); Matrix4x4 m = prism::translate(Matrix4x4(), bill.position);
BillPushConstant pc; BillPushConstant pc;
@ -368,7 +353,7 @@ void DebugPass::render_scene(Scene& scene, GFXCommandBuffer* commandBuffer) {
commandBuffer->set_graphics_pipeline(arrow_pipeline); commandBuffer->set_graphics_pipeline(arrow_pipeline);
// draw handles for selected object; // draw handles for selected object;
if(selected_object != prism::NullObject && engine->get_scene()->has<Transform>(selected_object)) { if (selected_object != prism::NullObject && engine->get_scene()->has<Transform>(selected_object)) {
const auto position = engine->get_scene()->get<Transform>(selected_object).get_world_position(); const auto position = engine->get_scene()->get<Transform>(selected_object).get_world_position();
const float base_scale = 0.05f; const float base_scale = 0.05f;
@ -381,10 +366,16 @@ void DebugPass::render_scene(Scene& scene, GFXCommandBuffer* commandBuffer) {
draw_arrow(commandBuffer, prism::float3(0, 1, 0), vp * base_model); draw_arrow(commandBuffer, prism::float3(0, 1, 0), vp * base_model);
// draw x axis // draw x axis
draw_arrow(commandBuffer, prism::float3(1, 0, 0), vp * base_model * matrix_from_quat(angle_axis(radians(-90.0f), prism::float3(0, 0, 1)))); draw_arrow(
commandBuffer,
prism::float3(1, 0, 0),
vp * base_model * matrix_from_quat(angle_axis(radians(-90.0f), prism::float3(0, 0, 1))));
// draw z axis // draw z axis
draw_arrow(commandBuffer, prism::float3(0, 0, 1), vp * base_model * matrix_from_quat(angle_axis(radians(90.0f), prism::float3(1, 0, 0)))); draw_arrow(
commandBuffer,
prism::float3(0, 0, 1),
vp * base_model * matrix_from_quat(angle_axis(radians(90.0f), prism::float3(1, 0, 0))));
} }
// draw sobel // draw sobel
@ -395,12 +386,12 @@ void DebugPass::render_scene(Scene& scene, GFXCommandBuffer* commandBuffer) {
commandBuffer->set_render_pass(info); commandBuffer->set_render_pass(info);
if(selected_object != prism::NullObject && engine->get_scene()->has<Renderable>(selected_object)) { if (selected_object != prism::NullObject && engine->get_scene()->has<Renderable>(selected_object)) {
commandBuffer->set_graphics_pipeline(sobelPipeline); commandBuffer->set_graphics_pipeline(sobelPipeline);
auto renderable = engine->get_scene()->get<Renderable>(selected_object); auto renderable = engine->get_scene()->get<Renderable>(selected_object);
if(!renderable.mesh) if (!renderable.mesh)
return; return;
struct PC { struct PC {
@ -416,7 +407,7 @@ void DebugPass::render_scene(Scene& scene, GFXCommandBuffer* commandBuffer) {
commandBuffer->set_vertex_buffer(renderable.mesh->position_buffer, 0, 0); commandBuffer->set_vertex_buffer(renderable.mesh->position_buffer, 0, 0);
commandBuffer->set_index_buffer(renderable.mesh->index_buffer, IndexType::UINT32); commandBuffer->set_index_buffer(renderable.mesh->index_buffer, IndexType::UINT32);
if(renderable.mesh) { if (renderable.mesh) {
for (auto& part : renderable.mesh->parts) for (auto& part : renderable.mesh->parts)
commandBuffer->draw_indexed(part.index_count, part.index_offset, part.vertex_offset, 0); commandBuffer->draw_indexed(part.index_count, part.index_offset, part.vertex_offset, 0);
} }
@ -424,7 +415,7 @@ void DebugPass::render_scene(Scene& scene, GFXCommandBuffer* commandBuffer) {
} }
void DebugPass::get_selected_object(int x, int y, const std::function<void(SelectableObject)>& callback) { void DebugPass::get_selected_object(int x, int y, const std::function<void(SelectableObject)>& callback) {
if(engine->get_scene() == nullptr) if (engine->get_scene() == nullptr)
return; return;
auto cameras = engine->get_scene()->get_all<Camera>(); auto cameras = engine->get_scene()->get_all<Camera>();
@ -434,7 +425,7 @@ void DebugPass::get_selected_object(int x, int y, const std::function<void(Selec
// calculate selectable objects // calculate selectable objects
selectable_objects.clear(); selectable_objects.clear();
for(auto& [obj, mesh] : engine->get_scene()->get_all<Renderable>()) { for (auto& [obj, mesh] : engine->get_scene()->get_all<Renderable>()) {
SelectableObject so; SelectableObject so;
so.type = SelectableObject::Type::Object; so.type = SelectableObject::Type::Object;
so.object = obj; so.object = obj;
@ -443,7 +434,7 @@ void DebugPass::get_selected_object(int x, int y, const std::function<void(Selec
selectable_objects.push_back(so); selectable_objects.push_back(so);
} }
for(auto& [obj, mesh] : engine->get_scene()->get_all<Light>()) { for (auto& [obj, mesh] : engine->get_scene()->get_all<Light>()) {
SelectableObject so; SelectableObject so;
so.type = SelectableObject::Type::Object; so.type = SelectableObject::Type::Object;
so.object = obj; so.object = obj;
@ -453,7 +444,7 @@ void DebugPass::get_selected_object(int x, int y, const std::function<void(Selec
selectable_objects.push_back(so); selectable_objects.push_back(so);
} }
for(auto& [obj, mesh] : engine->get_scene()->get_all<EnvironmentProbe>()) { for (auto& [obj, mesh] : engine->get_scene()->get_all<EnvironmentProbe>()) {
SelectableObject so; SelectableObject so;
so.type = SelectableObject::Type::Object; so.type = SelectableObject::Type::Object;
so.object = obj; so.object = obj;
@ -474,7 +465,7 @@ void DebugPass::get_selected_object(int x, int y, const std::function<void(Selec
selectable_objects.push_back(so); selectable_objects.push_back(so);
}; };
if(selected_object != prism::NullObject) { if (selected_object != prism::NullObject) {
const auto position = engine->get_scene()->get<Transform>(selected_object).get_world_position(); const auto position = engine->get_scene()->get<Transform>(selected_object).get_world_position();
const float base_scale = 0.05f; const float base_scale = 0.05f;
@ -485,9 +476,13 @@ void DebugPass::get_selected_object(int x, int y, const std::function<void(Selec
add_arrow(SelectableObject::Axis::Y, translate_model * scale_model); add_arrow(SelectableObject::Axis::Y, translate_model * scale_model);
add_arrow(SelectableObject::Axis::X, translate_model * matrix_from_quat(angle_axis(radians(-90.0f), prism::float3(0, 0, 1))) * scale_model); add_arrow(
SelectableObject::Axis::X,
translate_model * matrix_from_quat(angle_axis(radians(-90.0f), prism::float3(0, 0, 1))) * scale_model);
add_arrow(SelectableObject::Axis::Z, translate_model * matrix_from_quat(angle_axis(radians(90.0f), prism::float3(1, 0, 0))) * scale_model); add_arrow(
SelectableObject::Axis::Z,
translate_model * matrix_from_quat(angle_axis(radians(90.0f), prism::float3(1, 0, 0))) * scale_model);
} }
GFXCommandBuffer* commandBuffer = engine->get_gfx()->acquire_command_buffer(false); GFXCommandBuffer* commandBuffer = engine->get_gfx()->acquire_command_buffer(false);
@ -508,14 +503,14 @@ void DebugPass::get_selected_object(int x, int y, const std::function<void(Selec
commandBuffer->set_graphics_pipeline(selectPipeline); commandBuffer->set_graphics_pipeline(selectPipeline);
for(auto [i, object] : utility::enumerate(selectable_objects)) { for (auto [i, object] : utility::enumerate(selectable_objects)) {
AssetPtr<Mesh> mesh; AssetPtr<Mesh> mesh;
Matrix4x4 model; Matrix4x4 model;
if(object.type == SelectableObject::Type::Object) { if (object.type == SelectableObject::Type::Object) {
if(object.render_type == SelectableObject::RenderType::Mesh) { if (object.render_type == SelectableObject::RenderType::Mesh) {
auto& renderable = engine->get_scene()->get<Renderable>(object.object); auto& renderable = engine->get_scene()->get<Renderable>(object.object);
if(!renderable.mesh) if (!renderable.mesh)
continue; continue;
mesh = renderable.mesh; mesh = renderable.mesh;
@ -539,7 +534,7 @@ void DebugPass::get_selected_object(int x, int y, const std::function<void(Selec
pc.mvp = camera.perspective * camera.view * model; pc.mvp = camera.perspective * camera.view * model;
if(object.render_type == SelectableObject::RenderType::Sphere) if (object.render_type == SelectableObject::RenderType::Sphere)
pc.mvp = prism::scale(pc.mvp, prism::float3(object.sphere_size)); pc.mvp = prism::scale(pc.mvp, prism::float3(object.sphere_size));
pc.color = { pc.color = {
@ -565,13 +560,12 @@ void DebugPass::get_selected_object(int x, int y, const std::function<void(Selec
uint8_t a = mapped_texture[buffer_position + 3]; uint8_t a = mapped_texture[buffer_position + 3];
const int id = mapped_texture[buffer_position] + const int id = mapped_texture[buffer_position] + mapped_texture[buffer_position + 1] * 256 +
mapped_texture[buffer_position + 1] * 256 + mapped_texture[buffer_position + 2] * 256 * 256;
mapped_texture[buffer_position + 2] * 256 * 256;
engine->get_gfx()->release_buffer_contents(selectBuffer, mapped_texture); engine->get_gfx()->release_buffer_contents(selectBuffer, mapped_texture);
if(a != 0) { if (a != 0) {
callback(selectable_objects[id]); callback(selectable_objects[id]);
} else { } else {
SelectableObject o; SelectableObject o;

View file

@ -1,34 +1,34 @@
#include "undostack.hpp" #include "undostack.hpp"
void UndoStack::undo() { void UndoStack::undo() {
if(stack_position >= 0) { if (stack_position >= 0) {
command_stack[stack_position]->undo(); command_stack[stack_position]->undo();
stack_position--; stack_position--;
} }
} }
void UndoStack::redo() { void UndoStack::redo() {
if((stack_position + 1) < command_stack.size()) { if ((stack_position + 1) < command_stack.size()) {
stack_position++; stack_position++;
command_stack[stack_position]->execute(); command_stack[stack_position]->execute();
} }
} }
Command* UndoStack::get_last_command() { Command* UndoStack::get_last_command() {
if(command_stack.empty()) if (command_stack.empty())
return nullptr; return nullptr;
if(stack_position >= 0) if (stack_position >= 0)
return command_stack[stack_position].get(); return command_stack[stack_position].get();
return nullptr; return nullptr;
} }
Command* UndoStack::get_next_command() { Command* UndoStack::get_next_command() {
if(command_stack.empty()) if (command_stack.empty())
return nullptr; return nullptr;
if((stack_position + 1) < command_stack.size()) if ((stack_position + 1) < command_stack.size())
return command_stack[stack_position + 1].get(); return command_stack[stack_position + 1].get();
return nullptr; return nullptr;

View file

@ -1,14 +1,14 @@
add_platform_executable( add_platform_executable(
TARGET CutsceneEditor TARGET CutsceneEditor
APP_CLASS CutsceneEditor APP_CLASS CutsceneEditor
APP_INCLUDE cutsceneeditor.hpp APP_INCLUDE cutsceneeditor.hpp
SKIP_DATA ON SKIP_DATA ON
SRC SRC
src/cutsceneeditor.cpp src/cutsceneeditor.cpp
include/cutsceneeditor.hpp) include/cutsceneeditor.hpp)
target_link_libraries(CutsceneEditor PUBLIC target_link_libraries(CutsceneEditor PUBLIC
Core Core
EditorCommon) EditorCommon)
target_include_directories(CutsceneEditor PUBLIC target_include_directories(CutsceneEditor PUBLIC
include) include)
set_engine_properties(CutsceneEditor) set_engine_properties(CutsceneEditor)

View file

@ -3,11 +3,11 @@
#include <imgui.h> #include <imgui.h>
#include <imgui_stdlib.h> #include <imgui_stdlib.h>
#include "cutscene.hpp"
#include "engine.hpp" #include "engine.hpp"
#include "file.hpp" #include "file.hpp"
#include "json_conversions.hpp" #include "json_conversions.hpp"
#include "platform.hpp" #include "platform.hpp"
#include "cutscene.hpp"
Shot* currentShot = nullptr; Shot* currentShot = nullptr;
AnimationChannel* currentChannel = nullptr; AnimationChannel* currentChannel = nullptr;
@ -16,13 +16,15 @@ PositionKeyFrame* currentFrame = nullptr;
std::string currentPath; std::string currentPath;
void app_main(prism::engine* engine) { void app_main(prism::engine* engine) {
auto editor = (CommonEditor*)engine->get_app(); auto editor = (CommonEditor*)engine->get_app();
platform::open_window("Cutscene Editor", platform::open_window(
{editor->getDefaultX(), "Cutscene Editor",
editor->getDefaultY(), {editor->getDefaultX(),
static_cast<uint32_t>(editor->getDefaultWidth()), editor->getDefaultY(),
static_cast<uint32_t>(editor->getDefaultHeight())}, WindowFlags::Resizable); static_cast<uint32_t>(editor->getDefaultWidth()),
static_cast<uint32_t>(editor->getDefaultHeight())},
WindowFlags::Resizable);
} }
CutsceneEditor::CutsceneEditor() : CommonEditor("CutsceneEditor") {} CutsceneEditor::CutsceneEditor() : CommonEditor("CutsceneEditor") {}
@ -30,7 +32,7 @@ CutsceneEditor::CutsceneEditor() : CommonEditor("CutsceneEditor") {}
static bool has_been_docked = false; static bool has_been_docked = false;
void CutsceneEditor::renderEditor(GFXCommandBuffer* command_buffer) { void CutsceneEditor::renderEditor(GFXCommandBuffer* command_buffer) {
for(auto [id, render_target] : viewport_render_targets) { for (auto [id, render_target] : viewport_render_targets) {
engine->get_renderer()->render(command_buffer, render_target.scene, *render_target.target, nullptr); engine->get_renderer()->render(command_buffer, render_target.scene, *render_target.target, nullptr);
} }
} }
@ -42,7 +44,7 @@ void CutsceneEditor::drawUI() {
ImGui::End(); ImGui::End();
if(!has_been_docked) { if (!has_been_docked) {
const auto size = ImGui::GetMainViewport()->Size; const auto size = ImGui::GetMainViewport()->Size;
ImGui::DockBuilderRemoveNode(editor_dockspace); ImGui::DockBuilderRemoveNode(editor_dockspace);
@ -73,102 +75,103 @@ void CutsceneEditor::drawUI() {
ImGui::DockBuilderFinish(editor_dockspace); ImGui::DockBuilderFinish(editor_dockspace);
has_been_docked =true; has_been_docked = true;
} }
if (ImGui::BeginMainMenuBar()) if (ImGui::BeginMainMenuBar()) {
{ if (ImGui::BeginMenu("File")) {
if (ImGui::BeginMenu("File")) if (ImGui::MenuItem("New", "CTRL+N")) {
{
if(ImGui::MenuItem("New", "CTRL+N")) {
engine->cutscene = std::make_unique<Cutscene>(); engine->cutscene = std::make_unique<Cutscene>();
platform::set_window_title(engine->get_main_window(), "Cutscene Editor"); platform::set_window_title(engine->get_main_window(), "Cutscene Editor");
} }
if(ImGui::MenuItem("Open", "CTRL+O")) { if (ImGui::MenuItem("Open", "CTRL+O")) {
engine->get_imgui().open_dialog(true, [this](std::string path){ engine->get_imgui().open_dialog(true, [this](std::string path) {
currentPath = path; currentPath = path;
engine->load_cutscene(path); engine->load_cutscene(path);
platform::set_window_title(engine->get_main_window(), ("Cutscene Editor - " + path).c_str()); platform::set_window_title(engine->get_main_window(), ("Cutscene Editor - " + path).c_str());
addOpenedFile(path); addOpenedFile(path);
}); });
} }
const auto& recents = getOpenedFiles(); const auto& recents = getOpenedFiles();
if (ImGui::BeginMenu("Open Recent...", !recents.empty())) { if (ImGui::BeginMenu("Open Recent...", !recents.empty())) {
for (auto& file : recents) { for (auto& file : recents) {
if (ImGui::MenuItem(file.c_str())) { if (ImGui::MenuItem(file.c_str())) {
currentPath = file; currentPath = file;
engine->load_cutscene(file); engine->load_cutscene(file);
platform::set_window_title(0, ("Cutscene Editor - " + file).c_str()); platform::set_window_title(0, ("Cutscene Editor - " + file).c_str());
} }
} }
ImGui::Separator(); ImGui::Separator();
if (ImGui::MenuItem("Clear")) { if (ImGui::MenuItem("Clear")) {
clearOpenedFiles(); clearOpenedFiles();
} }
ImGui::EndMenu(); ImGui::EndMenu();
} }
if(ImGui::MenuItem("Save", "CTRL+S")) { if (ImGui::MenuItem("Save", "CTRL+S")) {
if (currentPath.empty()) { if (currentPath.empty()) {
engine->get_imgui().save_dialog([](std::string path) { engine->get_imgui().save_dialog([](std::string path) {
currentPath = path; currentPath = path;
engine->save_cutscene(path); engine->save_cutscene(path);
platform::set_window_title(0, ("Cutscene Editor - " + path).c_str()); platform::set_window_title(0, ("Cutscene Editor - " + path).c_str());
}); });
} } else {
else {
engine->save_cutscene(currentPath); engine->save_cutscene(currentPath);
} }
} }
if (ImGui::MenuItem("Save as...", "CTRL+S")) { if (ImGui::MenuItem("Save as...", "CTRL+S")) {
engine->get_imgui().save_dialog([](std::string path) { engine->get_imgui().save_dialog([](std::string path) {
currentPath = path; currentPath = path;
engine->save_cutscene(path); engine->save_cutscene(path);
platform::set_window_title(0, ("Cutscene Editor - " + path).c_str()); platform::set_window_title(0, ("Cutscene Editor - " + path).c_str());
}); });
} }
ImGui::Separator(); ImGui::Separator();
if(ImGui::MenuItem("Quit", "CTRL+Q")) if (ImGui::MenuItem("Quit", "CTRL+Q"))
engine->quit(); engine->quit();
ImGui::EndMenu(); ImGui::EndMenu();
} }
if (ImGui::BeginMenu("Edit")) if (ImGui::BeginMenu("Edit")) {
{ if (ImGui::MenuItem("Undo", "CTRL+Z")) {
if (ImGui::MenuItem("Undo", "CTRL+Z")) {} }
if (ImGui::MenuItem("Redo", "CTRL+Y", false, false)) {} // Disabled item if (ImGui::MenuItem("Redo", "CTRL+Y", false, false)) {
} // Disabled item
ImGui::Separator(); ImGui::Separator();
if (ImGui::MenuItem("Cut", "CTRL+X")) {} if (ImGui::MenuItem("Cut", "CTRL+X")) {
if (ImGui::MenuItem("Copy", "CTRL+C")) {} }
if (ImGui::MenuItem("Paste", "CTRL+V")) {} if (ImGui::MenuItem("Copy", "CTRL+C")) {
}
if (ImGui::MenuItem("Paste", "CTRL+V")) {
}
ImGui::EndMenu(); ImGui::EndMenu();
} }
if(ImGui::BeginMenu("Add...")) { if (ImGui::BeginMenu("Add...")) {
if (ImGui::MenuItem("Empty")) { if (ImGui::MenuItem("Empty")) {
auto new_obj = engine->get_scene()->add_object(); auto new_obj = engine->get_scene()->add_object();
engine->get_scene()->get(new_obj).name = "new object"; engine->get_scene()->get(new_obj).name = "new object";
} }
if(ImGui::MenuItem("Prefab")) { if (ImGui::MenuItem("Prefab")) {
engine->get_imgui().open_dialog(false, [](std::string path) { engine->get_imgui().open_dialog(false, [](std::string path) {
engine->add_prefab(*engine->get_scene(), path); engine->add_prefab(*engine->get_scene(), path);
}); });
@ -177,40 +180,39 @@ void CutsceneEditor::drawUI() {
ImGui::EndMenu(); ImGui::EndMenu();
} }
if (ImGui::BeginMenu("Help")) { if (ImGui::BeginMenu("Help")) {
if (ImGui::MenuItem("About")) { if (ImGui::MenuItem("About")) {
}
} ImGui::EndMenu();
}
ImGui::EndMenu();
}
ImGui::EndMainMenuBar(); ImGui::EndMainMenuBar();
} }
if(ImGui::Begin("Outliner")) { if (ImGui::Begin("Outliner")) {
drawOutline(); drawOutline();
} }
ImGui::End(); ImGui::End();
if(ImGui::Begin("Properties")) { if (ImGui::Begin("Properties")) {
drawPropertyEditor(); drawPropertyEditor();
} }
ImGui::End(); ImGui::End();
if(ImGui::Begin("Timeline")) { if (ImGui::Begin("Timeline")) {
if(engine->cutscene != nullptr) { if (engine->cutscene != nullptr) {
if(ImGui::Button("Add Shot")) { if (ImGui::Button("Add Shot")) {
engine->cutscene->shots.emplace_back(); engine->cutscene->shots.emplace_back();
currentShot = &engine->cutscene->shots.back(); currentShot = &engine->cutscene->shots.back();
} }
if(currentShot != nullptr) { if (currentShot != nullptr) {
ImGui::SameLine(); ImGui::SameLine();
if(ImGui::Button("Change scene")) { if (ImGui::Button("Change scene")) {
open_asset<Scene>(AssetType::Scene, [](prism::path path) { open_asset<Scene>(AssetType::Scene, [](prism::path path) {
currentShot->scene = engine->load_scene(prism::game_domain / path); currentShot->scene = engine->load_scene(prism::game_domain / path);
}); });
@ -230,7 +232,7 @@ void CutsceneEditor::drawUI() {
ImGui::SameLine(); ImGui::SameLine();
if(ImGui::Button("Remove")) { if (ImGui::Button("Remove")) {
utility::erase(engine->cutscene->shots, *currentShot); utility::erase(engine->cutscene->shots, *currentShot);
currentShot = nullptr; currentShot = nullptr;
} }
@ -242,11 +244,11 @@ void CutsceneEditor::drawUI() {
const ImVec2 p = ImGui::GetCursorScreenPos(); const ImVec2 p = ImGui::GetCursorScreenPos();
int i = 0; int i = 0;
for(auto& shot : engine->cutscene->shots) { for (auto& shot : engine->cutscene->shots) {
auto a = ImVec2(p.x + (5 * shot.begin), p.y); auto a = ImVec2(p.x + (5 * shot.begin), p.y);
auto b = ImVec2(p.x + (5 * (shot.begin + shot.length)), p.y + 50); auto b = ImVec2(p.x + (5 * (shot.begin + shot.length)), p.y + 50);
if(&shot == currentShot) { if (&shot == currentShot) {
draw_list->AddRectFilled(a, b, IM_COL32(0, 0, 100, 100)); draw_list->AddRectFilled(a, b, IM_COL32(0, 0, 100, 100));
} }
@ -255,10 +257,10 @@ void CutsceneEditor::drawUI() {
std::string name = "Shot " + std::to_string(i); std::string name = "Shot " + std::to_string(i);
draw_list->AddText(ImVec2(a.x + 2, a.y + 2), IM_COL32_WHITE, name.c_str()); draw_list->AddText(ImVec2(a.x + 2, a.y + 2), IM_COL32_WHITE, name.c_str());
if(ImGui::IsMouseClicked(0)) { if (ImGui::IsMouseClicked(0)) {
auto c = ImGui::GetMousePos(); auto c = ImGui::GetMousePos();
if(c.x > a.x && c.x < b.x && c.y > a.y && c.y < b.y) { if (c.x > a.x && c.x < b.x && c.y > a.y && c.y < b.y) {
if(currentShot == &shot) { if (currentShot == &shot) {
currentShot = nullptr; currentShot = nullptr;
} else { } else {
currentShot = &shot; currentShot = &shot;
@ -269,7 +271,10 @@ void CutsceneEditor::drawUI() {
i++; i++;
} }
draw_list->AddLine(ImVec2(p.x + (engine->current_cutscene_time * 5), p.y), ImVec2(p.x + (engine->current_cutscene_time * 5), p.y + 75), IM_COL32_WHITE); draw_list->AddLine(
ImVec2(p.x + (engine->current_cutscene_time * 5), p.y),
ImVec2(p.x + (engine->current_cutscene_time * 5), p.y + 75),
IM_COL32_WHITE);
} else { } else {
ImGui::Text("No cutscene loaded."); ImGui::Text("No cutscene loaded.");
} }
@ -277,25 +282,25 @@ void CutsceneEditor::drawUI() {
ImGui::End(); ImGui::End();
if(ImGui::Begin("Animation Editor")) { if (ImGui::Begin("Animation Editor")) {
if(currentShot != nullptr && currentShot->scene != nullptr) { if (currentShot != nullptr && currentShot->scene != nullptr) {
ImGui::BeginChild("animations", ImVec2(150, -1), true); ImGui::BeginChild("animations", ImVec2(150, -1), true);
if(ImGui::Button("Add Channel")) { if (ImGui::Button("Add Channel")) {
currentShot->channels.emplace_back(); currentShot->channels.emplace_back();
currentChannel = &currentShot->channels.back(); currentChannel = &currentShot->channels.back();
} }
int i = 0; int i = 0;
for(auto& channel : currentShot->channels) { for (auto& channel : currentShot->channels) {
std::string name = "Channel " + std::to_string(i); std::string name = "Channel " + std::to_string(i);
if(ImGui::Selectable(name.c_str(), &channel == currentChannel)) if (ImGui::Selectable(name.c_str(), &channel == currentChannel))
currentChannel = &channel; currentChannel = &channel;
i++; i++;
} }
if(currentShot->channels.empty()) if (currentShot->channels.empty())
ImGui::TextDisabled("No channels in this shot."); ImGui::TextDisabled("No channels in this shot.");
ImGui::EndChildFrame(); ImGui::EndChildFrame();
@ -304,8 +309,8 @@ void CutsceneEditor::drawUI() {
ImGui::BeginChild("editanim", ImVec2(-1, -1), false); ImGui::BeginChild("editanim", ImVec2(-1, -1), false);
if(currentChannel != nullptr) { if (currentChannel != nullptr) {
if(ImGui::Button("Add Position Frame")) { if (ImGui::Button("Add Position Frame")) {
currentChannel->positions.emplace_back(); currentChannel->positions.emplace_back();
currentFrame = &currentChannel->positions.back(); currentFrame = &currentChannel->positions.back();
} }
@ -315,21 +320,23 @@ void CutsceneEditor::drawUI() {
ImGui::SetNextItemWidth(50.0f); ImGui::SetNextItemWidth(50.0f);
const char* preview_value = "None"; const char* preview_value = "None";
if(currentChannel->target != prism::NullObject && currentShot->scene->has<Data>(currentChannel->target)) if (currentChannel->target != prism::NullObject &&
currentShot->scene->has<Data>(currentChannel->target))
preview_value = currentShot->scene->get(currentChannel->target).name.c_str(); preview_value = currentShot->scene->get(currentChannel->target).name.c_str();
if(ImGui::BeginCombo("Target", preview_value)) { if (ImGui::BeginCombo("Target", preview_value)) {
for(auto& object : currentShot->scene->get_objects()) { for (auto& object : currentShot->scene->get_objects()) {
if(ImGui::Selectable(currentShot->scene->get(object).name.c_str())) { if (ImGui::Selectable(currentShot->scene->get(object).name.c_str())) {
currentChannel->target = object; currentChannel->target = object;
currentChannel->bone = nullptr; currentChannel->bone = nullptr;
} }
if(currentShot->scene->has<Renderable>(object) && !currentShot->scene->get<Renderable>(object).mesh->bones.empty()) { if (currentShot->scene->has<Renderable>(object) &&
!currentShot->scene->get<Renderable>(object).mesh->bones.empty()) {
ImGui::Indent(); ImGui::Indent();
for(auto& bone : currentShot->scene->get<Renderable>(object).mesh->bones) { for (auto& bone : currentShot->scene->get<Renderable>(object).mesh->bones) {
if(ImGui::Selectable(bone.name.c_str())) { if (ImGui::Selectable(bone.name.c_str())) {
currentChannel->bone = &bone; currentChannel->bone = &bone;
currentChannel->target = prism::NullObject; currentChannel->target = prism::NullObject;
} }
@ -344,12 +351,12 @@ void CutsceneEditor::drawUI() {
ImGui::SameLine(); ImGui::SameLine();
if(ImGui::Button("Remove Channel")) { if (ImGui::Button("Remove Channel")) {
utility::erase(currentShot->channels, *currentChannel); utility::erase(currentShot->channels, *currentChannel);
currentChannel = nullptr; currentChannel = nullptr;
} }
if(currentFrame != nullptr) { if (currentFrame != nullptr) {
ImGui::SameLine(); ImGui::SameLine();
ImGui::SetNextItemWidth(10.0f); ImGui::SetNextItemWidth(10.0f);
@ -364,37 +371,37 @@ void CutsceneEditor::drawUI() {
ImGui::SameLine(); ImGui::SameLine();
if(ImGui::Button("Remove Keyframe")) { if (ImGui::Button("Remove Keyframe")) {
utility::erase(currentChannel->positions, *currentFrame); utility::erase(currentChannel->positions, *currentFrame);
currentFrame = nullptr; currentFrame = nullptr;
} }
} }
if(currentChannel != nullptr) { if (currentChannel != nullptr) {
const auto& draw_list = ImGui::GetWindowDrawList(); const auto& draw_list = ImGui::GetWindowDrawList();
const ImVec2 p = ImGui::GetCursorScreenPos(); const ImVec2 p = ImGui::GetCursorScreenPos();
for(auto& keyframe : currentChannel->positions) { for (auto& keyframe : currentChannel->positions) {
ImVec2 c = ImVec2(p.x + (keyframe.time * 5), p.y); ImVec2 c = ImVec2(p.x + (keyframe.time * 5), p.y);
if(&keyframe == currentFrame) if (&keyframe == currentFrame)
draw_list->AddCircleFilled(c, 5.0f, IM_COL32(0, 0, 100, 255)); draw_list->AddCircleFilled(c, 5.0f, IM_COL32(0, 0, 100, 255));
draw_list->AddCircle(c, 5.0f, IM_COL32_WHITE); draw_list->AddCircle(c, 5.0f, IM_COL32_WHITE);
if(ImGui::IsMouseClicked(0)) { if (ImGui::IsMouseClicked(0)) {
ImVec2 a = ImVec2(p.x + (keyframe.time * 5) - 5, p.y - 5); ImVec2 a = ImVec2(p.x + (keyframe.time * 5) - 5, p.y - 5);
ImVec2 b = ImVec2(p.x + (keyframe.time * 5) + 5, p.y + 5); ImVec2 b = ImVec2(p.x + (keyframe.time * 5) + 5, p.y + 5);
auto mouse_pos = ImGui::GetMousePos(); auto mouse_pos = ImGui::GetMousePos();
if(mouse_pos.x > a.x && mouse_pos.x < b.x && mouse_pos.y > a.y && mouse_pos.y < b.y) { if (mouse_pos.x > a.x && mouse_pos.x < b.x && mouse_pos.y > a.y && mouse_pos.y < b.y) {
if(currentFrame == &keyframe) { if (currentFrame == &keyframe) {
currentFrame = nullptr; currentFrame = nullptr;
} else { } else {
currentFrame = &keyframe; currentFrame = &keyframe;
} }
} }
} }
} }
ImVec2 shot_start = ImVec2(p.x + (currentShot->begin * 5), p.y + 10.0f); ImVec2 shot_start = ImVec2(p.x + (currentShot->begin * 5), p.y + 10.0f);
@ -403,7 +410,10 @@ void CutsceneEditor::drawUI() {
draw_list->AddCircleFilled(shot_start, 2.5f, IM_COL32(255, 0, 0, 255)); draw_list->AddCircleFilled(shot_start, 2.5f, IM_COL32(255, 0, 0, 255));
draw_list->AddCircleFilled(shot_end, 2.5f, IM_COL32(255, 0, 0, 255)); draw_list->AddCircleFilled(shot_end, 2.5f, IM_COL32(255, 0, 0, 255));
draw_list->AddLine(ImVec2(p.x + ((engine->current_cutscene_time - currentShot->begin) * 5), p.y), ImVec2(p.x + ((engine->current_cutscene_time - currentShot->begin) * 5), p.y + 75), IM_COL32_WHITE); draw_list->AddLine(
ImVec2(p.x + ((engine->current_cutscene_time - currentShot->begin) * 5), p.y),
ImVec2(p.x + ((engine->current_cutscene_time - currentShot->begin) * 5), p.y + 75),
IM_COL32_WHITE);
} }
} else { } else {
ImGui::TextDisabled("No animation selected."); ImGui::TextDisabled("No animation selected.");
@ -417,8 +427,8 @@ void CutsceneEditor::drawUI() {
ImGui::End(); ImGui::End();
if(ImGui::Begin("Playback Settings")) { if (ImGui::Begin("Playback Settings")) {
if(ImGui::Button(engine->play_cutscene ? "Stop" : "Play")) { if (ImGui::Button(engine->play_cutscene ? "Stop" : "Play")) {
engine->play_cutscene = !engine->play_cutscene; engine->play_cutscene = !engine->play_cutscene;
} }
@ -427,16 +437,16 @@ void CutsceneEditor::drawUI() {
ImGui::End(); ImGui::End();
if(ImGui::Begin("Viewport")) { if (ImGui::Begin("Viewport")) {
if(currentShot != nullptr && currentShot->scene != nullptr) if (currentShot != nullptr && currentShot->scene != nullptr)
drawViewport(currentShot->scene); drawViewport(currentShot->scene);
} }
ImGui::End(); ImGui::End();
if(ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_LeftArrow))) if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_LeftArrow)))
engine->current_cutscene_time -= 1.0f; engine->current_cutscene_time -= 1.0f;
if(ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_RightArrow))) if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_RightArrow)))
engine->current_cutscene_time += 1.0f; engine->current_cutscene_time += 1.0f;
} }

View file

@ -1,23 +1,23 @@
set(SRC set(SRC
include/prismeditor.hpp include/prismeditor.hpp
include/materialeditor.hpp include/materialeditor.hpp
include/sceneeditor.hpp include/sceneeditor.hpp
include/prefabeditor.hpp include/prefabeditor.hpp
src/prismeditor.cpp src/prismeditor.cpp
src/materialeditor.cpp src/materialeditor.cpp
src/sceneeditor.cpp src/sceneeditor.cpp
src/prefabeditor.cpp) src/prefabeditor.cpp)
add_platform_executable( add_platform_executable(
TARGET PrismEditor TARGET PrismEditor
APP_CLASS PrismEditor APP_CLASS PrismEditor
APP_INCLUDE prismeditor.hpp APP_INCLUDE prismeditor.hpp
SKIP_DATA ON SKIP_DATA ON
SRC ${SRC}) SRC ${SRC})
target_link_libraries(PrismEditor PUBLIC target_link_libraries(PrismEditor PUBLIC
Core Core
EditorCommon) EditorCommon)
target_include_directories(PrismEditor PUBLIC target_include_directories(PrismEditor PUBLIC
include) include)
set_engine_properties(PrismEditor) set_engine_properties(PrismEditor)

View file

@ -1,7 +1,7 @@
#pragma once #pragma once
#include "prismeditor.hpp"
#include "asset.hpp" #include "asset.hpp"
#include "prismeditor.hpp"
#include "scene.hpp" #include "scene.hpp"
class MaterialEditor : public Editor { class MaterialEditor : public Editor {

View file

@ -24,10 +24,16 @@ public:
return nullptr; return nullptr;
} }
virtual bool has_menubar() const { return false; } virtual bool has_menubar() const {
return false;
}
virtual std::string get_title() const {
return "";
}
virtual std::string get_title() const { return ""; }
virtual void draw([[maybe_unused]] CommonEditor* editor) {} virtual void draw([[maybe_unused]] CommonEditor* editor) {}
virtual void setup_windows([[maybe_unused]] ImGuiID dockspace) {} virtual void setup_windows([[maybe_unused]] ImGuiID dockspace) {}
ImGuiWindowClass get_window_class() const { ImGuiWindowClass get_window_class() const {

View file

@ -1,7 +1,7 @@
#pragma once #pragma once
#include "prismeditor.hpp"
#include "engine.hpp" #include "engine.hpp"
#include "prismeditor.hpp"
class AddObjectCommand : public Command { class AddObjectCommand : public Command {
public: public:

View file

@ -1,8 +1,8 @@
#include "materialeditor.hpp" #include "materialeditor.hpp"
#include <imgui.h> #include <imgui.h>
#include <imgui_stdlib.h>
#include <imgui_internal.h> #include <imgui_internal.h>
#include <imgui_stdlib.h>
#include "engine.hpp" #include "engine.hpp"
@ -38,12 +38,12 @@ void recompile(Material* material) {
} }
void MaterialEditor::draw(CommonEditor* editor) { void MaterialEditor::draw(CommonEditor* editor) {
if(!material) if (!material)
return; return;
if (ImGui::BeginMenuBar()) { if (ImGui::BeginMenuBar()) {
if (ImGui::BeginMenu("File")) { if (ImGui::BeginMenu("File")) {
if(ImGui::MenuItem("Save", "CTRL+S")) { if (ImGui::MenuItem("Save", "CTRL+S")) {
if (path.empty()) { if (path.empty()) {
engine->get_imgui().save_dialog([this](std::string path) { engine->get_imgui().save_dialog([this](std::string path) {
this->path = path; this->path = path;
@ -65,13 +65,13 @@ void MaterialEditor::draw(CommonEditor* editor) {
ImGui::Separator(); ImGui::Separator();
if(ImGui::MenuItem("Close")) if (ImGui::MenuItem("Close"))
wants_to_close = true; wants_to_close = true;
ImGui::EndMenu(); ImGui::EndMenu();
} }
if(ImGui::MenuItem("Compile")) if (ImGui::MenuItem("Compile"))
recompile(*material); recompile(*material);
ImGui::EndMenuBar(); ImGui::EndMenuBar();
@ -79,9 +79,9 @@ void MaterialEditor::draw(CommonEditor* editor) {
auto viewport_scene = engine->get_scene(); auto viewport_scene = engine->get_scene();
if(viewport_scene != nullptr) { if (viewport_scene != nullptr) {
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f)); ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
if(begin("Viewport")) if (begin("Viewport"))
editor->drawViewport(viewport_scene); editor->drawViewport(viewport_scene);
ImGui::End(); ImGui::End();
@ -89,7 +89,7 @@ void MaterialEditor::draw(CommonEditor* editor) {
ImGui::PopStyleVar(); ImGui::PopStyleVar();
} }
if(begin("Node Editor")) { if (begin("Node Editor")) {
const auto draw_list = ImGui::GetWindowDrawList(); const auto draw_list = ImGui::GetWindowDrawList();
const auto window_pos = ImGui::GetCursorScreenPos(); const auto window_pos = ImGui::GetCursorScreenPos();
@ -97,42 +97,40 @@ void MaterialEditor::draw(CommonEditor* editor) {
auto& property = material->colorProperty; auto& property = material->colorProperty;
ImGui::PushID(property.name.c_str()); ImGui::PushID(property.name.c_str());
if(ImGui::BeginCombo("Type", "test")) { if (ImGui::BeginCombo("Type", "test")) {
if(ImGui::Selectable("Vector3")) if (ImGui::Selectable("Vector3"))
property.type = DataType::Vector3; property.type = DataType::Vector3;
if(ImGui::Selectable("Texture")) if (ImGui::Selectable("Texture"))
property.type = DataType::AssetTexture; property.type = DataType::AssetTexture;
if(ImGui::Selectable("Float")) if (ImGui::Selectable("Float"))
property.type = DataType::Float; property.type = DataType::Float;
ImGui::EndCombo(); ImGui::EndCombo();
} }
ImGui::TextDisabled("%s", property.name.c_str()); ImGui::TextDisabled("%s", property.name.c_str());
switch(property.type) { switch (property.type) {
case DataType::Vector3: case DataType::Vector3:
changed |= ImGui::ColorEdit3("", property.value.ptr()); changed |= ImGui::ColorEdit3("", property.value.ptr());
break; break;
case DataType::Float: case DataType::Float:
changed |= ImGui::DragFloat("", &property.float_value); changed |= ImGui::DragFloat("", &property.float_value);
break; break;
case DataType::AssetTexture: case DataType::AssetTexture:
changed |= editor->edit_asset("", property.value_tex); changed |= editor->edit_asset("", property.value_tex);
break; break;
} }
ImGui::PopID(); ImGui::PopID();
if(changed) if (changed)
recompile(*material); recompile(*material);
} }
ImGui::End(); ImGui::End();
} }

View file

@ -1,8 +1,8 @@
#include "prefabeditor.hpp" #include "prefabeditor.hpp"
#include <imgui.h> #include <imgui.h>
#include <imgui_stdlib.h>
#include <imgui_internal.h> #include <imgui_internal.h>
#include <imgui_stdlib.h>
#include "engine.hpp" #include "engine.hpp"
@ -34,7 +34,7 @@ void PrefabEditor::setup_windows(ImGuiID dockspace) {
void PrefabEditor::draw(CommonEditor* editor) { void PrefabEditor::draw(CommonEditor* editor) {
if (ImGui::BeginMenuBar()) { if (ImGui::BeginMenuBar()) {
if (ImGui::BeginMenu("File")) { if (ImGui::BeginMenu("File")) {
if(ImGui::MenuItem("Save", "CTRL+S")) { if (ImGui::MenuItem("Save", "CTRL+S")) {
if (path.empty()) { if (path.empty()) {
engine->get_imgui().save_dialog([this](std::string path) { engine->get_imgui().save_dialog([this](std::string path) {
this->path = path; this->path = path;
@ -56,7 +56,7 @@ void PrefabEditor::draw(CommonEditor* editor) {
ImGui::Separator(); ImGui::Separator();
if(ImGui::MenuItem("Close")) if (ImGui::MenuItem("Close"))
wants_to_close = true; wants_to_close = true;
ImGui::EndMenu(); ImGui::EndMenu();
@ -67,13 +67,13 @@ void PrefabEditor::draw(CommonEditor* editor) {
auto viewport_scene = engine->get_scene(); auto viewport_scene = engine->get_scene();
if(viewport_scene != nullptr) { if (viewport_scene != nullptr) {
auto window_class = get_window_class(); auto window_class = get_window_class();
if(showOutliner) { if (showOutliner) {
ImGui::SetNextWindowClass(&window_class); ImGui::SetNextWindowClass(&window_class);
if(begin("Outliner", &showOutliner)) if (begin("Outliner", &showOutliner))
editor->drawOutline(); editor->drawOutline();
ImGui::End(); ImGui::End();
@ -91,7 +91,7 @@ void PrefabEditor::draw(CommonEditor* editor) {
ImGui::SetNextWindowClass(&window_class); ImGui::SetNextWindowClass(&window_class);
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f)); ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
if(begin("Viewport")) if (begin("Viewport"))
editor->drawViewport(viewport_scene); editor->drawViewport(viewport_scene);
ImGui::End(); ImGui::End();

View file

@ -1,17 +1,17 @@
#include "prismeditor.hpp" #include "prismeditor.hpp"
#include <imgui.h> #include <imgui.h>
#include <imgui_stdlib.h>
#include <imgui_internal.h> #include <imgui_internal.h>
#include <imgui_stdlib.h>
#include "engine.hpp" #include "engine.hpp"
#include "file.hpp" #include "file.hpp"
#include "json_conversions.hpp" #include "json_conversions.hpp"
#include "platform.hpp"
#include "string_utils.hpp"
#include "sceneeditor.hpp"
#include "materialeditor.hpp" #include "materialeditor.hpp"
#include "platform.hpp"
#include "prefabeditor.hpp" #include "prefabeditor.hpp"
#include "sceneeditor.hpp"
#include "string_utils.hpp"
std::string get_filename(const std::string path) { std::string get_filename(const std::string path) {
return path.substr(path.find_last_of("/") + 1, path.length()); return path.substr(path.find_last_of("/") + 1, path.length());
@ -20,21 +20,20 @@ std::string get_filename(const std::string path) {
std::vector<Editor*> editors; std::vector<Editor*> editors;
void app_main(prism::engine* engine) { void app_main(prism::engine* engine) {
CommonEditor* editor = (CommonEditor*)engine->get_app(); CommonEditor* editor = (CommonEditor*)engine->get_app();
platform::open_window("Prism Editor", platform::open_window(
{editor->getDefaultX(), "Prism Editor",
editor->getDefaultY(), {editor->getDefaultX(),
static_cast<uint32_t>(editor->getDefaultWidth()), editor->getDefaultY(),
static_cast<uint32_t>(editor->getDefaultHeight())}, static_cast<uint32_t>(editor->getDefaultWidth()),
WindowFlags::Resizable); static_cast<uint32_t>(editor->getDefaultHeight())},
WindowFlags::Resizable);
engine->update_physics = false; engine->update_physics = false;
} }
PrismEditor::PrismEditor() : CommonEditor("PrismEditor") { PrismEditor::PrismEditor() : CommonEditor("PrismEditor") {}
}
void prepScene() { void prepScene() {
auto scene = engine->get_scene(); auto scene = engine->get_scene();
@ -93,7 +92,8 @@ Renderable* prepMaterialScene() {
scene->get<Transform>(plane).scale = prism::float3(50); scene->get<Transform>(plane).scale = prism::float3(50);
scene->add<Renderable>(plane).mesh = assetm->get<Mesh>(prism::base_domain / "models/plane.model"); scene->add<Renderable>(plane).mesh = assetm->get<Mesh>(prism::base_domain / "models/plane.model");
scene->get<Renderable>(plane).materials.push_back(assetm->get<Material>(prism::base_domain / "materials/Material.material")); scene->get<Renderable>(plane).materials.push_back(
assetm->get<Material>(prism::base_domain / "materials/Material.material"));
auto sphere = scene->add_object(); auto sphere = scene->add_object();
scene->get(sphere).name = "sphere"; scene->get(sphere).name = "sphere";
@ -120,7 +120,7 @@ std::vector<OpenAssetRequest> open_requests;
void PrismEditor::setup_editor(Editor*) {} void PrismEditor::setup_editor(Editor*) {}
void PrismEditor::open_asset(const prism::path path) { void PrismEditor::open_asset(const prism::path path) {
if(path.extension() == ".prefab") { if (path.extension() == ".prefab") {
PrefabEditor* editor = new PrefabEditor(); PrefabEditor* editor = new PrefabEditor();
editor->path = path.string(); editor->path = path.string();
setup_editor(editor); setup_editor(editor);
@ -133,7 +133,7 @@ void PrismEditor::open_asset(const prism::path path) {
editor->scene = engine->get_scene(); editor->scene = engine->get_scene();
editors.push_back(editor); editors.push_back(editor);
} else if(path.extension() == ".scene") { } else if (path.extension() == ".scene") {
SceneEditor* editor = new SceneEditor(); SceneEditor* editor = new SceneEditor();
editor->path = path.string(); editor->path = path.string();
setup_editor(editor); setup_editor(editor);
@ -142,7 +142,7 @@ void PrismEditor::open_asset(const prism::path path) {
prepScene(); prepScene();
editors.push_back(editor); editors.push_back(editor);
} else if(path.extension() == ".material") { } else if (path.extension() == ".material") {
MaterialEditor* editor = new MaterialEditor(); MaterialEditor* editor = new MaterialEditor();
editor->path = path.string(); editor->path = path.string();
setup_editor(editor); setup_editor(editor);
@ -162,7 +162,7 @@ void PrismEditor::open_asset(const prism::path path) {
} }
void PrismEditor::renderEditor(GFXCommandBuffer* command_buffer) { void PrismEditor::renderEditor(GFXCommandBuffer* command_buffer) {
for(auto [id, render_target] : viewport_render_targets) { for (auto [id, render_target] : viewport_render_targets) {
engine->get_renderer()->render(command_buffer, render_target.scene, *render_target.target, nullptr); engine->get_renderer()->render(command_buffer, render_target.scene, *render_target.target, nullptr);
} }
} }
@ -176,8 +176,8 @@ void PrismEditor::drawUI() {
if (ImGui::BeginMainMenuBar()) { if (ImGui::BeginMainMenuBar()) {
if (ImGui::BeginMenu("File")) { if (ImGui::BeginMenu("File")) {
if(ImGui::BeginMenu("New")) { if (ImGui::BeginMenu("New")) {
if(ImGui::MenuItem("Scene")) { if (ImGui::MenuItem("Scene")) {
SceneEditor* editor = new SceneEditor(); SceneEditor* editor = new SceneEditor();
editor->modified = true; editor->modified = true;
setup_editor(editor); setup_editor(editor);
@ -189,7 +189,7 @@ void PrismEditor::drawUI() {
editors.push_back(editor); editors.push_back(editor);
} }
if(ImGui::MenuItem("Prefab")) { if (ImGui::MenuItem("Prefab")) {
PrefabEditor* editor = new PrefabEditor(); PrefabEditor* editor = new PrefabEditor();
editor->modified = true; editor->modified = true;
setup_editor(editor); setup_editor(editor);
@ -201,7 +201,7 @@ void PrismEditor::drawUI() {
editors.push_back(editor); editors.push_back(editor);
} }
if(ImGui::MenuItem("Material")) { if (ImGui::MenuItem("Material")) {
MaterialEditor* editor = new MaterialEditor(); MaterialEditor* editor = new MaterialEditor();
editor->modified = true; editor->modified = true;
setup_editor(editor); setup_editor(editor);
@ -220,32 +220,32 @@ void PrismEditor::drawUI() {
ImGui::EndMenu(); ImGui::EndMenu();
} }
if(ImGui::MenuItem("Open", "CTRL+O")) { if (ImGui::MenuItem("Open", "CTRL+O")) {
engine->get_imgui().open_dialog(true, [this](std::string path) { engine->get_imgui().open_dialog(true, [this](std::string path) {
open_requests.emplace_back(path, false); open_requests.emplace_back(path, false);
addOpenedFile(path); addOpenedFile(path);
}); });
} }
const auto& recents = getOpenedFiles(); const auto& recents = getOpenedFiles();
if (ImGui::BeginMenu("Open Recent...", !recents.empty())) { if (ImGui::BeginMenu("Open Recent...", !recents.empty())) {
for (auto& file : recents) { for (auto& file : recents) {
if (ImGui::MenuItem(file.c_str())) if (ImGui::MenuItem(file.c_str()))
open_requests.emplace_back(file, false); open_requests.emplace_back(file, false);
} }
ImGui::Separator(); ImGui::Separator();
if (ImGui::MenuItem("Clear")) if (ImGui::MenuItem("Clear"))
clearOpenedFiles(); clearOpenedFiles();
ImGui::EndMenu(); ImGui::EndMenu();
} }
ImGui::Separator(); ImGui::Separator();
if(ImGui::MenuItem("Quit", "CTRL+Q")) if (ImGui::MenuItem("Quit", "CTRL+Q"))
engine->quit(); engine->quit();
ImGui::EndMenu(); ImGui::EndMenu();
@ -254,8 +254,8 @@ void PrismEditor::drawUI() {
ImGui::EndMainMenuBar(); ImGui::EndMainMenuBar();
} }
for(auto& editor : editors) { for (auto& editor : editors) {
if(!editor->has_been_docked) { if (!editor->has_been_docked) {
ImGui::DockBuilderDockWindow(editor->get_window_title().c_str(), dock_id); ImGui::DockBuilderDockWindow(editor->get_window_title().c_str(), dock_id);
ImGui::DockBuilderFinish(dock_id); ImGui::DockBuilderFinish(dock_id);
@ -264,25 +264,25 @@ void PrismEditor::drawUI() {
const ImGuiID editor_dockspace = ImGui::GetID(editor); const ImGuiID editor_dockspace = ImGui::GetID(editor);
if(ImGui::DockBuilderGetNode(editor_dockspace) == nullptr) { if (ImGui::DockBuilderGetNode(editor_dockspace) == nullptr) {
const auto size = ImGui::GetMainViewport()->Size; const auto size = ImGui::GetMainViewport()->Size;
ImGui::DockBuilderRemoveNode(editor_dockspace); ImGui::DockBuilderRemoveNode(editor_dockspace);
ImGui::DockBuilderAddNode(editor_dockspace, ImGuiDockNodeFlags_DockSpace); ImGui::DockBuilderAddNode(editor_dockspace, ImGuiDockNodeFlags_DockSpace);
ImGui::DockBuilderSetNodeSize(editor_dockspace, size); ImGui::DockBuilderSetNodeSize(editor_dockspace, size);
editor->setup_windows(editor_dockspace); editor->setup_windows(editor_dockspace);
ImGui::DockBuilderFinish(editor_dockspace); ImGui::DockBuilderFinish(editor_dockspace);
} }
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f)); ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
int window_flags = 0; int window_flags = 0;
if(editor->has_menubar()) if (editor->has_menubar())
window_flags |= ImGuiWindowFlags_MenuBar; window_flags |= ImGuiWindowFlags_MenuBar;
if(editor->modified) if (editor->modified)
window_flags |= ImGuiWindowFlags_UnsavedDocument; window_flags |= ImGuiWindowFlags_UnsavedDocument;
bool should_draw = ImGui::Begin(editor->get_window_title().c_str(), nullptr, window_flags); bool should_draw = ImGui::Begin(editor->get_window_title().c_str(), nullptr, window_flags);
@ -291,7 +291,7 @@ void PrismEditor::drawUI() {
ImGui::DockSpace(editor_dockspace, ImVec2(0.0f, 0.0f), ImGuiDockNodeFlags_None); ImGui::DockSpace(editor_dockspace, ImVec2(0.0f, 0.0f), ImGuiDockNodeFlags_None);
if(should_draw) { if (should_draw) {
/*debugPass = editor->debug_pass; /*debugPass = editor->debug_pass;
if(debugPass != nullptr) if(debugPass != nullptr)
debugPass->selected_object = selected_object;*/ debugPass->selected_object = selected_object;*/
@ -318,7 +318,7 @@ void PrismEditor::asset_selected(const std::filesystem::path& path, AssetType) {
} }
void PrismEditor::updateEditor(float) { void PrismEditor::updateEditor(float) {
for(auto [path, is_relative] : open_requests) for (auto [path, is_relative] : open_requests)
open_asset(path); open_asset(path);
open_requests.clear(); open_requests.clear();

View file

@ -1,8 +1,8 @@
#include "sceneeditor.hpp" #include "sceneeditor.hpp"
#include <imgui.h> #include <imgui.h>
#include <imgui_stdlib.h>
#include <imgui_internal.h> #include <imgui_internal.h>
#include <imgui_stdlib.h>
#include "engine.hpp" #include "engine.hpp"
@ -42,7 +42,7 @@ void SceneEditor::setup_windows(ImGuiID dockspace) {
void SceneEditor::draw(CommonEditor* editor) { void SceneEditor::draw(CommonEditor* editor) {
if (ImGui::BeginMenuBar()) { if (ImGui::BeginMenuBar()) {
if (ImGui::BeginMenu("File")) { if (ImGui::BeginMenu("File")) {
if(ImGui::MenuItem("Save", "CTRL+S")) { if (ImGui::MenuItem("Save", "CTRL+S")) {
if (path.empty()) { if (path.empty()) {
engine->get_imgui().save_dialog([this](std::string path) { engine->get_imgui().save_dialog([this](std::string path) {
this->path = path; this->path = path;
@ -50,11 +50,11 @@ void SceneEditor::draw(CommonEditor* editor) {
engine->save_scene(path); engine->save_scene(path);
}); });
} else { } else {
engine->save_scene(path); engine->save_scene(path);
} }
} }
if(ImGui::MenuItem("Save as...", "CTRL+S")) { if (ImGui::MenuItem("Save as...", "CTRL+S")) {
engine->get_imgui().save_dialog([this](std::string path) { engine->get_imgui().save_dialog([this](std::string path) {
this->path = path; this->path = path;
@ -64,7 +64,7 @@ void SceneEditor::draw(CommonEditor* editor) {
ImGui::Separator(); ImGui::Separator();
if(ImGui::MenuItem("Close")) if (ImGui::MenuItem("Close"))
wants_to_close = true; wants_to_close = true;
ImGui::EndMenu(); ImGui::EndMenu();
@ -96,7 +96,7 @@ void SceneEditor::draw(CommonEditor* editor) {
ImGui::EndMenu(); ImGui::EndMenu();
} }
if(ImGui::BeginMenu("Add...")) { if (ImGui::BeginMenu("Add...")) {
if (ImGui::MenuItem("Empty")) { if (ImGui::MenuItem("Empty")) {
auto new_obj = engine->get_scene()->add_object(); auto new_obj = engine->get_scene()->add_object();
engine->get_scene()->get(new_obj).name = "new object"; engine->get_scene()->get(new_obj).name = "new object";
@ -106,7 +106,7 @@ void SceneEditor::draw(CommonEditor* editor) {
command.name = engine->get_scene()->get(new_obj).name; command.name = engine->get_scene()->get(new_obj).name;
} }
if(ImGui::MenuItem("Prefab")) { if (ImGui::MenuItem("Prefab")) {
engine->get_imgui().open_dialog(false, [](std::string path) { engine->get_imgui().open_dialog(false, [](std::string path) {
engine->add_prefab(*engine->get_scene(), path); engine->add_prefab(*engine->get_scene(), path);
}); });
@ -130,32 +130,31 @@ void SceneEditor::draw(CommonEditor* editor) {
} }
auto viewport_scene = engine->get_scene(); auto viewport_scene = engine->get_scene();
if(viewport_scene != nullptr) { if (viewport_scene != nullptr) {
if(showSceneSettings) { if (showSceneSettings) {
if(begin("Scene Settings", &showSceneSettings)) { if (begin("Scene Settings", &showSceneSettings)) {
} }
ImGui::End(); ImGui::End();
} }
if(showOutliner) { if (showOutliner) {
if(begin("Outliner", &showOutliner)) if (begin("Outliner", &showOutliner))
editor->drawOutline(); editor->drawOutline();
ImGui::End(); ImGui::End();
} }
if(showProperties) { if (showProperties) {
if(begin("Properties", &showProperties)) if (begin("Properties", &showProperties))
editor->drawPropertyEditor(); editor->drawPropertyEditor();
ImGui::End(); ImGui::End();
} }
if(showViewport) { if (showViewport) {
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f)); ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
if(begin("Viewport", &showViewport)) if (begin("Viewport", &showViewport))
editor->drawViewport(viewport_scene); editor->drawViewport(viewport_scene);
ImGui::PopStyleVar(); ImGui::PopStyleVar();
@ -163,11 +162,11 @@ void SceneEditor::draw(CommonEditor* editor) {
ImGui::End(); ImGui::End();
} }
if(showUndoStack) { if (showUndoStack) {
if(begin("Undo Stack", &showUndoStack)) { if (begin("Undo Stack", &showUndoStack)) {
for(auto [i, command] : utility::enumerate(undo_stack.command_stack)) { for (auto [i, command] : utility::enumerate(undo_stack.command_stack)) {
std::string name = command->get_name(); std::string name = command->get_name();
if(i == undo_stack.stack_position) if (i == undo_stack.stack_position)
name = "-> " + name; name = "-> " + name;
ImGui::Selectable(name.c_str()); ImGui::Selectable(name.c_str());
@ -177,14 +176,14 @@ void SceneEditor::draw(CommonEditor* editor) {
ImGui::End(); ImGui::End();
} }
if(showAssets) { if (showAssets) {
if(begin("Assets", &showAssets)) if (begin("Assets", &showAssets))
editor->drawAssets(); editor->drawAssets();
ImGui::End(); ImGui::End();
} }
if(begin("Console")) if (begin("Console"))
editor->drawConsole(); editor->drawConsole();
ImGui::End(); ImGui::End();

View file

@ -1,15 +1,12 @@
#include <cstdio> #include <cstdio>
#include <string_view>
#include <array> #include <array>
#include <iostream> #include <iostream>
#include <string_view>
#include <stb_truetype.h> #include <stb_truetype.h>
constexpr std::array sizes_to_pack = { constexpr std::array sizes_to_pack = {36.0f, 24.0f};
36.0f,
24.0f
};
constexpr int num_glyphs = 95; constexpr int num_glyphs = 95;
constexpr int texture_width = 2048, texture_height = 1150; constexpr int texture_width = 2048, texture_height = 1150;
@ -42,7 +39,7 @@ void load_ttf(const std::string_view path) {
} }
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
if(argc != 3) { if (argc != 3) {
std::cout << "Usage: FontCompiler [input ttf] [output fp]" << std::endl; std::cout << "Usage: FontCompiler [input ttf] [output fp]" << std::endl;
return 0; return 0;
} }
@ -53,14 +50,14 @@ int main(int argc, char* argv[]) {
stbtt_PackSetOversampling(&pack_context, 2, 2); stbtt_PackSetOversampling(&pack_context, 2, 2);
stbtt_pack_range ranges[sizes_to_pack.size()]; stbtt_pack_range ranges[sizes_to_pack.size()];
for(int i = 0; i < sizes_to_pack.size(); i++) for (int i = 0; i < sizes_to_pack.size(); i++)
ranges[i] = {sizes_to_pack[i], 32, nullptr, 95, packed_chars[i], 0, 0}; ranges[i] = {sizes_to_pack[i], 32, nullptr, 95, packed_chars[i], 0, 0};
stbtt_PackFontRanges(&pack_context, font_data, 0, ranges, sizes_to_pack.size()); stbtt_PackFontRanges(&pack_context, font_data, 0, ranges, sizes_to_pack.size());
stbtt_PackEnd(&pack_context); stbtt_PackEnd(&pack_context);
FILE* file = fopen(argv[2], "wb"); FILE* file = fopen(argv[2], "wb");
if(!file) if (!file)
return -1; return -1;
fwrite(&texture_width, sizeof(int), 1, file); fwrite(&texture_width, sizeof(int), 1, file);
@ -73,10 +70,10 @@ int main(int argc, char* argv[]) {
fwrite(&descent, sizeof(int), 1, file); fwrite(&descent, sizeof(int), 1, file);
fwrite(&gap, sizeof(int), 1, file); fwrite(&gap, sizeof(int), 1, file);
for(auto& packed_char : packed_chars) for (auto& packed_char : packed_chars)
fwrite(&packed_char, sizeof(packed_char), 1, file); fwrite(&packed_char, sizeof(packed_char), 1, file);
for(auto& range : ranges) { for (auto& range : ranges) {
const float f = (ascent + descent) * stbtt_ScaleForPixelHeight(&font_info, range.font_size); const float f = (ascent + descent) * stbtt_ScaleForPixelHeight(&font_info, range.font_size);
fwrite(&f, sizeof(float), 1, file); fwrite(&f, sizeof(float), 1, file);
} }

View file

@ -1,16 +1,16 @@
add_platform_executable( add_platform_executable(
TARGET ModelCompiler TARGET ModelCompiler
APP_CLASS ModelEditor APP_CLASS ModelEditor
APP_INCLUDE modeleditor.hpp APP_INCLUDE modeleditor.hpp
SRC SRC
src/modeleditor.cpp src/modeleditor.cpp
include/modeleditor.hpp include/modeleditor.hpp
SKIP_DATA TRUE) SKIP_DATA TRUE)
target_link_libraries(ModelCompiler PUBLIC target_link_libraries(ModelCompiler PUBLIC
Core Core
EditorCommon EditorCommon
PRIVATE PRIVATE
assimp) assimp)
target_include_directories(ModelCompiler PUBLIC target_include_directories(ModelCompiler PUBLIC
include) include)
set_engine_properties(ModelCompiler) set_engine_properties(ModelCompiler)

View file

@ -4,9 +4,9 @@
class ModelEditor : public CommonEditor { class ModelEditor : public CommonEditor {
public: public:
ModelEditor(); ModelEditor();
void drawUI() override; void drawUI() override;
struct Flags { struct Flags {
bool hide_ui = false; bool hide_ui = false;

View file

@ -1,15 +1,15 @@
#include "modeleditor.hpp" #include "modeleditor.hpp"
#include <imgui.h>
#include <imgui_stdlib.h>
#include <nlohmann/json.hpp>
#include <magic_enum.hpp>
#include <cstdio>
#include <assimp/Importer.hpp> #include <assimp/Importer.hpp>
#include <assimp/postprocess.h> #include <assimp/postprocess.h>
#include <assimp/scene.h> #include <assimp/scene.h>
#include <unordered_map> #include <cstdio>
#include <functional> #include <functional>
#include <imgui.h>
#include <imgui_stdlib.h>
#include <magic_enum.hpp>
#include <nlohmann/json.hpp>
#include <unordered_map>
#include "engine.hpp" #include "engine.hpp"
#include "file.hpp" #include "file.hpp"
@ -23,24 +23,23 @@ void app_main(prism::engine* engine) {
engine->debug_enabled = false; engine->debug_enabled = false;
engine->console_enabled = false; engine->console_enabled = false;
if(utility::contains(engine->command_line_arguments, "--no_ui")) if (utility::contains(engine->command_line_arguments, "--no_ui"))
editor->flags.hide_ui = true; editor->flags.hide_ui = true;
if(!editor->flags.hide_ui) { if (!editor->flags.hide_ui) {
platform::open_window("Model Compiler", platform::open_window(
{editor->getDefaultX(), editor->getDefaultY(), 300, 300}, "Model Compiler", {editor->getDefaultX(), editor->getDefaultY(), 300, 300}, WindowFlags::None);
WindowFlags::None);
} else { } else {
std::string compiled_model_path; std::string compiled_model_path;
for(auto [i, argument] : utility::enumerate(engine->command_line_arguments)) { for (auto [i, argument] : utility::enumerate(engine->command_line_arguments)) {
if(argument == "--model-path") if (argument == "--model-path")
editor->model_path = engine->command_line_arguments[i + 1]; editor->model_path = engine->command_line_arguments[i + 1];
if(argument == "--compiled-model-path") if (argument == "--compiled-model-path")
compiled_model_path = engine->command_line_arguments[i + 1]; compiled_model_path = engine->command_line_arguments[i + 1];
if(argument == "--compile-static") if (argument == "--compile-static")
editor->flags.compile_static = true; editor->flags.compile_static = true;
} }
@ -56,9 +55,9 @@ void app_main(prism::engine* engine) {
ModelEditor::ModelEditor() : CommonEditor("ModelEditor") {} ModelEditor::ModelEditor() : CommonEditor("ModelEditor") {}
void traverseNode(const aiScene* scene, aiNode* node, const aiBone* bone, aiString& parent) { void traverseNode(const aiScene* scene, aiNode* node, const aiBone* bone, aiString& parent) {
for(int i = 0; i < node->mNumChildren; i++) { for (int i = 0; i < node->mNumChildren; i++) {
aiNode* child = node->mChildren[i]; aiNode* child = node->mChildren[i];
if(child->mName == bone->mName) { if (child->mName == bone->mName) {
parent = node->mName; parent = node->mName;
} else { } else {
traverseNode(scene, child, bone, parent); traverseNode(scene, child, bone, parent);
@ -67,9 +66,9 @@ void traverseNode(const aiScene* scene, aiNode* node, const aiBone* bone, aiStri
} }
void traverseNode(const aiScene* scene, aiNode* node, const aiBone* bone, aiVector3D& pos) { void traverseNode(const aiScene* scene, aiNode* node, const aiBone* bone, aiVector3D& pos) {
for(int i = 0; i < node->mNumChildren; i++) { for (int i = 0; i < node->mNumChildren; i++) {
aiNode* child = node->mChildren[i]; aiNode* child = node->mChildren[i];
if(child->mName == bone->mName) { if (child->mName == bone->mName) {
aiVector3D scale, position; aiVector3D scale, position;
aiQuaternion rotation; aiQuaternion rotation;
@ -83,9 +82,9 @@ void traverseNode(const aiScene* scene, aiNode* node, const aiBone* bone, aiVect
} }
void traverseNodeScale(const aiScene* scene, aiNode* node, const aiBone* bone, aiVector3D& pos) { void traverseNodeScale(const aiScene* scene, aiNode* node, const aiBone* bone, aiVector3D& pos) {
for(int i = 0; i < node->mNumChildren; i++) { for (int i = 0; i < node->mNumChildren; i++) {
aiNode* child = node->mChildren[i]; aiNode* child = node->mChildren[i];
if(child->mName == bone->mName) { if (child->mName == bone->mName) {
aiVector3D scale, position; aiVector3D scale, position;
aiQuaternion rotation; aiQuaternion rotation;
@ -99,9 +98,9 @@ void traverseNodeScale(const aiScene* scene, aiNode* node, const aiBone* bone, a
} }
void traverseNode(const aiScene* scene, aiNode* node, const aiBone* bone, aiQuaternion& rot) { void traverseNode(const aiScene* scene, aiNode* node, const aiBone* bone, aiQuaternion& rot) {
for(int i = 0; i < node->mNumChildren; i++) { for (int i = 0; i < node->mNumChildren; i++) {
aiNode* child = node->mChildren[i]; aiNode* child = node->mChildren[i];
if(child->mName == bone->mName) { if (child->mName == bone->mName) {
aiVector3D scale, position; aiVector3D scale, position;
aiQuaternion rotation; aiQuaternion rotation;
@ -148,7 +147,7 @@ aiVector3D getBoneScale(const aiScene* scene, const aiBone* bone) {
void write_string(FILE* file, const aiString& str) { void write_string(FILE* file, const aiString& str) {
fwrite(&str.length, sizeof(unsigned int), 1, file); fwrite(&str.length, sizeof(unsigned int), 1, file);
if(str.length > 0) { if (str.length > 0) {
fwrite(str.C_Str(), sizeof(char) * str.length, 1, file); fwrite(str.C_Str(), sizeof(char) * str.length, 1, file);
prism::log("writing string {}", str.C_Str()); prism::log("writing string {}", str.C_Str());
} }
@ -158,7 +157,7 @@ void write_string(FILE* file, const std::string& str) {
unsigned int len = str.length(); unsigned int len = str.length();
fwrite(&len, sizeof(unsigned int), 1, file); fwrite(&len, sizeof(unsigned int), 1, file);
if(str.length() > 0) { if (str.length() > 0) {
fwrite(str.c_str(), sizeof(char) * len, 1, file); fwrite(str.c_str(), sizeof(char) * len, 1, file);
prism::log("writing string {}", str.c_str()); prism::log("writing string {}", str.c_str());
} }
@ -189,15 +188,11 @@ void ModelEditor::compile_model(std::string compiled_model_path) {
Assimp::Importer importer; Assimp::Importer importer;
unsigned int importer_flags = unsigned int importer_flags = aiProcess_Triangulate | aiProcess_ImproveCacheLocality |
aiProcess_Triangulate | aiProcess_JoinIdenticalVertices | aiProcess_OptimizeMeshes |
aiProcess_ImproveCacheLocality | aiProcess_CalcTangentSpace | aiProcess_GenNormals;
aiProcess_JoinIdenticalVertices |
aiProcess_OptimizeMeshes |
aiProcess_CalcTangentSpace |
aiProcess_GenNormals;
if(flags.compile_static) { if (flags.compile_static) {
importer.SetPropertyFloat(AI_CONFIG_GLOBAL_SCALE_FACTOR_KEY, 1.0); importer.SetPropertyFloat(AI_CONFIG_GLOBAL_SCALE_FACTOR_KEY, 1.0);
importer_flags |= aiProcess_GlobalScale; importer_flags |= aiProcess_GlobalScale;
@ -240,10 +235,10 @@ void ModelEditor::compile_model(std::string compiled_model_path) {
std::vector<BoneVertexData> bone_vertex_data; std::vector<BoneVertexData> bone_vertex_data;
for(unsigned int i = 0; i < sc->mNumMeshes; i++) { for (unsigned int i = 0; i < sc->mNumMeshes; i++) {
aiMesh* mesh = sc->mMeshes[i]; aiMesh* mesh = sc->mMeshes[i];
if(mesh->HasBones()) if (mesh->HasBones())
mesh_type = MeshType::Skinned; mesh_type = MeshType::Skinned;
} }
@ -254,10 +249,10 @@ void ModelEditor::compile_model(std::string compiled_model_path) {
aiMesh* armature_mesh = nullptr; aiMesh* armature_mesh = nullptr;
int vertex_offset = 0; int vertex_offset = 0;
for(unsigned int i = 0; i < sc->mNumMeshes; i++) { for (unsigned int i = 0; i < sc->mNumMeshes; i++) {
aiMesh* mesh = sc->mMeshes[i]; aiMesh* mesh = sc->mMeshes[i];
if(armature_mesh == nullptr && mesh->mNumBones != 0) { if (armature_mesh == nullptr && mesh->mNumBones != 0) {
armature_mesh = mesh; armature_mesh = mesh;
} }
@ -265,7 +260,7 @@ void ModelEditor::compile_model(std::string compiled_model_path) {
positions.push_back(mesh->mVertices[v]); positions.push_back(mesh->mVertices[v]);
normals.push_back(mesh->mNormals[v]); normals.push_back(mesh->mNormals[v]);
if(mesh->HasTextureCoords(0)) { if (mesh->HasTextureCoords(0)) {
texture_coords.emplace_back(mesh->mTextureCoords[0][v].x, mesh->mTextureCoords[0][v].y); texture_coords.emplace_back(mesh->mTextureCoords[0][v].x, mesh->mTextureCoords[0][v].y);
} else { } else {
texture_coords.emplace_back(0, 0); texture_coords.emplace_back(0, 0);
@ -283,8 +278,8 @@ void ModelEditor::compile_model(std::string compiled_model_path) {
indices.push_back(face.mIndices[2]); indices.push_back(face.mIndices[2]);
} }
for(unsigned int b = 0; b < mesh->mNumBones; b++) { for (unsigned int b = 0; b < mesh->mNumBones; b++) {
for(int y = 0; y < mesh->mBones[b]->mNumWeights; y++) { for (int y = 0; y < mesh->mBones[b]->mNumWeights; y++) {
BoneWeight bw; BoneWeight bw;
bw.bone_index = b; bw.bone_index = b;
bw.vertex_index = vertex_offset + mesh->mBones[b]->mWeights[y].mVertexId; bw.vertex_index = vertex_offset + mesh->mBones[b]->mWeights[y].mVertexId;
@ -297,16 +292,16 @@ void ModelEditor::compile_model(std::string compiled_model_path) {
std::string material = sc->mMaterials[mesh->mMaterialIndex]->GetName().C_Str(); std::string material = sc->mMaterials[mesh->mMaterialIndex]->GetName().C_Str();
meshToMaterial[i] = material; meshToMaterial[i] = material;
if(!matNameToIndex.count(material)) if (!matNameToIndex.count(material))
matNameToIndex[material] = last_material++; matNameToIndex[material] = last_material++;
vertex_offset += mesh->mNumVertices; vertex_offset += mesh->mNumVertices;
} }
if(mesh_type == MeshType::Skinned) { if (mesh_type == MeshType::Skinned) {
bone_vertex_data.resize(positions.size()); bone_vertex_data.resize(positions.size());
for(auto bw : bone_weights) for (auto bw : bone_weights)
bone_vertex_data[bw.vertex_index].add(bw.bone_index, bw.weight); bone_vertex_data[bw.vertex_index].add(bw.bone_index, bw.weight);
} }
@ -316,7 +311,7 @@ void ModelEditor::compile_model(std::string compiled_model_path) {
fwrite(&vert_len, sizeof(int), 1, file); fwrite(&vert_len, sizeof(int), 1, file);
const auto write_buffer = [numVertices = positions.size(), file](auto vec, unsigned int size) { const auto write_buffer = [numVertices = positions.size(), file](auto vec, unsigned int size) {
for(unsigned int i = 0; i < numVertices; i++) { for (unsigned int i = 0; i < numVertices; i++) {
fwrite(&vec[i], size, 1, file); fwrite(&vec[i], size, 1, file);
} }
}; };
@ -327,7 +322,7 @@ void ModelEditor::compile_model(std::string compiled_model_path) {
write_buffer(tangents, sizeof(prism::float3)); write_buffer(tangents, sizeof(prism::float3));
write_buffer(bitangents, sizeof(prism::float3)); write_buffer(bitangents, sizeof(prism::float3));
if(mesh_type == MeshType::Skinned) if (mesh_type == MeshType::Skinned)
write_buffer(bone_vertex_data, sizeof(BoneVertexData)); write_buffer(bone_vertex_data, sizeof(BoneVertexData));
int element_len = indices.size(); int element_len = indices.size();
@ -336,13 +331,13 @@ void ModelEditor::compile_model(std::string compiled_model_path) {
fwrite(indices.data(), sizeof(uint32_t) * indices.size(), 1, file); fwrite(indices.data(), sizeof(uint32_t) * indices.size(), 1, file);
int bone_len = 0; int bone_len = 0;
if(armature_mesh != nullptr) { if (armature_mesh != nullptr) {
bone_len = armature_mesh->mNumBones; bone_len = armature_mesh->mNumBones;
} }
fwrite(&bone_len, sizeof(int), 1, file); fwrite(&bone_len, sizeof(int), 1, file);
if(bone_len > 0) { if (bone_len > 0) {
auto transform = sc->mRootNode->mTransformation; auto transform = sc->mRootNode->mTransformation;
transform.Inverse(); transform.Inverse();
transform.Transpose(); transform.Transpose();
@ -378,22 +373,22 @@ void ModelEditor::compile_model(std::string compiled_model_path) {
float min_x = 0.0f, min_y = 0.0f, min_z = 0.0f; float min_x = 0.0f, min_y = 0.0f, min_z = 0.0f;
float max_x = 0.0f, max_y = 0.0f, max_z = 0.0f; float max_x = 0.0f, max_y = 0.0f, max_z = 0.0f;
for(unsigned int i = 0; i < mesh->mNumVertices; i++) { for (unsigned int i = 0; i < mesh->mNumVertices; i++) {
auto vertex_pos = mesh->mVertices[i]; auto vertex_pos = mesh->mVertices[i];
if(vertex_pos.x < min_x) if (vertex_pos.x < min_x)
min_x = vertex_pos.x; min_x = vertex_pos.x;
else if(vertex_pos.x > max_x) else if (vertex_pos.x > max_x)
max_x = vertex_pos.x; max_x = vertex_pos.x;
if(vertex_pos.y < min_y) if (vertex_pos.y < min_y)
min_y = vertex_pos.y; min_y = vertex_pos.y;
else if(vertex_pos.y > max_y) else if (vertex_pos.y > max_y)
max_y = vertex_pos.y; max_y = vertex_pos.y;
if(vertex_pos.z < min_z) if (vertex_pos.z < min_z)
min_z = vertex_pos.z; min_z = vertex_pos.z;
else if(vertex_pos.z > max_z) else if (vertex_pos.z > max_z)
max_z = vertex_pos.z; max_z = vertex_pos.z;
} }
@ -410,7 +405,7 @@ void ModelEditor::compile_model(std::string compiled_model_path) {
int numOffsetMatrices = mesh->mNumBones; int numOffsetMatrices = mesh->mNumBones;
fwrite(&numOffsetMatrices, sizeof(int), 1, file); fwrite(&numOffsetMatrices, sizeof(int), 1, file);
for(int b = 0; b < mesh->mNumBones; b++) { for (int b = 0; b < mesh->mNumBones; b++) {
auto offset = mesh->mBones[b]->mOffsetMatrix; auto offset = mesh->mBones[b]->mOffsetMatrix;
offset.Transpose(); offset.Transpose();
@ -427,20 +422,20 @@ void ModelEditor::compile_model(std::string compiled_model_path) {
fmt::print("Finished writing model!\n"); fmt::print("Finished writing model!\n");
if(flags.export_materials) { if (flags.export_materials) {
for(int i = 0; i < sc->mNumMaterials; i++) { for (int i = 0; i < sc->mNumMaterials; i++) {
auto path = data_path + "/materials/" + sc->mMaterials[i]->GetName().C_Str() + ".material"; auto path = data_path + "/materials/" + sc->mMaterials[i]->GetName().C_Str() + ".material";
Material mat; Material mat;
aiColor4D color; aiColor4D color;
aiGetMaterialColor(sc->mMaterials[i], AI_MATKEY_COLOR_DIFFUSE,&color); aiGetMaterialColor(sc->mMaterials[i], AI_MATKEY_COLOR_DIFFUSE, &color);
mat.colorProperty.type = DataType::Vector3; mat.colorProperty.type = DataType::Vector3;
mat.colorProperty.value = prism::float3(color.r, color.g, color.b); mat.colorProperty.value = prism::float3(color.r, color.g, color.b);
aiString diffuse_path; aiString diffuse_path;
if(aiReturn_SUCCESS == aiGetMaterialTexture(sc->mMaterials[i], aiTextureType_DIFFUSE, 0, &diffuse_path)) { if (aiReturn_SUCCESS == aiGetMaterialTexture(sc->mMaterials[i], aiTextureType_DIFFUSE, 0, &diffuse_path)) {
mat.colorProperty.type = DataType::AssetTexture; mat.colorProperty.type = DataType::AssetTexture;
mat.colorProperty.value_tex.handle = new Texture(); mat.colorProperty.value_tex.handle = new Texture();
mat.colorProperty.value_tex->path = std::string("textures/") + diffuse_path.C_Str(); mat.colorProperty.value_tex->path = std::string("textures/") + diffuse_path.C_Str();
@ -448,7 +443,7 @@ void ModelEditor::compile_model(std::string compiled_model_path) {
} }
aiString normal_path; aiString normal_path;
if(aiReturn_SUCCESS == aiGetMaterialTexture(sc->mMaterials[i], aiTextureType_NORMALS, 0, &normal_path)) { if (aiReturn_SUCCESS == aiGetMaterialTexture(sc->mMaterials[i], aiTextureType_NORMALS, 0, &normal_path)) {
mat.normalProperty.type = DataType::AssetTexture; mat.normalProperty.type = DataType::AssetTexture;
mat.normalProperty.value_tex.handle = new Texture(); mat.normalProperty.value_tex.handle = new Texture();
mat.normalProperty.value_tex->path = std::string("textures/") + normal_path.C_Str(); mat.normalProperty.value_tex->path = std::string("textures/") + normal_path.C_Str();
@ -459,12 +454,12 @@ void ModelEditor::compile_model(std::string compiled_model_path) {
} }
} }
if(flags.export_animations) { if (flags.export_animations) {
for(auto i = 0; i < sc->mNumAnimations; i++) { for (auto i = 0; i < sc->mNumAnimations; i++) {
const aiAnimation* animation = sc->mAnimations[i]; const aiAnimation* animation = sc->mAnimations[i];
std::string animName = animation->mName.C_Str(); std::string animName = animation->mName.C_Str();
if(animName.length() == 0) if (animName.length() == 0)
animName = "default"; animName = "default";
std::string finalName = (name + animName + ".anim"); std::string finalName = (name + animName + ".anim");
@ -478,16 +473,19 @@ void ModelEditor::compile_model(std::string compiled_model_path) {
fwrite(&animation->mNumChannels, sizeof(unsigned int), 1, file); fwrite(&animation->mNumChannels, sizeof(unsigned int), 1, file);
for(auto j = 0; j < animation->mNumChannels; j++) { for (auto j = 0; j < animation->mNumChannels; j++) {
const aiNodeAnim* channel = animation->mChannels[j]; const aiNodeAnim* channel = animation->mChannels[j];
write_string(file, channel->mNodeName); write_string(file, channel->mNodeName);
fwrite(&channel->mNumPositionKeys, sizeof(unsigned int), 1, file); fwrite(&channel->mNumPositionKeys, sizeof(unsigned int), 1, file);
for(auto k = 0; k < channel->mNumPositionKeys; k++) { for (auto k = 0; k < channel->mNumPositionKeys; k++) {
PositionKeyFrame key; PositionKeyFrame key;
key.value = prism::float3(channel->mPositionKeys[k].mValue.x, channel->mPositionKeys[k].mValue.y, channel->mPositionKeys[k].mValue.z); key.value = prism::float3(
channel->mPositionKeys[k].mValue.x,
channel->mPositionKeys[k].mValue.y,
channel->mPositionKeys[k].mValue.z);
key.time = channel->mPositionKeys[k].mTime; key.time = channel->mPositionKeys[k].mTime;
fwrite(&key, sizeof(PositionKeyFrame), 1, file); fwrite(&key, sizeof(PositionKeyFrame), 1, file);
@ -495,9 +493,13 @@ void ModelEditor::compile_model(std::string compiled_model_path) {
fwrite(&channel->mNumRotationKeys, sizeof(unsigned int), 1, file); fwrite(&channel->mNumRotationKeys, sizeof(unsigned int), 1, file);
for(auto k = 0; k < channel->mNumRotationKeys; k++) { for (auto k = 0; k < channel->mNumRotationKeys; k++) {
RotationKeyFrame key; RotationKeyFrame key;
key.value = Quaternion(channel->mRotationKeys[k].mValue.x, channel->mRotationKeys[k].mValue.y, channel->mRotationKeys[k].mValue.z, channel->mRotationKeys[k].mValue.w); key.value = Quaternion(
channel->mRotationKeys[k].mValue.x,
channel->mRotationKeys[k].mValue.y,
channel->mRotationKeys[k].mValue.z,
channel->mRotationKeys[k].mValue.w);
key.time = channel->mRotationKeys[k].mTime; key.time = channel->mRotationKeys[k].mTime;
fwrite(&key, sizeof(RotationKeyFrame), 1, file); fwrite(&key, sizeof(RotationKeyFrame), 1, file);
@ -505,9 +507,12 @@ void ModelEditor::compile_model(std::string compiled_model_path) {
fwrite(&channel->mNumScalingKeys, sizeof(unsigned int), 1, file); fwrite(&channel->mNumScalingKeys, sizeof(unsigned int), 1, file);
for(auto k = 0; k < channel->mNumScalingKeys; k++) { for (auto k = 0; k < channel->mNumScalingKeys; k++) {
ScaleKeyFrame key; ScaleKeyFrame key;
key.value = prism::float3(channel->mScalingKeys[k].mValue.x, channel->mScalingKeys[k].mValue.y, channel->mScalingKeys[k].mValue.z); key.value = prism::float3(
channel->mScalingKeys[k].mValue.x,
channel->mScalingKeys[k].mValue.y,
channel->mScalingKeys[k].mValue.z);
key.time = channel->mScalingKeys[k].mTime; key.time = channel->mScalingKeys[k].mTime;
fwrite(&key, sizeof(ScaleKeyFrame), 1, file); fwrite(&key, sizeof(ScaleKeyFrame), 1, file);
@ -523,31 +528,35 @@ void ModelEditor::drawUI() {
auto viewport = ImGui::GetMainViewport(); auto viewport = ImGui::GetMainViewport();
ImGui::Begin("mcompile", nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoDecoration); ImGui::Begin(
"mcompile", nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoDecoration);
ImGui::SetWindowPos(viewport->Pos, ImGuiCond_Always); ImGui::SetWindowPos(viewport->Pos, ImGuiCond_Always);
ImGui::SetWindowSize(viewport->Size, ImGuiCond_Always); ImGui::SetWindowSize(viewport->Size, ImGuiCond_Always);
if(ImGui::Button("Open model to compile...")) { if (ImGui::Button("Open model to compile...")) {
engine->get_imgui().open_dialog(true, [this](std::string path) { engine->get_imgui().open_dialog(true, [this](std::string path) {
model_path = path; model_path = path;
}); });
} }
if(ImGui::Button("Open data path...")) { if (ImGui::Button("Open data path...")) {
engine->get_imgui().open_dialog(true, [this](std::string path) { engine->get_imgui().open_dialog(
data_path = path; true,
}, true); [this](std::string path) {
data_path = path;
},
true);
} }
ImGui::Checkbox("Compile as static (remove transforms)", &flags.compile_static); ImGui::Checkbox("Compile as static (remove transforms)", &flags.compile_static);
ImGui::Checkbox("Export materials", &flags.export_materials); ImGui::Checkbox("Export materials", &flags.export_materials);
ImGui::Checkbox("Export animations", &flags.export_animations); ImGui::Checkbox("Export animations", &flags.export_animations);
if(!model_path.empty() && !data_path.empty()) { if (!model_path.empty() && !data_path.empty()) {
ImGui::Text("%s will be compiled for data path %s", model_path.c_str(), data_path.c_str()); ImGui::Text("%s will be compiled for data path %s", model_path.c_str(), data_path.c_str());
if(ImGui::Button("Compile")) { if (ImGui::Button("Compile")) {
auto name = model_path.substr(model_path.find_last_of("/") + 1, model_path.length()); auto name = model_path.substr(model_path.find_last_of("/") + 1, model_path.length());
name = name.substr(0, name.find_last_of(".")); name = name.substr(0, name.find_last_of("."));
compile_model(data_path + "/models/" + name + ".model"); compile_model(data_path + "/models/" + name + ".model");

View file

@ -1,8 +1,8 @@
add_executable(ShaderCompilerTool main.cpp) add_executable(ShaderCompilerTool main.cpp)
target_link_libraries(ShaderCompilerTool target_link_libraries(ShaderCompilerTool
PRIVATE PRIVATE
ShaderCompiler ShaderCompiler
Log Log
Utility) Utility)
set_engine_properties(ShaderCompilerTool) set_engine_properties(ShaderCompilerTool)
set_output_dir(ShaderCompilerTool) set_output_dir(ShaderCompilerTool)

View file

@ -36,10 +36,10 @@
#pragma once #pragma once
#include <vector>
#include <string>
#include <fstream>
#include <algorithm> #include <algorithm>
#include <fstream>
#include <string>
#include <vector>
#include <glslang/Public/ShaderLang.h> #include <glslang/Public/ShaderLang.h>
@ -48,19 +48,15 @@
// Can be overridden to customize. // Can be overridden to customize.
class DirStackFileIncluder : public glslang::TShader::Includer { class DirStackFileIncluder : public glslang::TShader::Includer {
public: public:
DirStackFileIncluder() : externalLocalDirectoryCount(0) { } DirStackFileIncluder() : externalLocalDirectoryCount(0) {}
virtual IncludeResult* includeLocal(const char* headerName, virtual IncludeResult*
const char* includerName, includeLocal(const char* headerName, const char* includerName, size_t inclusionDepth) override {
size_t inclusionDepth) override
{
return readLocalPath(headerName, includerName, (int)inclusionDepth); return readLocalPath(headerName, includerName, (int)inclusionDepth);
} }
virtual IncludeResult* includeSystem(const char* headerName, virtual IncludeResult*
const char* /*includerName*/, includeSystem(const char* headerName, const char* /*includerName*/, size_t /*inclusionDepth*/) override {
size_t /*inclusionDepth*/) override
{
return readSystemPath(headerName); return readSystemPath(headerName);
} }
@ -70,21 +66,19 @@ public:
// is checked. // is checked.
// - This only applies to the "local" form of #include. // - This only applies to the "local" form of #include.
// - Makes its own copy of the path. // - Makes its own copy of the path.
virtual void pushExternalLocalDirectory(const std::string& dir) virtual void pushExternalLocalDirectory(const std::string& dir) {
{
directoryStack.push_back(dir); directoryStack.push_back(dir);
externalLocalDirectoryCount = (int)directoryStack.size(); externalLocalDirectoryCount = (int)directoryStack.size();
} }
virtual void releaseInclude(IncludeResult* result) override virtual void releaseInclude(IncludeResult* result) override {
{
if (result != nullptr) { if (result != nullptr) {
delete [] static_cast<tUserDataElement*>(result->userData); delete[] static_cast<tUserDataElement*>(result->userData);
delete result; delete result;
} }
} }
virtual ~DirStackFileIncluder() override { } virtual ~DirStackFileIncluder() override {}
protected: protected:
typedef char tUserDataElement; typedef char tUserDataElement;
@ -93,8 +87,7 @@ protected:
// Search for a valid "local" path based on combining the stack of include // Search for a valid "local" path based on combining the stack of include
// directories and the nominal name of the header. // directories and the nominal name of the header.
virtual IncludeResult* readLocalPath(const char* headerName, const char* includerName, int depth) virtual IncludeResult* readLocalPath(const char* headerName, const char* includerName, int depth) {
{
// Discard popped include directories, and // Discard popped include directories, and
// initialize when at parse-time first level. // initialize when at parse-time first level.
directoryStack.resize(depth + externalLocalDirectoryCount); directoryStack.resize(depth + externalLocalDirectoryCount);
@ -117,15 +110,13 @@ protected:
// Search for a valid <system> path. // Search for a valid <system> path.
// Not implemented yet; returning nullptr signals failure to find. // Not implemented yet; returning nullptr signals failure to find.
virtual IncludeResult* readSystemPath(const char* /*headerName*/) const virtual IncludeResult* readSystemPath(const char* /*headerName*/) const {
{
return nullptr; return nullptr;
} }
// Do actual reading of the file, filling in a new include result. // Do actual reading of the file, filling in a new include result.
virtual IncludeResult* newIncludeResult(const std::string& path, std::ifstream& file, int length) const virtual IncludeResult* newIncludeResult(const std::string& path, std::ifstream& file, int length) const {
{ char* content = new tUserDataElement[length];
char* content = new tUserDataElement [length];
file.seekg(0, file.beg); file.seekg(0, file.beg);
file.read(content, length); file.read(content, length);
return new IncludeResult(path, content, length, content); return new IncludeResult(path, content, length, content);
@ -133,8 +124,7 @@ protected:
// If no path markers, return current working directory. // If no path markers, return current working directory.
// Otherwise, strip file name and return path leading up to it. // Otherwise, strip file name and return path leading up to it.
virtual std::string getDirectory(const std::string path) const virtual std::string getDirectory(const std::string path) const {
{
size_t last = path.find_last_of("/\\"); size_t last = path.find_last_of("/\\");
return last == std::string::npos ? "." : path.substr(0, last); return last == std::string::npos ? "." : path.substr(0, last);
} }

View file

@ -1,8 +1,8 @@
#include <sstream>
#include <filesystem> #include <filesystem>
#include <sstream>
#include "shadercompiler.hpp"
#include "log.hpp" #include "log.hpp"
#include "shadercompiler.hpp"
#include "string_utils.hpp" #include "string_utils.hpp"
bool has_extension(const std::filesystem::path& path, const std::string_view extension) { bool has_extension(const std::filesystem::path& path, const std::string_view extension) {
@ -10,7 +10,7 @@ bool has_extension(const std::filesystem::path& path, const std::string_view ext
} }
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
if(argc < 2) { if (argc < 2) {
prism::log("Not enough arguments!"); prism::log("Not enough arguments!");
return -1; return -1;
} }
@ -22,75 +22,70 @@ int main(int argc, char* argv[]) {
ShaderLanguage language = ShaderLanguage::SPIRV; ShaderLanguage language = ShaderLanguage::SPIRV;
std::string_view shader_language_string = argv[3]; std::string_view shader_language_string = argv[3];
if(shader_language_string == "spv") { if (shader_language_string == "spv") {
language = ShaderLanguage::SPIRV; language = ShaderLanguage::SPIRV;
} else if(shader_language_string == "msl") { } else if (shader_language_string == "msl") {
language = ShaderLanguage::MSL; language = ShaderLanguage::MSL;
} else if(shader_language_string == "glsl") { } else if (shader_language_string == "glsl") {
language = ShaderLanguage::GLSL; language = ShaderLanguage::GLSL;
} else if(shader_language_string == "hlsl") { } else if (shader_language_string == "hlsl") {
language = ShaderLanguage::HLSL; language = ShaderLanguage::HLSL;
} }
CompileOptions options; CompileOptions options;
std::string_view extra_options = argc > 4 ? argv[4] : ""; std::string_view extra_options = argc > 4 ? argv[4] : "";
if(extra_options == "mobile") if (extra_options == "mobile")
options.is_apple_mobile = true; options.is_apple_mobile = true;
std::ifstream t(source_path); std::ifstream t(source_path);
std::stringstream buffer; std::stringstream buffer;
buffer << t.rdbuf(); buffer << t.rdbuf();
if(has_extension(source_path, "nocompile")) { if (has_extension(source_path, "nocompile")) {
destination_path = remove_substring(destination_path.string(), ".nocompile"); // remove extension destination_path = remove_substring(destination_path.string(), ".nocompile"); // remove extension
std::ofstream out(destination_path); std::ofstream out(destination_path);
out << buffer.rdbuf(); out << buffer.rdbuf();
} else { } else {
ShaderStage stage = ShaderStage::Vertex; ShaderStage stage = ShaderStage::Vertex;
if(has_extension(source_path, ".vert")) if (has_extension(source_path, ".vert"))
stage = ShaderStage::Vertex; stage = ShaderStage::Vertex;
else if(has_extension(source_path, ".frag")) else if (has_extension(source_path, ".frag"))
stage = ShaderStage::Fragment; stage = ShaderStage::Fragment;
else if(has_extension(source_path, ".comp")) else if (has_extension(source_path, ".comp"))
stage = ShaderStage::Compute; stage = ShaderStage::Compute;
const auto compiled_source = shader_compiler.compile(ShaderLanguage::GLSL, stage, ShaderSource(buffer.str()), language, options); const auto compiled_source =
if(!compiled_source.has_value()) { shader_compiler.compile(ShaderLanguage::GLSL, stage, ShaderSource(buffer.str()), language, options);
if (!compiled_source.has_value()) {
prism::log("Error when compiling {}!", source_path.string()); prism::log("Error when compiling {}!", source_path.string());
return -1; return -1;
} }
switch(language) { switch (language) {
// right now, WGSL is outputted as SPIR-V with some WGSL compatibility stuff included // right now, WGSL is outputted as SPIR-V with some WGSL compatibility stuff included
case ShaderLanguage::SPIRV: case ShaderLanguage::SPIRV: {
{
const auto spirv = compiled_source->as_bytecode(); const auto spirv = compiled_source->as_bytecode();
std::ofstream out(destination_path, std::ios::binary); // remove .glsl std::ofstream out(destination_path, std::ios::binary); // remove .glsl
out.write((char*)spirv.data(), spirv.size() * sizeof(uint32_t)); out.write((char*)spirv.data(), spirv.size() * sizeof(uint32_t));
} } break;
break; case ShaderLanguage::MSL: {
case ShaderLanguage::MSL:
{
std::ofstream out(destination_path); // remove .glsl std::ofstream out(destination_path); // remove .glsl
out << compiled_source->as_string(); out << compiled_source->as_string();
} } break;
break; case ShaderLanguage::HLSL: {
case ShaderLanguage::HLSL:
{
std::ofstream out(destination_path); // remove .glsl std::ofstream out(destination_path); // remove .glsl
out << compiled_source->as_string(); out << compiled_source->as_string();
} } break;
break;
default: default:
break; break;
} }
} }
// TODO: output disabled for now, will have to expose in a better arg system // TODO: output disabled for now, will have to expose in a better arg system
//prism::log::info(System::Core, "Successfully written shader from {} to {}.", source_path, destination_path); // prism::log::info(System::Core, "Successfully written shader from {} to {}.", source_path, destination_path);
return 0; return 0;
} }