independent studio WIP

This commit is contained in:
Mikulas Florek 2016-01-13 23:36:38 +01:00
parent ad7949bc6e
commit 4f783ddfe1
12 changed files with 440 additions and 334 deletions

View file

@ -197,7 +197,7 @@ project "editor"
files { "../src/editor/**.h", "../src/editor/**.cpp" }
includedirs { "../src", "../src/editor", "../external/bgfx/include" }
defines { "BUILDING_EDITOR" }
links { "renderer", "engine" }
links { "engine" }
useLua()
defaultConfigurations()

View file

@ -5,10 +5,7 @@
#include "core/resource_manager.h"
#include "core/resource_manager_base.h"
#include "engine.h"
#include "renderer/material.h"
#include "renderer/model.h"
#include "renderer/pipeline.h"
#include "renderer/render_scene.h"
#include "render_interface.h"
#include "world_editor.h"
#include <cmath>
@ -17,40 +14,33 @@ namespace Lumix
{
static const char* ICON_NAMES[EditorIcon::COUNT] = {
"models/editor/phy_controller_icon.msh",
"models/editor/phy_box_icon.msh",
"models/editor/camera_icon.msh",
"models/editor/directional_light_icon.msh",
"models/editor/terrain_icon.msh",
"models/editor/icon.msh"};
static Model* icon_models[EditorIcon::COUNT];
bool EditorIcon::loadIcons(Engine& engine)
static struct
{
bool status = true;
for (int i = 0; i < sizeof(ICON_NAMES) / sizeof(ICON_NAMES[0]); ++i)
const char* name;
RenderInterface::ModelHandle model;
} ICONS[EditorIcon::COUNT] = {
{ "models/editor/phy_controller_icon.msh", -1 },
{ "models/editor/phy_box_icon.msh", -1 },
{ "models/editor/camera_icon.msh", -1 },
{ "models/editor/directional_light_icon.msh", -1 },
{ "models/editor/terrain_icon.msh", -1 },
{ "models/editor/icon.msh", -1 } };
void EditorIcon::loadIcons(WorldEditor& editor)
{
for (int i = 0; i < lengthOf(ICONS); ++i)
{
icon_models[i] = static_cast<Model*>(engine.getResourceManager()
.get(ResourceManager::MODEL)
->load(Path(ICON_NAMES[i])));
status = status && icon_models[i];
ICONS[i].model = editor.getRenderInterface()->loadModel(Path(ICONS[i].name));
}
return status;
}
void EditorIcon::unloadIcons()
void EditorIcon::unloadIcons(WorldEditor& editor)
{
for (int i = 0; i < lengthOf(icon_models); ++i)
for (int i = 0; i < lengthOf(ICONS); ++i)
{
icon_models[i]
->getResourceManager()
.get(ResourceManager::MODEL)
->unload(*icon_models[i]);
editor.getRenderInterface()->unloadModel(ICONS[i].model);
}
}
@ -91,16 +81,12 @@ EditorIcon::EditorIcon(WorldEditor& editor, RenderScene& scene, Entity entity)
break;
}
}
m_model = static_cast<Model*>(editor.getEngine()
.getResourceManager()
.get(ResourceManager::MODEL)
->load(Path(ICON_NAMES[m_type])));
m_model = ICONS[m_type].model;
}
EditorIcon::~EditorIcon()
{
m_model->getResourceManager().get(ResourceManager::MODEL)->unload(*m_model);
}
@ -116,14 +102,13 @@ void EditorIcon::hide()
}
float EditorIcon::hit(const Vec3& origin, const Vec3& dir) const
float EditorIcon::hit(WorldEditor& editor, const Vec3& origin, const Vec3& dir) const
{
if (m_is_visible)
{
Matrix m = m_matrix;
m.multiply3x3(m_scale);
RayCastModelHit hit = m_model->castRay(origin, dir, m);
return hit.m_is_hit ? hit.m_t : -1;
return editor.getRenderInterface()->castRay(m_model, origin, dir, m);
}
else
{
@ -132,18 +117,18 @@ float EditorIcon::hit(const Vec3& origin, const Vec3& dir) const
}
void EditorIcon::render(Pipeline& pipeline)
void EditorIcon::render(WorldEditor& editor)
{
static const float MIN_SCALE_FACTOR = 10;
static const float MAX_SCALE_FACTOR = 60;
if (m_is_visible)
{
ComponentIndex camera = m_scene->getCameraInSlot("editor");
ComponentIndex camera = editor.getEditCamera().index;
if (camera < 0) return;
const Universe& universe = m_scene->getUniverse();
Lumix::Matrix mtx = universe.getMatrix(m_scene->getCameraEntity(camera));
const Universe& universe = *editor.getUniverse();
Lumix::Matrix mtx = universe.getMatrix(editor.getEditCamera().entity);
float fov = m_scene->getCameraFOV(camera);
float fov = editor.getRenderInterface()->getCameraFOV(camera);
Vec3 position = universe.getPosition(m_entity);
float distance = (position - mtx.getTranslation()).length();
@ -159,10 +144,7 @@ void EditorIcon::render(Pipeline& pipeline)
mtx = mtx * scale_mtx;
m_scale = scale;
if (m_model->isReady())
{
pipeline.renderModel(*m_model, mtx);
}
editor.getRenderInterface()->renderModel(m_model, mtx);
}
}

View file

@ -33,19 +33,19 @@ class EditorIcon
public:
EditorIcon(WorldEditor& editor, RenderScene& scene, Entity entity);
~EditorIcon();
void render(Pipeline& pipeline);
void render(WorldEditor& editor);
void show();
void hide();
float hit(const Vec3& origin, const Vec3& dir) const;
float hit(WorldEditor& editor, const Vec3& origin, const Vec3& dir) const;
Entity getEntity() const { return m_entity; }
static bool loadIcons(Engine& engine);
static void unloadIcons();
static void loadIcons(WorldEditor& editor);
static void unloadIcons(WorldEditor& editor);
private:
RenderScene* m_scene;
Entity m_entity;
Model* m_model;
int m_model;
Matrix m_matrix;
float m_scale;
bool m_is_visible;

View file

@ -7,12 +7,8 @@
#include "editor/gizmo.h"
#include "editor/world_editor.h"
#include "engine.h"
#include "renderer/model.h"
#include "renderer/pipeline.h"
#include "render_interface.h"
#include "renderer/render_scene.h"
#include "renderer/renderer.h"
#include "renderer/shader.h"
#include "renderer/transient_geometry.h"
#include "universe/universe.h"
#include <cfloat>
#include <cmath>
@ -29,19 +25,11 @@ static const uint32 Y_COLOR = 0xff63cf63;
static const uint32 Z_COLOR = 0xffcf6363;
static const uint32 SELECTED_COLOR = 0xff63cfcf;
struct Vertex
{
Vec3 position;
uint32 color;
float u, v;
};
Gizmo::Gizmo(WorldEditor& editor)
: m_editor(editor)
{
m_is_autosnap_down = false;
m_shader = nullptr;
m_pivot = Pivot::OBJECT_PIVOT;
m_coord_system = CoordSystem::LOCAL;
m_is_transforming = false;
@ -58,17 +46,12 @@ Gizmo::~Gizmo()
void Gizmo::destroy()
{
m_editor.getEngine().getResourceManager().get(ResourceManager::SHADER)->unload(*m_shader);
}
void Gizmo::create()
{
m_scale = 1;
m_shader = static_cast<Shader*>(m_editor.getEngine()
.getResourceManager()
.get(ResourceManager::SHADER)
->load(Path("shaders/debugline.shd")));
m_scene = static_cast<RenderScene*>(m_editor.getScene(crc32("renderer")));
}
@ -90,24 +73,8 @@ void Gizmo::getEnityMatrix(Matrix& mtx, int selection_index)
else if (m_pivot == Pivot::CENTER)
{
mtx = m_universe->getPositionAndRotation(entity);
ComponentIndex cmp = m_scene->getRenderableComponent(entity);
if (cmp >= 0)
{
Model* model = m_scene->getRenderableModel(cmp);
if (model && model->isReady())
{
Vec3 center = (model->getAABB().getMin() + model->getAABB().getMax()) * 0.5f;
mtx.setTranslation(mtx.multiplyPosition(center));
}
else
{
mtx = m_universe->getPositionAndRotation(entity);
}
}
else
{
mtx = m_universe->getPositionAndRotation(entity);
}
Vec3 center = m_editor.getRenderInterface()->getModelCenter(entity);
mtx.setTranslation(mtx.multiplyPosition(center));
}
else
{
@ -283,17 +250,15 @@ bool Gizmo::isHit()
}
void Gizmo::renderTranslateGizmo(Pipeline& pipeline)
void Gizmo::renderTranslateGizmo()
{
if (!m_shader->isReady()) return;
Matrix scale_mtx = Matrix::IDENTITY;
scale_mtx.m11 = scale_mtx.m22 = scale_mtx.m33 = m_scale;
Matrix gizmo_mtx;
getMatrix(gizmo_mtx);
Matrix mtx = gizmo_mtx * scale_mtx;
Vertex vertices[9];
RenderInterface::Vertex vertices[9];
uint16 indices[9];
vertices[0].position = Vec3(0, 0, 0);
vertices[0].color = m_transform_axis == Axis::X ? SELECTED_COLOR : X_COLOR;
@ -314,14 +279,7 @@ void Gizmo::renderTranslateGizmo(Pipeline& pipeline)
vertices[5].color = m_transform_axis == Axis::Z ? SELECTED_COLOR : Z_COLOR;
indices[5] = 5;
auto& renderer = static_cast<Lumix::Renderer&>(m_scene->getPlugin());
Lumix::TransientGeometry geom(vertices, 6, renderer.getBasicVertexDecl(), indices, 6);
pipeline.render(geom,
mtx,
0,
6,
BGFX_STATE_PT_LINES | BGFX_STATE_DEPTH_TEST_LEQUAL,
m_shader->getInstance(0).m_program_handles[pipeline.getPassIdx()]);
m_editor.getRenderInterface()->render(mtx, indices, 6, vertices, 6, true);
if (dotProduct(gizmo_mtx.getXVector(), m_camera_dir) < 0) mtx.setXVector(-mtx.getXVector());
if (dotProduct(gizmo_mtx.getYVector(), m_camera_dir) < 0) mtx.setYVector(-mtx.getYVector());
@ -357,15 +315,13 @@ void Gizmo::renderTranslateGizmo(Pipeline& pipeline)
vertices[8].color = m_transform_axis == Axis::XZ ? SELECTED_COLOR : Y_COLOR;
indices[8] = 8;
Lumix::TransientGeometry geom2(vertices, 9, renderer.getBasicVertexDecl(), indices, 9);
auto program_handle = m_shader->getInstance(0).m_program_handles[pipeline.getPassIdx()];
pipeline.render(geom2, mtx, 0, 9, BGFX_STATE_DEPTH_TEST_LEQUAL, program_handle);
m_editor.getRenderInterface()->render(mtx, indices, 9, vertices, 9, false);
}
void Gizmo::renderQuarterRing(Pipeline& pipeline, const Matrix& mtx, const Vec3& a, const Vec3& b, uint32 color)
void Gizmo::renderQuarterRing(const Matrix& mtx, const Vec3& a, const Vec3& b, uint32 color)
{
Vertex vertices[1200];
RenderInterface::Vertex vertices[1200];
uint16 indices[1200];
const float ANGLE_STEP = Math::degreesToRadians(1.0f / 100.0f * 360.0f);
Vec3 n = crossProduct(a, b) * 0.05f;
@ -412,14 +368,7 @@ void Gizmo::renderQuarterRing(Pipeline& pipeline, const Matrix& mtx, const Vec3&
indices[offset] = offset;
}
auto& renderer = static_cast<Lumix::Renderer&>(m_scene->getPlugin());
Lumix::TransientGeometry ring_geom(vertices, offset, renderer.getBasicVertexDecl(), indices, offset);
pipeline.render(ring_geom,
mtx,
0,
offset,
BGFX_STATE_DEPTH_TEST_LEQUAL,
m_shader->getInstance(0).m_program_handles[pipeline.getPassIdx()]);
m_editor.getRenderInterface()->render(mtx, indices, offset, vertices, offset, false);
const int GRID_SIZE = 5;
offset = -1;
@ -449,20 +398,12 @@ void Gizmo::renderQuarterRing(Pipeline& pipeline, const Matrix& mtx, const Vec3&
indices[offset] = offset;
}
Lumix::TransientGeometry plane_geom(vertices, offset, renderer.getBasicVertexDecl(), indices, offset);
pipeline.render(plane_geom,
mtx,
0,
offset,
BGFX_STATE_DEPTH_TEST_LEQUAL | BGFX_STATE_PT_LINES,
m_shader->getInstance(0).m_program_handles[pipeline.getPassIdx()]);
m_editor.getRenderInterface()->render(mtx, indices, offset, vertices, offset, true);
};
void Gizmo::renderRotateGizmo(Pipeline& pipeline)
void Gizmo::renderRotateGizmo()
{
if (!m_shader->isReady()) return;
Matrix scale_mtx = Matrix::IDENTITY;
scale_mtx.m11 = scale_mtx.m22 = scale_mtx.m33 = m_scale;
Matrix gizmo_mtx;
@ -480,9 +421,9 @@ void Gizmo::renderRotateGizmo(Pipeline& pipeline)
if (!m_is_transforming)
{
renderQuarterRing(pipeline, mtx, right, up, m_transform_axis == Axis::Z ? SELECTED_COLOR : Z_COLOR);
renderQuarterRing(pipeline, mtx, up, dir, m_transform_axis == Axis::X ? SELECTED_COLOR : X_COLOR);
renderQuarterRing(pipeline, mtx, right, dir, m_transform_axis == Axis::Y ? SELECTED_COLOR : Y_COLOR);
renderQuarterRing(mtx, right, up, m_transform_axis == Axis::Z ? SELECTED_COLOR : Z_COLOR);
renderQuarterRing(mtx, up, dir, m_transform_axis == Axis::X ? SELECTED_COLOR : X_COLOR);
renderQuarterRing(mtx, right, dir, m_transform_axis == Axis::Y ? SELECTED_COLOR : Y_COLOR);
}
else
{
@ -502,24 +443,24 @@ void Gizmo::renderRotateGizmo(Pipeline& pipeline)
axis2 = up;
break;
}
renderQuarterRing(pipeline, mtx, axis1, axis2, SELECTED_COLOR);
renderQuarterRing(pipeline, mtx, -axis1, axis2, SELECTED_COLOR);
renderQuarterRing(pipeline, mtx, -axis1, -axis2, SELECTED_COLOR);
renderQuarterRing(pipeline, mtx, axis1, -axis2, SELECTED_COLOR);
renderQuarterRing(mtx, axis1, axis2, SELECTED_COLOR);
renderQuarterRing(mtx, -axis1, axis2, SELECTED_COLOR);
renderQuarterRing(mtx, -axis1, -axis2, SELECTED_COLOR);
renderQuarterRing(mtx, axis1, -axis2, SELECTED_COLOR);
}
}
void Gizmo::render(Pipeline& pipeline)
void Gizmo::render()
{
if (m_editor.getSelectedEntities().empty()) return;
if (m_mode == Mode::TRANSLATE)
{
renderTranslateGizmo(pipeline);
renderTranslateGizmo();
}
else
{
renderRotateGizmo(pipeline);
renderRotateGizmo();
}
}

View file

@ -4,8 +4,6 @@
#include "lumix.h"
#include "core/vec.h"
#include "universe/universe.h"
#include "renderer/model.h"
#include <bgfx/bgfx.h>
namespace Lumix
@ -15,6 +13,7 @@ namespace Lumix
class Event;
struct Matrix;
class Pipeline;
class RenderInterface;
class RenderScene;
class Universe;
class WorldEditor;
@ -68,7 +67,7 @@ class LUMIX_EDITOR_API Gizmo
void setMode(Mode mode) { m_mode = mode; }
Mode getMode() const { return m_mode; }
void transform(ComponentIndex camera, int x, int y, int relx, int rely, bool use_step);
void render(Pipeline& pipeline);
void render();
bool isHit();
void togglePivot();
void toggleCoordSystem();
@ -83,9 +82,9 @@ class LUMIX_EDITOR_API Gizmo
Vec3 getMousePlaneIntersection(ComponentIndex camera, int x, int y);
void rotate(int relx, int rely, bool use_step);
float computeRotateAngle(int relx, int rely, bool use_step);
void renderTranslateGizmo(Pipeline& pipeline);
void renderRotateGizmo(Pipeline& pipeline);
void renderQuarterRing(Pipeline& pipeline, const Matrix& mtx, const Vec3& a, const Vec3& b, uint32 color);
void renderTranslateGizmo();
void renderRotateGizmo();
void renderQuarterRing(const Matrix& mtx, const Vec3& a, const Vec3& b, uint32 color);
private:
WorldEditor& m_editor;
@ -97,7 +96,6 @@ class LUMIX_EDITOR_API Gizmo
int m_relx_accum;
int m_rely_accum;
float m_scale;
class Shader* m_shader;
Pivot m_pivot;
Mode m_mode;
CoordSystem m_coord_system;

View file

@ -0,0 +1,45 @@
#pragma once
#include "lumix.h"
#include "core/aabb.h"
#include "core/matrix.h"
#include "core/path.h"
#include "core/vec.h"
namespace Lumix
{
class RenderInterface
{
public:
typedef int ModelHandle;
struct Vertex
{
Lumix::Vec3 position;
uint32 color;
float u, v;
};
public:
virtual AABB getEntityAABB(Universe& universe, Entity entity) = 0;
virtual float getCameraFOV(ComponentIndex cmp) = 0;
virtual float castRay(ModelHandle model, const Vec3& origin, const Vec3& dir, const Matrix& mtx) = 0;
virtual void renderModel(ModelHandle model, const Matrix& mtx) = 0;
virtual ModelHandle loadModel(Lumix::Path& path) = 0;
virtual void unloadModel(ModelHandle handle) = 0;
virtual Vec3 getModelCenter(Entity entity) = 0;
virtual void render(const Matrix& mtx,
uint16* indices,
int indices_count,
Vertex* vertices,
int vertices_count,
bool lines) = 0;
};
}

View file

@ -16,6 +16,7 @@
#include "core/json_serializer.h"
#include "core/log.h"
#include "core/matrix.h"
#include "core/path.h"
#include "core/path_utils.h"
#include "core/profiler.h"
#include "core/resource_manager.h"
@ -31,14 +32,12 @@
#include "editor/iproperty_descriptor.h"
#include "editor/property_register.h"
#include "engine.h"
#include "ieditor_command.h"
#include "iplugin.h"
#include "plugin_manager.h"
#include "renderer/material.h"
#include "renderer/model.h"
#include "render_interface.h"
#include "renderer/pipeline.h"
#include "renderer/render_scene.h"
#include "renderer/texture.h"
#include "ieditor_command.h"
#include "universe/universe.h"
@ -48,8 +47,6 @@ namespace Lumix
static const uint32 RENDERABLE_HASH = crc32("renderable");
static const uint32 CAMERA_HASH = crc32("camera");
static const uint32 GLOBAL_LIGHT_HASH = crc32("global_light");
static const uint32 POINT_LIGHT_HASH = crc32("point_light");
class SetEntityNameCommand : public IEditorCommand
@ -1425,148 +1422,6 @@ public:
Engine& getEngine() override { return *m_engine; }
Vec3 minCoords(const Vec3& a, const Vec3& b)
{
return Vec3(Math::minValue(a.x, b.x),
Math::minValue(a.y, b.y),
Math::minValue(a.z, b.z));
}
Vec3 maxCoords(const Vec3& a, const Vec3& b)
{
return Vec3(Math::maxValue(a.x, b.x),
Math::maxValue(a.y, b.y),
Math::maxValue(a.z, b.z));
}
void showPointLightGizmo(ComponentUID light)
{
RenderScene* scene = static_cast<RenderScene*>(light.scene);
Universe& universe = scene->getUniverse();
float range = scene->getLightRange(light.index);
Vec3 pos = universe.getPosition(light.entity);
scene->addDebugSphere(pos, range, 0xff0000ff, 0);
}
void showRenderableGizmo(ComponentUID renderable)
{
RenderScene* scene = static_cast<RenderScene*>(renderable.scene);
Universe& universe = scene->getUniverse();
Model* model = scene->getRenderableModel(renderable.index);
Vec3 points[8];
if (!model) return;
const AABB& aabb = model->getAABB();
points[0] = aabb.getMin();
points[7] = aabb.getMax();
points[1].set(points[0].x, points[0].y, points[7].z);
points[2].set(points[0].x, points[7].y, points[0].z);
points[3].set(points[0].x, points[7].y, points[7].z);
points[4].set(points[7].x, points[0].y, points[0].z);
points[5].set(points[7].x, points[0].y, points[7].z);
points[6].set(points[7].x, points[7].y, points[0].z);
Matrix mtx = universe.getMatrix(renderable.entity);
for (int j = 0; j < 8; ++j)
{
points[j] = mtx.multiplyPosition(points[j]);
}
Vec3 this_min = points[0];
Vec3 this_max = points[0];
for (int j = 0; j < 8; ++j)
{
this_min = minCoords(points[j], this_min);
this_max = maxCoords(points[j], this_max);
}
scene->addDebugCube(this_min, this_max, 0xffff0000, 0);
}
void showCameraGizmo(ComponentUID camera)
{
RenderScene* scene = static_cast<RenderScene*>(camera.scene);
Universe& universe = scene->getUniverse();
Vec3 pos = universe.getPosition(camera.entity);
float fov = scene->getCameraFOV(camera.index);
float near_distance = scene->getCameraNearPlane(camera.index);
float far_distance = scene->getCameraFarPlane(camera.index);
Vec3 dir = universe.getRotation(camera.entity) * Vec3(0, 0, -1);
Vec3 right = universe.getRotation(camera.entity) * Vec3(1, 0, 0);
Vec3 up = universe.getRotation(camera.entity) * Vec3(0, 1, 0);
float w = scene->getCameraWidth(camera.index);
float h = scene->getCameraHeight(camera.index);
float ratio = h < 1.0f ? 1 : w / h;
scene->addDebugFrustum(pos,
dir,
up,
fov,
ratio,
near_distance,
far_distance,
0xffff0000,
0);
}
void showGlobalLightGizmo(ComponentUID light)
{
RenderScene* scene = static_cast<RenderScene*>(light.scene);
Universe& universe = scene->getUniverse();
Vec3 pos = universe.getPosition(light.entity);
Vec3 dir = universe.getRotation(light.entity) * Vec3(0, 0, 1);
Vec3 right = universe.getRotation(light.entity) * Vec3(1, 0, 0);
Vec3 up = universe.getRotation(light.entity) * Vec3(0, 1, 0);
scene->addDebugLine(pos, pos + dir, 0xff0000ff, 0);
scene->addDebugLine(pos + right, pos + dir + right, 0xff0000ff, 0);
scene->addDebugLine(pos - right, pos + dir - right, 0xff0000ff, 0);
scene->addDebugLine(pos + up, pos + dir + up, 0xff0000ff, 0);
scene->addDebugLine(pos - up, pos + dir - up, 0xff0000ff, 0);
scene->addDebugLine(pos + right + up, pos + dir + right + up, 0xff0000ff, 0);
scene->addDebugLine(pos + right - up, pos + dir + right - up, 0xff0000ff, 0);
scene->addDebugLine(pos - right - up, pos + dir - right - up, 0xff0000ff, 0);
scene->addDebugLine(pos - right + up, pos + dir - right + up, 0xff0000ff, 0);
scene->addDebugSphere(pos - dir, 0.1f, 0xff0000ff, 0);
}
AABB getEntityAABB(Universe& universe, Entity entity)
{
AABB aabb;
ComponentUID cmp = getComponent(entity, RENDERABLE_HASH);
if (cmp.isValid())
{
RenderScene* scene = static_cast<RenderScene*>(cmp.scene);
Model* model = scene->getRenderableModel(cmp.index);
if (!model) return aabb;
aabb = model->getAABB();
aabb.transform(universe.getMatrix(entity));
return aabb;
}
Vec3 pos = universe.getPosition(entity);
aabb.set(pos, pos);
return aabb;
}
void showGizmos()
{
if (m_selected_entities.empty()) return;
@ -1577,11 +1432,11 @@ public:
if (m_selected_entities.size() > 1)
{
AABB aabb = getEntityAABB(*universe, m_selected_entities[0]);
AABB aabb = m_render_interface->getEntityAABB(*universe, m_selected_entities[0]);
for (int i = 1; i < m_selected_entities.size(); ++i)
{
AABB entity_aabb =
getEntityAABB(*universe, m_selected_entities[i]);
m_render_interface->getEntityAABB(*universe, m_selected_entities[i]);
aabb.merge(entity_aabb);
}
@ -1598,23 +1453,6 @@ public:
if (plugin->showGizmo(cmp))
break;
}
if (cmp.type == RENDERABLE_HASH)
{
showRenderableGizmo(cmp);
}
else if (cmp.type == CAMERA_HASH)
{
showCameraGizmo(cmp);
}
else if (cmp.type == GLOBAL_LIGHT_HASH)
{
showGlobalLightGizmo(cmp);
}
else if (cmp.type == POINT_LIGHT_HASH)
{
showPointLightGizmo(cmp);
}
}
}
@ -1683,7 +1521,7 @@ public:
auto& library_loaded_callback = m_engine->getPluginManager().libraryLoaded();
library_loaded_callback.unbind<WorldEditorImpl, &WorldEditorImpl::onPluginLibraryLoaded>(this);
EditorIcon::unloadIcons();
EditorIcon::unloadIcons(*this);
removePlugin(*m_measure_tool);
LUMIX_DELETE(m_allocator, m_measure_tool);
for (auto* plugin : m_plugins)
@ -1704,7 +1542,7 @@ public:
hit.m_t = -1;
for (int i = 0, c = m_editor_icons.size(); i < c; ++i)
{
float t = m_editor_icons[i]->hit(origin, dir);
float t = m_editor_icons[i]->hit(*this, origin, dir);
if (t >= 0)
{
hit.m_icon = m_editor_icons[i];
@ -1886,6 +1724,19 @@ public:
}
void setRenderInterface(class RenderInterface* interface) override
{
m_render_interface = interface;
EditorIcon::loadIcons(*this);
}
RenderInterface* getRenderInterface() override
{
return m_render_interface;
}
void snapDown() override
{
if (m_selected_entities.empty()) return;
@ -2537,6 +2388,7 @@ public:
}
}
void resetAndLoad(FS::IFile& file)
{
destroyUniverse();
@ -2561,12 +2413,12 @@ public:
}
void renderIcons(Pipeline& pipeline) override
void renderIcons() override
{
PROFILE_FUNCTION();
for (int i = 0, c = m_editor_icons.size(); i < c; ++i)
{
m_editor_icons[i]->render(pipeline);
m_editor_icons[i]->render(*this);
}
}
@ -2646,8 +2498,6 @@ public:
m_editor_command_creators.insert(
crc32("add_entity"), &WorldEditorImpl::constructEditorCommand<AddEntityCommand>);
EditorIcon::loadIcons(*m_engine);
plugin_manager.libraryLoaded().bind<WorldEditorImpl, &WorldEditorImpl::onPluginLibraryLoaded>(this);
const auto& libs = plugin_manager.getLibraries();
for (auto* lib : libs)
@ -3345,6 +3195,7 @@ private:
bool m_is_loading;
UniverseContext* m_universe_context;
EntityGroups m_entity_groups;
RenderInterface* m_render_interface;
};

