2015-09-14 18:03:45 +02:00
|
|
|
#include "asset_browser.h"
|
2015-08-12 22:57:42 +02:00
|
|
|
#include "core/blob.h"
|
2015-10-07 20:22:56 +02:00
|
|
|
#include "core/command_line_parser.h"
|
2015-08-12 22:57:42 +02:00
|
|
|
#include "core/crc32.h"
|
|
|
|
#include "core/default_allocator.h"
|
2015-10-03 01:14:38 +02:00
|
|
|
#include "core/fs/file_system.h"
|
2015-08-12 22:57:42 +02:00
|
|
|
#include "core/input_system.h"
|
2015-09-29 22:21:43 +02:00
|
|
|
#include "core/log.h"
|
2015-09-27 11:34:00 +02:00
|
|
|
#include "core/mt/thread.h"
|
2015-09-13 12:00:25 +02:00
|
|
|
#include "core/path_utils.h"
|
2015-09-14 18:03:45 +02:00
|
|
|
#include "core/profiler.h"
|
2015-08-12 22:57:42 +02:00
|
|
|
#include "core/resource_manager.h"
|
2015-09-20 20:50:32 +02:00
|
|
|
#include "core/system.h"
|
2015-09-27 11:34:00 +02:00
|
|
|
#include "core/timer.h"
|
2015-11-13 16:52:42 +01:00
|
|
|
#include "debug/debug.h"
|
2015-09-12 14:51:13 +02:00
|
|
|
#include "editor/gizmo.h"
|
2015-09-19 11:38:53 +02:00
|
|
|
#include "editor/entity_template_system.h"
|
2015-09-12 14:51:13 +02:00
|
|
|
#include "editor/world_editor.h"
|
2015-08-12 22:57:42 +02:00
|
|
|
#include "engine.h"
|
2015-08-17 23:45:26 +02:00
|
|
|
#include "engine/plugin_manager.h"
|
2015-10-10 01:40:51 +02:00
|
|
|
#include "game_view.h"
|
2015-09-24 22:22:53 +02:00
|
|
|
#include "hierarchy_ui.h"
|
2015-09-14 18:03:45 +02:00
|
|
|
#include "import_asset_dialog.h"
|
|
|
|
#include "log_ui.h"
|
2015-09-29 22:21:43 +02:00
|
|
|
#include "metadata.h"
|
2015-09-29 02:36:24 +02:00
|
|
|
#include "ocornut-imgui/imgui.h"
|
2015-10-25 13:07:53 +01:00
|
|
|
#include "platform_interface.h"
|
2015-09-19 01:18:52 +02:00
|
|
|
#include "profiler_ui.h"
|
2015-09-21 11:43:31 +02:00
|
|
|
#include "property_grid.h"
|
2015-09-20 17:30:37 +02:00
|
|
|
#include "renderer/frame_buffer.h"
|
2015-08-17 23:45:26 +02:00
|
|
|
#include "renderer/material.h"
|
|
|
|
#include "renderer/pipeline.h"
|
|
|
|
#include "renderer/renderer.h"
|
|
|
|
#include "renderer/texture.h"
|
|
|
|
#include "renderer/transient_geometry.h"
|
2015-09-20 17:30:37 +02:00
|
|
|
#include "scene_view.h"
|
2015-09-29 02:36:24 +02:00
|
|
|
#include "settings.h"
|
2015-09-16 01:08:28 +02:00
|
|
|
#include "shader_compiler.h"
|
2015-10-27 20:40:00 +01:00
|
|
|
#include "shader_editor.h"
|
2015-09-24 19:11:53 +02:00
|
|
|
#include "universe/hierarchy.h"
|
2015-09-24 22:22:53 +02:00
|
|
|
#include "utils.h"
|
2015-08-12 22:57:42 +02:00
|
|
|
|
2015-10-01 02:07:22 +02:00
|
|
|
#include <bgfx/bgfx.h>
|
2015-10-25 13:07:53 +01:00
|
|
|
|
2015-08-12 22:57:42 +02:00
|
|
|
|
2015-11-14 00:25:08 +01:00
|
|
|
static void imGuiCallback(ImDrawData* draw_data);
|
2015-08-14 22:12:51 +02:00
|
|
|
|
|
|
|
|
2015-09-27 12:56:01 +02:00
|
|
|
class StudioApp
|
2015-08-12 22:57:42 +02:00
|
|
|
{
|
2015-08-12 23:21:39 +02:00
|
|
|
public:
|
2015-09-27 12:56:01 +02:00
|
|
|
StudioApp()
|
2015-09-29 02:36:24 +02:00
|
|
|
: m_is_entity_list_opened(true)
|
2015-09-14 18:03:45 +02:00
|
|
|
, m_finished(false)
|
2015-09-29 02:36:24 +02:00
|
|
|
, m_is_style_editor_opened(false)
|
2015-09-14 18:03:45 +02:00
|
|
|
, m_import_asset_dialog(nullptr)
|
2015-09-16 01:08:28 +02:00
|
|
|
, m_shader_compiler(nullptr)
|
2015-09-19 11:38:53 +02:00
|
|
|
, m_is_wireframe(false)
|
|
|
|
, m_is_entity_template_list_opened(false)
|
|
|
|
, m_selected_template_name(m_allocator)
|
2015-09-20 23:24:38 +02:00
|
|
|
, m_profiler_ui(nullptr)
|
|
|
|
, m_asset_browser(nullptr)
|
2015-09-21 11:43:31 +02:00
|
|
|
, m_property_grid(nullptr)
|
2015-09-29 02:36:24 +02:00
|
|
|
, m_actions(m_allocator)
|
2015-09-29 22:21:43 +02:00
|
|
|
, m_metadata(m_allocator)
|
2015-10-09 13:15:32 +02:00
|
|
|
, m_gui_pipeline(nullptr)
|
2015-10-11 21:18:33 +02:00
|
|
|
, m_is_welcome_screen_opened(true)
|
2015-10-27 20:40:00 +01:00
|
|
|
, m_shader_editor(nullptr)
|
2015-11-04 23:00:34 +01:00
|
|
|
, m_editor(nullptr)
|
2015-08-12 22:57:42 +02:00
|
|
|
{
|
2015-09-29 02:36:24 +02:00
|
|
|
m_entity_list_search[0] = '\0';
|
2015-10-20 20:37:59 +02:00
|
|
|
m_template_name[0] = '\0';
|
2015-08-12 22:57:42 +02:00
|
|
|
}
|
|
|
|
|
2015-10-01 02:07:22 +02:00
|
|
|
|
2015-09-29 20:48:26 +02:00
|
|
|
void autosave()
|
|
|
|
{
|
|
|
|
m_time_to_autosave = float(m_settings.m_autosave_time);
|
|
|
|
if (!m_editor->getUniversePath().isValid()) return;
|
|
|
|
|
|
|
|
char filename[Lumix::MAX_PATH_LENGTH];
|
|
|
|
Lumix::copyString(filename, m_editor->getUniversePath().c_str());
|
|
|
|
Lumix::catString(filename, "_autosave.unv");
|
|
|
|
|
|
|
|
m_editor->saveUniverse(Lumix::Path(filename), false);
|
|
|
|
}
|
|
|
|
|
2015-08-14 22:12:51 +02:00
|
|
|
|
2015-09-14 18:03:45 +02:00
|
|
|
void update()
|
|
|
|
{
|
2015-09-25 21:44:46 +02:00
|
|
|
PROFILE_FUNCTION();
|
2015-09-14 18:03:45 +02:00
|
|
|
float time_delta = m_editor->getEngine().getLastTimeDelta();
|
|
|
|
|
2015-09-29 20:48:26 +02:00
|
|
|
m_time_to_autosave -= time_delta;
|
2015-10-03 01:14:38 +02:00
|
|
|
if (m_time_to_autosave < 0) autosave();
|
2015-09-29 20:48:26 +02:00
|
|
|
|
2015-09-21 11:43:31 +02:00
|
|
|
m_editor->update();
|
|
|
|
m_sceneview.update();
|
|
|
|
m_engine->update(*m_editor->getUniverseContext());
|
|
|
|
|
2015-09-20 20:28:51 +02:00
|
|
|
m_asset_browser->update();
|
2015-09-16 01:08:28 +02:00
|
|
|
m_shader_compiler->update(time_delta);
|
2015-09-14 18:03:45 +02:00
|
|
|
m_log_ui->update(time_delta);
|
2015-09-21 11:43:31 +02:00
|
|
|
|
|
|
|
m_gui_pipeline->render();
|
|
|
|
onGUI();
|
|
|
|
Lumix::Renderer* renderer =
|
|
|
|
static_cast<Lumix::Renderer*>(m_engine->getPluginManager().getPlugin("renderer"));
|
2015-09-27 12:56:01 +02:00
|
|
|
|
2015-09-21 11:43:31 +02:00
|
|
|
renderer->frame();
|
2015-09-14 18:03:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-10-11 21:18:33 +02:00
|
|
|
void showWelcomeScreen()
|
|
|
|
{
|
|
|
|
ImGuiWindowFlags flags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize |
|
|
|
|
ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoSavedSettings;
|
2015-10-25 13:07:53 +01:00
|
|
|
ImVec2 size((float)PlatformInterface::getWindowWidth(),
|
|
|
|
(float)PlatformInterface::getWindowHeight());
|
2015-10-11 21:18:33 +02:00
|
|
|
if (ImGui::Begin("Welcome", nullptr, size, -1, flags))
|
|
|
|
{
|
|
|
|
ImGui::Text("Welcome to Lumix Studio");
|
|
|
|
|
|
|
|
ImVec2 half_size = ImGui::GetContentRegionAvail();
|
|
|
|
half_size.x = half_size.x * 0.5f - ImGui::GetStyle().FramePadding.x;
|
|
|
|
half_size.y *= 0.75f;
|
|
|
|
auto right_pos = ImGui::GetCursorPos();
|
|
|
|
right_pos.x += half_size.x + ImGui::GetStyle().FramePadding.x;
|
|
|
|
if (ImGui::BeginChild("left", half_size, true))
|
|
|
|
{
|
|
|
|
if (ImGui::Button("New Universe")) m_is_welcome_screen_opened = false;
|
|
|
|
|
|
|
|
ImGui::Separator();
|
|
|
|
ImGui::Text("Open universe:");
|
|
|
|
ImGui::Indent();
|
|
|
|
auto& universes = m_asset_browser->getResources(AssetBrowser::UNIVERSE);
|
|
|
|
for (auto& univ : universes)
|
|
|
|
{
|
|
|
|
if (ImGui::MenuItem(univ.c_str()))
|
|
|
|
{
|
|
|
|
m_editor->loadUniverse(univ);
|
|
|
|
setTitle(univ.c_str());
|
|
|
|
m_is_welcome_screen_opened = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ImGui::Unindent();
|
|
|
|
}
|
|
|
|
ImGui::EndChild();
|
|
|
|
|
|
|
|
ImGui::SetCursorPos(right_pos);
|
|
|
|
|
|
|
|
if (ImGui::BeginChild("right", half_size, true))
|
|
|
|
{
|
2015-11-02 16:30:34 +01:00
|
|
|
ImGui::Text("Version 0.18. - News");
|
2015-11-08 16:40:07 +01:00
|
|
|
ImGui::BulletText("Basic particle system");
|
2015-11-02 16:30:34 +01:00
|
|
|
ImGui::Separator();
|
2015-10-11 21:18:33 +02:00
|
|
|
ImGui::Text("Version 0.17. - News");
|
2015-10-31 01:29:10 +01:00
|
|
|
ImGui::BulletText("Back button in the asset browser");
|
|
|
|
ImGui::BulletText("Grass culling");
|
|
|
|
ImGui::BulletText("Importing compressed embedded textures");
|
|
|
|
ImGui::BulletText("Euler angles");
|
|
|
|
ImGui::BulletText("Textures relative to root");
|
2015-10-21 22:22:47 +02:00
|
|
|
ImGui::BulletText("Painting entities - align with normal");
|
|
|
|
ImGui::BulletText("Painting entities - random x and z rotation");
|
2015-10-19 00:14:16 +02:00
|
|
|
ImGui::BulletText("Lua properties with types");
|
|
|
|
ImGui::BulletText("Moving the Light Texel-Sized Increments");
|
2015-10-18 14:49:46 +02:00
|
|
|
ImGui::BulletText("Terrain brush for removing entities");
|
|
|
|
ImGui::BulletText("Improved shadows on terrain");
|
2015-10-17 00:50:51 +02:00
|
|
|
ImGui::BulletText("Fog height");
|
|
|
|
ImGui::BulletText("Bitmap to heightmap convertor");
|
2015-10-16 00:11:18 +02:00
|
|
|
ImGui::BulletText("LOD preview");
|
|
|
|
ImGui::BulletText("New gizmo");
|
2015-10-12 10:58:22 +02:00
|
|
|
ImGui::BulletText("Orbit camera");
|
2015-10-11 21:18:33 +02:00
|
|
|
ImGui::BulletText("Welcome screen");
|
|
|
|
ImGui::BulletText("Visualization of physical contorller");
|
|
|
|
ImGui::BulletText("Game view fixed");
|
|
|
|
ImGui::Separator();
|
|
|
|
if (ImGui::Button("Download new version"))
|
|
|
|
{
|
|
|
|
Lumix::shellExecuteOpen(
|
|
|
|
"https://github.com/nem0/lumixengine_data/archive/master.zip");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ImGui::Button("Show major releases"))
|
|
|
|
{
|
|
|
|
Lumix::shellExecuteOpen("https://github.com/nem0/LumixEngine/releases");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ImGui::Button("Show latest commits"))
|
|
|
|
{
|
|
|
|
Lumix::shellExecuteOpen("https://github.com/nem0/LumixEngine/commits/master");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ImGui::Button("Show issues"))
|
|
|
|
{
|
|
|
|
Lumix::shellExecuteOpen("https://github.com/nem0/lumixengine/issues");
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
ImGui::EndChild();
|
|
|
|
|
|
|
|
if (ImGui::Button("Close")) m_is_welcome_screen_opened = false;
|
|
|
|
}
|
|
|
|
ImGui::End();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-08-14 22:12:51 +02:00
|
|
|
void onGUI()
|
|
|
|
{
|
2015-09-25 21:44:46 +02:00
|
|
|
PROFILE_FUNCTION();
|
2015-10-03 01:14:38 +02:00
|
|
|
|
2015-10-10 01:40:51 +02:00
|
|
|
if (!m_gui_pipeline_source->isReady()) return;
|
2015-10-03 01:14:38 +02:00
|
|
|
|
2015-08-14 22:12:51 +02:00
|
|
|
ImGuiIO& io = ImGui::GetIO();
|
2015-10-25 13:07:53 +01:00
|
|
|
io.DisplaySize = ImVec2((float)PlatformInterface::getWindowWidth(),
|
|
|
|
(float)PlatformInterface::getWindowHeight());
|
2015-08-14 22:12:51 +02:00
|
|
|
io.DeltaTime = m_engine->getLastTimeDelta();
|
2015-10-25 13:07:53 +01:00
|
|
|
io.KeyCtrl = PlatformInterface::isPressed((int)PlatformInterface::Keys::CONTROL);
|
|
|
|
io.KeyShift = PlatformInterface::isPressed((int)PlatformInterface::Keys::SHIFT);
|
|
|
|
io.KeyAlt = PlatformInterface::isPressed((int)PlatformInterface::Keys::ALT);
|
|
|
|
io.KeysDown[(int)PlatformInterface::Keys::ALT] = io.KeyAlt;
|
|
|
|
io.KeysDown[(int)PlatformInterface::Keys::SHIFT] = io.KeyShift;
|
|
|
|
io.KeysDown[(int)PlatformInterface::Keys::CONTROL] = io.KeyCtrl;
|
2015-08-14 22:12:51 +02:00
|
|
|
|
2015-10-25 13:07:53 +01:00
|
|
|
PlatformInterface::setCursor(io.MouseDrawCursor ? PlatformInterface::Cursor::NONE
|
|
|
|
: PlatformInterface::Cursor::DEFAULT);
|
2015-08-14 22:12:51 +02:00
|
|
|
|
|
|
|
ImGui::NewFrame();
|
2015-09-21 21:39:28 +02:00
|
|
|
|
2015-10-11 21:18:33 +02:00
|
|
|
if (m_is_welcome_screen_opened)
|
|
|
|
{
|
|
|
|
showWelcomeScreen();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
showMainMenu();
|
|
|
|
m_profiler_ui->onGUI();
|
|
|
|
m_asset_browser->onGUI();
|
|
|
|
m_log_ui->onGUI();
|
|
|
|
m_import_asset_dialog->onGUI();
|
|
|
|
m_property_grid->onGUI();
|
|
|
|
showEntityList();
|
|
|
|
showEntityTemplateList();
|
|
|
|
m_sceneview.onGUI();
|
|
|
|
m_hierarchy_ui.onGUI();
|
|
|
|
m_gameview.onGui();
|
2015-11-06 16:38:57 +01:00
|
|
|
m_shader_editor->onGUI();
|
2015-10-11 21:18:33 +02:00
|
|
|
if (m_is_style_editor_opened) ImGui::ShowStyleEditor();
|
|
|
|
m_settings.onGUI(&m_actions[0], m_actions.size());
|
|
|
|
}
|
2015-09-16 01:08:28 +02:00
|
|
|
|
2015-09-14 18:03:45 +02:00
|
|
|
ImGui::Render();
|
|
|
|
}
|
|
|
|
|
2015-09-21 21:39:28 +02:00
|
|
|
|
2015-09-27 22:06:58 +02:00
|
|
|
void setTitle(const char* title)
|
|
|
|
{
|
|
|
|
char tmp[100];
|
|
|
|
Lumix::copyString(tmp, "Lumix Studio - ");
|
|
|
|
Lumix::catString(tmp, title);
|
2015-10-25 13:07:53 +01:00
|
|
|
PlatformInterface::setWindowTitle(tmp);
|
2015-09-27 22:06:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-09-29 02:36:24 +02:00
|
|
|
static void getShortcut(const Action& action, char* buf, int max_size)
|
|
|
|
{
|
|
|
|
buf[0] = 0;
|
|
|
|
for (int i = 0; i < Lumix::lengthOf(action.shortcut); ++i)
|
|
|
|
{
|
2015-10-01 02:07:22 +02:00
|
|
|
char str[30];
|
2015-10-25 13:07:53 +01:00
|
|
|
PlatformInterface::getKeyName(action.shortcut[i], str, Lumix::lengthOf(str));
|
2015-09-29 02:36:24 +02:00
|
|
|
if (str[0] == 0) return;
|
|
|
|
if (i > 0) Lumix::catString(buf, max_size, " - ");
|
|
|
|
Lumix::catString(buf, max_size, str);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-10-01 02:07:22 +02:00
|
|
|
void doMenuItem(Action& a, bool selected, bool enabled)
|
2015-09-29 02:36:24 +02:00
|
|
|
{
|
2015-10-01 02:07:22 +02:00
|
|
|
char buf[20];
|
|
|
|
getShortcut(a, buf, sizeof(buf));
|
|
|
|
if (ImGui::MenuItem(a.label, buf, selected, enabled))
|
2015-09-29 02:36:24 +02:00
|
|
|
{
|
2015-10-01 02:07:22 +02:00
|
|
|
a.func.invoke();
|
2015-09-29 02:36:24 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void save()
|
|
|
|
{
|
2015-09-29 20:48:26 +02:00
|
|
|
m_time_to_autosave = float(m_settings.m_autosave_time);
|
2015-09-29 02:36:24 +02:00
|
|
|
if (m_editor->getUniversePath().isValid())
|
|
|
|
{
|
2015-09-29 20:48:26 +02:00
|
|
|
m_editor->saveUniverse(m_editor->getUniversePath(), true);
|
2015-09-29 02:36:24 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
char filename[Lumix::MAX_PATH_LENGTH];
|
|
|
|
if (Lumix::getSaveFilename(
|
|
|
|
filename, sizeof(filename), "Universes\0*.unv\0", "unv"))
|
|
|
|
{
|
2015-09-29 20:48:26 +02:00
|
|
|
m_editor->saveUniverse(Lumix::Path(filename), true);
|
2015-09-29 02:36:24 +02:00
|
|
|
setTitle(filename);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void saveAs()
|
|
|
|
{
|
2015-09-29 20:48:26 +02:00
|
|
|
m_time_to_autosave = float(m_settings.m_autosave_time);
|
2015-09-29 02:36:24 +02:00
|
|
|
char filename[Lumix::MAX_PATH_LENGTH];
|
|
|
|
if (Lumix::getSaveFilename(filename, sizeof(filename), "Universes\0*.unv\0", "unv"))
|
|
|
|
{
|
2015-09-29 20:48:26 +02:00
|
|
|
m_editor->saveUniverse(Lumix::Path(filename), true);
|
2015-09-29 02:36:24 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-10-25 13:07:53 +01:00
|
|
|
void exit() { m_finished = true; }
|
2015-09-29 20:48:26 +02:00
|
|
|
|
|
|
|
void newUniverse()
|
|
|
|
{
|
|
|
|
m_editor->newUniverse();
|
|
|
|
m_time_to_autosave = float(m_settings.m_autosave_time);
|
|
|
|
}
|
|
|
|
|
2015-11-02 16:30:34 +01:00
|
|
|
void undo() { m_shader_editor->isFocused() ? m_shader_editor->undo() : m_editor->undo(); }
|
|
|
|
void redo() { m_shader_editor->isFocused() ? m_shader_editor->redo() :m_editor->redo(); }
|
2015-09-29 02:36:24 +02:00
|
|
|
void copy() { m_editor->copyEntity(); }
|
|
|
|
void paste() { m_editor->pasteEntity(); }
|
2015-10-12 10:58:22 +02:00
|
|
|
void toggleOrbitCamera() { m_editor->setOrbitCamera(!m_editor->isOrbitCamera()); }
|
2015-10-15 20:53:13 +02:00
|
|
|
void togglePivotMode() { m_editor->getGizmo().togglePivot(); }
|
2015-09-29 02:36:24 +02:00
|
|
|
void toggleCoordSystem() { m_editor->getGizmo().toggleCoordSystem(); }
|
|
|
|
void createEntity() { m_editor->addEntity(); }
|
|
|
|
void showEntities() { m_editor->showEntities(); }
|
|
|
|
void hideEntities() { m_editor->hideEntities(); }
|
|
|
|
void toggleMeasure() { m_editor->toggleMeasure(); }
|
2015-10-20 21:46:13 +02:00
|
|
|
void snapDown() { m_editor->snapDown(); }
|
2015-09-29 02:36:24 +02:00
|
|
|
void lookAtSelected() { m_editor->lookAtSelected(); }
|
|
|
|
void toggleStats() { m_gui_pipeline->toggleStats(); }
|
|
|
|
|
2015-10-20 21:46:13 +02:00
|
|
|
void autosnapDown()
|
|
|
|
{
|
|
|
|
auto& gizmo = m_editor->getGizmo();
|
|
|
|
gizmo.setAutosnapDown(!gizmo.isAutosnapDown());
|
|
|
|
}
|
2015-09-29 02:36:24 +02:00
|
|
|
|
2015-10-15 20:53:13 +02:00
|
|
|
void toggleGizmoMode()
|
|
|
|
{
|
|
|
|
auto& gizmo = m_editor->getGizmo();
|
|
|
|
if (gizmo.getMode() == Lumix::Gizmo::Mode::TRANSLATE)
|
|
|
|
{
|
|
|
|
gizmo.setMode(Lumix::Gizmo::Mode::ROTATE);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gizmo.setMode(Lumix::Gizmo::Mode::TRANSLATE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-09-29 02:36:24 +02:00
|
|
|
void setWireframe()
|
|
|
|
{
|
|
|
|
m_is_wireframe = !m_is_wireframe;
|
|
|
|
m_sceneview.setWireframe(m_is_wireframe);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void destroyEntity()
|
|
|
|
{
|
|
|
|
auto& selected_entities = m_editor->getSelectedEntities();
|
|
|
|
if (selected_entities.empty()) return;
|
|
|
|
m_editor->destroyEntities(&selected_entities[0], selected_entities.size());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-09-29 20:48:26 +02:00
|
|
|
void loadAndExecuteCommands()
|
|
|
|
{
|
|
|
|
char filename[Lumix::MAX_PATH_LENGTH];
|
|
|
|
if (Lumix::getOpenFilename(filename, Lumix::lengthOf(filename), "JSON files\0*.json\0"))
|
|
|
|
{
|
|
|
|
m_editor->executeUndoStack(Lumix::Path(filename));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void saveUndoStack()
|
|
|
|
{
|
|
|
|
char filename[Lumix::MAX_PATH_LENGTH];
|
|
|
|
if (Lumix::getSaveFilename(filename, Lumix::lengthOf(filename), "JSON files\0*.json\0", "json"))
|
|
|
|
{
|
|
|
|
m_editor->saveUndoStack(Lumix::Path(filename));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-10-01 02:07:22 +02:00
|
|
|
template <void (StudioApp::*func)()>
|
|
|
|
void addAction(const char* label, const char* name)
|
|
|
|
{
|
|
|
|
auto* a = LUMIX_NEW(m_editor->getAllocator(), Action)(label, name);
|
|
|
|
a->func.bind<StudioApp, func>(this);
|
|
|
|
m_actions.push(a);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template <void (StudioApp::*func)()>
|
|
|
|
void addAction(const char* label, const char* name, int shortcut0, int shortcut1, int shortcut2)
|
|
|
|
{
|
|
|
|
auto* a = LUMIX_NEW(m_editor->getAllocator(), Action)(
|
|
|
|
label, name, shortcut0, shortcut1, shortcut2);
|
|
|
|
a->func.bind<StudioApp, func>(this);
|
|
|
|
m_actions.push(a);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Action& getAction(const char* name)
|
|
|
|
{
|
|
|
|
for (auto* a : m_actions)
|
|
|
|
{
|
2015-11-12 17:54:02 +01:00
|
|
|
if (Lumix::compareString(a->name, name) == 0) return *a;
|
2015-10-01 02:07:22 +02:00
|
|
|
}
|
|
|
|
ASSERT(false);
|
|
|
|
return *m_actions[0];
|
|
|
|
}
|
|
|
|
|
2015-11-02 16:30:34 +01:00
|
|
|
|
2015-09-14 18:03:45 +02:00
|
|
|
void showMainMenu()
|
|
|
|
{
|
2015-09-19 11:38:53 +02:00
|
|
|
bool is_any_entity_selected = !m_editor->getSelectedEntities().empty();
|
2015-08-14 22:12:51 +02:00
|
|
|
if (ImGui::BeginMainMenuBar())
|
|
|
|
{
|
|
|
|
if (ImGui::BeginMenu("File"))
|
|
|
|
{
|
2015-10-01 02:07:22 +02:00
|
|
|
doMenuItem(getAction("newUniverse"), false, true);
|
2015-09-14 18:03:45 +02:00
|
|
|
if (ImGui::BeginMenu("Open"))
|
2015-09-12 14:51:13 +02:00
|
|
|
{
|
2015-09-27 12:56:01 +02:00
|
|
|
auto& universes = m_asset_browser->getResources(AssetBrowser::UNIVERSE);
|
2015-09-14 18:03:45 +02:00
|
|
|
for (auto& univ : universes)
|
|
|
|
{
|
|
|
|
if (ImGui::MenuItem(univ.c_str()))
|
|
|
|
{
|
2015-09-29 20:48:26 +02:00
|
|
|
m_time_to_autosave = float(m_settings.m_autosave_time);
|
2015-09-14 18:03:45 +02:00
|
|
|
m_editor->loadUniverse(univ);
|
2015-09-27 22:06:58 +02:00
|
|
|
setTitle(univ.c_str());
|
2015-09-14 18:03:45 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
ImGui::EndMenu();
|
2015-09-12 14:51:13 +02:00
|
|
|
}
|
2015-10-01 02:07:22 +02:00
|
|
|
doMenuItem(getAction("save"), false, true);
|
|
|
|
doMenuItem(getAction("saveAs"), false, true);
|
|
|
|
doMenuItem(getAction("exit"), false, true);
|
2015-09-14 18:03:45 +02:00
|
|
|
|
2015-08-14 22:12:51 +02:00
|
|
|
ImGui::EndMenu();
|
|
|
|
}
|
2015-09-12 14:51:13 +02:00
|
|
|
|
|
|
|
if (ImGui::BeginMenu("Edit"))
|
|
|
|
{
|
2015-10-01 02:07:22 +02:00
|
|
|
doMenuItem(getAction("undo"), false, m_editor->canUndo());
|
|
|
|
doMenuItem(getAction("redo"), false, m_editor->canRedo());
|
2015-09-19 11:38:53 +02:00
|
|
|
ImGui::Separator();
|
2015-10-01 02:07:22 +02:00
|
|
|
doMenuItem(getAction("copy"), false, is_any_entity_selected);
|
|
|
|
doMenuItem(getAction("paste"), false, m_editor->canPasteEntity());
|
2015-09-19 11:38:53 +02:00
|
|
|
ImGui::Separator();
|
2015-10-12 10:58:22 +02:00
|
|
|
doMenuItem(getAction("orbitCamera"),
|
|
|
|
m_editor->isOrbitCamera(),
|
|
|
|
is_any_entity_selected || m_editor->isOrbitCamera());
|
2015-10-15 20:53:13 +02:00
|
|
|
doMenuItem(getAction("toggleGizmoMode"), false, is_any_entity_selected);
|
2015-10-01 02:07:22 +02:00
|
|
|
doMenuItem(getAction("togglePivotMode"), false, is_any_entity_selected);
|
2015-10-15 20:53:13 +02:00
|
|
|
doMenuItem(getAction("toggleCoordSystem"), false, is_any_entity_selected);
|
2015-09-19 11:38:53 +02:00
|
|
|
if (ImGui::BeginMenu("Select"))
|
|
|
|
{
|
2015-09-27 12:56:01 +02:00
|
|
|
if (ImGui::MenuItem("Same mesh", nullptr, nullptr, is_any_entity_selected))
|
2015-09-19 11:38:53 +02:00
|
|
|
m_editor->selectEntitiesWithSameMesh();
|
|
|
|
ImGui::EndMenu();
|
|
|
|
}
|
2015-09-12 14:51:13 +02:00
|
|
|
ImGui::EndMenu();
|
|
|
|
}
|
2015-09-14 18:03:45 +02:00
|
|
|
|
2015-09-19 11:38:53 +02:00
|
|
|
if (ImGui::BeginMenu("Entity"))
|
|
|
|
{
|
2015-10-01 02:07:22 +02:00
|
|
|
doMenuItem(getAction("createEntity"), false, true);
|
|
|
|
doMenuItem(getAction("destroyEntity"), false, is_any_entity_selected);
|
2015-09-19 11:38:53 +02:00
|
|
|
|
|
|
|
if (ImGui::BeginMenu("Create template", is_any_entity_selected))
|
|
|
|
{
|
|
|
|
static char name[255] = "";
|
|
|
|
ImGui::InputText("Name##templatename", name, sizeof(name));
|
|
|
|
if (ImGui::Button("Create"))
|
|
|
|
{
|
|
|
|
auto entity = m_editor->getSelectedEntities()[0];
|
|
|
|
auto& system = m_editor->getEntityTemplateSystem();
|
|
|
|
system.createTemplateFromEntity(name, entity);
|
|
|
|
ImGui::CloseCurrentPopup();
|
|
|
|
}
|
|
|
|
ImGui::EndMenu();
|
|
|
|
}
|
|
|
|
if (ImGui::MenuItem("Instantiate template",
|
2015-09-27 12:56:01 +02:00
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
m_selected_template_name.length() > 0))
|
2015-09-19 11:38:53 +02:00
|
|
|
{
|
|
|
|
Lumix::Vec3 pos = m_editor->getCameraRaycastHit();
|
|
|
|
m_editor->getEntityTemplateSystem().createInstance(
|
|
|
|
m_selected_template_name.c_str(), pos);
|
|
|
|
}
|
2015-09-29 02:36:24 +02:00
|
|
|
|
2015-10-01 02:07:22 +02:00
|
|
|
doMenuItem(getAction("showEntities"), false, is_any_entity_selected);
|
|
|
|
doMenuItem(getAction("hideEntities"), false, is_any_entity_selected);
|
2015-09-19 11:38:53 +02:00
|
|
|
ImGui::EndMenu();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-09-13 12:00:25 +02:00
|
|
|
if (ImGui::BeginMenu("Tools"))
|
|
|
|
{
|
2015-10-01 02:07:22 +02:00
|
|
|
doMenuItem(getAction("toggleGameMode"), m_editor->isGameMode(), true);
|
|
|
|
doMenuItem(getAction("toggleMeasure"), m_editor->isMeasureToolActive(), true);
|
2015-10-20 21:46:13 +02:00
|
|
|
doMenuItem(getAction("snapDown"), false, is_any_entity_selected);
|
|
|
|
doMenuItem(getAction("autosnapDown"), m_editor->getGizmo().isAutosnapDown(), true);
|
2015-09-29 20:48:26 +02:00
|
|
|
if (ImGui::MenuItem("Save commands")) saveUndoStack();
|
|
|
|
if (ImGui::MenuItem("Load commands")) loadAndExecuteCommands();
|
2015-09-20 17:30:37 +02:00
|
|
|
|
2015-09-19 01:18:52 +02:00
|
|
|
ImGui::MenuItem("Import asset", nullptr, &m_import_asset_dialog->m_is_opened);
|
2015-09-14 18:03:45 +02:00
|
|
|
ImGui::EndMenu();
|
|
|
|
}
|
|
|
|
|
2015-09-19 11:38:53 +02:00
|
|
|
|
2015-09-14 18:03:45 +02:00
|
|
|
if (ImGui::BeginMenu("View"))
|
|
|
|
{
|
2015-10-01 02:07:22 +02:00
|
|
|
doMenuItem(getAction("lookAtSelected"), false, is_any_entity_selected);
|
|
|
|
doMenuItem(getAction("setWireframe"), m_is_wireframe, true);
|
|
|
|
doMenuItem(getAction("toggleStats"), false, true);
|
2015-09-19 11:38:53 +02:00
|
|
|
if (ImGui::BeginMenu("Windows"))
|
|
|
|
{
|
|
|
|
ImGui::MenuItem("Asset browser", nullptr, &m_asset_browser->m_is_opened);
|
2015-09-29 02:36:24 +02:00
|
|
|
ImGui::MenuItem("Entity list", nullptr, &m_is_entity_list_opened);
|
2015-09-19 11:38:53 +02:00
|
|
|
ImGui::MenuItem("Entity templates", nullptr, &m_is_entity_template_list_opened);
|
2015-10-10 01:40:51 +02:00
|
|
|
ImGui::MenuItem("Game view", nullptr, &m_gameview.m_is_opened);
|
2015-09-24 22:22:53 +02:00
|
|
|
ImGui::MenuItem("Hierarchy", nullptr, &m_hierarchy_ui.m_is_opened);
|
2015-09-19 11:38:53 +02:00
|
|
|
ImGui::MenuItem("Log", nullptr, &m_log_ui->m_is_opened);
|
2015-09-20 23:24:38 +02:00
|
|
|
ImGui::MenuItem("Profiler", nullptr, &m_profiler_ui->m_is_opened);
|
2015-09-21 11:43:31 +02:00
|
|
|
ImGui::MenuItem("Properties", nullptr, &m_property_grid->m_is_opened);
|
2015-09-29 02:36:24 +02:00
|
|
|
ImGui::MenuItem("Settings", nullptr, &m_settings.m_is_opened);
|
2015-11-06 16:38:57 +01:00
|
|
|
ImGui::MenuItem("Shader editor", nullptr, &m_shader_editor->m_is_opened);
|
2015-09-29 02:36:24 +02:00
|
|
|
ImGui::MenuItem("Style editor", nullptr, &m_is_style_editor_opened);
|
2015-09-19 11:38:53 +02:00
|
|
|
ImGui::EndMenu();
|
|
|
|
}
|
2015-09-13 12:00:25 +02:00
|
|
|
ImGui::EndMenu();
|
|
|
|
}
|
2015-09-20 20:28:51 +02:00
|
|
|
StringBuilder<100> stats("FPS: ");
|
2015-09-21 21:26:49 +02:00
|
|
|
stats << m_engine->getFPS();
|
2015-09-20 20:28:51 +02:00
|
|
|
auto stats_size = ImGui::CalcTextSize(stats);
|
|
|
|
ImGui::SameLine(ImGui::GetContentRegionMax().x - stats_size.x);
|
|
|
|
ImGui::Text(stats);
|
2015-09-12 14:51:13 +02:00
|
|
|
|
2015-08-14 22:12:51 +02:00
|
|
|
ImGui::EndMainMenuBar();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-09-27 12:56:01 +02:00
|
|
|
void toggleGameMode() { m_editor->toggleGameMode(); }
|
2015-09-13 12:00:25 +02:00
|
|
|
|
|
|
|
|
2015-09-19 11:38:53 +02:00
|
|
|
void showEntityTemplateList()
|
|
|
|
{
|
|
|
|
if (!m_is_entity_template_list_opened) return;
|
|
|
|
|
|
|
|
if (ImGui::Begin("Entity templates", &m_is_entity_template_list_opened))
|
|
|
|
{
|
2015-10-20 20:37:59 +02:00
|
|
|
if (m_editor->getSelectedEntities().size() == 1)
|
|
|
|
{
|
|
|
|
ImGui::InputText("Template name", m_template_name, Lumix::lengthOf(m_template_name));
|
|
|
|
|
|
|
|
if (ImGui::Button("Create from selected"))
|
|
|
|
{
|
|
|
|
auto entity = m_editor->getSelectedEntities()[0];
|
|
|
|
auto& system = m_editor->getEntityTemplateSystem();
|
|
|
|
system.createTemplateFromEntity(m_template_name, entity);
|
|
|
|
}
|
|
|
|
ImGui::Separator();
|
|
|
|
}
|
|
|
|
ImGui::Text("Templates:");
|
2015-09-19 11:38:53 +02:00
|
|
|
auto& template_system = m_editor->getEntityTemplateSystem();
|
|
|
|
|
|
|
|
for (auto& template_name : template_system.getTemplateNames())
|
|
|
|
{
|
|
|
|
bool b = m_selected_template_name == template_name;
|
|
|
|
if (ImGui::Selectable(template_name.c_str(), &b))
|
|
|
|
{
|
|
|
|
m_selected_template_name = template_name;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ImGui::End();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-09-13 12:00:25 +02:00
|
|
|
void showEntityList()
|
|
|
|
{
|
2015-09-29 02:36:24 +02:00
|
|
|
if (!m_is_entity_list_opened) return;
|
2015-09-19 01:18:52 +02:00
|
|
|
|
2015-09-29 02:36:24 +02:00
|
|
|
if (ImGui::Begin("Entity list", &m_is_entity_list_opened))
|
2015-09-13 12:00:25 +02:00
|
|
|
{
|
|
|
|
if (ImGui::Button("Create entity"))
|
|
|
|
{
|
|
|
|
m_editor->addEntity();
|
|
|
|
}
|
|
|
|
auto* universe = m_editor->getUniverse();
|
2015-09-29 02:36:24 +02:00
|
|
|
int scroll_to = -1;
|
2015-09-21 21:39:28 +02:00
|
|
|
|
2015-09-29 02:36:24 +02:00
|
|
|
if (ImGui::InputText("Search", m_entity_list_search, sizeof(m_entity_list_search)))
|
2015-09-13 12:00:25 +02:00
|
|
|
{
|
2015-09-29 02:36:24 +02:00
|
|
|
for (int i = 0, c = universe->getEntityCount(); i < c; ++i)
|
2015-09-13 12:00:25 +02:00
|
|
|
{
|
2015-09-29 02:36:24 +02:00
|
|
|
static char buf[1024];
|
|
|
|
auto entity = universe->getEntityFromDenseIdx(i);
|
2015-09-24 22:22:53 +02:00
|
|
|
getEntityListDisplayName(*m_editor, buf, sizeof(buf), entity);
|
2015-09-29 02:36:24 +02:00
|
|
|
if (Lumix::stristr(buf, m_entity_list_search) != nullptr)
|
2015-09-14 18:03:45 +02:00
|
|
|
{
|
2015-09-29 02:36:24 +02:00
|
|
|
scroll_to = i;
|
|
|
|
break;
|
2015-09-14 18:03:45 +02:00
|
|
|
}
|
2015-09-13 12:00:25 +02:00
|
|
|
}
|
|
|
|
}
|
2015-09-29 02:36:24 +02:00
|
|
|
ImGui::Separator();
|
|
|
|
|
|
|
|
struct ListBoxData
|
|
|
|
{
|
|
|
|
Lumix::WorldEditor* m_editor;
|
|
|
|
Lumix::Universe* universe;
|
|
|
|
char buffer[1024];
|
|
|
|
static bool itemsGetter(void* data, int idx, const char** txt)
|
|
|
|
{
|
|
|
|
auto* d = static_cast<ListBoxData*>(data);
|
|
|
|
auto entity = d->universe->getEntityFromDenseIdx(idx);
|
|
|
|
getEntityListDisplayName(*d->m_editor, d->buffer, sizeof(d->buffer), entity);
|
|
|
|
*txt = d->buffer;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
ListBoxData data;
|
|
|
|
data.universe = universe;
|
|
|
|
data.m_editor = m_editor;
|
|
|
|
static int current_item;
|
|
|
|
if (ImGui::ListBox("Entities",
|
|
|
|
¤t_item,
|
|
|
|
scroll_to,
|
|
|
|
&ListBoxData::itemsGetter,
|
|
|
|
&data,
|
|
|
|
universe->getEntityCount(),
|
|
|
|
15))
|
|
|
|
{
|
|
|
|
auto e = universe->getEntityFromDenseIdx(current_item);
|
|
|
|
m_editor->selectEntities(&e, 1);
|
|
|
|
};
|
2015-09-13 12:00:25 +02:00
|
|
|
}
|
|
|
|
ImGui::End();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-09-29 02:36:24 +02:00
|
|
|
void saveSettings()
|
|
|
|
{
|
|
|
|
m_settings.m_is_asset_browser_opened = m_asset_browser->m_is_opened;
|
|
|
|
m_settings.m_is_entity_list_opened = m_is_entity_list_opened;
|
|
|
|
m_settings.m_is_entity_template_list_opened = m_is_entity_template_list_opened;
|
2015-10-10 01:40:51 +02:00
|
|
|
m_settings.m_is_gameview_opened = m_gameview.m_is_opened;
|
2015-09-29 02:36:24 +02:00
|
|
|
m_settings.m_is_hierarchy_opened = m_hierarchy_ui.m_is_opened;
|
|
|
|
m_settings.m_is_log_opened = m_log_ui->m_is_opened;
|
|
|
|
m_settings.m_is_profiler_opened = m_profiler_ui->m_is_opened;
|
|
|
|
m_settings.m_is_properties_opened = m_property_grid->m_is_opened;
|
2015-11-06 16:38:57 +01:00
|
|
|
m_settings.m_is_shader_editor_opened = m_shader_editor->m_is_opened;
|
2015-09-29 02:36:24 +02:00
|
|
|
m_settings.m_is_style_editor_opened = m_is_style_editor_opened;
|
|
|
|
|
|
|
|
m_settings.save(&m_actions[0], m_actions.size());
|
2015-09-29 22:21:43 +02:00
|
|
|
|
|
|
|
if (!m_metadata.save())
|
|
|
|
{
|
|
|
|
Lumix::g_log_warning.log("studio") << "Could not save metadata";
|
|
|
|
}
|
2015-09-29 02:36:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-08-14 22:12:51 +02:00
|
|
|
void shutdown()
|
|
|
|
{
|
2015-09-29 02:36:24 +02:00
|
|
|
saveSettings();
|
|
|
|
|
2015-10-01 02:07:22 +02:00
|
|
|
for (auto* a : m_actions)
|
|
|
|
{
|
2015-11-11 23:25:44 +01:00
|
|
|
LUMIX_DELETE(m_editor->getAllocator(), a);
|
2015-10-01 02:07:22 +02:00
|
|
|
}
|
|
|
|
m_actions.clear();
|
|
|
|
|
2015-08-14 22:12:51 +02:00
|
|
|
shutdownImGui();
|
|
|
|
|
2015-11-11 23:25:44 +01:00
|
|
|
LUMIX_DELETE(m_allocator, m_profiler_ui);
|
|
|
|
LUMIX_DELETE(m_allocator, m_asset_browser);
|
|
|
|
LUMIX_DELETE(m_allocator, m_log_ui);
|
|
|
|
LUMIX_DELETE(m_allocator, m_property_grid);
|
|
|
|
LUMIX_DELETE(m_allocator, m_import_asset_dialog);
|
|
|
|
LUMIX_DELETE(m_allocator, m_shader_compiler);
|
|
|
|
LUMIX_DELETE(m_allocator, m_shader_editor);
|
2015-09-21 21:39:28 +02:00
|
|
|
Lumix::WorldEditor::destroy(m_editor, m_allocator);
|
2015-09-20 20:28:51 +02:00
|
|
|
m_sceneview.shutdown();
|
2015-10-10 01:40:51 +02:00
|
|
|
m_gameview.shutdown();
|
2015-09-20 17:30:37 +02:00
|
|
|
Lumix::PipelineInstance::destroy(m_gui_pipeline);
|
|
|
|
m_gui_pipeline_source->getResourceManager()
|
2015-08-14 22:12:51 +02:00
|
|
|
.get(Lumix::ResourceManager::PIPELINE)
|
2015-09-20 17:30:37 +02:00
|
|
|
->unload(*m_gui_pipeline_source);
|
2015-09-21 21:39:28 +02:00
|
|
|
Lumix::Engine::destroy(m_engine, m_allocator);
|
2015-08-14 22:12:51 +02:00
|
|
|
m_engine = nullptr;
|
2015-09-20 17:30:37 +02:00
|
|
|
m_gui_pipeline = nullptr;
|
|
|
|
m_gui_pipeline_source = nullptr;
|
2015-09-12 14:51:13 +02:00
|
|
|
m_editor = nullptr;
|
2015-10-28 20:27:57 +01:00
|
|
|
m_shader_editor = nullptr;
|
2015-10-08 21:36:25 +02:00
|
|
|
|
2015-10-25 13:07:53 +01:00
|
|
|
PlatformInterface::shutdown();
|
2015-08-14 22:12:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void shutdownImGui()
|
|
|
|
{
|
|
|
|
ImGui::Shutdown();
|
2015-09-21 21:39:28 +02:00
|
|
|
|
2015-08-14 22:12:51 +02:00
|
|
|
Lumix::Texture* texture = m_material->getTexture(0);
|
|
|
|
m_material->setTexture(0, nullptr);
|
|
|
|
texture->destroy();
|
2015-11-11 23:25:44 +01:00
|
|
|
LUMIX_DELETE(m_allocator, texture);
|
2015-08-14 22:12:51 +02:00
|
|
|
|
2015-09-27 12:56:01 +02:00
|
|
|
m_material->getResourceManager().get(Lumix::ResourceManager::MATERIAL)->unload(*m_material);
|
2015-08-14 22:12:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-10-08 21:36:25 +02:00
|
|
|
void initIMGUI()
|
2015-08-14 22:12:51 +02:00
|
|
|
{
|
2015-09-21 22:35:36 +02:00
|
|
|
ImGuiIO& io = ImGui::GetIO();
|
|
|
|
io.Fonts->AddFontFromFileTTF("editor/VeraMono.ttf", 13);
|
|
|
|
|
2015-08-14 22:12:51 +02:00
|
|
|
m_decl.begin()
|
|
|
|
.add(bgfx::Attrib::Position, 2, bgfx::AttribType::Float)
|
|
|
|
.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float)
|
|
|
|
.add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true)
|
|
|
|
.end();
|
|
|
|
|
2015-10-25 13:07:53 +01:00
|
|
|
io.KeyMap[ImGuiKey_Tab] = (int)PlatformInterface::Keys::TAB;
|
|
|
|
io.KeyMap[ImGuiKey_LeftArrow] = (int)PlatformInterface::Keys::LEFT;
|
|
|
|
io.KeyMap[ImGuiKey_RightArrow] = (int)PlatformInterface::Keys::RIGHT;
|
|
|
|
io.KeyMap[ImGuiKey_UpArrow] = (int)PlatformInterface::Keys::UP;
|
|
|
|
io.KeyMap[ImGuiKey_DownArrow] = (int)PlatformInterface::Keys::DOWN;
|
|
|
|
io.KeyMap[ImGuiKey_PageUp] = (int)PlatformInterface::Keys::PAGE_UP;
|
|
|
|
io.KeyMap[ImGuiKey_PageDown] = (int)PlatformInterface::Keys::PAGE_DOWN;
|
|
|
|
io.KeyMap[ImGuiKey_Home] = (int)PlatformInterface::Keys::HOME;
|
|
|
|
io.KeyMap[ImGuiKey_End] = (int)PlatformInterface::Keys::END;
|
|
|
|
io.KeyMap[ImGuiKey_Delete] = (int)PlatformInterface::Keys::DEL;
|
|
|
|
io.KeyMap[ImGuiKey_Backspace] = (int)PlatformInterface::Keys::BACKSPACE;
|
|
|
|
io.KeyMap[ImGuiKey_Enter] = (int)PlatformInterface::Keys::ENTER;
|
|
|
|
io.KeyMap[ImGuiKey_Escape] = (int)PlatformInterface::Keys::ESCAPE;
|
2015-08-14 22:12:51 +02:00
|
|
|
io.KeyMap[ImGuiKey_A] = 'A';
|
|
|
|
io.KeyMap[ImGuiKey_C] = 'C';
|
|
|
|
io.KeyMap[ImGuiKey_V] = 'V';
|
|
|
|
io.KeyMap[ImGuiKey_X] = 'X';
|
|
|
|
io.KeyMap[ImGuiKey_Y] = 'Y';
|
|
|
|
io.KeyMap[ImGuiKey_Z] = 'Z';
|
|
|
|
|
2015-10-24 14:05:24 +02:00
|
|
|
io.RenderDrawListsFn = ::imGuiCallback;
|
2015-08-14 22:12:51 +02:00
|
|
|
|
|
|
|
unsigned char* pixels;
|
|
|
|
int width, height;
|
|
|
|
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
|
2015-10-08 21:36:25 +02:00
|
|
|
auto* material_manager =
|
|
|
|
m_engine->getResourceManager().get(Lumix::ResourceManager::MATERIAL);
|
|
|
|
auto* resource = material_manager->load(Lumix::Path("models/imgui.mat"));
|
|
|
|
m_material = static_cast<Lumix::Material*>(resource);
|
2015-08-14 22:12:51 +02:00
|
|
|
|
2015-10-03 01:14:38 +02:00
|
|
|
Lumix::Texture* texture = LUMIX_NEW(m_allocator, Lumix::Texture)(
|
2015-08-14 22:12:51 +02:00
|
|
|
Lumix::Path("font"), m_engine->getResourceManager(), m_allocator);
|
|
|
|
|
|
|
|
texture->create(width, height, pixels);
|
|
|
|
m_material->setTexture(0, texture);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-09-12 14:51:13 +02:00
|
|
|
void onUniverseCreated()
|
|
|
|
{
|
2015-09-20 17:30:37 +02:00
|
|
|
auto* scene =
|
|
|
|
static_cast<Lumix::RenderScene*>(m_editor->getScene(Lumix::crc32("renderer")));
|
2015-09-12 14:51:13 +02:00
|
|
|
|
2015-09-20 17:30:37 +02:00
|
|
|
m_gui_pipeline->setScene(scene);
|
2015-09-12 14:51:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-09-20 17:30:37 +02:00
|
|
|
void onUniverseDestroyed()
|
2015-09-12 14:51:13 +02:00
|
|
|
{
|
2015-09-20 17:30:37 +02:00
|
|
|
m_gui_pipeline->setScene(nullptr);
|
2015-09-12 14:51:13 +02:00
|
|
|
}
|
|
|
|
|
2015-09-21 21:39:28 +02:00
|
|
|
|
2015-09-29 02:36:24 +02:00
|
|
|
void loadSettings()
|
|
|
|
{
|
|
|
|
m_settings.load(&m_actions[0], m_actions.size());
|
|
|
|
|
|
|
|
m_asset_browser->m_is_opened = m_settings.m_is_asset_browser_opened;
|
|
|
|
m_is_entity_list_opened = m_settings.m_is_entity_list_opened;
|
|
|
|
m_is_entity_template_list_opened = m_settings.m_is_entity_template_list_opened;
|
2015-10-10 01:40:51 +02:00
|
|
|
m_gameview.m_is_opened = m_settings.m_is_gameview_opened;
|
2015-09-29 02:36:24 +02:00
|
|
|
m_hierarchy_ui.m_is_opened = m_settings.m_is_hierarchy_opened;
|
|
|
|
m_log_ui->m_is_opened = m_settings.m_is_log_opened;
|
|
|
|
m_profiler_ui->m_is_opened = m_settings.m_is_profiler_opened;
|
|
|
|
m_property_grid->m_is_opened = m_settings.m_is_properties_opened;
|
2015-11-06 16:38:57 +01:00
|
|
|
m_shader_editor->m_is_opened = m_settings.m_is_shader_editor_opened;
|
2015-09-29 02:36:24 +02:00
|
|
|
m_is_style_editor_opened = m_settings.m_is_style_editor_opened;
|
|
|
|
|
|
|
|
if (m_settings.m_is_maximized)
|
|
|
|
{
|
2015-10-25 13:07:53 +01:00
|
|
|
PlatformInterface::maximizeWindow();
|
2015-09-29 02:36:24 +02:00
|
|
|
}
|
|
|
|
else if (m_settings.m_window.w > 0)
|
|
|
|
{
|
2015-10-25 13:07:53 +01:00
|
|
|
PlatformInterface::moveWindow(m_settings.m_window.x,
|
2015-09-29 02:36:24 +02:00
|
|
|
m_settings.m_window.y,
|
|
|
|
m_settings.m_window.w,
|
2015-10-25 13:07:53 +01:00
|
|
|
m_settings.m_window.h);
|
2015-09-29 02:36:24 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-10-01 02:07:22 +02:00
|
|
|
void addActions()
|
|
|
|
{
|
|
|
|
addAction<&StudioApp::newUniverse>("New", "newUniverse");
|
2015-10-25 13:07:53 +01:00
|
|
|
addAction<&StudioApp::save>("Save", "save", (int)PlatformInterface::Keys::CONTROL, 'S', -1);
|
|
|
|
addAction<&StudioApp::saveAs>("Save As",
|
|
|
|
"saveAs",
|
|
|
|
(int)PlatformInterface::Keys::CONTROL,
|
|
|
|
(int)PlatformInterface::Keys::SHIFT,
|
|
|
|
'S');
|
|
|
|
addAction<&StudioApp::exit>("Exit", "exit", (int)PlatformInterface::Keys::CONTROL, 'X', -1);
|
|
|
|
|
|
|
|
addAction<&StudioApp::redo>("Redo",
|
|
|
|
"redo",
|
|
|
|
(int)PlatformInterface::Keys::CONTROL,
|
|
|
|
(int)PlatformInterface::Keys::SHIFT,
|
|
|
|
'Z');
|
|
|
|
addAction<&StudioApp::undo>("Undo", "undo", (int)PlatformInterface::Keys::CONTROL, 'Z', -1);
|
|
|
|
addAction<&StudioApp::copy>("Copy", "copy", (int)PlatformInterface::Keys::CONTROL, 'C', -1);
|
|
|
|
addAction<&StudioApp::paste>(
|
|
|
|
"Paste", "paste", (int)PlatformInterface::Keys::CONTROL, 'V', -1);
|
2015-10-12 10:58:22 +02:00
|
|
|
addAction<&StudioApp::toggleOrbitCamera>("Orbit camera", "orbitCamera");
|
2015-10-15 20:53:13 +02:00
|
|
|
addAction<&StudioApp::toggleGizmoMode>("Translate/Rotate", "toggleGizmoMode");
|
2015-10-01 02:07:22 +02:00
|
|
|
addAction<&StudioApp::togglePivotMode>("Center/Pivot", "togglePivotMode");
|
|
|
|
addAction<&StudioApp::toggleCoordSystem>("Local/Global", "toggleCoordSystem");
|
|
|
|
|
|
|
|
addAction<&StudioApp::createEntity>("Create", "createEntity");
|
2015-10-25 13:07:53 +01:00
|
|
|
addAction<&StudioApp::destroyEntity>(
|
|
|
|
"Destroy", "destroyEntity", (int)PlatformInterface::Keys::DEL, -1, -1);
|
2015-10-01 02:07:22 +02:00
|
|
|
addAction<&StudioApp::showEntities>("Show", "showEntities");
|
|
|
|
addAction<&StudioApp::hideEntities>("Hide", "hideEntities");
|
|
|
|
|
|
|
|
addAction<&StudioApp::toggleGameMode>("Game Mode", "toggleGameMode");
|
|
|
|
addAction<&StudioApp::toggleMeasure>("Toggle measure", "toggleMeasure");
|
2015-10-20 21:46:13 +02:00
|
|
|
addAction<&StudioApp::autosnapDown>("Autosnap down", "autosnapDown");
|
|
|
|
addAction<&StudioApp::snapDown>("Snap down", "snapDown");
|
2015-10-01 02:07:22 +02:00
|
|
|
addAction<&StudioApp::lookAtSelected>("Look at selected", "lookAtSelected");
|
|
|
|
|
|
|
|
addAction<&StudioApp::setWireframe>("Wireframe", "setWireframe");
|
|
|
|
addAction<&StudioApp::toggleStats>("Stats", "toggleStats");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-10-07 20:22:56 +02:00
|
|
|
void loadUserPlugins()
|
|
|
|
{
|
|
|
|
char cmd_line[2048];
|
|
|
|
Lumix::getCommandLine(cmd_line, Lumix::lengthOf(cmd_line));
|
|
|
|
|
|
|
|
Lumix::CommandLineParser parser(cmd_line);
|
|
|
|
auto& plugin_manager = m_editor->getEngine().getPluginManager();
|
|
|
|
while (parser.next())
|
|
|
|
{
|
|
|
|
if (!parser.currentEquals("-plugin")) continue;
|
|
|
|
if (!parser.next()) break;
|
|
|
|
|
|
|
|
char tmp[Lumix::MAX_PATH_LENGTH];
|
|
|
|
parser.getCurrent(tmp, Lumix::lengthOf(tmp));
|
|
|
|
bool loaded = plugin_manager.load(tmp) != nullptr;
|
|
|
|
if (!loaded)
|
|
|
|
{
|
|
|
|
Lumix::g_log_error.log("init") << "Could not load plugin " << tmp
|
|
|
|
<< " requested by command line";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-10-08 21:36:25 +02:00
|
|
|
void run()
|
|
|
|
{
|
|
|
|
Lumix::Timer* timer = Lumix::Timer::create(m_allocator);
|
|
|
|
while (!m_finished)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
timer->tick();
|
|
|
|
PROFILE_BLOCK("all");
|
|
|
|
float frame_time;
|
|
|
|
{
|
|
|
|
PROFILE_BLOCK("tick");
|
2015-10-25 13:07:53 +01:00
|
|
|
m_finished = !PlatformInterface::processSystemEvents();
|
2015-10-08 21:36:25 +02:00
|
|
|
update();
|
|
|
|
frame_time = timer->tick();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (frame_time < 1 / 60.0f)
|
|
|
|
{
|
|
|
|
PROFILE_BLOCK("sleep");
|
2015-11-11 21:54:25 +01:00
|
|
|
Lumix::MT::sleep(Lumix::uint32(1000 / 60.0f - frame_time * 1000));
|
2015-10-08 21:36:25 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
Lumix::g_profiler.frame();
|
|
|
|
Lumix::g_profiler.checkRecording();
|
|
|
|
}
|
|
|
|
Lumix::Timer::destroy(timer);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void checkWorkingDirector()
|
|
|
|
{
|
|
|
|
if (!Lumix::dirExists("shaders"))
|
|
|
|
{
|
|
|
|
Lumix::messageBox("Shaders directory not found, please check working directory.");
|
|
|
|
}
|
|
|
|
else if (!Lumix::dirExists("bin"))
|
|
|
|
{
|
|
|
|
Lumix::messageBox("Bin directory not found, please check working directory.");
|
|
|
|
}
|
|
|
|
else if (!Lumix::dirExists("pipelines"))
|
|
|
|
{
|
|
|
|
Lumix::messageBox("Pipelines directory not found, please check working directory.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-10-25 13:07:53 +01:00
|
|
|
struct SystemEventHandler : public PlatformInterface::SystemEventHandler
|
2015-08-12 23:21:39 +02:00
|
|
|
{
|
2015-10-25 13:07:53 +01:00
|
|
|
void onWindowTransformed(int x, int y, int w, int h) override
|
|
|
|
{
|
|
|
|
m_app->onWindowTransformed(x, y, w, h);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void onMouseLeftWindow() override { m_app->clearInputs(); }
|
2015-11-04 14:05:45 +01:00
|
|
|
|
2015-10-25 13:07:53 +01:00
|
|
|
|
|
|
|
void onMouseMove(int x, int y, int rel_x, int rel_y) override
|
|
|
|
{
|
|
|
|
m_mouse_x = x;
|
|
|
|
m_mouse_y = y;
|
|
|
|
auto& input_system = m_app->m_editor->getEngine().getInputSystem();
|
|
|
|
input_system.injectMouseXMove(float(rel_x));
|
|
|
|
input_system.injectMouseYMove(float(rel_y));
|
|
|
|
|
|
|
|
if (m_app->m_gameview.isMouseCaptured()) return;
|
|
|
|
|
|
|
|
m_app->m_sceneview.onMouseMove(x, y, rel_x, rel_y);
|
|
|
|
|
|
|
|
ImGuiIO& io = ImGui::GetIO();
|
|
|
|
io.MousePos.x = (float)x;
|
|
|
|
io.MousePos.y = (float)y;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void onMouseWheel(int amount) override
|
|
|
|
{
|
|
|
|
ImGui::GetIO().MouseWheel = amount / 600.0f;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void onMouseButtonDown(MouseButton button) override
|
|
|
|
{
|
|
|
|
switch (button)
|
|
|
|
{
|
|
|
|
case PlatformInterface::SystemEventHandler::MouseButton::LEFT:
|
|
|
|
m_app->m_editor->setAdditiveSelection(ImGui::GetIO().KeyCtrl);
|
|
|
|
if (!m_app->m_sceneview.onMouseDown(
|
|
|
|
m_mouse_x, m_mouse_y, Lumix::MouseButton::LEFT) &&
|
|
|
|
!m_app->m_gameview.isMouseCaptured())
|
|
|
|
{
|
|
|
|
ImGui::GetIO().MouseDown[0] = true;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case PlatformInterface::SystemEventHandler::MouseButton::RIGHT:
|
2015-11-04 14:05:45 +01:00
|
|
|
if(!m_app->m_sceneview.onMouseDown(
|
|
|
|
m_mouse_x, m_mouse_y, Lumix::MouseButton::RIGHT) &&
|
2015-10-25 13:07:53 +01:00
|
|
|
!m_app->m_gameview.isMouseCaptured())
|
|
|
|
{
|
|
|
|
ImGui::GetIO().MouseDown[1] = true;
|
|
|
|
}
|
|
|
|
break;
|
2015-11-04 14:05:45 +01:00
|
|
|
case PlatformInterface::SystemEventHandler::MouseButton::MIDDLE:
|
|
|
|
if(!m_app->m_sceneview.onMouseDown(
|
|
|
|
m_mouse_x, m_mouse_y, Lumix::MouseButton::MIDDLE) &&
|
|
|
|
!m_app->m_gameview.isMouseCaptured())
|
|
|
|
{
|
|
|
|
ImGui::GetIO().MouseDown[2] = true;
|
|
|
|
}
|
|
|
|
break;
|
2015-10-25 13:07:53 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void onMouseButtonUp(MouseButton button) override
|
|
|
|
{
|
|
|
|
switch (button)
|
|
|
|
{
|
|
|
|
case PlatformInterface::SystemEventHandler::MouseButton::LEFT:
|
|
|
|
m_app->m_sceneview.onMouseUp(Lumix::MouseButton::LEFT);
|
|
|
|
ImGui::GetIO().MouseDown[0] = false;
|
|
|
|
break;
|
|
|
|
case PlatformInterface::SystemEventHandler::MouseButton::RIGHT:
|
|
|
|
m_app->m_sceneview.onMouseUp(Lumix::MouseButton::RIGHT);
|
|
|
|
ImGui::GetIO().MouseDown[1] = false;
|
2015-11-04 14:05:45 +01:00
|
|
|
break;
|
|
|
|
case PlatformInterface::SystemEventHandler::MouseButton::MIDDLE:
|
|
|
|
m_app->m_sceneview.onMouseUp(Lumix::MouseButton::MIDDLE);
|
|
|
|
ImGui::GetIO().MouseDown[2] = false;
|
2015-10-25 13:07:53 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void onKeyDown(int key) override
|
|
|
|
{
|
|
|
|
ImGui::GetIO().KeysDown[key] = true;
|
|
|
|
m_app->checkShortcuts();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void onKeyUp(int key) override
|
|
|
|
{
|
|
|
|
ImGui::GetIO().KeysDown[key] = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void onChar(int key)
|
|
|
|
{
|
|
|
|
ImGui::GetIO().AddInputCharacter(key);
|
|
|
|
}
|
|
|
|
|
2015-10-24 14:28:03 +02:00
|
|
|
|
2015-10-25 13:07:53 +01:00
|
|
|
int m_mouse_x;
|
|
|
|
int m_mouse_y;
|
|
|
|
StudioApp* m_app;
|
|
|
|
};
|
2015-10-24 14:28:03 +02:00
|
|
|
|
|
|
|
|
2015-10-25 13:07:53 +01:00
|
|
|
SystemEventHandler m_handler;
|
|
|
|
|
|
|
|
|
|
|
|
void init()
|
2015-10-24 14:28:03 +02:00
|
|
|
{
|
|
|
|
checkWorkingDirector();
|
2015-10-25 13:07:53 +01:00
|
|
|
m_handler.m_app = this;
|
2015-11-04 23:00:34 +01:00
|
|
|
PlatformInterface::createWindow(nullptr);
|
2015-10-24 14:28:03 +02:00
|
|
|
|
2015-08-17 23:45:26 +02:00
|
|
|
m_engine = Lumix::Engine::create(nullptr, m_allocator);
|
2015-10-25 13:07:53 +01:00
|
|
|
char current_dir[Lumix::MAX_PATH_LENGTH];
|
|
|
|
PlatformInterface::getCurrentDirectory(current_dir, Lumix::lengthOf(current_dir));
|
2015-09-21 21:26:49 +02:00
|
|
|
m_editor = Lumix::WorldEditor::create(current_dir, *m_engine, m_allocator);
|
2015-10-07 20:22:56 +02:00
|
|
|
loadUserPlugins();
|
|
|
|
|
2015-10-01 02:07:22 +02:00
|
|
|
addActions();
|
|
|
|
|
2015-10-28 20:27:57 +01:00
|
|
|
m_asset_browser = LUMIX_NEW(m_allocator, AssetBrowser)(*m_editor, m_metadata);
|
|
|
|
m_property_grid = LUMIX_NEW(m_allocator, PropertyGrid)(*m_editor, *m_asset_browser, m_actions);
|
2015-09-21 21:26:49 +02:00
|
|
|
auto engine_allocator = static_cast<Lumix::Debug::Allocator*>(&m_engine->getAllocator());
|
2015-10-28 20:27:57 +01:00
|
|
|
m_profiler_ui = LUMIX_NEW(m_allocator, ProfilerUI)(engine_allocator, &m_engine->getResourceManager());
|
|
|
|
m_log_ui = LUMIX_NEW(m_allocator, LogUI)(m_editor->getAllocator());
|
|
|
|
m_import_asset_dialog = LUMIX_NEW(m_allocator, ImportAssetDialog)(*m_editor, m_metadata);
|
|
|
|
m_shader_compiler = LUMIX_NEW(m_allocator, ShaderCompiler)(*m_editor, *m_log_ui);
|
2015-09-24 22:22:53 +02:00
|
|
|
m_hierarchy_ui.setWorldEditor(*m_editor);
|
2015-10-28 20:27:57 +01:00
|
|
|
m_shader_editor = LUMIX_NEW(m_allocator, ShaderEditor)(m_editor->getAllocator());
|
2015-09-12 14:51:13 +02:00
|
|
|
|
2015-09-27 12:56:01 +02:00
|
|
|
m_editor->universeCreated().bind<StudioApp, &StudioApp::onUniverseCreated>(this);
|
|
|
|
m_editor->universeDestroyed().bind<StudioApp, &StudioApp::onUniverseDestroyed>(this);
|
2015-08-12 23:21:39 +02:00
|
|
|
|
2015-09-20 17:30:37 +02:00
|
|
|
auto* pipeline_manager =
|
|
|
|
m_engine->getResourceManager().get(Lumix::ResourceManager::PIPELINE);
|
|
|
|
|
|
|
|
m_gui_pipeline_source = static_cast<Lumix::Pipeline*>(
|
|
|
|
pipeline_manager->load(Lumix::Path("pipelines/imgui.lua")));
|
2015-09-27 12:56:01 +02:00
|
|
|
m_gui_pipeline =
|
|
|
|
Lumix::PipelineInstance::create(*m_gui_pipeline_source, m_engine->getAllocator());
|
2015-09-20 17:30:37 +02:00
|
|
|
|
2015-10-16 21:19:27 +02:00
|
|
|
m_sceneview.init(*m_editor, m_actions);
|
2015-10-25 13:07:53 +01:00
|
|
|
m_gameview.init(*m_editor);
|
2015-08-12 23:21:39 +02:00
|
|
|
|
2015-10-25 13:07:53 +01:00
|
|
|
int w = PlatformInterface::getWindowWidth();
|
|
|
|
int h = PlatformInterface::getWindowHeight();
|
|
|
|
m_gui_pipeline->setViewport(0, 0, w, h);
|
2015-09-20 20:28:51 +02:00
|
|
|
auto& plugin_manager = m_editor->getEngine().getPluginManager();
|
|
|
|
auto* renderer = static_cast<Lumix::Renderer*>(plugin_manager.getPlugin("renderer"));
|
2015-10-25 13:07:53 +01:00
|
|
|
renderer->resize(w, h);
|
2015-09-20 17:30:37 +02:00
|
|
|
onUniverseCreated();
|
2015-10-08 21:36:25 +02:00
|
|
|
initIMGUI();
|
2015-09-29 02:36:24 +02:00
|
|
|
|
2015-11-04 23:00:34 +01:00
|
|
|
PlatformInterface::setSystemEventHandler(&m_handler);
|
2015-09-29 02:36:24 +02:00
|
|
|
loadSettings();
|
2015-09-29 22:21:43 +02:00
|
|
|
|
2015-10-08 21:36:25 +02:00
|
|
|
if (!m_metadata.load()) Lumix::g_log_info.log("studio") << "Could not load metadata";
|
2015-11-08 16:40:07 +01:00
|
|
|
|
|
|
|
void registerProperties(Lumix::WorldEditor&);
|
|
|
|
registerProperties(*m_editor);
|
2015-08-12 23:21:39 +02:00
|
|
|
}
|
|
|
|
|
2015-10-24 14:28:03 +02:00
|
|
|
|
2015-09-13 12:00:25 +02:00
|
|
|
void checkShortcuts()
|
|
|
|
{
|
2015-09-20 17:30:37 +02:00
|
|
|
if (ImGui::IsAnyItemActive()) return;
|
|
|
|
|
2015-09-29 02:36:24 +02:00
|
|
|
bool* keysDown = ImGui::GetIO().KeysDown;
|
2015-10-01 02:07:22 +02:00
|
|
|
for (auto* a : m_actions)
|
2015-09-19 11:38:53 +02:00
|
|
|
{
|
2015-10-01 02:07:22 +02:00
|
|
|
if (!a->is_global || a->shortcut[0] == -1) continue;
|
2015-09-29 02:36:24 +02:00
|
|
|
|
2015-10-01 02:07:22 +02:00
|
|
|
for (int i = 0; i < Lumix::lengthOf(a->shortcut) + 1; ++i)
|
2015-09-13 12:00:25 +02:00
|
|
|
{
|
2015-10-01 02:07:22 +02:00
|
|
|
if (a->shortcut[i] == -1 || i == Lumix::lengthOf(a->shortcut))
|
2015-09-13 12:00:25 +02:00
|
|
|
{
|
2015-10-01 02:07:22 +02:00
|
|
|
a->func.invoke();
|
2015-09-29 02:36:24 +02:00
|
|
|
return;
|
2015-09-13 12:00:25 +02:00
|
|
|
}
|
2015-09-29 02:36:24 +02:00
|
|
|
|
2015-10-01 02:07:22 +02:00
|
|
|
if (!keysDown[a->shortcut[i]]) break;
|
2015-09-13 12:00:25 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-10-25 13:07:53 +01:00
|
|
|
void onWindowTransformed(int x, int y, int width, int height)
|
2015-09-29 02:36:24 +02:00
|
|
|
{
|
2015-10-25 13:07:53 +01:00
|
|
|
m_settings.m_window.x = x;
|
|
|
|
m_settings.m_window.y = y;
|
|
|
|
m_settings.m_window.w = width;
|
|
|
|
m_settings.m_window.h = height;
|
|
|
|
m_settings.m_is_maximized = PlatformInterface::isMaximized();
|
2015-09-29 02:36:24 +02:00
|
|
|
|
2015-11-04 23:00:34 +01:00
|
|
|
if (m_gui_pipeline) m_gui_pipeline->setViewport(0, 0, width, height);
|
|
|
|
if (!m_editor) return;
|
|
|
|
|
2015-10-25 13:07:53 +01:00
|
|
|
auto& plugin_manager = m_editor->getEngine().getPluginManager();
|
|
|
|
auto* renderer =
|
|
|
|
static_cast<Lumix::Renderer*>(plugin_manager.getPlugin("renderer"));
|
2015-11-04 23:00:34 +01:00
|
|
|
if(renderer) renderer->resize(width, height);
|
2015-09-21 21:39:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-10-20 20:57:04 +02:00
|
|
|
void clearInputs()
|
|
|
|
{
|
|
|
|
auto& io = ImGui::GetIO();
|
|
|
|
io.KeyAlt = false;
|
|
|
|
io.KeyCtrl = false;
|
|
|
|
io.KeyShift = false;
|
|
|
|
memset(io.KeysDown, 0, sizeof(io.KeysDown));
|
|
|
|
memset(io.MouseDown, 0, sizeof(io.MouseDown));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-10-24 14:05:24 +02:00
|
|
|
void setGUIProjection()
|
|
|
|
{
|
|
|
|
float width = ImGui::GetIO().DisplaySize.x;
|
|
|
|
float height = ImGui::GetIO().DisplaySize.y;
|
|
|
|
Lumix::Matrix ortho;
|
|
|
|
ortho.setOrtho(0.0f, width, 0.0f, height, -1.0f, 1.0f);
|
|
|
|
m_gui_pipeline->setViewProjection(ortho, (int)width, (int)height);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void drawGUICmdList(ImDrawList* cmd_list)
|
|
|
|
{
|
|
|
|
Lumix::TransientGeometry geom(&cmd_list->VtxBuffer[0],
|
|
|
|
cmd_list->VtxBuffer.size(),
|
|
|
|
m_decl,
|
|
|
|
&cmd_list->IdxBuffer[0],
|
|
|
|
cmd_list->IdxBuffer.size());
|
|
|
|
|
|
|
|
if (geom.getNumVertices() < 0) return;
|
|
|
|
|
2015-11-11 21:54:25 +01:00
|
|
|
Lumix::uint32 elem_offset = 0;
|
2015-10-24 14:05:24 +02:00
|
|
|
const ImDrawCmd* pcmd_begin = cmd_list->CmdBuffer.begin();
|
|
|
|
const ImDrawCmd* pcmd_end = cmd_list->CmdBuffer.end();
|
|
|
|
for (const ImDrawCmd* pcmd = pcmd_begin; pcmd != pcmd_end; pcmd++)
|
|
|
|
{
|
|
|
|
if (pcmd->UserCallback)
|
|
|
|
{
|
|
|
|
pcmd->UserCallback(cmd_list, pcmd);
|
|
|
|
elem_offset += pcmd->ElemCount;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (0 == pcmd->ElemCount) continue;
|
|
|
|
|
|
|
|
m_gui_pipeline->setScissor(
|
2015-11-11 21:54:25 +01:00
|
|
|
Lumix::uint16(Lumix::Math::maxValue(pcmd->ClipRect.x, 0.0f)),
|
|
|
|
Lumix::uint16(Lumix::Math::maxValue(pcmd->ClipRect.y, 0.0f)),
|
|
|
|
Lumix::uint16(Lumix::Math::minValue(pcmd->ClipRect.z, 65535.0f) -
|
2015-10-24 14:05:24 +02:00
|
|
|
Lumix::Math::maxValue(pcmd->ClipRect.x, 0.0f)),
|
2015-11-11 21:54:25 +01:00
|
|
|
Lumix::uint16(Lumix::Math::minValue(pcmd->ClipRect.w, 65535.0f) -
|
2015-10-24 14:05:24 +02:00
|
|
|
Lumix::Math::maxValue(pcmd->ClipRect.y, 0.0f)));
|
|
|
|
|
|
|
|
auto material = m_material;
|
|
|
|
int pass_idx = m_gui_pipeline->getPassIdx();
|
2015-11-14 00:25:08 +01:00
|
|
|
const auto& texture_id = pcmd->TextureId
|
2015-10-24 14:05:24 +02:00
|
|
|
? *(bgfx::TextureHandle*)pcmd->TextureId
|
|
|
|
: material->getTexture(0)->getTextureHandle();
|
|
|
|
auto texture_uniform = material->getShader()->getTextureSlot(0).m_uniform_handle;
|
|
|
|
m_gui_pipeline->setTexture(0, texture_id, texture_uniform);
|
|
|
|
m_gui_pipeline->render(geom,
|
|
|
|
Lumix::Matrix::IDENTITY,
|
|
|
|
elem_offset,
|
|
|
|
pcmd->ElemCount,
|
|
|
|
material->getRenderStates(),
|
|
|
|
material->getShaderInstance().m_program_handles[pass_idx]);
|
|
|
|
|
|
|
|
elem_offset += pcmd->ElemCount;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void imGuiCallback(ImDrawData* draw_data)
|
|
|
|
{
|
|
|
|
PROFILE_FUNCTION();
|
|
|
|
if (!m_material || !m_material->isReady()) return;
|
|
|
|
if (!m_material->getTexture(0)) return;
|
|
|
|
|
|
|
|
setGUIProjection();
|
|
|
|
|
2015-11-11 21:54:25 +01:00
|
|
|
for (int i = 0; i < draw_data->CmdListsCount; ++i)
|
2015-10-24 14:05:24 +02:00
|
|
|
{
|
|
|
|
ImDrawList* cmd_list = draw_data->CmdLists[i];
|
|
|
|
drawGUICmdList(cmd_list);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-09-29 02:36:24 +02:00
|
|
|
Lumix::DefaultAllocator m_allocator;
|
2015-08-14 22:12:51 +02:00
|
|
|
bgfx::VertexDecl m_decl;
|
|
|
|
Lumix::Material* m_material;
|
2015-08-12 22:57:42 +02:00
|
|
|
Lumix::Engine* m_engine;
|
2015-09-20 17:30:37 +02:00
|
|
|
|
|
|
|
SceneView m_sceneview;
|
2015-10-10 01:40:51 +02:00
|
|
|
GameView m_gameview;
|
2015-09-20 17:30:37 +02:00
|
|
|
|
|
|
|
Lumix::Pipeline* m_gui_pipeline_source;
|
|
|
|
Lumix::PipelineInstance* m_gui_pipeline;
|
|
|
|
|
2015-09-29 20:48:26 +02:00
|
|
|
float m_time_to_autosave;
|
2015-10-01 02:07:22 +02:00
|
|
|
Lumix::Array<Action*> m_actions;
|
2015-09-12 14:51:13 +02:00
|
|
|
Lumix::WorldEditor* m_editor;
|
2015-09-14 18:03:45 +02:00
|
|
|
AssetBrowser* m_asset_browser;
|
2015-09-21 11:43:31 +02:00
|
|
|
PropertyGrid* m_property_grid;
|
2015-09-14 18:03:45 +02:00
|
|
|
LogUI* m_log_ui;
|
2015-09-20 23:24:38 +02:00
|
|
|
ProfilerUI* m_profiler_ui;
|
2015-09-14 18:03:45 +02:00
|
|
|
ImportAssetDialog* m_import_asset_dialog;
|
2015-09-16 01:08:28 +02:00
|
|
|
ShaderCompiler* m_shader_compiler;
|
2015-09-19 11:38:53 +02:00
|
|
|
Lumix::string m_selected_template_name;
|
2015-09-24 22:22:53 +02:00
|
|
|
HierarchyUI m_hierarchy_ui;
|
2015-09-29 02:36:24 +02:00
|
|
|
Settings m_settings;
|
2015-09-29 22:21:43 +02:00
|
|
|
Metadata m_metadata;
|
2015-10-27 20:40:00 +01:00
|
|
|
ShaderEditor* m_shader_editor;
|
2015-09-29 02:36:24 +02:00
|
|
|
char m_entity_list_search[100];
|
2015-10-20 20:37:59 +02:00
|
|
|
char m_template_name[100];
|
2015-09-19 11:38:53 +02:00
|
|
|
|
2015-09-14 18:03:45 +02:00
|
|
|
bool m_finished;
|
|
|
|
|
2015-10-11 21:18:33 +02:00
|
|
|
bool m_is_welcome_screen_opened;
|
2015-09-29 02:36:24 +02:00
|
|
|
bool m_is_entity_list_opened;
|
2015-09-19 11:38:53 +02:00
|
|
|
bool m_is_entity_template_list_opened;
|
2015-09-29 02:36:24 +02:00
|
|
|
bool m_is_style_editor_opened;
|
2015-09-19 11:38:53 +02:00
|
|
|
bool m_is_wireframe;
|
2015-08-12 22:57:42 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-10-08 21:36:25 +02:00
|
|
|
StudioApp* g_app;
|
2015-08-12 22:57:42 +02:00
|
|
|
|
|
|
|
|
2015-08-14 22:12:51 +02:00
|
|
|
static void imGuiCallback(ImDrawData* draw_data)
|
|
|
|
{
|
2015-10-24 14:05:24 +02:00
|
|
|
g_app->imGuiCallback(draw_data);
|
2015-08-14 22:12:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-10-25 13:07:53 +01:00
|
|
|
int studioMain()
|
2015-08-12 22:57:42 +02:00
|
|
|
{
|
2015-10-08 21:36:25 +02:00
|
|
|
StudioApp app;
|
|
|
|
g_app = &app;
|
2015-09-13 12:00:25 +02:00
|
|
|
|
2015-10-25 13:07:53 +01:00
|
|
|
app.init();
|
2015-10-08 21:36:25 +02:00
|
|
|
app.run();
|
|
|
|
app.shutdown();
|
|
|
|
|
|
|
|
g_app = nullptr;
|
2015-08-12 22:57:42 +02:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|