1800 lines
52 KiB
C++
1800 lines
52 KiB
C++
#include <iostream>
|
|
#include <OgreOverlaySystem.h>
|
|
#include <OgreOverlayManager.h>
|
|
#include <OgreImGuiOverlay.h>
|
|
#include <OgreImGuiInputListener.h>
|
|
#include <OgreRenderTargetListener.h>
|
|
#include <OgreSceneNode.h>
|
|
#include <OgreApplicationContext.h>
|
|
#include <OgreImGuiInputListener.h>
|
|
#include <OgreFontManager.h>
|
|
#include <OgreTerrainGroup.h>
|
|
#include <OgrePagedWorld.h>
|
|
#include <OgreTerrainPaging.h>
|
|
#include <OgreTerrainPagedWorldSection.h>
|
|
#include <nlohmann/json.hpp>
|
|
#include "GameData.h"
|
|
#include "Components.h"
|
|
#include "LuaData.h"
|
|
#include "AppModule.h"
|
|
#include "TerrainModule.h"
|
|
#include "StaticGeometryModule.h"
|
|
#include "EditorGizmoModule.h"
|
|
#include "PhysicsModule.h"
|
|
#include "items.h"
|
|
#include "GUIModule.h"
|
|
namespace ECS
|
|
{
|
|
struct GUIListener;
|
|
struct EditorGUIListener;
|
|
struct GUIData {
|
|
Ogre::ImGuiOverlay *mGuiOverlay;
|
|
std::vector<Ogre::String> glb_names;
|
|
GUIListener *mGUIListener;
|
|
};
|
|
struct EditorGUIData {
|
|
Ogre::ImGuiOverlay *mGuiOverlay;
|
|
std::vector<Ogre::String> glb_names;
|
|
EditorGUIListener *mGUIListener;
|
|
};
|
|
struct GUIListener : public Ogre::RenderTargetListener {
|
|
float panel_width;
|
|
bool enableEditor;
|
|
bool enableMapEditor;
|
|
ImFont *smallFont, *midFont, *bigFont;
|
|
Ogre::FontPtr _smallFont, _midFont, _bigFont;
|
|
GUIListener()
|
|
: Ogre::RenderTargetListener()
|
|
{
|
|
_midFont = createFont("midFont", "General",
|
|
"Jupiteroid-Regular.ttf", 18.0f);
|
|
_smallFont = createFont("smallFont", "General",
|
|
"Jupiteroid-Regular.ttf", 13.0f);
|
|
_bigFont = createFont("bigFont", "General", "Kenney Bold.ttf",
|
|
32.0f);
|
|
smallFont = ECS::get<GUIData>().mGuiOverlay->addFont(
|
|
"smallFont", "General");
|
|
OgreAssert(smallFont, "Could not load font");
|
|
midFont = ECS::get<GUIData>().mGuiOverlay->addFont("midFont",
|
|
"General");
|
|
OgreAssert(midFont, "Could not load font");
|
|
bigFont = ECS::get<GUIData>().mGuiOverlay->addFont("bigFont",
|
|
"General");
|
|
OgreAssert(bigFont, "Could not load font");
|
|
#if 0
|
|
Ogre::FontPtr _midFont = createFont("midFont", "General",
|
|
"Kenney Bold.ttf", 28.0f);
|
|
#endif
|
|
#if 0
|
|
ImGui::GetIO().Fonts->Build();
|
|
#endif
|
|
}
|
|
Ogre::FontPtr createFont(const Ogre::String &name,
|
|
const Ogre::String &group,
|
|
const Ogre::String &ttfname, float fontSize)
|
|
{
|
|
Ogre::FontPtr ret =
|
|
Ogre::FontManager::getSingleton().create(name, group);
|
|
ret->setType(Ogre::FontType::FT_TRUETYPE);
|
|
ret->setSource(ttfname);
|
|
ret->setTrueTypeSize(fontSize);
|
|
ret->setTrueTypeResolution(75);
|
|
ret->addCodePointRange(Ogre::Font::CodePointRange(30, 128));
|
|
ret->load();
|
|
return ret;
|
|
}
|
|
void
|
|
preViewportUpdate(const Ogre::RenderTargetViewportEvent &evt) override
|
|
{
|
|
preview(evt);
|
|
}
|
|
void buttons_panel()
|
|
{
|
|
ImVec2 size = ImGui::GetMainViewport()->Size;
|
|
float window_width = size.x * 0.2f;
|
|
if (window_width > panel_width)
|
|
window_width = panel_width;
|
|
float window_height = size.y * 0.5f - 20;
|
|
ImGui::SetNextWindowPos(ImVec2(0, size.y * 0.5f + 20),
|
|
ImGuiCond_Always);
|
|
ImGui::SetNextWindowSize(ImVec2(window_width, window_height),
|
|
ImGuiCond_Always);
|
|
ImGui::Begin("Control");
|
|
// if (ECS::get().get<GUI>().enabled)
|
|
// ECS::get().get<App>().app->setWindowGrab(true);
|
|
if (ImGui::Button("Quit"))
|
|
Ogre::Root::getSingleton().queueEndRendering();
|
|
if (ImGui::Button("Return"))
|
|
ECS::get().get<GUI>().finish();
|
|
if (ImGui::Button("Enable/Disable item editor")) {
|
|
enableEditor ^= true;
|
|
if (enableEditor)
|
|
enableMapEditor = false;
|
|
}
|
|
if (ImGui::Button("Enable/Disable map editor")) {
|
|
enableMapEditor ^= true;
|
|
if (enableMapEditor)
|
|
enableEditor = false;
|
|
}
|
|
ImGui::Text("Text message...");
|
|
ImGui::End();
|
|
}
|
|
void create_entity_node(const Ogre::String &name, int key)
|
|
{
|
|
Ogre::Entity *ent =
|
|
ECS::get().get<EngineData>().mScnMgr->createEntity(
|
|
name);
|
|
Ogre::SceneNode *pnode =
|
|
ECS::get()
|
|
.get<EngineData>()
|
|
.mScnMgr->getRootSceneNode()
|
|
->createChildSceneNode(
|
|
"ent:" + name +
|
|
Ogre::StringConverter::toString(
|
|
key),
|
|
ECS::get()
|
|
.get<Camera>()
|
|
.mCameraPivot->getPosition(),
|
|
ECS::get()
|
|
.get<Camera>()
|
|
.mCameraPivot->getOrientation());
|
|
pnode->attachObject(ent);
|
|
Ogre::Quaternion q = pnode->getOrientation();
|
|
Ogre::Radian yaw = q.getYaw();
|
|
Ogre::Quaternion nq(yaw, Ogre::Vector3(0, 1, 0));
|
|
pnode->setOrientation(nq);
|
|
|
|
ECS::get().get<GUI>().finish();
|
|
}
|
|
void buildings_editor()
|
|
{
|
|
int i;
|
|
ImVec2 size = ImGui::GetMainViewport()->Size;
|
|
float window_width = size.x * 0.2f;
|
|
if (window_width > panel_width)
|
|
window_width = panel_width;
|
|
float window_height = size.y * 0.5 - 20;
|
|
ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_Always);
|
|
ImGui::SetNextWindowSize(ImVec2(window_width, window_height),
|
|
ImGuiCond_Always);
|
|
ImGui::Begin("Droppings...");
|
|
for (i = 0; i < ECS::get().get<GUIData>().glb_names.size();
|
|
i++) {
|
|
Ogre::String id_button =
|
|
"Create entity: " +
|
|
ECS::get().get<GUIData>().glb_names[i] +
|
|
"##ent:" +
|
|
ECS::get().get<GUIData>().glb_names[i];
|
|
if (ImGui::Button(id_button.c_str())) {
|
|
create_entity_node(
|
|
ECS::get().get<GUIData>().glb_names[i],
|
|
i);
|
|
}
|
|
}
|
|
ImGui::End();
|
|
}
|
|
void position_editor(Ogre::SceneNode *node)
|
|
{
|
|
Ogre::Vector3 position = node->getPosition();
|
|
float v[3] = { position.x, position.y, position.z };
|
|
ImGui::InputFloat3("position", v);
|
|
position.x = v[0];
|
|
position.y = v[1];
|
|
position.z = v[2];
|
|
node->setPosition(position);
|
|
}
|
|
void orientation_editor(Ogre::SceneNode *node)
|
|
{
|
|
Ogre::Quaternion q = node->getOrientation();
|
|
float yaw = Ogre::Radian(q.getYaw()).valueDegrees();
|
|
float pitch = Ogre::Radian(q.getPitch()).valueDegrees();
|
|
float roll = Ogre::Radian(q.getRoll()).valueDegrees();
|
|
bool m1 = ImGui::InputFloat("yaw", &yaw);
|
|
bool m2 = ImGui::InputFloat("pitch", &pitch);
|
|
bool m3 = ImGui::InputFloat("roll", &roll);
|
|
if (m1 || m2 || m3) {
|
|
Ogre::Quaternion q1(Ogre::Radian(Ogre::Degree(yaw)),
|
|
Ogre::Vector3::UNIT_Y);
|
|
Ogre::Quaternion q2(Ogre::Degree(pitch),
|
|
Ogre::Vector3::UNIT_X);
|
|
Ogre::Quaternion q3(Ogre::Degree(roll),
|
|
Ogre::Vector3::UNIT_Z);
|
|
node->setOrientation(q1 * q2 * q3);
|
|
}
|
|
}
|
|
void attachments_editor(Ogre::SceneNode *node)
|
|
{
|
|
const Ogre::SceneNode::ObjectMap &pmap =
|
|
node->getAttachedObjects();
|
|
int i;
|
|
for (i = 0; i < pmap.size(); i++) {
|
|
const Ogre::MovableObject *mobj = pmap[i];
|
|
const Ogre::String &pname = mobj->getName();
|
|
ImGui::Text("Name: %s", pname.c_str());
|
|
}
|
|
}
|
|
void map_editor()
|
|
{
|
|
}
|
|
void preview(const Ogre::RenderTargetViewportEvent &evt)
|
|
{
|
|
int i;
|
|
Ogre::ImGuiOverlay::NewFrame();
|
|
if (ECS::get().get<EngineData>().startupDelay > 0.0f) {
|
|
ImVec2 size = ImGui::GetMainViewport()->Size;
|
|
ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_Always);
|
|
ImGui::SetNextWindowSize(ImVec2(size.x, size.y),
|
|
ImGuiCond_Always);
|
|
ImGui::Begin(
|
|
"StartupScreen", nullptr,
|
|
ImGuiWindowFlags_NoTitleBar |
|
|
ImGuiWindowFlags_NoDecoration |
|
|
|
|
ImGuiWindowFlags_NoResize |
|
|
ImGuiWindowFlags_NoMove |
|
|
ImGuiWindowFlags_NoCollapse |
|
|
ImGuiWindowFlags_NoFocusOnAppearing |
|
|
ImGuiWindowFlags_NoInputs);
|
|
// if (ECS::get().get<GUI>().enabled)
|
|
// ECS::get().get<App>().app->setWindowGrab(true);
|
|
ImGui::PushFont(bigFont);
|
|
ImGui::TextWrapped(
|
|
"%s",
|
|
"This game does not autosave. Please use save function to keep your state");
|
|
ImGui::PopFont();
|
|
ImGui::End();
|
|
} else if (ECS::get().get<GUI>().enabled) {
|
|
if (ECS::get().get<GUI>().narrationBox) {
|
|
ImVec2 size = ImGui::GetMainViewport()->Size;
|
|
ImGui::SetNextWindowPos(ImVec2(0,
|
|
size.y * 0.75f),
|
|
ImGuiCond_Always);
|
|
ImGui::SetNextWindowSize(ImVec2(size.x,
|
|
size.y * 0.25f),
|
|
ImGuiCond_Always);
|
|
ImGui::Begin("Narration...", NULL,
|
|
ImGuiWindowFlags_NoTitleBar);
|
|
ImGui::PushFont(midFont);
|
|
ImVec2 p = ImGui::GetCursorScreenPos();
|
|
ImGui::TextWrapped(
|
|
"%s", ECS::get()
|
|
.get<GUI>()
|
|
.narrationText.c_str());
|
|
if (ECS::get().get<GUI>().choices.size() == 0) {
|
|
ImGui::SetCursorScreenPos(p);
|
|
if (ImGui::InvisibleButton(
|
|
"Background",
|
|
ImGui::GetWindowSize()))
|
|
ECS::get<LuaBase>().mLua->call_handler(
|
|
"narration_progress");
|
|
} else {
|
|
int i;
|
|
for (i = 0; i < ECS::get()
|
|
.get<GUI>()
|
|
.choices.size();
|
|
i++) {
|
|
if (ImGui::Button(
|
|
ECS::get()
|
|
.get<GUI>()
|
|
.choices[i]
|
|
.c_str())) {
|
|
ECS::get()
|
|
.get_mut<GUI>()
|
|
.narration_answer =
|
|
i + 1;
|
|
std::cout << "answer: "
|
|
<< i + 1
|
|
<< std::endl;
|
|
ECS::modified<GUI>();
|
|
ECS::get<LuaBase>()
|
|
.mLua
|
|
->call_handler(
|
|
"narration_answered");
|
|
}
|
|
}
|
|
}
|
|
ImGui::Spacing();
|
|
ImGui::PopFont();
|
|
ImGui::End();
|
|
} else if (ECS::get().get<GUI>().mainMenu) {
|
|
ImVec2 size = ImGui::GetMainViewport()->Size;
|
|
ImGui::SetNextWindowPos(ImVec2(0, 0),
|
|
ImGuiCond_Always);
|
|
ImGui::SetNextWindowSize(ImVec2(size.x, size.y),
|
|
ImGuiCond_Always);
|
|
ImGui::Begin(
|
|
"MainMenu", nullptr,
|
|
ImGuiWindowFlags_NoTitleBar |
|
|
ImGuiWindowFlags_NoDecoration |
|
|
|
|
ImGuiWindowFlags_NoResize |
|
|
ImGuiWindowFlags_NoMove |
|
|
ImGuiWindowFlags_NoCollapse |
|
|
ImGuiWindowFlags_NoFocusOnAppearing |
|
|
0);
|
|
// if (ECS::get().get<GUI>().enabled)
|
|
// ECS::get().get<App>().app->setWindowGrab(true);
|
|
ImGui::PushFont(bigFont);
|
|
ImGui::TextWrapped("%s", "Booo!!!!");
|
|
bool pressed = false;
|
|
bool new_game = false, cont = false,
|
|
load_game = false, opts = false,
|
|
quit = false;
|
|
ImGui::SetCursorPosY(size.y / 2.0f - 300.0f);
|
|
ImGui::SetCursorPosX(size.x / 2.0f - 300.0f);
|
|
new_game = ImGui::Button("New Game");
|
|
ImGui::SetCursorPosX(size.x / 2.0f - 300.0f);
|
|
cont = ImGui::Button("Continue");
|
|
ImGui::SetCursorPosX(size.x / 2.0f - 300.0f);
|
|
load_game = ImGui::Button("Load Game");
|
|
ImGui::SetCursorPosX(size.x / 2.0f - 300.0f);
|
|
opts = ImGui::Button("Options");
|
|
ImGui::SetCursorPosX(size.x / 2.0f - 300.0f);
|
|
quit = ImGui::Button("Quit###quit");
|
|
pressed = new_game || cont || load_game ||
|
|
opts || quit;
|
|
ImGui::PopFont();
|
|
ImGui::Spacing();
|
|
ImGui::End();
|
|
if (quit)
|
|
Ogre::Root::getSingleton()
|
|
.queueEndRendering();
|
|
if (pressed)
|
|
ECS::get().get<GUI>().finish();
|
|
if (new_game) {
|
|
ECS::get<LuaBase>().mLua->call_handler(
|
|
"new_game");
|
|
}
|
|
} else {
|
|
buttons_panel();
|
|
if (enableEditor)
|
|
buildings_editor();
|
|
if (enableMapEditor)
|
|
map_editor();
|
|
ImVec2 size = ImGui::GetMainViewport()->Size;
|
|
float window_width = size.x * 0.2f;
|
|
if (window_width > panel_width)
|
|
window_width = panel_width;
|
|
float window_height = size.y * 0.5f - 20;
|
|
ImGui::SetNextWindowPos(
|
|
ImVec2(size.x - window_width,
|
|
size.y * 0.5f + 20),
|
|
ImGuiCond_Always);
|
|
ImGui::SetNextWindowSize(ImVec2(window_width,
|
|
window_height),
|
|
ImGuiCond_Always);
|
|
// ImGui::Begin("Dumb and Stupid", &mKbd.gui_active);
|
|
ImGui::Begin("Panel...");
|
|
std::deque<Ogre::SceneNode *> tree_input_queue,
|
|
tree_output_queue;
|
|
std::vector<Ogre::SceneNode *> tree_list;
|
|
tree_input_queue.push_back(
|
|
ECS::get()
|
|
.get<EngineData>()
|
|
.mScnMgr->getRootSceneNode());
|
|
tree_input_queue.push_back(nullptr);
|
|
std::set<Ogre::SceneNode *> visited;
|
|
while (true) {
|
|
int new_nodes_count = 0;
|
|
while (!tree_input_queue.empty()) {
|
|
int child;
|
|
Ogre::SceneNode *item =
|
|
tree_input_queue.front();
|
|
tree_input_queue.pop_front();
|
|
if (item &&
|
|
visited.find(item) ==
|
|
visited.end()) { // new node
|
|
new_nodes_count++;
|
|
tree_output_queue
|
|
.push_back(
|
|
item);
|
|
visited.insert(item);
|
|
const Ogre::Node::ChildNodeMap
|
|
&children =
|
|
item->getChildren();
|
|
for (child = 0;
|
|
child <
|
|
children.size();
|
|
child++) {
|
|
tree_output_queue
|
|
.push_back(static_cast<
|
|
Ogre::SceneNode
|
|
*>(
|
|
children[child]));
|
|
tree_output_queue
|
|
.push_back(
|
|
nullptr);
|
|
}
|
|
} else
|
|
tree_output_queue
|
|
.push_back(
|
|
item);
|
|
}
|
|
if (new_nodes_count == 0)
|
|
break;
|
|
tree_input_queue = tree_output_queue;
|
|
tree_output_queue.clear();
|
|
}
|
|
tree_list.insert(tree_list.begin(),
|
|
tree_output_queue.begin(),
|
|
tree_output_queue.end());
|
|
int count = 0;
|
|
int depth = 0;
|
|
std::vector<int> check_depth;
|
|
int max_depth = 0;
|
|
check_depth.push_back(0);
|
|
for (count = 0; count < tree_list.size();
|
|
count++) {
|
|
int t;
|
|
|
|
Ogre::SceneNode *node =
|
|
tree_list[count];
|
|
if (node && max_depth >= depth) {
|
|
Ogre::String name =
|
|
node->getName();
|
|
if (name.length() == 0) {
|
|
name = "Node #" +
|
|
Ogre::StringConverter::
|
|
toString(
|
|
count);
|
|
}
|
|
if (ImGui::TreeNode(
|
|
name.c_str())) {
|
|
check_depth.push_back(
|
|
max_depth);
|
|
max_depth++;
|
|
ImGui::Text(
|
|
"%s",
|
|
(name +
|
|
"##caption")
|
|
.c_str());
|
|
position_editor(node);
|
|
ImGui::Separator();
|
|
orientation_editor(
|
|
node);
|
|
ImGui::Separator();
|
|
ImGui::Text(
|
|
"Attachments");
|
|
attachments_editor(
|
|
node);
|
|
}
|
|
} else if (!node &&
|
|
max_depth >= depth) {
|
|
max_depth = check_depth.back();
|
|
check_depth.pop_back();
|
|
ImGui::TreePop();
|
|
}
|
|
if (tree_list[count])
|
|
depth++;
|
|
else
|
|
depth--;
|
|
}
|
|
ImGui::Spacing();
|
|
ImGui::End();
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
struct EditorGUIListener : public Ogre::RenderTargetListener {
|
|
float panel_width;
|
|
bool enableEditor;
|
|
bool enableMapEditor;
|
|
ImFont *smallFont, *midFont, *bigFont;
|
|
Ogre::FontPtr _smallFont, _midFont, _bigFont;
|
|
Ogre::TexturePtr worldMap;
|
|
Ogre::Image worldMapImage;
|
|
|
|
EditorGUIListener(Ogre::ImGuiOverlay *overlay)
|
|
: Ogre::RenderTargetListener()
|
|
, enableEditor(false)
|
|
, enableMapEditor(false)
|
|
, keepCameraAbove(true)
|
|
, command(COMMAND_NONE)
|
|
{
|
|
_midFont = createFont("midFont", "General",
|
|
"Jupiteroid-Regular.ttf", 18.0f);
|
|
_smallFont = createFont("smallFont", "General",
|
|
"Jupiteroid-Regular.ttf", 13.0f);
|
|
_bigFont = createFont("bigFont", "General", "Kenney Bold.ttf",
|
|
32.0f);
|
|
smallFont = overlay->addFont("smallFont", "General");
|
|
OgreAssert(smallFont, "Could not load font");
|
|
midFont = overlay->addFont("midFont", "General");
|
|
OgreAssert(midFont, "Could not load font");
|
|
bigFont = overlay->addFont("bigFont", "General");
|
|
OgreAssert(bigFont, "Could not load font");
|
|
worldMapImage.load(
|
|
"world_map.png",
|
|
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
|
|
#if 0
|
|
int x, y, i, j;
|
|
for (y = 0; y < worldMapImage.getWidth(); y++)
|
|
for (x = 0; x < worldMapImage.getWidth(); x++) {
|
|
float r = 0.0f;
|
|
for (i = -2; i < 3; i++)
|
|
for (j = -2; j < 3; j++) {
|
|
int xj = Ogre::Math::Clamp(
|
|
x + j, 0,
|
|
(int)worldMapImage
|
|
.getWidth() -
|
|
1);
|
|
int yi = Ogre::Math::Clamp(
|
|
y + i, 0,
|
|
(int)worldMapImage
|
|
.getHeight() -
|
|
1);
|
|
r += worldMapImage
|
|
.getColourAt(xj,
|
|
yi, 0)
|
|
.r;
|
|
}
|
|
r /= 25.0f;
|
|
Ogre::ColourValue cv =
|
|
worldMapImage.getColourAt(x, y, 0);
|
|
cv.r = r;
|
|
worldMapImage.setColourAt(cv, x, y, 0);
|
|
}
|
|
#endif
|
|
worldMap = Ogre::TextureManager::getSingleton().createManual(
|
|
"worldMap",
|
|
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
|
|
Ogre::TEX_TYPE_2D, worldMapImage.getWidth(),
|
|
worldMapImage.getHeight(),
|
|
worldMapImage.getNumMipmaps(),
|
|
worldMapImage.getFormat(), Ogre::TU_DYNAMIC_WRITE_ONLY);
|
|
worldMap->loadImage(worldMapImage);
|
|
OgreAssert(worldMap, "could not load world map");
|
|
}
|
|
Ogre::FontPtr createFont(const Ogre::String &name,
|
|
const Ogre::String &group,
|
|
const Ogre::String &ttfname, float fontSize)
|
|
{
|
|
Ogre::FontPtr ret =
|
|
Ogre::FontManager::getSingleton().create(name, group);
|
|
ret->setType(Ogre::FontType::FT_TRUETYPE);
|
|
ret->setSource(ttfname);
|
|
ret->setTrueTypeSize(fontSize);
|
|
ret->setTrueTypeResolution(75);
|
|
ret->addCodePointRange(Ogre::Font::CodePointRange(30, 128));
|
|
ret->load();
|
|
return ret;
|
|
}
|
|
void
|
|
preViewportUpdate(const Ogre::RenderTargetViewportEvent &evt) override
|
|
{
|
|
preview(evt);
|
|
}
|
|
void
|
|
postViewportUpdate(const Ogre::RenderTargetViewportEvent &evt) override
|
|
{
|
|
#if 0
|
|
if (switchWindow) {
|
|
ECS::get().set<EditorSceneSwitch>({ 1 });
|
|
switchWindow = false;
|
|
}
|
|
#endif
|
|
}
|
|
#if 0
|
|
bool switchWindow = false;
|
|
#endif
|
|
void buttons_panel()
|
|
{
|
|
bool enableDebugRender = ECS::get<EngineData>().enableDbgDraw;
|
|
|
|
ImVec2 size = ImGui::GetMainViewport()->Size;
|
|
float window_width = size.x * 0.2f;
|
|
if (window_width > panel_width)
|
|
window_width = panel_width;
|
|
float window_height = size.y * 0.5f - 20;
|
|
ImGui::SetNextWindowPos(ImVec2(0, size.y * 0.5f + 20),
|
|
ImGuiCond_Always);
|
|
ImGui::SetNextWindowSize(ImVec2(window_width, window_height),
|
|
ImGuiCond_Always);
|
|
ImGui::Begin("Control");
|
|
// if (ECS::get().get<GUI>().enabled)
|
|
// ECS::get().get<App>().app->setWindowGrab(true);
|
|
if (ImGui::Button("Quit"))
|
|
Ogre::Root::getSingleton().queueEndRendering();
|
|
if (ImGui::Button("Return"))
|
|
ECS::get().get<GUI>().finish();
|
|
if (ImGui::Checkbox("Enable physics debug",
|
|
&enableDebugRender)) {
|
|
ECS::get_mut<EngineData>().enableDbgDraw =
|
|
enableDebugRender;
|
|
ECS::modified<EngineData>();
|
|
PhysicsModule::setDebugDraw(enableDebugRender);
|
|
}
|
|
#if 0
|
|
if (ImGui::Button("AltCam")) {
|
|
switchWindow = true;
|
|
}
|
|
#endif
|
|
if (ImGui::Button("Deploy config")) {
|
|
std::function m = [&](const Ogre::String &src,
|
|
const Ogre::String &dst) {
|
|
std::ifstream source(src, std::ios::binary);
|
|
std::ofstream destination(dst,
|
|
std::ios::binary);
|
|
|
|
OgreAssert(source.is_open(),
|
|
"Failed to copy files " + src +
|
|
" -> " + dst);
|
|
OgreAssert(destination.is_open(),
|
|
"Failed to copy files " + src +
|
|
" -> " + dst);
|
|
OgreAssert(source.is_open() &&
|
|
destination.is_open(),
|
|
"Failed to copy files " + src +
|
|
" -> " + dst);
|
|
destination << source.rdbuf();
|
|
destination.close();
|
|
source.close();
|
|
};
|
|
m("resources/buildings/items.list",
|
|
"../../resources/buildings/items.list");
|
|
m("resources/terrain/world_map.png",
|
|
"../../resources/terrain/world_map.png");
|
|
}
|
|
ImGui::Checkbox("Keep camera above 0", &keepCameraAbove);
|
|
#if 0
|
|
if (ImGui::Button("Enable/Disable item editor")) {
|
|
enableEditor ^= true;
|
|
if (enableEditor)
|
|
enableMapEditor = false;
|
|
}
|
|
if (ImGui::Button("Enable/Disable map editor")) {
|
|
enableMapEditor ^= true;
|
|
if (enableMapEditor)
|
|
enableEditor = false;
|
|
}
|
|
ImGui::Text("Text message...");
|
|
#endif
|
|
ImGui::Checkbox("Enable Map", &enableMapEditor);
|
|
ImGui::End();
|
|
}
|
|
void create_entity_node(const Ogre::String &name, int key)
|
|
{
|
|
Ogre::Entity *ent =
|
|
ECS::get().get<EngineData>().mScnMgr->createEntity(
|
|
name);
|
|
Ogre::SceneNode *pnode =
|
|
ECS::get()
|
|
.get<EngineData>()
|
|
.mScnMgr->getRootSceneNode()
|
|
->createChildSceneNode(
|
|
"ent:" + name +
|
|
Ogre::StringConverter::toString(
|
|
key),
|
|
ECS::get()
|
|
.get<Camera>()
|
|
.mCameraPivot->getPosition(),
|
|
ECS::get()
|
|
.get<Camera>()
|
|
.mCameraPivot->getOrientation());
|
|
pnode->attachObject(ent);
|
|
Ogre::Quaternion q = pnode->getOrientation();
|
|
Ogre::Radian yaw = q.getYaw();
|
|
Ogre::Quaternion nq(yaw, Ogre::Vector3(0, 1, 0));
|
|
pnode->setOrientation(nq);
|
|
|
|
ECS::get().get<GUI>().finish();
|
|
}
|
|
#if 0
|
|
void buildings_editor()
|
|
{
|
|
int i;
|
|
ImVec2 size = ImGui::GetMainViewport()->Size;
|
|
float window_width = size.x * 0.2f;
|
|
if (window_width > panel_width)
|
|
window_width = panel_width;
|
|
float window_height = size.y * 0.5 - 20;
|
|
ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_Always);
|
|
ImGui::SetNextWindowSize(ImVec2(window_width, window_height),
|
|
ImGuiCond_Always);
|
|
ImGui::Begin("Droppings...");
|
|
for (i = 0;
|
|
i < ECS::get().get<EditorGUIData>().glb_names.size();
|
|
i++) {
|
|
Ogre::String id_button =
|
|
"Create entity: " +
|
|
ECS::get().get<EditorGUIData>().glb_names[i] +
|
|
"##ent:" +
|
|
ECS::get().get<EditorGUIData>().glb_names[i];
|
|
if (ImGui::Button(id_button.c_str())) {
|
|
create_entity_node(ECS::get()
|
|
.get<EditorGUIData>()
|
|
.glb_names[i],
|
|
i);
|
|
}
|
|
}
|
|
ImGui::End();
|
|
}
|
|
#endif
|
|
void position_editor(Ogre::SceneNode *node)
|
|
{
|
|
Ogre::Vector3 position = node->getPosition();
|
|
float v[3] = { position.x, position.y, position.z };
|
|
ImGui::InputFloat3("position", v);
|
|
position.x = v[0];
|
|
position.y = v[1];
|
|
position.z = v[2];
|
|
node->setPosition(position);
|
|
}
|
|
void orientation_editor(Ogre::SceneNode *node)
|
|
{
|
|
Ogre::Quaternion q = node->getOrientation();
|
|
float yaw = Ogre::Radian(q.getYaw()).valueDegrees();
|
|
float pitch = Ogre::Radian(q.getPitch()).valueDegrees();
|
|
float roll = Ogre::Radian(q.getRoll()).valueDegrees();
|
|
bool m1 = ImGui::InputFloat("yaw", &yaw);
|
|
bool m2 = ImGui::InputFloat("pitch", &pitch);
|
|
bool m3 = ImGui::InputFloat("roll", &roll);
|
|
if (m1 || m2 || m3) {
|
|
Ogre::Quaternion q1(Ogre::Radian(Ogre::Degree(yaw)),
|
|
Ogre::Vector3::UNIT_Y);
|
|
Ogre::Quaternion q2(Ogre::Degree(pitch),
|
|
Ogre::Vector3::UNIT_X);
|
|
Ogre::Quaternion q3(Ogre::Degree(roll),
|
|
Ogre::Vector3::UNIT_Z);
|
|
node->setOrientation(q1 * q2 * q3);
|
|
}
|
|
}
|
|
void attachments_editor(Ogre::SceneNode *node)
|
|
{
|
|
const Ogre::SceneNode::ObjectMap &pmap =
|
|
node->getAttachedObjects();
|
|
int i;
|
|
for (i = 0; i < pmap.size(); i++) {
|
|
const Ogre::MovableObject *mobj = pmap[i];
|
|
const Ogre::String &pname = mobj->getName();
|
|
ImGui::Text("Name: %s", pname.c_str());
|
|
}
|
|
}
|
|
#if 0
|
|
void map_editor()
|
|
{
|
|
}
|
|
#endif
|
|
int pos_x = 0;
|
|
int pos_y = 0;
|
|
int top_x = 0;
|
|
int top_y = 0;
|
|
int selected_x = 0;
|
|
int selected_y = 0;
|
|
bool locationSelected = false;
|
|
float strength = 0.0f;
|
|
int size = 0;
|
|
long slot_x, slot_y;
|
|
float cursorAngle = 0;
|
|
void updateWorldTexture()
|
|
{
|
|
// Get the hardware pixel buffer
|
|
Ogre::HardwarePixelBufferSharedPtr pixelBuffer =
|
|
worldMap->getBuffer();
|
|
|
|
// Lock the buffer for writing, discarding previous contents for performance
|
|
pixelBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD);
|
|
|
|
// Get information about the locked region (PixelBox)
|
|
const Ogre::PixelBox &pixelBox = pixelBuffer->getCurrentLock();
|
|
|
|
// Ensure the image format matches the texture format
|
|
OgreAssert(pixelBox.format == worldMapImage.getFormat(),
|
|
"bad format");
|
|
|
|
// Copy the image data to the pixel box's data pointer
|
|
memcpy(pixelBox.data, worldMapImage.getData(),
|
|
worldMapImage.getSize());
|
|
|
|
// Unlock the buffer to apply changes to the GPU
|
|
pixelBuffer->unlock();
|
|
}
|
|
void updateHeightmap()
|
|
{
|
|
Ogre::Vector3 worldPos =
|
|
ECS::get<Camera>().mCameraPivot->_getDerivedPosition();
|
|
TerrainModule::update_heightmap(worldMapImage);
|
|
long x, y;
|
|
ECS::get<Terrain>()
|
|
.mTerrainGroup->convertWorldPositionToTerrainSlot(
|
|
worldPos, &x, &y);
|
|
for (auto &slot :
|
|
ECS::get<Terrain>().mTerrainGroup->getTerrainSlots()) {
|
|
Ogre::uint32 page =
|
|
ECS::get<Terrain>().mTerrainGroup->packIndex(
|
|
slot.second->x, slot.second->y);
|
|
Ogre::Terrain *terrain =
|
|
ECS::get<Terrain>().mTerrainGroup->getTerrain(
|
|
x, y);
|
|
if (terrain)
|
|
terrain->waitForDerivedProcesses();
|
|
ECS::get<Terrain>()
|
|
.mTerrainPagedWorldSection->unloadPage(page,
|
|
false);
|
|
}
|
|
ECS::get<Terrain>().mTerrainGroup->update(false);
|
|
}
|
|
void setCursorPos(Ogre::Vector3 &cursorPosition,
|
|
Ogre::Quaternion &orientation)
|
|
{
|
|
Ogre::Vector3 worldPos =
|
|
ECS::get<EditorGizmo>().sceneNode->_getDerivedPosition();
|
|
worldPos.x = TerrainModule::get_world_x(selected_x);
|
|
worldPos.z = TerrainModule::get_world_y(selected_y);
|
|
worldPos.y = TerrainModule::get_height(
|
|
ECS::get<Terrain>().mTerrainGroup, worldPos);
|
|
ECS::get<EditorGizmo>().sceneNode->_setDerivedPosition(
|
|
worldPos);
|
|
cursorPosition = worldPos;
|
|
orientation = ECS::get<EditorGizmo>()
|
|
.sceneNode->_getDerivedOrientation();
|
|
}
|
|
bool keepCameraAbove = true;
|
|
void setCameraPos()
|
|
{
|
|
Ogre::Vector3 cursorPos;
|
|
Ogre::Quaternion cursorOrientation;
|
|
setCursorPos(cursorPos, cursorOrientation);
|
|
Ogre::Vector3 cameraPos =
|
|
ECS::get<Camera>().mCameraPivot->_getDerivedPosition();
|
|
Ogre::Vector3 cameraOffset =
|
|
cursorOrientation * Ogre::Vector3::UNIT_Z * 30.0f;
|
|
cameraPos.x = cursorPos.x;
|
|
cameraPos.z = cursorPos.z;
|
|
cameraPos += cameraOffset;
|
|
cameraPos.y =
|
|
TerrainModule::get_height(
|
|
ECS::get<Terrain>().mTerrainGroup, cameraPos) +
|
|
10.0f;
|
|
if (keepCameraAbove) {
|
|
if (cameraPos.y < 0.0f)
|
|
cameraPos.y = 10.0f;
|
|
} else {
|
|
Ogre::TerrainGroup *tg =
|
|
ECS::get<Terrain>().mTerrainGroup;
|
|
long x, y;
|
|
tg->convertWorldPositionToTerrainSlot(cameraPos, &x,
|
|
&y);
|
|
if (tg->getTerrain(x, y) &&
|
|
tg->getTerrain(x, y)->isLoaded()) {
|
|
float height =
|
|
tg->getHeightAtWorldPosition(cameraPos);
|
|
cameraPos.y = height + 10.0f;
|
|
}
|
|
}
|
|
ECS::get<Camera>().mCameraPivot->_setDerivedPosition(cameraPos);
|
|
ECS::get<Camera>().mCameraPivot->_setDerivedOrientation(
|
|
cursorOrientation);
|
|
cameraPos =
|
|
ECS::get<Camera>().mCameraGoal->_getDerivedPosition();
|
|
ECS::get<Camera>().mCameraNode->_setDerivedPosition(cameraPos);
|
|
ECS::get<Camera>().mCameraNode->_setDerivedOrientation(
|
|
ECS::get<Camera>()
|
|
.mCameraGoal->_getDerivedOrientation());
|
|
updateHeightmap();
|
|
}
|
|
void setCursorSelectedPos(flecs::entity e, Ogre::Vector3 &position,
|
|
Ogre::Quaternion &orientation)
|
|
{
|
|
StaticGeometryModule::getItemPositionAndRotation(e, position,
|
|
orientation);
|
|
selected_x = TerrainModule::get_img_x(position.x);
|
|
selected_y = TerrainModule::get_img_y(position.z);
|
|
ECS::get<EditorGizmo>().sceneNode->_setDerivedPosition(
|
|
position);
|
|
ECS::get<EditorGizmo>().sceneNode->_setDerivedOrientation(
|
|
orientation);
|
|
}
|
|
void setCameraSelectedPos(flecs::entity e)
|
|
{
|
|
Ogre::Vector3 cursorPos;
|
|
Ogre::Quaternion cursorOrientation;
|
|
setCursorSelectedPos(e, cursorPos, cursorOrientation);
|
|
Ogre::Vector3 cameraPos =
|
|
ECS::get<Camera>().mCameraPivot->_getDerivedPosition();
|
|
Ogre::Vector3 cameraOffset =
|
|
cursorOrientation * Ogre::Vector3::UNIT_Z * 30.0f;
|
|
cameraPos.x = cursorPos.x;
|
|
cameraPos.z = cursorPos.z;
|
|
cameraPos += cameraOffset;
|
|
cameraPos.y =
|
|
TerrainModule::get_height(
|
|
ECS::get<Terrain>().mTerrainGroup, cameraPos) +
|
|
10.0f;
|
|
if (keepCameraAbove) {
|
|
if (cameraPos.y < 0.0f)
|
|
cameraPos.y = 10.0f;
|
|
} else {
|
|
Ogre::TerrainGroup *tg =
|
|
ECS::get<Terrain>().mTerrainGroup;
|
|
long x, y;
|
|
tg->convertWorldPositionToTerrainSlot(cameraPos, &x,
|
|
&y);
|
|
if (tg->getTerrain(x, y) &&
|
|
tg->getTerrain(x, y)->isLoaded()) {
|
|
float height =
|
|
tg->getHeightAtWorldPosition(cameraPos);
|
|
cameraPos.y = height + 10.0f;
|
|
}
|
|
}
|
|
ECS::get<Camera>().mCameraPivot->_setDerivedPosition(cameraPos);
|
|
ECS::get<Camera>().mCameraPivot->_setDerivedOrientation(
|
|
cursorOrientation);
|
|
cameraPos =
|
|
ECS::get<Camera>().mCameraGoal->_getDerivedPosition();
|
|
ECS::get<Camera>().mCameraNode->_setDerivedPosition(cameraPos);
|
|
ECS::get<Camera>().mCameraNode->_setDerivedOrientation(
|
|
ECS::get<Camera>()
|
|
.mCameraGoal->_getDerivedOrientation());
|
|
updateHeightmap();
|
|
}
|
|
void setSurfaceLevel(int actualSize, int center_x, int center_y,
|
|
float level)
|
|
{
|
|
int i, j;
|
|
float original = level;
|
|
if (actualSize == 1)
|
|
level += 0.4f;
|
|
else if (actualSize == 2)
|
|
level += 0.35f;
|
|
original = Ogre::Math::Clamp(original, 0.0f, 1.0f);
|
|
for (i = -actualSize; i < actualSize + 1; i++)
|
|
for (j = -actualSize; j < actualSize + 1; j++) {
|
|
if (i * i + j * j > actualSize * actualSize)
|
|
continue;
|
|
if (center_x + j < 0 ||
|
|
center_x + j >= worldMap->getWidth())
|
|
continue;
|
|
if (center_y + i < 0 ||
|
|
center_y + i >= worldMap->getHeight())
|
|
continue;
|
|
Ogre::ColourValue cv =
|
|
worldMapImage.getColourAt(
|
|
center_x + j, center_y + i, 0);
|
|
cv.r = original;
|
|
worldMapImage.setColourAt(cv, center_x + j,
|
|
center_y + i, 0);
|
|
}
|
|
updateWorldTexture();
|
|
updateHeightmap();
|
|
}
|
|
void setHarbourSurface()
|
|
{
|
|
int base_size = 3;
|
|
float base_height = 0.517f;
|
|
float base_step = 0.1f;
|
|
float deep = 0.25f;
|
|
float shallow = 0.35f;
|
|
float maxStep = 600.0f;
|
|
Ogre::Vector3 basePos =
|
|
ECS::get<EditorGizmo>().sceneNode->_getDerivedPosition();
|
|
Ogre::Quaternion baseRot =
|
|
ECS::get<EditorGizmo>()
|
|
.sceneNode->_getDerivedOrientation();
|
|
float baseOffset = 200.0f;
|
|
Ogre::Vector3 stepOffset =
|
|
baseRot * Ogre::Vector3::NEGATIVE_UNIT_Z * baseOffset;
|
|
std::vector<float> heights = { deep, shallow, base_height,
|
|
base_height + base_step,
|
|
base_height + base_step * 2.0f };
|
|
int step_count = 0;
|
|
for (float height : heights) {
|
|
float localStep = 0.0f;
|
|
Ogre::Vector3 currentPosition =
|
|
basePos + stepOffset * (float)step_count -
|
|
stepOffset * 0.5f;
|
|
float goTill = maxStep;
|
|
if (step_count < 2)
|
|
goTill += 420.0f;
|
|
while (localStep <
|
|
goTill - 150.0f * (float)step_count) {
|
|
localStep += baseOffset;
|
|
currentPosition += stepOffset;
|
|
int center_x = TerrainModule::get_img_x(
|
|
currentPosition.x);
|
|
int center_y = TerrainModule::get_img_y(
|
|
currentPosition.z);
|
|
int size = base_size + 10 - step_count * 2;
|
|
if (step_count < 2)
|
|
size = base_size + 14 - step_count * 2;
|
|
if (step_count == 0)
|
|
size += 1;
|
|
|
|
setSurfaceLevel(size, center_x, center_y,
|
|
height);
|
|
}
|
|
step_count++;
|
|
}
|
|
}
|
|
static void to_json(nlohmann::json &j, const Ogre::Vector3 &position)
|
|
{
|
|
j["x"] = position.x;
|
|
j["y"] = position.y;
|
|
j["z"] = position.z;
|
|
}
|
|
float setLevelValue = 0.0f;
|
|
float riseLowerChange = 0.0f;
|
|
enum {
|
|
COMMAND_NONE,
|
|
COMMAND_RISELOWER,
|
|
COMMAND_RISELOWER2,
|
|
COMMAND_SMOOTH,
|
|
COMMAND_SETLEVEL
|
|
};
|
|
int command;
|
|
void heightmapMenu()
|
|
{
|
|
command = COMMAND_NONE;
|
|
if (ImGui::Button("Elevate")) {
|
|
riseLowerChange = strength;
|
|
command = COMMAND_RISELOWER;
|
|
}
|
|
ImGui::SameLine();
|
|
if (ImGui::Button("Elevate2")) {
|
|
riseLowerChange = strength;
|
|
command = COMMAND_RISELOWER2;
|
|
}
|
|
ImGui::SameLine();
|
|
if (ImGui::Button("Lower")) {
|
|
riseLowerChange = -strength;
|
|
command = COMMAND_RISELOWER;
|
|
}
|
|
std::pair<Ogre::String, float> setLevelCommands[] = {
|
|
{ "Deepest", 0.0f }, { "Deep", 0.25f },
|
|
{ "Shallow1", 0.35f }, { "Shallow2", 0.47f },
|
|
{ "Beach", 0.517f }, { "Shore1", 0.536f },
|
|
{ "Shore2", 0.556f }, { "Shore3", 0.586f },
|
|
{ "Shore4", 0.606f }, { "Shore5", 0.626f },
|
|
{ "Shore6", 0.646f }, { "Highest", 1.0f },
|
|
};
|
|
int buttonCounter = 0;
|
|
for (const auto &mb : setLevelCommands) {
|
|
if (ImGui::SmallButton(mb.first.c_str())) {
|
|
setLevelValue = mb.second;
|
|
command = COMMAND_SETLEVEL;
|
|
}
|
|
if ((buttonCounter & 3) != 0)
|
|
ImGui::SameLine();
|
|
buttonCounter++;
|
|
}
|
|
ImGui::Spacing();
|
|
if (ImGui::Button("Smooth")) {
|
|
command = COMMAND_SMOOTH;
|
|
}
|
|
ImGui::Separator();
|
|
if (ImGui::MenuItem("Save heightmap")) {
|
|
updateWorldTexture();
|
|
updateHeightmap();
|
|
TerrainModule::save_heightmap();
|
|
}
|
|
}
|
|
void executeCommands()
|
|
{
|
|
switch (command) {
|
|
case COMMAND_RISELOWER: {
|
|
int actualSize = 1 + size * 2;
|
|
int i, j;
|
|
for (i = -actualSize; i < actualSize + 1; i++)
|
|
for (j = -actualSize; j < actualSize + 1; j++) {
|
|
if (i * i + j * j >
|
|
actualSize * actualSize)
|
|
continue;
|
|
if (selected_x + j < 0 ||
|
|
selected_x + j >=
|
|
worldMap->getWidth())
|
|
continue;
|
|
if (selected_y + i < 0 ||
|
|
selected_y + i >=
|
|
worldMap->getHeight())
|
|
continue;
|
|
Ogre::ColourValue cv =
|
|
worldMapImage.getColourAt(
|
|
selected_x + j,
|
|
selected_y + i, 0);
|
|
float original = cv.r;
|
|
original += riseLowerChange;
|
|
original = Ogre::Math::Clamp(
|
|
original, 0.0f, 1.0f);
|
|
cv.r = original;
|
|
worldMapImage.setColourAt(
|
|
cv, selected_x + j,
|
|
selected_y + i, 0);
|
|
}
|
|
updateWorldTexture();
|
|
updateHeightmap();
|
|
|
|
} break;
|
|
case COMMAND_RISELOWER2: {
|
|
int actualSize = 1 + size * 2;
|
|
int i, j;
|
|
Ogre::ColourValue maxcv = worldMapImage.getColourAt(
|
|
selected_x, selected_y, 0);
|
|
for (i = -actualSize; i < actualSize + 1; i++)
|
|
for (j = -actualSize; j < actualSize + 1; j++) {
|
|
if (i * i + j * j >
|
|
actualSize * actualSize)
|
|
continue;
|
|
if (selected_x + j < 0 ||
|
|
selected_x + j >=
|
|
worldMap->getWidth())
|
|
continue;
|
|
if (selected_y + i < 0 ||
|
|
selected_y + i >=
|
|
worldMap->getHeight())
|
|
continue;
|
|
float actualStrength =
|
|
riseLowerChange /
|
|
(1.0f + (float)(i * i + j * j));
|
|
Ogre::ColourValue cv =
|
|
worldMapImage.getColourAt(
|
|
selected_x + j,
|
|
selected_y + i, 0);
|
|
float original =
|
|
maxcv.r + actualStrength;
|
|
original = Ogre::Math::Clamp(
|
|
original, 0.0f, 1.0f);
|
|
if (cv.r >= original)
|
|
continue;
|
|
cv.r = original;
|
|
worldMapImage.setColourAt(
|
|
cv, selected_x + j,
|
|
selected_y + i, 0);
|
|
}
|
|
updateWorldTexture();
|
|
updateHeightmap();
|
|
} break;
|
|
case COMMAND_SMOOTH: {
|
|
int actualSize = 1 + size * 2;
|
|
int i, j, k, l;
|
|
for (i = -actualSize; i < actualSize + 1; i++)
|
|
for (j = -actualSize; j < actualSize + 1; j++) {
|
|
if (i * i + j * j >
|
|
actualSize * actualSize)
|
|
continue;
|
|
if (selected_x + j < 0 ||
|
|
selected_x + j >=
|
|
worldMap->getWidth())
|
|
continue;
|
|
if (selected_y + i < 0 ||
|
|
selected_y + i >=
|
|
worldMap->getHeight())
|
|
continue;
|
|
int kernel = 3;
|
|
float original = 0.0f;
|
|
Ogre::ColourValue cv;
|
|
float count = 0.0f;
|
|
for (k = -kernel; k < kernel + 1; k++) {
|
|
if (selected_y + i + k < 0 ||
|
|
selected_y + i + k >=
|
|
worldMap->getHeight())
|
|
continue;
|
|
for (l = -kernel;
|
|
l < kernel + 1; l++) {
|
|
if (selected_x + j + l <
|
|
0 ||
|
|
selected_x + j +
|
|
l >=
|
|
worldMap->getWidth())
|
|
continue;
|
|
cv = worldMapImage.getColourAt(
|
|
selected_x + j,
|
|
selected_y + i,
|
|
0);
|
|
original += cv.r;
|
|
count += 1.0f;
|
|
}
|
|
}
|
|
original /= count;
|
|
cv = worldMapImage.getColourAt(
|
|
selected_x + j, selected_y + i,
|
|
0);
|
|
original = Ogre::Math::Clamp(
|
|
original, 0.0f, 1.0f);
|
|
cv.r = original;
|
|
worldMapImage.setColourAt(
|
|
cv, selected_x + j,
|
|
selected_y + i, 0);
|
|
}
|
|
updateWorldTexture();
|
|
updateHeightmap();
|
|
} break;
|
|
case COMMAND_SETLEVEL: {
|
|
int actualSize = 1 + size * 2;
|
|
int i, j;
|
|
float original = setLevelValue;
|
|
original = Ogre::Math::Clamp(original, 0.0f, 1.0f);
|
|
for (i = -actualSize; i < actualSize + 1; i++)
|
|
for (j = -actualSize; j < actualSize + 1; j++) {
|
|
if (i * i + j * j >
|
|
actualSize * actualSize)
|
|
continue;
|
|
if (selected_x + j < 0 ||
|
|
selected_x + j >=
|
|
worldMap->getWidth())
|
|
continue;
|
|
if (selected_y + i < 0 ||
|
|
selected_y + i >=
|
|
worldMap->getHeight())
|
|
continue;
|
|
Ogre::ColourValue cv =
|
|
worldMapImage.getColourAt(
|
|
selected_x + j,
|
|
selected_y + i, 0);
|
|
cv.r = original;
|
|
worldMapImage.setColourAt(
|
|
cv, selected_x + j,
|
|
selected_y + i, 0);
|
|
}
|
|
updateWorldTexture();
|
|
updateHeightmap();
|
|
|
|
} break;
|
|
}
|
|
}
|
|
void displayItems()
|
|
{
|
|
std::pair<flecs::entity, Ogre::String> selected_item;
|
|
std::list<std::pair<flecs::entity, Ogre::String> > items;
|
|
StaticGeometryModule::getItemsProperties(&items);
|
|
bool item_is_selected = false;
|
|
for (const auto &item : items) {
|
|
nlohmann::json j = nlohmann::json::parse(item.second);
|
|
Ogre::String label = Ogre::StringConverter::toString(
|
|
item.first.id());
|
|
label += ":" + j["type"].get<Ogre::String>();
|
|
if (ImGui::SmallButton(label.c_str())) { /* select */
|
|
selected_item = item;
|
|
item_is_selected = true;
|
|
}
|
|
Items::showItemButtons(item);
|
|
}
|
|
if (item_is_selected)
|
|
setCameraSelectedPos(selected_item.first);
|
|
for (const auto &item : items)
|
|
Items::showItemPopup(item);
|
|
}
|
|
void displayInfo()
|
|
{
|
|
ImGui::Text("Position: %d %d", pos_x, pos_y);
|
|
ImGui::Text("Selected Position: %d %d", selected_x, selected_y);
|
|
ImGui::Text("Height: %f",
|
|
worldMapImage.getColourAt(pos_x, pos_y, 0).r);
|
|
ImGui::Text(
|
|
"Selected height: %f",
|
|
worldMapImage.getColourAt(selected_x, selected_y, 0).r);
|
|
{
|
|
Ogre::Vector3 position =
|
|
ECS::get<EditorGizmo>()
|
|
.sceneNode->_getDerivedPosition();
|
|
ImGui::Text("Cursor position %f %f %f", position.x,
|
|
position.y, position.z);
|
|
}
|
|
}
|
|
void worldMapView()
|
|
{
|
|
bool update_cursor_position = false;
|
|
bool update_cursor_height = false;
|
|
bool update_cursor_angle = false;
|
|
OgreAssert(TerrainModule::get_img_x(0) ==
|
|
worldMap->getWidth() / 2,
|
|
"get_img_x");
|
|
OgreAssert(TerrainModule::get_img_y(0) ==
|
|
worldMap->getHeight() / 2,
|
|
"get_img_x");
|
|
OgreAssert(TerrainModule::get_world_x(worldMap->getWidth() /
|
|
2) == 0.0f,
|
|
"get_world_x");
|
|
OgreAssert(TerrainModule::get_world_y(worldMap->getHeight() /
|
|
2) == 0.0f,
|
|
"get_world_y");
|
|
if (ECS::get<EditorGizmo>().sceneNode) {
|
|
Ogre::Vector3 worldPos =
|
|
ECS::get<EditorGizmo>()
|
|
.sceneNode->_getDerivedPosition();
|
|
selected_x = TerrainModule::get_img_x(worldPos.x);
|
|
selected_y = TerrainModule::get_img_y(worldPos.z);
|
|
locationSelected = true;
|
|
OgreAssert(selected_x >= 0 &&
|
|
selected_x < worldMap->getWidth(),
|
|
"mix width");
|
|
OgreAssert(selected_y >= 0 &&
|
|
selected_y < worldMap->getHeight(),
|
|
"mix height");
|
|
ECS::get<Terrain>()
|
|
.mTerrainGroup
|
|
->convertWorldPositionToTerrainSlot(
|
|
worldPos, &slot_x, &slot_y);
|
|
}
|
|
ImGui::SetNextWindowSizeConstraints(ImVec2(512 + 20, 512 + 20),
|
|
ImVec2(768, 768));
|
|
// ImGui::SetNextWindowScroll(
|
|
// ImVec2(worldMap->getWidth(), worldMap->getHeight()));
|
|
ImGui::Begin("WorldMap...", nullptr, ImGuiWindowFlags_MenuBar);
|
|
if (ImGui::BeginMenuBar()) {
|
|
if (ImGui::BeginMenu("Create")) {
|
|
Items::createItemsMenu();
|
|
ImGui::EndMenu();
|
|
}
|
|
if (ImGui::BeginMenu("Heightmap")) {
|
|
if (ImGui::MenuItem("Update terrain"))
|
|
ECS::get<Terrain>()
|
|
.mTerrainGroup->update(false);
|
|
ImGui::Separator();
|
|
ImGui::SliderFloat("Strength...", &strength,
|
|
0.0f, 1.0f);
|
|
ImGui::SliderInt("Size", &size, 0, 32);
|
|
ImGui::Separator();
|
|
heightmapMenu();
|
|
ImGui::EndMenu();
|
|
}
|
|
if (ImGui::BeginMenu("Cursor")) {
|
|
if (ImGui::MenuItem("Update cursor position"))
|
|
update_cursor_height = true;
|
|
Ogre::Vector3 cursorPosition =
|
|
ECS::get<EditorGizmo>()
|
|
.sceneNode
|
|
->_getDerivedPosition();
|
|
bool modified = false;
|
|
if (ImGui::SmallButton("X-1")) {
|
|
cursorPosition.x -= 1.0f;
|
|
modified = true;
|
|
}
|
|
ImGui::SameLine();
|
|
if (ImGui::SmallButton("X+1")) {
|
|
cursorPosition.x += 1.0f;
|
|
modified = true;
|
|
}
|
|
ImGui::SameLine();
|
|
if (ImGui::SmallButton("Y-1")) {
|
|
cursorPosition.y -= 1.0f;
|
|
modified = true;
|
|
}
|
|
ImGui::SameLine();
|
|
if (ImGui::SmallButton("Y+1")) {
|
|
cursorPosition.y += 1.0f;
|
|
modified = true;
|
|
}
|
|
ImGui::SameLine();
|
|
if (ImGui::SmallButton("Z-1")) {
|
|
cursorPosition.z -= 1.0f;
|
|
modified = true;
|
|
}
|
|
ImGui::SameLine();
|
|
if (ImGui::SmallButton("Z+1")) {
|
|
cursorPosition.z += 1.0f;
|
|
modified = true;
|
|
}
|
|
ImGui::EndMenu();
|
|
if (modified) {
|
|
ECS::get<EditorGizmo>()
|
|
.sceneNode->_setDerivedPosition(
|
|
cursorPosition);
|
|
modified = false;
|
|
}
|
|
}
|
|
if (ImGui::BeginMenu("Furniture")) {
|
|
if (ImGui::BeginMenu("Create New Furniture")) {
|
|
static char nameBuffer[32];
|
|
static int current_mesh = 0;
|
|
static std::vector<Ogre::String>
|
|
glb_names;
|
|
const std::vector<Ogre::String> &groups =
|
|
Ogre::ResourceGroupManager::
|
|
getSingleton()
|
|
.getResourceGroups();
|
|
if (glb_names.size() == 0) {
|
|
int i;
|
|
glb_names.push_back("");
|
|
for (i = 0; i < groups.size();
|
|
i++) {
|
|
std::vector<Ogre::String> names =
|
|
*Ogre::ResourceGroupManager::getSingleton()
|
|
.findResourceNames(
|
|
groups[i],
|
|
"furniture-*.glb");
|
|
glb_names.insert(
|
|
glb_names.end(),
|
|
names.begin(),
|
|
names.end());
|
|
}
|
|
}
|
|
ImGui::InputText(
|
|
"Furniture Name", nameBuffer,
|
|
IM_ARRAYSIZE(nameBuffer));
|
|
if (glb_names.size() > 0) {
|
|
if (ImGui::BeginCombo(
|
|
"Furniture Mesh",
|
|
glb_names[current_mesh]
|
|
.c_str())) {
|
|
int i;
|
|
for (i = 0;
|
|
i <
|
|
glb_names.size();
|
|
i++) {
|
|
bool isSelected =
|
|
i ==
|
|
current_mesh;
|
|
if (ImGui::Selectable(
|
|
(glb_names[i] +
|
|
"##select" +
|
|
Ogre::StringConverter::
|
|
toString(
|
|
i))
|
|
.c_str(),
|
|
isSelected)) {
|
|
current_mesh =
|
|
i;
|
|
}
|
|
if (isSelected)
|
|
ImGui::SetItemDefaultFocus();
|
|
}
|
|
ImGui::EndCombo();
|
|
}
|
|
} else
|
|
ImGui::Text(
|
|
"No furniture meshes found");
|
|
if (ImGui::MenuItem(
|
|
"Create Furniture")) {
|
|
}
|
|
ImGui::EndMenu();
|
|
}
|
|
if (ImGui::BeginMenu("Edit Furniture")) {
|
|
if (ImGui::MenuItem("Edit Furniture")) {
|
|
}
|
|
ImGui::EndMenu();
|
|
}
|
|
ImGui::EndMenu();
|
|
}
|
|
ImGui::EndMenuBar();
|
|
}
|
|
ImGui::Spacing();
|
|
ImGui::BeginChild("WorldMap...", ImVec2(480, 480),
|
|
ImGuiChildFlags_None,
|
|
ImGuiWindowFlags_HorizontalScrollbar);
|
|
ImGui::Spacing();
|
|
Ogre::ResourceHandle hdl = worldMap->getHandle();
|
|
int w = worldMap->getWidth();
|
|
int h = worldMap->getHeight();
|
|
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding,
|
|
ImVec2((float)5, (float)5));
|
|
ImGui::ImageButton("WorldMapPress", (ImTextureID)hdl,
|
|
ImVec2(w, h));
|
|
ImVec2 mouse_absolute_pos = ImGui::GetMousePos();
|
|
ImVec2 item_absolute_pos = ImGui::GetItemRectMin();
|
|
top_x = item_absolute_pos.x + 5;
|
|
top_y = item_absolute_pos.y + 5;
|
|
bool hovered = false;
|
|
if (ImGui::IsItemHovered()) {
|
|
ImVec2 mouse_absolute_pos = ImGui::GetMousePos();
|
|
ImVec2 item_absolute_pos = ImGui::GetItemRectMin();
|
|
pos_x = mouse_absolute_pos.x - item_absolute_pos.x - 5;
|
|
pos_y = mouse_absolute_pos.y - item_absolute_pos.y - 5;
|
|
hovered = true;
|
|
}
|
|
pos_x = Ogre::Math::Clamp(pos_x, 0,
|
|
(int)worldMap->getWidth() - 1);
|
|
pos_y = Ogre::Math::Clamp(pos_y, 0,
|
|
(int)worldMap->getHeight() - 1);
|
|
if (pos_x < 0)
|
|
pos_x = 0;
|
|
if (pos_x >= worldMap->getWidth())
|
|
pos_x = worldMap->getWidth() - 1;
|
|
if (pos_y < 0)
|
|
pos_y = 0;
|
|
if (pos_y >= worldMap->getHeight())
|
|
pos_y = worldMap->getHeight() - 1;
|
|
if (ImGui::IsItemActivated()) {
|
|
locationSelected = true;
|
|
selected_x = pos_x;
|
|
selected_y = pos_y;
|
|
OgreAssert(selected_x >= 0 &&
|
|
selected_x < worldMap->getWidth(),
|
|
"mix width");
|
|
OgreAssert(selected_y >= 0 &&
|
|
selected_y < worldMap->getHeight(),
|
|
"mix height");
|
|
setCameraPos();
|
|
std::cout << "worldClickPos: " << pos_x << " " << pos_y
|
|
<< std::endl;
|
|
}
|
|
ImDrawList *draw_list = ImGui::GetWindowDrawList();
|
|
draw_list->AddCircleFilled(ImVec2(top_x + pos_x, top_y + pos_y),
|
|
1.0f, IM_COL32(0, 255, 0, 255));
|
|
{
|
|
std::list<Ogre::Vector3> positions;
|
|
StaticGeometryModule::getItemPositions(&positions);
|
|
for (auto pos : positions) {
|
|
int item_x = TerrainModule::get_img_x(pos.x);
|
|
int item_y = TerrainModule::get_img_y(pos.z);
|
|
draw_list->AddCircleFilled(
|
|
ImVec2(top_x + item_x, top_y + item_y),
|
|
3.0f, IM_COL32(255, 255, 0, 255));
|
|
}
|
|
}
|
|
if (locationSelected)
|
|
draw_list->AddCircleFilled(
|
|
ImVec2(top_x + selected_x, top_y + selected_y),
|
|
4.0f, IM_COL32(64, 255, 64, 255));
|
|
{
|
|
Ogre::Vector3 cursorPos =
|
|
ECS::get<EditorGizmo>()
|
|
.sceneNode->_getDerivedPosition();
|
|
int cursor_x = TerrainModule::get_img_x(cursorPos.x);
|
|
int cursor_y = TerrainModule::get_img_y(cursorPos.z);
|
|
draw_list->AddCircleFilled(
|
|
ImVec2(top_x + cursor_x, top_y + cursor_y),
|
|
4.0f, IM_COL32(255, 64, 64, 128));
|
|
}
|
|
ImGui::PopStyleVar();
|
|
ImGui::Spacing();
|
|
ImGui::EndChild();
|
|
ImGui::SameLine();
|
|
ImGui::BeginChild("WorldMap...", ImVec2(64, 480),
|
|
ImGuiChildFlags_None,
|
|
ImGuiWindowFlags_HorizontalScrollbar);
|
|
ImGui::EndChild();
|
|
ImGui::Spacing();
|
|
ImGui::BeginChild("WorldMap Bottom...", ImVec2(0, 0));
|
|
if (ImGui::CollapsingHeader("Display Info")) {
|
|
displayInfo();
|
|
if (ImGui::SliderFloat("Cursor Angle...", &cursorAngle,
|
|
-180.0f, 180.0f))
|
|
update_cursor_angle = true;
|
|
}
|
|
displayItems();
|
|
ImGui::EndChild();
|
|
ImGui::Spacing();
|
|
ImGui::End();
|
|
if (update_cursor_height || update_cursor_angle) {
|
|
if (update_cursor_height) {
|
|
Ogre::Vector3 position =
|
|
ECS::get<EditorGizmo>()
|
|
.sceneNode
|
|
->_getDerivedPosition();
|
|
position.y = ECS::get<Terrain>()
|
|
.mTerrainGroup
|
|
->getHeightAtWorldPosition(
|
|
position);
|
|
ECS::get<EditorGizmo>()
|
|
.sceneNode->_setDerivedPosition(
|
|
position);
|
|
}
|
|
if (update_cursor_angle)
|
|
ECS::get<EditorGizmo>()
|
|
.sceneNode->_setDerivedOrientation(
|
|
Ogre::Quaternion(
|
|
Ogre::Degree(
|
|
cursorAngle),
|
|
Ogre::Vector3::UNIT_Y));
|
|
}
|
|
executeCommands();
|
|
}
|
|
void panel()
|
|
{
|
|
ImVec2 size = ImGui::GetMainViewport()->Size;
|
|
float window_width = size.x * 0.2f;
|
|
if (window_width > panel_width)
|
|
window_width = panel_width;
|
|
float window_height = size.y * 0.5f - 20;
|
|
ImGui::SetNextWindowPos(ImVec2(size.x - window_width, 20),
|
|
ImGuiCond_Always);
|
|
ImGui::SetNextWindowSize(ImVec2(window_width, window_height),
|
|
ImGuiCond_Always);
|
|
// ImGui::Begin("Dumb and Stupid", &mKbd.gui_active);
|
|
ImGui::Begin("Panel...");
|
|
std::deque<Ogre::SceneNode *> tree_input_queue,
|
|
tree_output_queue;
|
|
std::vector<Ogre::SceneNode *> tree_list;
|
|
tree_input_queue.push_back(
|
|
ECS::get()
|
|
.get<EngineData>()
|
|
.mScnMgr->getRootSceneNode());
|
|
tree_input_queue.push_back(nullptr);
|
|
std::set<Ogre::SceneNode *> visited;
|
|
while (true) {
|
|
int new_nodes_count = 0;
|
|
while (!tree_input_queue.empty()) {
|
|
int child;
|
|
Ogre::SceneNode *item =
|
|
tree_input_queue.front();
|
|
tree_input_queue.pop_front();
|
|
if (item && visited.find(item) ==
|
|
visited.end()) { // new node
|
|
new_nodes_count++;
|
|
tree_output_queue.push_back(item);
|
|
visited.insert(item);
|
|
const Ogre::Node::ChildNodeMap
|
|
&children = item->getChildren();
|
|
for (child = 0; child < children.size();
|
|
child++) {
|
|
tree_output_queue.push_back(
|
|
static_cast<Ogre::SceneNode
|
|
*>(
|
|
children[child]));
|
|
tree_output_queue.push_back(
|
|
nullptr);
|
|
}
|
|
} else
|
|
tree_output_queue.push_back(item);
|
|
}
|
|
if (new_nodes_count == 0)
|
|
break;
|
|
tree_input_queue = tree_output_queue;
|
|
tree_output_queue.clear();
|
|
}
|
|
tree_list.insert(tree_list.begin(), tree_output_queue.begin(),
|
|
tree_output_queue.end());
|
|
int count = 0;
|
|
int depth = 0;
|
|
std::vector<int> check_depth;
|
|
int max_depth = 0;
|
|
check_depth.push_back(0);
|
|
for (count = 0; count < tree_list.size(); count++) {
|
|
int t;
|
|
|
|
Ogre::SceneNode *node = tree_list[count];
|
|
if (node && max_depth >= depth) {
|
|
Ogre::String name = node->getName();
|
|
if (name.length() == 0) {
|
|
name = "Node #" +
|
|
Ogre::StringConverter::toString(
|
|
count);
|
|
}
|
|
if (ImGui::TreeNode(name.c_str())) {
|
|
check_depth.push_back(max_depth);
|
|
max_depth++;
|
|
ImGui::Text(
|
|
"%s",
|
|
(name + "##caption").c_str());
|
|
position_editor(node);
|
|
ImGui::Separator();
|
|
orientation_editor(node);
|
|
ImGui::Separator();
|
|
if (ImGui::Button("From Cursor"))
|
|
std::cout << name
|
|
<< " From Cursor"
|
|
<< std::endl;
|
|
if (ImGui::Button("To Cursor"))
|
|
std::cout << name
|
|
<< " To Cursor"
|
|
<< std::endl;
|
|
ImGui::Separator();
|
|
ImGui::Text("Attachments");
|
|
attachments_editor(node);
|
|
}
|
|
} else if (!node && max_depth >= depth) {
|
|
max_depth = check_depth.back();
|
|
check_depth.pop_back();
|
|
ImGui::TreePop();
|
|
}
|
|
if (tree_list[count])
|
|
depth++;
|
|
else
|
|
depth--;
|
|
}
|
|
ImGui::Spacing();
|
|
ImGui::End();
|
|
}
|
|
void preview(const Ogre::RenderTargetViewportEvent &evt)
|
|
{
|
|
int i;
|
|
Ogre::ImGuiOverlay::NewFrame();
|
|
if (ECS::get().get<GUI>().enabled) {
|
|
buttons_panel();
|
|
panel();
|
|
if (enableMapEditor)
|
|
worldMapView();
|
|
}
|
|
}
|
|
};
|
|
GUIModule::GUIModule(flecs::world &ecs)
|
|
{
|
|
ecs.module<GUIModule>();
|
|
ecs.import <AppModule>();
|
|
ecs.component<GUI>()
|
|
.on_add([](GUI &gui) {
|
|
gui.enabled = false;
|
|
gui.grab = false;
|
|
gui.grabChanged = false;
|
|
})
|
|
.add(flecs::Singleton);
|
|
ecs.component<GUIData>()
|
|
.on_add([](GUIData &priv) {
|
|
priv.glb_names.clear();
|
|
priv.mGUIListener = nullptr;
|
|
priv.mGuiOverlay = nullptr;
|
|
})
|
|
.add(flecs::Singleton);
|
|
ecs.set<GUI>({ false, true, false, false, false, "", {}, -1 });
|
|
ecs.set<GUIData>({ nullptr, {}, nullptr });
|
|
ui_wait =
|
|
ecs.system<const RenderWindow, App, GUIData>("SetupGUI")
|
|
.kind(flecs::OnUpdate)
|
|
.each([this](const RenderWindow &window, App &app,
|
|
GUIData &gui) {
|
|
if (!gui.mGuiOverlay) {
|
|
float vpScale =
|
|
window.dpi / 96 *
|
|
window.window->getWidth() /
|
|
1600.0f;
|
|
Ogre::OverlayManager::getSingleton()
|
|
.setPixelRatio(vpScale);
|
|
std::cout << "GUI configure\n";
|
|
OgreAssert(app.mGuiOverlay,
|
|
"No ImGUI overlay");
|
|
gui.mGuiOverlay = app.mGuiOverlay;
|
|
gui.mGUIListener = new GUIListener();
|
|
gui.mGuiOverlay->setZOrder(300);
|
|
gui.mGuiOverlay->show();
|
|
gui.mGUIListener->panel_width = 300.0f;
|
|
gui.mGUIListener->enableEditor = false;
|
|
window.window->addListener(
|
|
gui.mGUIListener);
|
|
int i;
|
|
|
|
const std::vector<Ogre::String> &groups =
|
|
Ogre::ResourceGroupManager::
|
|
getSingleton()
|
|
.getResourceGroups();
|
|
for (i = 0; i < groups.size(); i++) {
|
|
std::vector<Ogre::String> names =
|
|
*Ogre::ResourceGroupManager::getSingleton()
|
|
.findResourceNames(
|
|
groups[i],
|
|
"*.glb");
|
|
gui.glb_names.insert(
|
|
gui.glb_names.end(),
|
|
names.begin(),
|
|
names.end());
|
|
}
|
|
ECS::modified<ECS::GUI>();
|
|
std::cout << "GUI configure finished\n";
|
|
}
|
|
});
|
|
}
|
|
EditorGUIModule::EditorGUIModule(flecs::world &ecs)
|
|
{
|
|
ecs.module<EditorGUIModule>();
|
|
ecs.import <AppModule>();
|
|
ecs.import <StaticGeometryModule>();
|
|
ecs.component<GUI>()
|
|
.on_add([](GUI &gui) {
|
|
gui.enabled = true;
|
|
gui.grab = false;
|
|
gui.grabChanged = false;
|
|
})
|
|
.add(flecs::Singleton);
|
|
ecs.component<EditorGUIData>()
|
|
.on_add([](EditorGUIData &priv) {
|
|
priv.glb_names.clear();
|
|
priv.mGUIListener = nullptr;
|
|
priv.mGuiOverlay = nullptr;
|
|
})
|
|
.add(flecs::Singleton);
|
|
ecs.observer<const RenderWindow, const App, GUI>("SupportEditorGUI")
|
|
.event(flecs::OnSet)
|
|
.without<EditorGUIData>()
|
|
.each([](const RenderWindow &window, const App &app, GUI &gui) {
|
|
float vpScale = window.dpi / 96 *
|
|
window.window->getWidth() / 1600.0f;
|
|
Ogre::OverlayManager::getSingleton().setPixelRatio(
|
|
vpScale);
|
|
std::cout << "Editor GUI configure\n";
|
|
OgreAssert(app.mGuiOverlay, "No ImGUI overlay");
|
|
Ogre::ImGuiOverlay *guiOverlay = app.mGuiOverlay;
|
|
EditorGUIListener *guiListener =
|
|
new EditorGUIListener(guiOverlay);
|
|
guiOverlay->setZOrder(300);
|
|
guiOverlay->show();
|
|
guiListener->panel_width = 300.0f;
|
|
guiListener->enableEditor = false;
|
|
window.window->addListener(guiListener);
|
|
|
|
ECS::get().set<EditorGUIData>(
|
|
{ app.mGuiOverlay, {}, guiListener });
|
|
std::cout << "Editor GUI configure finished\n";
|
|
});
|
|
}
|
|
}
|