2020-08-11 12:07:21 -04:00
|
|
|
#include "prismeditor.hpp"
|
|
|
|
|
|
|
|
#include <imgui.h>
|
|
|
|
#include <imgui_stdlib.h>
|
|
|
|
#include <imgui_internal.h>
|
|
|
|
#include <nlohmann/json.hpp>
|
|
|
|
|
|
|
|
#include "engine.hpp"
|
|
|
|
#include "imguipass.hpp"
|
|
|
|
#include "file.hpp"
|
|
|
|
#include "json_conversions.hpp"
|
|
|
|
#include "platform.hpp"
|
|
|
|
#include "string_utils.hpp"
|
|
|
|
#include "sceneeditor.hpp"
|
|
|
|
#include "materialeditor.hpp"
|
|
|
|
#include "prefabeditor.hpp"
|
|
|
|
#include "log.hpp"
|
|
|
|
|
|
|
|
std::string get_filename(const std::string path) {
|
|
|
|
return path.substr(path.find_last_of("/") + 1, path.length());
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<Editor*> editors;
|
|
|
|
|
2021-04-19 12:23:18 -04:00
|
|
|
void app_main(prism::engine* engine) {
|
2020-08-11 12:07:21 -04:00
|
|
|
CommonEditor* editor = (CommonEditor*)engine->get_app();
|
|
|
|
|
|
|
|
platform::open_window("Prism Editor",
|
|
|
|
{editor->getDefaultX(),
|
|
|
|
editor->getDefaultY(),
|
|
|
|
static_cast<uint32_t>(editor->getDefaultWidth()),
|
|
|
|
static_cast<uint32_t>(editor->getDefaultHeight())},
|
|
|
|
WindowFlags::Resizable);
|
|
|
|
|
|
|
|
engine->update_physics = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
PrismEditor::PrismEditor() : CommonEditor("PrismEditor") {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void prepScene() {
|
|
|
|
auto scene = engine->get_scene();
|
|
|
|
|
|
|
|
auto camera = scene->add_object();
|
|
|
|
scene->get(camera).name = "editor camera";
|
|
|
|
scene->get(camera).editor_object = true;
|
|
|
|
|
|
|
|
scene->add<Camera>(camera);
|
|
|
|
|
2021-05-12 09:56:44 -04:00
|
|
|
camera_look_at(*scene, camera, prism::float3(0, 2, 3), prism::float3(0));
|
2020-08-11 12:07:21 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void prepThreePointLighting() {
|
|
|
|
auto scene = engine->get_scene();
|
2020-08-17 10:50:20 -04:00
|
|
|
|
|
|
|
auto probe = scene->add_object();
|
|
|
|
scene->add<EnvironmentProbe>(probe).is_sized = false;
|
2020-08-11 12:07:21 -04:00
|
|
|
|
2020-08-17 10:50:20 -04:00
|
|
|
auto sun_light = scene->add_object();
|
|
|
|
scene->get(sun_light).name = "sun light";
|
|
|
|
scene->get(sun_light).editor_object = true;
|
2020-08-11 12:07:21 -04:00
|
|
|
|
2021-05-12 09:56:44 -04:00
|
|
|
scene->get<Transform>(sun_light).position = prism::float3(15);
|
2020-08-17 10:50:20 -04:00
|
|
|
scene->add<Light>(sun_light).type = Light::Type::Sun;
|
|
|
|
scene->get<Light>(sun_light).power = 5.0f;
|
2021-05-12 10:47:44 -04:00
|
|
|
scene->get<Light>(sun_light).size = 0.2f;
|
2020-08-11 12:07:21 -04:00
|
|
|
|
2020-08-17 10:50:20 -04:00
|
|
|
scene->reset_shadows();
|
|
|
|
scene->reset_environment();
|
2020-08-11 12:07:21 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void prepPrefabScene() {
|
|
|
|
auto scene = engine->get_scene();
|
|
|
|
|
|
|
|
auto plane = scene->add_object();
|
|
|
|
scene->get(plane).name = "plane";
|
|
|
|
scene->get(plane).editor_object = true;
|
|
|
|
|
2021-05-12 09:56:44 -04:00
|
|
|
scene->get<Transform>(plane).position = prism::float3(0, -1, 0);
|
|
|
|
scene->get<Transform>(plane).scale = prism::float3(50);
|
2020-08-11 12:07:21 -04:00
|
|
|
|
2021-05-12 08:50:02 -04:00
|
|
|
scene->add<Renderable>(plane).mesh = assetm->get<Mesh>(prism::app_domain / "models/plane.model");
|
2020-08-11 12:07:21 -04:00
|
|
|
|
|
|
|
prepThreePointLighting();
|
|
|
|
}
|
|
|
|
|
|
|
|
Renderable* prepMaterialScene() {
|
|
|
|
auto scene = engine->get_scene();
|
|
|
|
|
|
|
|
auto plane = scene->add_object();
|
|
|
|
scene->get(plane).name = "plane";
|
|
|
|
scene->get(plane).editor_object = true;
|
|
|
|
|
2021-05-12 09:56:44 -04:00
|
|
|
scene->get<Transform>(plane).position = prism::float3(0, -1, 0);
|
|
|
|
scene->get<Transform>(plane).scale = prism::float3(50);
|
2020-08-11 12:07:21 -04:00
|
|
|
|
2021-05-12 08:50:02 -04:00
|
|
|
scene->add<Renderable>(plane).mesh = assetm->get<Mesh>(prism::app_domain / "models/plane.model");
|
|
|
|
scene->get<Renderable>(plane).materials.push_back(assetm->get<Material>(prism::app_domain / "materials/Material.material"));
|
2020-08-11 12:07:21 -04:00
|
|
|
|
2020-08-17 10:50:20 -04:00
|
|
|
auto sphere = scene->add_object();
|
|
|
|
scene->get(sphere).name = "sphere";
|
|
|
|
scene->get(sphere).editor_object = true;
|
2020-08-11 12:07:21 -04:00
|
|
|
|
2021-05-12 09:56:44 -04:00
|
|
|
scene->get<Transform>(sphere).rotation = euler_to_quat(prism::float3(radians(90.0f), 0, 0));
|
2020-08-17 10:50:20 -04:00
|
|
|
|
2021-05-12 08:50:02 -04:00
|
|
|
scene->add<Renderable>(sphere).mesh = assetm->get<Mesh>(prism::app_domain / "models/sphere.model");
|
2020-08-11 12:07:21 -04:00
|
|
|
|
|
|
|
prepThreePointLighting();
|
|
|
|
|
2020-08-17 10:50:20 -04:00
|
|
|
return &scene->get<Renderable>(sphere);
|
2020-08-11 12:07:21 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
struct OpenAssetRequest {
|
|
|
|
OpenAssetRequest(std::string p, bool is_r) : path(p), is_relative(is_r) {}
|
|
|
|
|
|
|
|
std::string path;
|
|
|
|
bool is_relative;
|
|
|
|
};
|
|
|
|
|
|
|
|
std::vector<OpenAssetRequest> open_requests;
|
|
|
|
|
|
|
|
void PrismEditor::setup_editor(Editor* editor) {
|
2021-02-16 19:22:32 -05:00
|
|
|
|
2020-08-11 12:07:21 -04:00
|
|
|
}
|
|
|
|
|
2021-05-12 09:05:56 -04:00
|
|
|
void PrismEditor::open_asset(const prism::path path) {
|
2020-08-11 12:07:21 -04:00
|
|
|
if(path.extension() == ".prefab") {
|
|
|
|
PrefabEditor* editor = new PrefabEditor();
|
2020-12-28 15:44:54 -05:00
|
|
|
editor->path = path.string();
|
2020-08-11 12:07:21 -04:00
|
|
|
setup_editor(editor);
|
|
|
|
|
|
|
|
engine->create_empty_scene();
|
|
|
|
editor->root_object = engine->add_prefab(*engine->get_scene(), path);
|
|
|
|
prepScene();
|
|
|
|
prepPrefabScene();
|
|
|
|
|
|
|
|
editor->scene = engine->get_scene();
|
|
|
|
|
|
|
|
editors.push_back(editor);
|
|
|
|
} else if(path.extension() == ".scene") {
|
|
|
|
SceneEditor* editor = new SceneEditor();
|
2020-12-28 15:44:54 -05:00
|
|
|
editor->path = path.string();
|
2020-08-11 12:07:21 -04:00
|
|
|
setup_editor(editor);
|
|
|
|
|
|
|
|
editor->scene = engine->load_scene(path);
|
|
|
|
prepScene();
|
|
|
|
|
|
|
|
editors.push_back(editor);
|
|
|
|
} else if(path.extension() == ".material") {
|
|
|
|
MaterialEditor* editor = new MaterialEditor();
|
2020-12-28 15:44:54 -05:00
|
|
|
editor->path = path.string();
|
2020-08-11 12:07:21 -04:00
|
|
|
setup_editor(editor);
|
|
|
|
|
|
|
|
engine->create_empty_scene();
|
|
|
|
prepScene();
|
|
|
|
editor->renderable = prepMaterialScene();
|
|
|
|
|
|
|
|
editor->material = assetm->get<Material>(path);
|
|
|
|
|
|
|
|
editor->setup_material();
|
|
|
|
|
|
|
|
editor->scene = engine->get_scene();
|
|
|
|
|
|
|
|
editors.push_back(editor);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-05 19:35:13 -05:00
|
|
|
void PrismEditor::renderEditor(GFXCommandBuffer* command_buffer) {
|
2021-02-17 00:15:59 -05:00
|
|
|
for(auto [id, render_target] : viewport_render_targets) {
|
|
|
|
engine->get_renderer()->render(command_buffer, render_target.scene, *render_target.target, -1);
|
2021-02-05 19:35:13 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-11 12:07:21 -04:00
|
|
|
void PrismEditor::drawUI() {
|
|
|
|
createDockArea();
|
|
|
|
|
|
|
|
auto dock_id = ImGui::GetID("dockspace");
|
|
|
|
|
|
|
|
ImGui::End();
|
|
|
|
|
|
|
|
if (ImGui::BeginMainMenuBar()) {
|
|
|
|
if (ImGui::BeginMenu("File")) {
|
|
|
|
if(ImGui::BeginMenu("New")) {
|
|
|
|
if(ImGui::MenuItem("Scene")) {
|
|
|
|
SceneEditor* editor = new SceneEditor();
|
|
|
|
editor->modified = true;
|
|
|
|
setup_editor(editor);
|
|
|
|
|
|
|
|
engine->create_empty_scene();
|
|
|
|
editor->scene = engine->get_scene();
|
|
|
|
prepScene();
|
|
|
|
|
|
|
|
editors.push_back(editor);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(ImGui::MenuItem("Prefab")) {
|
|
|
|
PrefabEditor* editor = new PrefabEditor();
|
|
|
|
editor->modified = true;
|
|
|
|
setup_editor(editor);
|
|
|
|
|
|
|
|
engine->create_empty_scene();
|
|
|
|
editor->scene = engine->get_scene();
|
|
|
|
prepScene();
|
|
|
|
|
|
|
|
editors.push_back(editor);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(ImGui::MenuItem("Material")) {
|
|
|
|
MaterialEditor* editor = new MaterialEditor();
|
|
|
|
editor->modified = true;
|
|
|
|
setup_editor(editor);
|
|
|
|
|
|
|
|
engine->create_empty_scene();
|
|
|
|
prepScene();
|
|
|
|
editor->material = assetm->add<Material>();
|
|
|
|
editor->renderable = prepMaterialScene();
|
|
|
|
editor->scene = engine->get_scene();
|
|
|
|
|
|
|
|
editor->setup_material();
|
|
|
|
|
|
|
|
editors.push_back(editor);
|
|
|
|
}
|
|
|
|
|
|
|
|
ImGui::EndMenu();
|
|
|
|
}
|
|
|
|
|
|
|
|
if(ImGui::MenuItem("Open", "CTRL+O")) {
|
2021-10-11 13:39:15 -04:00
|
|
|
engine->get_imgui().open_dialog(true, [this](std::string path) {
|
2020-08-11 12:07:21 -04:00
|
|
|
open_requests.emplace_back(path, false);
|
|
|
|
|
|
|
|
addOpenedFile(path);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
const auto& recents = getOpenedFiles();
|
|
|
|
if (ImGui::BeginMenu("Open Recent...", !recents.empty())) {
|
|
|
|
for (auto& file : recents) {
|
|
|
|
if (ImGui::MenuItem(file.c_str()))
|
|
|
|
open_requests.emplace_back(file, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
ImGui::Separator();
|
|
|
|
|
|
|
|
if (ImGui::MenuItem("Clear"))
|
|
|
|
clearOpenedFiles();
|
|
|
|
|
|
|
|
ImGui::EndMenu();
|
|
|
|
}
|
|
|
|
|
|
|
|
ImGui::Separator();
|
|
|
|
|
|
|
|
if(ImGui::MenuItem("Quit", "CTRL+Q"))
|
|
|
|
engine->quit();
|
|
|
|
|
|
|
|
ImGui::EndMenu();
|
|
|
|
}
|
|
|
|
|
|
|
|
ImGui::EndMainMenuBar();
|
|
|
|
}
|
|
|
|
|
|
|
|
for(auto& editor : editors) {
|
|
|
|
if(!editor->has_been_docked) {
|
|
|
|
ImGui::DockBuilderDockWindow(editor->get_window_title().c_str(), dock_id);
|
|
|
|
ImGui::DockBuilderFinish(dock_id);
|
|
|
|
|
|
|
|
editor->has_been_docked = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
const ImGuiID editor_dockspace = ImGui::GetID(editor);
|
|
|
|
|
|
|
|
if(ImGui::DockBuilderGetNode(editor_dockspace) == nullptr) {
|
|
|
|
const auto size = ImGui::GetMainViewport()->Size;
|
|
|
|
|
|
|
|
ImGui::DockBuilderRemoveNode(editor_dockspace);
|
|
|
|
ImGui::DockBuilderAddNode(editor_dockspace, ImGuiDockNodeFlags_DockSpace);
|
|
|
|
ImGui::DockBuilderSetNodeSize(editor_dockspace, size);
|
|
|
|
|
|
|
|
editor->setup_windows(editor_dockspace);
|
|
|
|
|
|
|
|
ImGui::DockBuilderFinish(editor_dockspace);
|
|
|
|
}
|
|
|
|
|
|
|
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
|
|
|
|
|
|
|
|
int window_flags = 0;
|
|
|
|
if(editor->has_menubar())
|
|
|
|
window_flags |= ImGuiWindowFlags_MenuBar;
|
|
|
|
|
|
|
|
if(editor->modified)
|
|
|
|
window_flags |= ImGuiWindowFlags_UnsavedDocument;
|
|
|
|
|
|
|
|
bool should_draw = ImGui::Begin(editor->get_window_title().c_str(), nullptr, window_flags);
|
|
|
|
|
|
|
|
ImGui::PopStyleVar();
|
|
|
|
|
|
|
|
ImGui::DockSpace(editor_dockspace, ImVec2(0.0f, 0.0f), ImGuiDockNodeFlags_None);
|
|
|
|
|
2021-02-16 19:22:32 -05:00
|
|
|
if(should_draw) {
|
|
|
|
/*debugPass = editor->debug_pass;
|
2020-08-11 12:07:21 -04:00
|
|
|
if(debugPass != nullptr)
|
2021-02-16 19:22:32 -05:00
|
|
|
debugPass->selected_object = selected_object;*/
|
2020-08-11 12:07:21 -04:00
|
|
|
|
|
|
|
engine->set_current_scene(editor->get_scene());
|
|
|
|
set_undo_stack(&editor->undo_stack);
|
|
|
|
editor->draw(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
ImGui::End();
|
|
|
|
}
|
|
|
|
|
|
|
|
utility::erase_if(editors, [](Editor* editor) {
|
|
|
|
return editor->wants_to_close;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
void PrismEditor::object_selected(Object object) {
|
|
|
|
selected_object = object;
|
|
|
|
}
|
|
|
|
|
|
|
|
void PrismEditor::asset_selected(std::filesystem::path path, AssetType) {
|
|
|
|
open_requests.emplace_back(path.string(), true);
|
|
|
|
}
|
|
|
|
|
|
|
|
void PrismEditor::updateEditor(float) {
|
|
|
|
for(auto [path, is_relative] : open_requests)
|
|
|
|
open_asset(path);
|
|
|
|
|
|
|
|
open_requests.clear();
|
|
|
|
}
|