View file

@ -3,7 +3,7 @@
#include "lumix.h"
#include "core/array.h"
#include "core/delegate_list.h"
#include "core/quat.h"
#include "core/vec.h"
#include "universe/component.h"
@ -18,7 +18,9 @@ class IPlugin;
class IPropertyDescriptor;
class Path;
class Pipeline;
class RayCastModelHit;
class RenderInterface;
struct Quat;
struct RayCastModelHit;
class Universe;
struct UniverseContext;
@ -70,6 +72,8 @@ public:
static WorldEditor* create(const char* base_path, Engine& engine, IAllocator& allocator);
static void destroy(WorldEditor* editor, IAllocator& allocator);
virtual void setRenderInterface(RenderInterface* interface) = 0;
virtual RenderInterface* getRenderInterface() = 0;
virtual void update() = 0;
virtual void updateEngine() = 0;
virtual void executeCommand(IEditorCommand* command) = 0;
@ -81,7 +85,7 @@ public:
virtual IScene* getScene(uint32 hash) = 0;
virtual IScene* getSceneByComponentType(uint32 hash) = 0;
virtual IAllocator& getAllocator() = 0;
virtual void renderIcons(Pipeline& pipeline) = 0;
virtual void renderIcons() = 0;
virtual ComponentUID getEditCamera() = 0;
virtual class Gizmo& getGizmo() = 0;
virtual void setGizmoUseStep(bool use) = 0;

