2015-09-20 17:30:37 +02:00
|
|
|
#include "scene_view.h"
|
2016-05-24 21:14:34 +02:00
|
|
|
#include "editor/gizmo.h"
|
2016-06-08 16:36:00 +02:00
|
|
|
#include "editor/ieditor_command.h"
|
2016-05-24 21:14:34 +02:00
|
|
|
#include "editor/log_ui.h"
|
|
|
|
#include "editor/platform_interface.h"
|
|
|
|
#include "editor/settings.h"
|
2016-06-08 15:35:35 +02:00
|
|
|
#include "editor/studio_app.h"
|
2016-05-10 08:24:31 +02:00
|
|
|
#include "engine/crc32.h"
|
2016-06-08 15:35:35 +02:00
|
|
|
#include "engine/engine.h"
|
2016-05-10 08:24:31 +02:00
|
|
|
#include "engine/input_system.h"
|
2016-06-08 16:36:00 +02:00
|
|
|
#include "engine/json_serializer.h"
|
2016-05-10 08:24:31 +02:00
|
|
|
#include "engine/path.h"
|
|
|
|
#include "engine/profiler.h"
|
|
|
|
#include "engine/resource_manager.h"
|
|
|
|
#include "engine/string.h"
|
2016-06-08 15:35:35 +02:00
|
|
|
#include "engine/path_utils.h"
|
2016-02-05 14:32:21 +01:00
|
|
|
#include "engine/plugin_manager.h"
|
2016-06-08 15:35:35 +02:00
|
|
|
#include "engine/property_register.h"
|
|
|
|
#include "engine/universe/component.h"
|
|
|
|
#include "engine/universe/universe.h"
|
2016-05-07 13:58:08 +02:00
|
|
|
#include "imgui/imgui.h"
|
2015-09-20 17:30:37 +02:00
|
|
|
#include "renderer/frame_buffer.h"
|
2016-06-08 15:35:35 +02:00
|
|
|
#include "renderer/model.h"
|
2015-09-20 17:30:37 +02:00
|
|
|
#include "renderer/pipeline.h"
|
2015-10-24 14:28:03 +02:00
|
|
|
#include "renderer/render_scene.h"
|
2016-01-12 13:52:14 +01:00
|
|
|
#include "renderer/renderer.h"
|
2016-05-24 21:14:34 +02:00
|
|
|
#include <SDL.h>
|
2015-09-20 17:30:37 +02:00
|
|
|
|
|
|
|
|
2016-06-22 00:46:48 +02:00
|
|
|
static const Lumix::ComponentType RENDERABLE_TYPE = Lumix::PropertyRegister::getComponentType("renderable");
|
2016-06-08 15:35:35 +02:00
|
|
|
|
|
|
|
|
2016-06-08 16:36:00 +02:00
|
|
|
struct InsertMeshCommand : public Lumix::IEditorCommand
|
|
|
|
{
|
|
|
|
Lumix::Vec3 m_position;
|
|
|
|
Lumix::Path m_mesh_path;
|
|
|
|
Lumix::Entity m_entity;
|
|
|
|
Lumix::WorldEditor& m_editor;
|
|
|
|
|
|
|
|
|
|
|
|
InsertMeshCommand(Lumix::WorldEditor& editor)
|
|
|
|
: m_editor(editor)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
InsertMeshCommand(Lumix::WorldEditor& editor, const Lumix::Vec3& position, const Lumix::Path& mesh_path)
|
|
|
|
: m_mesh_path(mesh_path)
|
|
|
|
, m_position(position)
|
|
|
|
, m_editor(editor)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void serialize(Lumix::JsonSerializer& serializer)
|
|
|
|
{
|
|
|
|
serializer.serialize("path", m_mesh_path.c_str());
|
|
|
|
serializer.beginArray("pos");
|
|
|
|
serializer.serializeArrayItem(m_position.x);
|
|
|
|
serializer.serializeArrayItem(m_position.y);
|
|
|
|
serializer.serializeArrayItem(m_position.z);
|
|
|
|
serializer.endArray();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void deserialize(Lumix::JsonSerializer& serializer)
|
|
|
|
{
|
|
|
|
char path[Lumix::MAX_PATH_LENGTH];
|
|
|
|
serializer.deserialize("path", path, sizeof(path), "");
|
|
|
|
m_mesh_path = path;
|
|
|
|
serializer.deserializeArrayBegin("pos");
|
|
|
|
serializer.deserializeArrayItem(m_position.x, 0);
|
|
|
|
serializer.deserializeArrayItem(m_position.y, 0);
|
|
|
|
serializer.deserializeArrayItem(m_position.z, 0);
|
|
|
|
serializer.deserializeArrayEnd();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool execute()
|
|
|
|
{
|
|
|
|
auto* universe = m_editor.getUniverse();
|
2016-07-01 23:05:00 +02:00
|
|
|
m_entity = universe->createEntity({0, 0, 0}, {0, 0, 0, 1});
|
2016-06-08 16:36:00 +02:00
|
|
|
universe->setPosition(m_entity, m_position);
|
2016-06-13 02:22:04 +02:00
|
|
|
const auto& scenes = universe->getScenes();
|
2016-06-22 15:05:19 +02:00
|
|
|
Lumix::ComponentHandle cmp = Lumix::INVALID_COMPONENT;
|
2016-06-08 16:36:00 +02:00
|
|
|
Lumix::IScene* scene = nullptr;
|
|
|
|
for (int i = 0; i < scenes.size(); ++i)
|
|
|
|
{
|
2016-06-22 00:46:48 +02:00
|
|
|
cmp = scenes[i]->createComponent(RENDERABLE_TYPE, m_entity);
|
2016-06-08 16:36:00 +02:00
|
|
|
|
2016-06-22 15:05:19 +02:00
|
|
|
if (isValid(cmp))
|
2016-06-08 16:36:00 +02:00
|
|
|
{
|
|
|
|
scene = scenes[i];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2016-06-22 15:05:19 +02:00
|
|
|
if (isValid(cmp)) static_cast<Lumix::RenderScene*>(scene)->setRenderablePath(cmp, m_mesh_path);
|
2016-06-08 16:36:00 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void undo()
|
|
|
|
{
|
|
|
|
m_editor.getUniverse()->destroyEntity(m_entity);
|
|
|
|
m_entity = Lumix::INVALID_ENTITY;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Lumix::uint32 getType()
|
|
|
|
{
|
|
|
|
static const Lumix::uint32 TYPE = Lumix::crc32("insert_mesh");
|
|
|
|
return TYPE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool merge(Lumix::IEditorCommand&) { return false; }
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
static Lumix::IEditorCommand* createInsertMeshCommand(Lumix::WorldEditor& editor)
|
|
|
|
{
|
|
|
|
return LUMIX_NEW(editor.getAllocator(), InsertMeshCommand)(editor);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-06-08 15:35:35 +02:00
|
|
|
SceneView::SceneView(StudioApp& app)
|
|
|
|
: m_app(app)
|
2015-09-20 17:30:37 +02:00
|
|
|
{
|
2015-09-20 20:28:51 +02:00
|
|
|
m_camera_speed = 0.1f;
|
2016-01-25 16:35:56 +01:00
|
|
|
m_is_mouse_captured = false;
|
2016-01-28 15:19:56 +01:00
|
|
|
m_show_stats = false;
|
2016-06-08 16:36:00 +02:00
|
|
|
m_app.getWorldEditor()->registerEditorCommandCreator("insert_mesh", createInsertMeshCommand);
|
2016-06-12 12:04:41 +02:00
|
|
|
|
|
|
|
m_log_ui = m_app.getLogUI();
|
|
|
|
m_editor = m_app.getWorldEditor();
|
|
|
|
auto& engine = m_editor->getEngine();
|
|
|
|
auto& allocator = engine.getAllocator();
|
|
|
|
auto* renderer = static_cast<Lumix::Renderer*>(engine.getPluginManager().getPlugin("renderer"));
|
|
|
|
m_is_opengl = renderer->isOpenGL();
|
|
|
|
Lumix::Path path("pipelines/main.lua");
|
|
|
|
m_pipeline = Lumix::Pipeline::create(*renderer, path, engine.getAllocator());
|
|
|
|
m_pipeline->load();
|
|
|
|
m_pipeline->addCustomCommandHandler("renderGizmos").callback.bind<SceneView, &SceneView::renderGizmos>(this);
|
|
|
|
m_pipeline->addCustomCommandHandler("renderIcons").callback.bind<SceneView, &SceneView::renderIcons>(this);
|
|
|
|
|
|
|
|
m_editor->universeCreated().bind<SceneView, &SceneView::onUniverseCreated>(this);
|
|
|
|
m_editor->universeDestroyed().bind<SceneView, &SceneView::onUniverseDestroyed>(this);
|
|
|
|
|
|
|
|
m_toggle_gizmo_step_action =
|
|
|
|
LUMIX_NEW(m_editor->getAllocator(), Action)("Enable/disable gizmo step", "toggleGizmoStep");
|
|
|
|
m_toggle_gizmo_step_action->is_global = false;
|
|
|
|
m_app.addAction(m_toggle_gizmo_step_action);
|
|
|
|
|
|
|
|
m_move_forward_action = LUMIX_NEW(m_editor->getAllocator(), Action)("Move forward", "moveForward");
|
|
|
|
m_move_forward_action->is_global = false;
|
|
|
|
m_app.addAction(m_move_forward_action);
|
|
|
|
|
|
|
|
m_move_back_action = LUMIX_NEW(m_editor->getAllocator(), Action)("Move back", "moveBack");
|
|
|
|
m_move_back_action->is_global = false;
|
|
|
|
m_app.addAction(m_move_back_action);
|
|
|
|
|
|
|
|
m_move_left_action = LUMIX_NEW(m_editor->getAllocator(), Action)("Move left", "moveLeft");
|
|
|
|
m_move_left_action->is_global = false;
|
|
|
|
m_app.addAction(m_move_left_action);
|
|
|
|
|
|
|
|
m_move_right_action = LUMIX_NEW(m_editor->getAllocator(), Action)("Move right", "moveRight");
|
|
|
|
m_move_right_action->is_global = false;
|
|
|
|
m_app.addAction(m_move_right_action);
|
|
|
|
|
|
|
|
m_move_up_action = LUMIX_NEW(m_editor->getAllocator(), Action)("Move up", "moveUp");
|
|
|
|
m_move_up_action->is_global = false;
|
|
|
|
m_app.addAction(m_move_up_action);
|
|
|
|
|
|
|
|
m_move_down_action = LUMIX_NEW(m_editor->getAllocator(), Action)("Move down", "moveDown");
|
|
|
|
m_move_down_action->is_global = false;
|
|
|
|
m_app.addAction(m_move_down_action);
|
2016-06-13 13:57:37 +02:00
|
|
|
|
|
|
|
m_camera_speed_action = LUMIX_NEW(m_editor->getAllocator(), Action)("Camera speed", "cameraSpeed");
|
|
|
|
m_camera_speed_action->is_global = false;
|
|
|
|
m_camera_speed_action->func.bind<SceneView, &SceneView::resetCameraSpeed>(this);
|
|
|
|
m_app.addAction(m_camera_speed_action);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SceneView::resetCameraSpeed()
|
|
|
|
{
|
|
|
|
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)
|
|
|
|
{
|
2016-02-26 17:09:19 +01:00
|
|
|
m_pipeline->setWireframe(wireframe);
|
2015-09-21 22:55:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-09-20 17:30:37 +02:00
|
|
|
void SceneView::setScene(Lumix::RenderScene* scene)
|
|
|
|
{
|
2016-02-26 17:09:19 +01:00
|
|
|
m_pipeline->setScene(scene);
|
2015-09-20 17:30:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SceneView::shutdown()
|
|
|
|
{
|
2016-01-13 17:21:59 +01:00
|
|
|
m_editor->universeCreated().unbind<SceneView, &SceneView::onUniverseCreated>(this);
|
|
|
|
m_editor->universeDestroyed().unbind<SceneView, &SceneView::onUniverseDestroyed>(this);
|
2016-02-26 17:09:19 +01:00
|
|
|
Lumix::Pipeline::destroy(m_pipeline);
|
|
|
|
m_pipeline = nullptr;
|
2015-09-20 17:30:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-10-24 14:28:03 +02:00
|
|
|
void SceneView::onUniverseCreated()
|
|
|
|
{
|
2016-06-13 02:22:04 +02:00
|
|
|
auto* scene = m_editor->getUniverse()->getScene(Lumix::crc32("renderer"));
|
2016-02-26 17:09:19 +01:00
|
|
|
m_pipeline->setScene(static_cast<Lumix::RenderScene*>(scene));
|
2015-10-24 14:28:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SceneView::onUniverseDestroyed()
|
|
|
|
{
|
2016-02-26 17:09:19 +01:00
|
|
|
m_pipeline->setScene(nullptr);
|
2015-10-24 14:28:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-09-20 17:30:37 +02:00
|
|
|
void SceneView::update()
|
|
|
|
{
|
2015-09-25 21:44:46 +02:00
|
|
|
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
|
|
|
|
|
|
|
int screen_x = int(ImGui::GetIO().MousePos.x);
|
|
|
|
int screen_y = int(ImGui::GetIO().MousePos.y);
|
2016-03-22 15:56:39 +01:00
|
|
|
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;
|
2015-09-20 17:30:37 +02:00
|
|
|
if (!is_inside) return;
|
|
|
|
|
2016-05-24 21:14:34 +02:00
|
|
|
m_camera_speed = Lumix::Math::maximum(0.01f, m_camera_speed + ImGui::GetIO().MouseWheel / 20.0f);
|
|
|
|
|
2015-09-20 20:28:51 +02:00
|
|
|
float speed = m_camera_speed;
|
2016-03-22 15:56:39 +01:00
|
|
|
if (ImGui::GetIO().KeyShift) speed *= 10;
|
|
|
|
if (m_move_forward_action->isActive()) m_editor->navigate(1.0f, 0, 0, speed);
|
|
|
|
if (m_move_back_action->isActive()) m_editor->navigate(-1.0f, 0, 0, speed);
|
|
|
|
if (m_move_left_action->isActive()) m_editor->navigate(0.0f, -1.0f, 0, speed);
|
|
|
|
if (m_move_right_action->isActive()) m_editor->navigate(0.0f, 1.0f, 0, speed);
|
|
|
|
if (m_move_down_action->isActive()) m_editor->navigate(0, 0, -1.0f, speed);
|
|
|
|
if (m_move_up_action->isActive()) m_editor->navigate(0, 0, 1.0f, speed);
|
2015-09-20 17:30:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-01-30 22:50:28 +01:00
|
|
|
void SceneView::renderIcons()
|
2015-09-20 17:30:37 +02:00
|
|
|
{
|
2016-01-13 23:36:38 +01:00
|
|
|
m_editor->renderIcons();
|
2016-01-30 22:50:28 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SceneView::renderGizmos()
|
|
|
|
{
|
2016-01-13 23:36:38 +01:00
|
|
|
m_editor->getGizmo().render();
|
2015-09-20 17:30:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-01-22 12:09:05 +01:00
|
|
|
void SceneView::captureMouse(bool capture)
|
|
|
|
{
|
2016-01-25 16:35:56 +01:00
|
|
|
if(m_is_mouse_captured == capture) return;
|
2016-01-22 12:09:05 +01:00
|
|
|
m_is_mouse_captured = capture;
|
2016-05-24 21:14:34 +02:00
|
|
|
SDL_ShowCursor(m_is_mouse_captured ? 0 : 1);
|
|
|
|
SDL_SetRelativeMouseMode(capture ? SDL_TRUE : SDL_FALSE);
|
2016-01-22 12:09:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-06-08 15:35:35 +02:00
|
|
|
Lumix::RayCastModelHit SceneView::castRay(float x, float y)
|
|
|
|
{
|
|
|
|
auto* scene = m_pipeline->getScene();
|
|
|
|
ASSERT(scene);
|
|
|
|
|
|
|
|
Lumix::ComponentUID camera_cmp = m_editor->getEditCamera();
|
2016-06-22 15:05:19 +02:00
|
|
|
Lumix::Vec2 screen_size = scene->getCameraScreenSize(camera_cmp.handle);
|
2016-06-08 15:35:35 +02:00
|
|
|
screen_size.x *= x;
|
|
|
|
screen_size.y *= y;
|
|
|
|
|
|
|
|
Lumix::Vec3 origin;
|
|
|
|
Lumix::Vec3 dir;
|
2016-06-22 15:05:19 +02:00
|
|
|
scene->getRay(camera_cmp.handle, (float)screen_size.x, (float)screen_size.y, origin, dir);
|
2016-06-08 15:35:35 +02:00
|
|
|
return scene->castRay(origin, dir, Lumix::INVALID_COMPONENT);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SceneView::handleDrop(float x, float y)
|
|
|
|
{
|
|
|
|
const char* path = (const char*)m_app.getDragData().data;
|
|
|
|
auto hit = castRay(x, y);
|
|
|
|
|
|
|
|
if (hit.m_is_hit)
|
|
|
|
{
|
|
|
|
if (Lumix::PathUtils::hasExtension(path, "msh"))
|
|
|
|
{
|
2016-06-08 16:36:00 +02:00
|
|
|
auto* command = LUMIX_NEW(m_editor->getAllocator(), InsertMeshCommand)(
|
2016-06-08 15:35:35 +02:00
|
|
|
*m_editor, hit.m_origin + hit.m_t * hit.m_dir, Lumix::Path(path));
|
|
|
|
|
|
|
|
m_editor->executeCommand(command);
|
|
|
|
}
|
|
|
|
else if (Lumix::PathUtils::hasExtension(path, "mat") && hit.m_mesh)
|
|
|
|
{
|
2016-06-22 00:46:48 +02:00
|
|
|
auto* desc = Lumix::PropertyRegister::getDescriptor(RENDERABLE_TYPE, Lumix::crc32("Material"));
|
2016-06-08 15:35:35 +02:00
|
|
|
auto drag_data = m_app.getDragData();
|
|
|
|
m_editor->selectEntities(&hit.m_entity, 1);
|
|
|
|
auto* model = m_pipeline->getScene()->getRenderableModel(hit.m_component);
|
|
|
|
int mesh_index = 0;
|
|
|
|
for (int i = 0; i < model->getMeshCount(); ++i)
|
|
|
|
{
|
|
|
|
if (&model->getMesh(i) == hit.m_mesh)
|
|
|
|
{
|
|
|
|
mesh_index = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-22 00:46:48 +02:00
|
|
|
m_editor->setProperty(RENDERABLE_TYPE, mesh_index, *desc, drag_data.data, drag_data.size);
|
2016-06-08 15:35:35 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-06-09 20:44:02 +02:00
|
|
|
void SceneView::onToolbar()
|
|
|
|
{
|
|
|
|
static const char* actions_names[] = { "setTranslateGizmoMode",
|
|
|
|
"setRotateGizmoMode",
|
|
|
|
"setLocalCoordSystem",
|
|
|
|
"setGlobalCoordSystem",
|
|
|
|
"setPivotCenter",
|
2016-06-15 22:19:45 +02:00
|
|
|
"setPivotOrigin",
|
|
|
|
"viewTop",
|
|
|
|
"viewFront",
|
|
|
|
"viewSide" };
|
2016-06-09 20:44:02 +02:00
|
|
|
|
|
|
|
auto pos = ImGui::GetCursorScreenPos();
|
2016-06-16 22:32:30 +02:00
|
|
|
if (ImGui::BeginToolbar("scene_view_toolbar", pos, ImVec2(0, 24)))
|
2016-06-09 20:44:02 +02:00
|
|
|
{
|
2016-06-12 17:44:22 +02:00
|
|
|
for (auto* action_name : actions_names)
|
|
|
|
{
|
|
|
|
auto& action = m_app.getAction(action_name);
|
|
|
|
action.toolbarButton();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-13 13:57:37 +02:00
|
|
|
m_app.getAction("cameraSpeed").toolbarButton();
|
|
|
|
|
2016-06-12 17:44:22 +02:00
|
|
|
ImGui::PushItemWidth(50);
|
|
|
|
ImGui::SameLine();
|
2016-06-13 13:57:37 +02:00
|
|
|
float offset = (24 - ImGui::GetTextLineHeightWithSpacing()) / 2;
|
2016-06-12 17:44:22 +02:00
|
|
|
pos = ImGui::GetCursorPos();
|
2016-06-13 13:57:37 +02:00
|
|
|
pos.y += offset;
|
2016-06-12 17:44:22 +02:00
|
|
|
ImGui::SetCursorPos(pos);
|
2016-06-13 13:57:37 +02:00
|
|
|
ImGui::DragFloat("##camera_speed", &m_camera_speed, 0.1f, 0.01f, 999.0f, "%.2f");
|
2016-06-12 17:44:22 +02:00
|
|
|
|
|
|
|
int step = m_editor->getGizmo().getStep();
|
2016-06-13 13:57:37 +02:00
|
|
|
Action* mode_action;
|
|
|
|
if (m_editor->getGizmo().isTranslateMode())
|
2016-06-12 17:44:22 +02:00
|
|
|
{
|
2016-06-13 13:57:37 +02:00
|
|
|
mode_action = &m_app.getAction("setTranslateGizmoMode");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
mode_action = &m_app.getAction("setRotateGizmoMode");
|
2016-06-12 17:44:22 +02:00
|
|
|
}
|
2016-06-13 13:57:37 +02:00
|
|
|
|
|
|
|
ImGui::SameLine();
|
|
|
|
pos = ImGui::GetCursorPos();
|
|
|
|
pos.y -= offset;
|
|
|
|
ImGui::SetCursorPos(pos);
|
2016-06-13 16:56:22 +02:00
|
|
|
ImVec4 tint_color = ImGui::GetStyle().Colors[ImGuiCol_Text];
|
|
|
|
ImGui::Image(mode_action->icon, ImVec2(24, 24), ImVec2(0, 0), ImVec2(1, 1), tint_color);
|
2016-06-13 13:57:37 +02:00
|
|
|
if (ImGui::IsItemHovered()) ImGui::SetTooltip("%s", "Snap amount");
|
2016-06-12 17:44:22 +02:00
|
|
|
|
|
|
|
ImGui::SameLine();
|
2016-06-13 13:57:37 +02:00
|
|
|
pos = ImGui::GetCursorPos();
|
|
|
|
pos.y += offset;
|
|
|
|
ImGui::SetCursorPos(pos);
|
|
|
|
if (ImGui::DragInt("##gizmoStep", &step, 1.0f, 0, 200))
|
|
|
|
{
|
|
|
|
m_editor->getGizmo().setStep(step);
|
|
|
|
}
|
|
|
|
|
|
|
|
ImGui::SameLine(0, 20);
|
2016-06-12 17:44:22 +02:00
|
|
|
ImGui::Checkbox("Stats", &m_show_stats);
|
|
|
|
|
2016-06-13 13:57:37 +02:00
|
|
|
ImGui::SameLine(0, 20);
|
2016-06-12 17:44:22 +02:00
|
|
|
m_pipeline->callLuaFunction("onGUI");
|
|
|
|
|
|
|
|
if (m_editor->isMeasureToolActive())
|
|
|
|
{
|
2016-06-13 13:57:37 +02:00
|
|
|
ImGui::SameLine(0, 20);
|
2016-06-12 17:44:22 +02:00
|
|
|
ImGui::Text(" | Measured distance: %f", m_editor->getMeasuredDistance());
|
2016-06-09 20:44:02 +02:00
|
|
|
}
|
2016-06-12 17:44:22 +02:00
|
|
|
|
|
|
|
ImGui::PopItemWidth();
|
|
|
|
|
2016-06-09 20:44:02 +02:00
|
|
|
ImGui::EndToolbar();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
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;
|
2016-01-28 15:19:56 +01:00
|
|
|
ImVec2 view_pos;
|
2016-02-12 23:49:56 +01:00
|
|
|
const char* title = "Scene View###Scene View";
|
|
|
|
if (m_log_ui && m_log_ui->getUnreadErrorCount() > 0)
|
|
|
|
{
|
|
|
|
title = "Scene View | errors in log###Scene View";
|
|
|
|
}
|
|
|
|
|
2016-05-24 21:14:34 +02:00
|
|
|
if (ImGui::BeginDock(title, nullptr, ImGuiWindowFlags_NoScrollWithMouse))
|
2015-09-20 17:30:37 +02:00
|
|
|
{
|
|
|
|
m_is_opened = true;
|
2016-06-09 20:44:02 +02:00
|
|
|
onToolbar();
|
2015-09-20 17:30:37 +02:00
|
|
|
auto size = ImGui::GetContentRegionAvail();
|
2016-02-26 17:09:19 +01:00
|
|
|
auto* fb = m_pipeline->getFramebuffer("default");
|
2016-01-22 22:05:58 +01:00
|
|
|
if (size.x > 0 && size.y > 0 && fb)
|
2015-09-21 21:26:49 +02:00
|
|
|
{
|
|
|
|
auto pos = ImGui::GetWindowPos();
|
2016-02-26 17:09:19 +01:00
|
|
|
m_pipeline->setViewport(0, 0, int(size.x), int(size.y));
|
2015-09-21 21:26:49 +02:00
|
|
|
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);
|
2016-01-22 12:09:05 +01:00
|
|
|
auto content_min = ImGui::GetCursorScreenPos();
|
|
|
|
ImVec2 content_max(content_min.x + size.x, content_min.y + size.y);
|
2016-06-03 02:17:47 +02:00
|
|
|
if (m_is_opengl)
|
|
|
|
{
|
|
|
|
ImGui::Image(&m_texture_handle, size, ImVec2(0, 1), ImVec2(1, 0));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ImGui::Image(&m_texture_handle, size);
|
|
|
|
}
|
2016-06-08 15:35:35 +02:00
|
|
|
if (ImGui::IsItemHoveredRect())
|
|
|
|
{
|
|
|
|
if (ImGui::IsMouseReleased(0) && m_app.getDragData().type == StudioApp::DragData::PATH)
|
|
|
|
{
|
|
|
|
float x = (ImGui::GetMousePos().x - content_min.x) / size.x;
|
|
|
|
float y = (ImGui::GetMousePos().y - content_min.y) / size.y;
|
|
|
|
handleDrop(x, y);
|
|
|
|
}
|
|
|
|
}
|
2016-01-28 15:19:56 +01:00
|
|
|
view_pos = content_min;
|
2016-03-06 13:04:26 +01:00
|
|
|
auto rel_mp = ImGui::GetMousePos();
|
|
|
|
rel_mp.x -= m_screen_x;
|
|
|
|
rel_mp.y -= m_screen_y;
|
2016-01-13 17:21:59 +01:00
|
|
|
if (ImGui::IsItemHovered())
|
|
|
|
{
|
2016-02-26 20:51:45 +01:00
|
|
|
m_editor->getGizmo().enableStep(m_toggle_gizmo_step_action->isActive());
|
2016-01-13 17:21:59 +01:00
|
|
|
for (int i = 0; i < 3; ++i)
|
|
|
|
{
|
|
|
|
if (ImGui::IsMouseClicked(i))
|
|
|
|
{
|
2016-01-22 12:09:05 +01:00
|
|
|
ImGui::ResetActiveID();
|
2016-05-24 21:14:34 +02:00
|
|
|
if(i == 1) captureMouse(true);
|
2016-01-13 17:21:59 +01:00
|
|
|
m_editor->onMouseDown((int)rel_mp.x, (int)rel_mp.y, (Lumix::MouseButton::Value)i);
|
2016-03-06 13:04:26 +01:00
|
|
|
break;
|
2016-01-13 17:21:59 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-03-06 13:04:26 +01:00
|
|
|
if (m_is_mouse_captured || ImGui::IsItemHovered())
|
2016-03-05 22:58:55 +01:00
|
|
|
{
|
2016-03-06 13:04:26 +01:00
|
|
|
auto& input = m_editor->getEngine().getInputSystem();
|
|
|
|
auto delta = Lumix::Vec2(input.getMouseXMove(), input.getMouseYMove());
|
|
|
|
if (delta.x != 0 || delta.y != 0)
|
2016-03-05 22:58:55 +01:00
|
|
|
{
|
2016-03-06 13:04:26 +01:00
|
|
|
m_editor->onMouseMove((int)rel_mp.x, (int)rel_mp.y, (int)delta.x, (int)delta.y);
|
2016-03-05 22:58:55 +01:00
|
|
|
}
|
|
|
|
}
|
2016-05-24 21:14:34 +02:00
|
|
|
for (int i = 0; i < 3; ++i)
|
2016-01-22 12:09:05 +01:00
|
|
|
{
|
2016-05-24 21:14:34 +02:00
|
|
|
auto rel_mp = ImGui::GetMousePos();
|
|
|
|
rel_mp.x -= m_screen_x;
|
|
|
|
rel_mp.y -= m_screen_y;
|
|
|
|
if (ImGui::IsMouseReleased(i))
|
2016-03-06 13:04:26 +01:00
|
|
|
{
|
2016-05-24 21:14:34 +02:00
|
|
|
if (i == 1) captureMouse(false);
|
|
|
|
m_editor->onMouseUp((int)rel_mp.x, (int)rel_mp.y, (Lumix::MouseButton::Value)i);
|
2016-03-06 13:04:26 +01:00
|
|
|
}
|
2016-01-22 12:09:05 +01:00
|
|
|
}
|
2016-02-26 17:09:19 +01:00
|
|
|
m_pipeline->render();
|
2015-09-21 21:26:49 +02:00
|
|
|
}
|
2015-11-10 22:25:36 +01:00
|
|
|
}
|
|
|
|
|
2016-01-01 20:31:34 +01:00
|
|
|
ImGui::EndDock();
|
2016-01-28 15:19:56 +01:00
|
|
|
|
|
|
|
if(m_show_stats)
|
|
|
|
{
|
2016-06-12 17:44:22 +02:00
|
|
|
float toolbar_height = 24 + ImGui::GetStyle().FramePadding.y * 2;
|
2016-01-28 15:19:56 +01:00
|
|
|
view_pos.x += ImGui::GetStyle().FramePadding.x;
|
2016-06-12 17:44:22 +02:00
|
|
|
view_pos.y += ImGui::GetStyle().FramePadding.y + toolbar_height;
|
2016-01-28 15:19:56 +01:00
|
|
|
ImGui::SetNextWindowPos(view_pos);
|
|
|
|
auto col = ImGui::GetStyle().Colors[ImGuiCol_WindowBg];
|
|
|
|
col.w = 0.3f;
|
|
|
|
ImGui::PushStyleColor(ImGuiCol_WindowBg, col);
|
|
|
|
if (ImGui::Begin("###stats_overlay",
|
|
|
|
nullptr,
|
|
|
|
ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_AlwaysAutoResize |
|
|
|
|
ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoSavedSettings |
|
|
|
|
ImGuiWindowFlags_ShowBorders))
|
|
|
|
{
|
2016-02-26 17:09:19 +01:00
|
|
|
const auto& stats = m_pipeline->getStats();
|
2016-03-26 13:19:07 +01:00
|
|
|
ImGui::LabelText("Draw calls", "%d", stats.draw_call_count);
|
|
|
|
ImGui::LabelText("Instances", "%d", stats.instance_count);
|
2016-01-28 15:19:56 +01:00
|
|
|
char buf[30];
|
2016-03-26 13:19:07 +01:00
|
|
|
Lumix::toCStringPretty(stats.triangle_count, buf, Lumix::lengthOf(buf));
|
2016-04-28 10:14:47 +02:00
|
|
|
ImGui::LabelText("Triangles", "%s", buf);
|
2016-03-06 17:20:39 +01:00
|
|
|
ImGui::LabelText("Resolution", "%dx%d", m_pipeline->getWidth(), m_pipeline->getHeight());
|
|
|
|
ImGui::LabelText("FPS", "%.2f", m_editor->getEngine().getFPS());
|
2016-03-14 22:16:16 +01:00
|
|
|
ImGui::LabelText("CPU time", "%.2f", m_pipeline->getCPUTime() * 1000.0f);
|
|
|
|
ImGui::LabelText("GPU time", "%.2f", m_pipeline->getGPUTime() * 1000.0f);
|
2016-05-15 19:33:03 +02:00
|
|
|
ImGui::LabelText("Waiting for submit", "%.2f", m_pipeline->getWaitSubmitTime() * 1000.0f);
|
|
|
|
ImGui::LabelText("Waiting for render thread", "%.2f", m_pipeline->getGPUTime() * 1000.0f);
|
2016-01-28 15:19:56 +01:00
|
|
|
}
|
|
|
|
ImGui::End();
|
|
|
|
ImGui::PopStyleColor();
|
|
|
|
}
|
2016-04-28 10:14:47 +02:00
|
|
|
}
|