LumixEngine/src/studio/scene_view.cpp

245 lines
6 KiB
C++
Raw Normal View History

2015-09-20 17:30:37 +02:00
#include "scene_view.h"
2015-10-24 14:28:03 +02:00
#include "core/crc32.h"
#include "core/profiler.h"
2015-09-20 17:30:37 +02:00
#include "core/resource_manager.h"
#include "editor/gizmo.h"
#include "editor/world_editor.h"
#include "engine/engine.h"
#include "ocornut-imgui/imgui.h"
#include "renderer/frame_buffer.h"
#include "renderer/pipeline.h"
2015-10-24 14:28:03 +02:00
#include "renderer/render_scene.h"
2015-12-19 20:42:50 +01:00
#include "settings.h"
2015-09-20 17:30:37 +02:00
static const char* WINDOW_NAME = "Scene view";
SceneView::SceneView()
{
m_pipeline = nullptr;
m_editor = nullptr;
m_camera_speed = 0.1f;
2015-09-20 17:30:37 +02:00
}
SceneView::~SceneView()
{
}
2015-09-21 22:55:15 +02:00
void SceneView::setWireframe(bool wireframe)
{
m_pipeline->setWireframe(wireframe);
}
2015-09-20 17:30:37 +02:00
void SceneView::setScene(Lumix::RenderScene* scene)
{
m_pipeline->setScene(scene);
}
void SceneView::shutdown()
{
Lumix::PipelineInstance::destroy(m_pipeline);
2015-10-16 21:19:27 +02:00
auto* pipeline_manager =
m_pipeline_source->getResourceManager().get(Lumix::ResourceManager::PIPELINE);
pipeline_manager->unload(*m_pipeline_source);
2015-09-20 17:30:37 +02:00
}
2015-10-24 14:28:03 +02:00
void SceneView::onUniverseCreated()
{
auto* scene = m_editor->getScene(Lumix::crc32("renderer"));
m_pipeline->setScene(static_cast<Lumix::RenderScene*>(scene));
}
void SceneView::onUniverseDestroyed()
{
m_pipeline->setScene(nullptr);
}
2015-10-16 21:19:27 +02:00
bool SceneView::init(Lumix::WorldEditor& editor, Lumix::Array<Action*>& actions)
2015-09-20 17:30:37 +02:00
{
m_editor = &editor;
auto& engine = editor.getEngine();
auto& allocator = engine.getAllocator();
auto* pipeline_manager = engine.getResourceManager().get(Lumix::ResourceManager::PIPELINE);
m_pipeline_source =
static_cast<Lumix::Pipeline*>(pipeline_manager->load(Lumix::Path("pipelines/main.lua")));
m_pipeline = Lumix::PipelineInstance::create(*m_pipeline_source, allocator);
m_pipeline->addCustomCommandHandler("render_gizmos")
.bind<SceneView, &SceneView::renderGizmos>(this);
2015-10-24 14:28:03 +02:00
editor.universeCreated().bind<SceneView, &SceneView::onUniverseCreated>(this);
editor.universeDestroyed().bind<SceneView, &SceneView::onUniverseDestroyed>(this);
onUniverseCreated();
2015-10-16 21:19:27 +02:00
m_toggle_gizmo_step_action =
LUMIX_NEW(editor.getAllocator(), Action)("Enable/disable gizmo step", "toggleGizmoStep");
m_toggle_gizmo_step_action->is_global = false;
actions.push(m_toggle_gizmo_step_action);
2015-09-20 17:30:37 +02:00
return true;
}
void SceneView::update()
{
PROFILE_FUNCTION();
2015-10-16 21:19:27 +02:00
if (ImGui::IsAnyItemActive()) return;
2015-09-20 17:30:37 +02:00
if (!m_is_opened) return;
2015-10-24 14:34:57 +02:00
if (ImGui::GetIO().KeyCtrl) return;
2015-09-20 17:30:37 +02:00
2015-10-16 21:19:27 +02:00
m_camera_speed =
Lumix::Math::maxValue(0.01f, m_camera_speed + ImGui::GetIO().MouseWheel / 20.0f);
2015-09-20 17:30:37 +02:00
int screen_x = int(ImGui::GetIO().MousePos.x);
int screen_y = int(ImGui::GetIO().MousePos.y);
bool is_inside = screen_x >= m_screen_x && screen_y >= m_screen_y &&
2015-10-16 21:19:27 +02:00
screen_x <= m_screen_x + m_width && screen_y <= m_screen_y + m_height;
2015-09-20 17:30:37 +02:00
if (!is_inside) return;
float speed = m_camera_speed;
2015-10-24 14:34:57 +02:00
if (ImGui::GetIO().KeyShift)
2015-09-20 17:30:37 +02:00
{
speed *= 10;
}
if (ImGui::GetIO().KeysDown['W'])
{
m_editor->navigate(1.0f, 0, speed);
}
if (ImGui::GetIO().KeysDown['S'])
{
m_editor->navigate(-1.0f, 0, speed);
}
if (ImGui::GetIO().KeysDown['A'])
{
m_editor->navigate(0.0f, -1.0f, speed);
}
if (ImGui::GetIO().KeysDown['D'])
{
m_editor->navigate(0.0f, 1.0f, speed);
}
}
void SceneView::renderGizmos()
{
m_editor->renderIcons(*m_pipeline);
m_editor->getGizmo().updateScale(m_editor->getEditCamera().index);
m_editor->getGizmo().render(*m_pipeline);
}
void SceneView::onMouseUp(Lumix::MouseButton::Value button)
{
auto pos = ImGui::GetIO().MousePos;
m_editor->onMouseUp(int(pos.x) - m_screen_x, int(pos.y) - m_screen_y, button);
}
bool SceneView::onMouseDown(int screen_x, int screen_y, Lumix::MouseButton::Value button)
{
if (!m_is_mouse_hovering_window) return false;
bool is_inside = screen_x >= m_screen_x && screen_y >= m_screen_y &&
screen_x <= m_screen_x + m_width && screen_y <= m_screen_y + m_height;
if (!is_inside) return false;
ImGui::ResetActiveID();
2015-09-20 17:30:37 +02:00
ImGui::SetWindowFocus(WINDOW_NAME);
m_editor->onMouseDown(screen_x - m_screen_x, screen_y - m_screen_y, button);
return true;
}
void SceneView::onMouseMove(int mouse_screen_x, int mouse_screen_y, int rel_x, int rel_y)
{
2015-10-16 21:19:27 +02:00
m_editor->setGizmoUseStep(m_toggle_gizmo_step_action->isActive());
2015-10-16 21:27:55 +02:00
m_editor->onMouseMove(mouse_screen_x - m_screen_x, mouse_screen_y - m_screen_y, rel_x, rel_y);
2015-09-20 17:30:37 +02:00
}
2015-10-03 01:14:38 +02:00
void SceneView::onGUI()
2015-09-20 17:30:37 +02:00
{
2015-09-27 12:56:01 +02:00
PROFILE_FUNCTION();
2015-09-20 17:30:37 +02:00
m_is_opened = false;
m_is_mouse_hovering_window = false;
if (ImGui::Begin(WINDOW_NAME))
{
m_is_mouse_hovering_window = ImGui::IsMouseHoveringWindow();
m_is_opened = true;
auto size = ImGui::GetContentRegionAvail();
size.y -= ImGui::GetTextLineHeightWithSpacing();
if (size.x > 0 && size.y > 0)
{
auto pos = ImGui::GetWindowPos();
auto cp = ImGui::GetCursorPos();
m_pipeline->setViewport(0, 0, int(size.x), int(size.y));
auto* fb = m_pipeline->getFramebuffer("default");
m_texture_handle = fb->getRenderbufferHandle(0);
auto cursor_pos = ImGui::GetCursorScreenPos();
m_screen_x = int(cursor_pos.x);
m_screen_y = int(cursor_pos.y);
m_width = int(size.x);
m_height = int(size.y);
ImGui::Image(&m_texture_handle, size);
m_pipeline->render();
}
2015-09-20 17:30:37 +02:00
}
ImGui::PushItemWidth(60);
2015-09-20 20:50:32 +02:00
ImGui::DragFloat("Camera speed", &m_camera_speed, 0.1f, 0.01f, 999.0f, "%.2f");
ImGui::SameLine();
if (m_editor->isMeasureToolActive())
{
ImGui::Text("| Measured distance: %f", m_editor->getMeasuredDistance());
}
2015-10-16 21:19:27 +02:00
ImGui::SameLine();
int step = m_editor->getGizmo().getStep();
if (ImGui::DragInt("Gizmo step", &step, 1.0f, 0, 200))
{
m_editor->getGizmo().setStep(step);
}
2015-11-10 22:25:36 +01:00
ImGui::SameLine();
int count = m_pipeline->getParameterCount();
if (count)
{
if (ImGui::Button("Pipeline"))
{
ImGui::OpenPopup("pipeline_parameters_popup");
}
if (ImGui::BeginPopup("pipeline_parameters_popup"))
{
for (int i = 0; i < count; ++i)
{
bool b = m_pipeline->getParameter(i);
if (ImGui::Checkbox(m_pipeline->getParameterName(i), &b))
{
2015-12-19 20:42:50 +01:00
auto* settings = Settings::getInstance();
if (settings)
{
settings->setValue(m_pipeline->getParameterName(i), b);
}
2015-11-10 22:25:36 +01:00
m_pipeline->setParameter(i, b);
}
}
ImGui::EndPopup();
}
}
2015-09-20 17:30:37 +02:00
ImGui::End();
}