View file

@ -8,17 +8,16 @@
namespace Lumix
{
class LUMIX_RENDERER_API RayCastModelHit
struct LUMIX_RENDERER_API RayCastModelHit
{
public:
bool m_is_hit;
float m_t;
Vec3 m_origin;
Vec3 m_dir;
class Mesh* m_mesh;
ComponentIndex m_component;
Entity m_entity;
uint32 m_component_type;
bool m_is_hit;
float m_t;
Vec3 m_origin;
Vec3 m_dir;
class Mesh* m_mesh;
ComponentIndex m_component;
Entity m_entity;
uint32 m_component_type;
};
} // ~ namespace Lumix

View file

@ -14,6 +14,7 @@
#include "engine/engine.h"
#include "engine/plugin_manager.h"
#include "game_view.h"
#include "editor/render_interface.h"
#include "renderer/material.h"
#include "renderer/model.h"
#include "renderer/pipeline.h"
@ -1126,16 +1127,156 @@ struct TerrainPlugin : public PropertyGrid::IPlugin
struct SceneViewPlugin : public StudioApp::IPlugin
{
SceneViewPlugin(StudioApp& app)
struct RenderInterfaceImpl : public RenderInterface
{
m_action = LUMIX_NEW(app.getWorldEditor()->getAllocator(), Action)("Scene View", "scene_view");
ModelHandle loadModel(Lumix::Path& path) override
{
auto& rm = m_editor.getEngine().getResourceManager();
m_models.insert(m_model_index, static_cast<Model*>(rm.get(ResourceManager::MODEL)->load(path)));
++m_model_index;
return m_model_index - 1;
}
AABB getEntityAABB(Universe& universe, Entity entity) override
{
AABB aabb;
auto cmp = m_render_scene->getRenderableComponent(entity);
if (cmp != INVALID_COMPONENT)
{
Model* model = m_render_scene->getRenderableModel(cmp);
if (!model) return aabb;
aabb = model->getAABB();
aabb.transform(universe.getMatrix(entity));
return aabb;
}
Vec3 pos = universe.getPosition(entity);
aabb.set(pos, pos);
return aabb;
}
void unloadModel(ModelHandle handle) override
{
auto* model = m_models[handle];
model->getResourceManager().get(ResourceManager::MODEL)->unload(*model);
m_models.erase(handle);
}
float getCameraFOV(ComponentIndex cmp) override
{
return m_render_scene->getCameraFOV(cmp);
}
float castRay(ModelHandle model, const Vec3& origin, const Vec3& dir, const Matrix& mtx) override
{
RayCastModelHit hit = m_models[model]->castRay(origin, dir, mtx);
return hit.m_is_hit ? hit.m_t : -1;
}
void renderModel(ModelHandle model, const Matrix& mtx) override
{
if (m_pipeline.isReady()) m_pipeline.renderModel(*m_models[model], mtx);
}
RenderInterfaceImpl(Lumix::WorldEditor& editor, Lumix::Pipeline& pipeline)
: m_pipeline(pipeline)
, m_editor(editor)
, m_models(editor.getAllocator())
{
m_model_index = -1;
auto& rm = editor.getEngine().getResourceManager();
Path shader_path("shaders/debugline.shd");
m_shader = static_cast<Shader*>(rm.get(ResourceManager::SHADER)->load(shader_path));
editor.universeCreated().bind<RenderInterfaceImpl, &RenderInterfaceImpl::onUniverseCreated>(this);
editor.universeDestroyed().bind<RenderInterfaceImpl, &RenderInterfaceImpl::onUniverseDestroyed>(this);
onUniverseCreated();
}
~RenderInterfaceImpl()
{
m_editor.universeCreated().bind<RenderInterfaceImpl, &RenderInterfaceImpl::onUniverseCreated>(this);
m_editor.universeDestroyed().bind<RenderInterfaceImpl, &RenderInterfaceImpl::onUniverseDestroyed>(this);
}
void onUniverseCreated()
{
m_render_scene = static_cast<RenderScene*>(m_editor.getUniverseContext()->getScene(crc32("renderer")));
}
void onUniverseDestroyed()
{
m_render_scene = nullptr;
}
Vec3 getModelCenter(Entity entity) override
{
auto cmp = m_render_scene->getRenderableComponent(entity);
Model* model = m_render_scene->getRenderableModel(cmp);
if (!model) return Vec3(0, 0, 0);
return (model->getAABB().getMin() + model->getAABB().getMax()) * 0.5f;
}
void render(const Matrix& mtx,
uint16* indices,
int indices_count,
Vertex* vertices,
int vertices_count,
bool lines) override
{
auto& renderer = static_cast<Lumix::Renderer&>(m_render_scene->getPlugin());
Lumix::TransientGeometry geom(
vertices, vertices_count, renderer.getBasicVertexDecl(), indices, indices_count);
uint64 flags = BGFX_STATE_DEPTH_TEST_LEQUAL;
if (lines) flags |= BGFX_STATE_PT_LINES;
m_pipeline.render(geom,
mtx,
0,
indices_count,
flags,
m_shader->getInstance(0).m_program_handles[m_pipeline.getPassIdx()]);
}
Lumix::WorldEditor& m_editor;
Lumix::Shader* m_shader;
Lumix::RenderScene* m_render_scene;
Lumix::Pipeline& m_pipeline;
Lumix::PODHashMap<int, Model*> m_models;
int m_model_index;
};
SceneViewPlugin(StudioApp& app)
: m_app(app)
{
auto& editor = *app.getWorldEditor();
auto& allocator = editor.getAllocator();
m_action = LUMIX_NEW(allocator, Action)("Scene View", "scene_view");
m_action->func.bind<SceneViewPlugin, &SceneViewPlugin::onAction>(this);
m_scene_view.init(*app.getWorldEditor(), app.getActions());
m_scene_view.init(editor, app.getActions());
m_render_interface = LUMIX_NEW(allocator, RenderInterfaceImpl)(editor, *m_scene_view.getPipeline());
editor.setRenderInterface(m_render_interface);
}
~SceneViewPlugin()
{
m_scene_view.shutdown();
}
@ -1144,8 +1285,9 @@ struct SceneViewPlugin : public StudioApp::IPlugin
void onAction() {}
void onWindowGUI() override { m_scene_view.onGUI(); }
StudioApp& m_app;
SceneView m_scene_view;
RenderInterfaceImpl* m_render_interface;
};
@ -1398,6 +1540,145 @@ struct ShaderEditorPlugin : public StudioApp::IPlugin
};
static const uint32 CAMERA_HASH = crc32("camera");
static const uint32 POINT_LIGHT_HASH = crc32("point_light");
static const uint32 GLOBAL_LIGHT_HASH = crc32("global_light");
static const uint32 RENDERABLE_HASH = crc32("renderable");
struct WorldEditorPlugin : public WorldEditor::Plugin
{
void showPointLightGizmo(ComponentUID light)
{
RenderScene* scene = static_cast<RenderScene*>(light.scene);
Universe& universe = scene->getUniverse();
float range = scene->getLightRange(light.index);
Vec3 pos = universe.getPosition(light.entity);
scene->addDebugSphere(pos, range, 0xff0000ff, 0);
}
static Vec3 minCoords(const Vec3& a, const Vec3& b)
{
return Vec3(Math::minValue(a.x, b.x),
Math::minValue(a.y, b.y),
Math::minValue(a.z, b.z));
}
static Vec3 maxCoords(const Vec3& a, const Vec3& b)
{
return Vec3(Math::maxValue(a.x, b.x),
Math::maxValue(a.y, b.y),
Math::maxValue(a.z, b.z));
}
void showRenderableGizmo(ComponentUID renderable)
{
RenderScene* scene = static_cast<RenderScene*>(renderable.scene);
Universe& universe = scene->getUniverse();
Model* model = scene->getRenderableModel(renderable.index);
Vec3 points[8];
if (!model) return;
const AABB& aabb = model->getAABB();
points[0] = aabb.getMin();
points[7] = aabb.getMax();
points[1].set(points[0].x, points[0].y, points[7].z);
points[2].set(points[0].x, points[7].y, points[0].z);
points[3].set(points[0].x, points[7].y, points[7].z);
points[4].set(points[7].x, points[0].y, points[0].z);
points[5].set(points[7].x, points[0].y, points[7].z);
points[6].set(points[7].x, points[7].y, points[0].z);
Matrix mtx = universe.getMatrix(renderable.entity);
for (int j = 0; j < 8; ++j)
{
points[j] = mtx.multiplyPosition(points[j]);
}
Vec3 this_min = points[0];
Vec3 this_max = points[0];
for (int j = 0; j < 8; ++j)
{
this_min = minCoords(points[j], this_min);
this_max = maxCoords(points[j], this_max);
}
scene->addDebugCube(this_min, this_max, 0xffff0000, 0);
}
void showGlobalLightGizmo(ComponentUID light)
{
RenderScene* scene = static_cast<RenderScene*>(light.scene);
Universe& universe = scene->getUniverse();
Vec3 pos = universe.getPosition(light.entity);
Vec3 dir = universe.getRotation(light.entity) * Vec3(0, 0, 1);
Vec3 right = universe.getRotation(light.entity) * Vec3(1, 0, 0);
Vec3 up = universe.getRotation(light.entity) * Vec3(0, 1, 0);
scene->addDebugLine(pos, pos + dir, 0xff0000ff, 0);
scene->addDebugLine(pos + right, pos + dir + right, 0xff0000ff, 0);
scene->addDebugLine(pos - right, pos + dir - right, 0xff0000ff, 0);
scene->addDebugLine(pos + up, pos + dir + up, 0xff0000ff, 0);
scene->addDebugLine(pos - up, pos + dir - up, 0xff0000ff, 0);
scene->addDebugLine(pos + right + up, pos + dir + right + up, 0xff0000ff, 0);
scene->addDebugLine(pos + right - up, pos + dir + right - up, 0xff0000ff, 0);
scene->addDebugLine(pos - right - up, pos + dir - right - up, 0xff0000ff, 0);
scene->addDebugLine(pos - right + up, pos + dir - right + up, 0xff0000ff, 0);
scene->addDebugSphere(pos - dir, 0.1f, 0xff0000ff, 0);
}
bool showGizmo(ComponentUID cmp) override
{
if (cmp.type == CAMERA_HASH)
{
RenderScene* scene = static_cast<RenderScene*>(cmp.scene);
Universe& universe = scene->getUniverse();
Vec3 pos = universe.getPosition(cmp.entity);
float fov = scene->getCameraFOV(cmp.index);
float near_distance = scene->getCameraNearPlane(cmp.index);
float far_distance = scene->getCameraFarPlane(cmp.index);
Vec3 dir = universe.getRotation(cmp.entity) * Vec3(0, 0, -1);
Vec3 right = universe.getRotation(cmp.entity) * Vec3(1, 0, 0);
Vec3 up = universe.getRotation(cmp.entity) * Vec3(0, 1, 0);
float w = scene->getCameraWidth(cmp.index);
float h = scene->getCameraHeight(cmp.index);
float ratio = h < 1.0f ? 1 : w / h;
scene->addDebugFrustum(
pos, dir, up, fov, ratio, near_distance, far_distance, 0xffff0000, 0);
return true;
}
if (cmp.type == POINT_LIGHT_HASH)
{
showPointLightGizmo(cmp);
return true;
}
if (cmp.type == GLOBAL_LIGHT_HASH)
{
showGlobalLightGizmo(cmp);
return true;
}
if (cmp.type == RENDERABLE_HASH)
{
showRenderableGizmo(cmp);
return true;
}
return false;
}
};
extern "C" {
@ -1433,6 +1714,9 @@ LUMIX_LIBRARY_EXPORT void setStudioApp(StudioApp& app)
auto* shader_editor_plugin =
LUMIX_NEW(app.getWorldEditor()->getAllocator(), ShaderEditorPlugin)(app);
app.addPlugin(*shader_editor_plugin);
auto* world_editor_plugin = LUMIX_NEW(app.getWorldEditor()->getAllocator(), WorldEditorPlugin)();
app.getWorldEditor()->addPlugin(*world_editor_plugin);
}

View file

@ -1,5 +1,6 @@
#include "scene_view.h"
#include "core/crc32.h"
#include "core/path.h"
#include "core/profiler.h"
#include "core/resource_manager.h"
#include "editor/gizmo.h"
@ -142,9 +143,9 @@ void SceneView::update()
void SceneView::renderGizmos()
{
m_editor->renderIcons(*m_pipeline);
m_editor->renderIcons();
m_editor->getGizmo().updateScale(m_editor->getEditCamera().index);
m_editor->getGizmo().render(*m_pipeline);
m_editor->getGizmo().render();
}

View file

@ -26,6 +26,7 @@ class SceneView
void shutdown();
void onGUI();
void setWireframe(bool wireframe);
Lumix::Pipeline* getPipeline() { return m_pipeline; }
private:
void renderGizmos();