Files
ogre-prototype/src/gamedata/GUIModule.cpp

792 lines
27 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 "PlayerActionModule.h"
#include "CharacterModule.h"
#include "CharacterManagerModule.h"
#include "items.h"
#include "physics.h"
#include "QuestModule.h"
#include "GUIModule.h"
#include "GUIModuleCommon.h"
#include <tracy/Tracy.hpp>
namespace ECS
{
struct GUIListener;
struct GUIData {
Ogre::ImGuiOverlay *mGuiOverlay;
std::vector<Ogre::String> glb_names;
GUIListener *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()
{
ZoneScoped;
_midFont = createFont("midFont", "General",
"Jupiteroid-Regular.ttf", 24.0f);
_smallFont = createFont("smallFont", "General",
"Jupiteroid-Regular.ttf", 18.0f);
_bigFont = createFont("bigFont", "General", "Kenney Bold.ttf",
36.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");
}
Ogre::FontPtr createFont(const Ogre::String &name,
const Ogre::String &group,
const Ogre::String &ttfname, float fontSize)
{
ZoneScoped;
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
{
ZoneScopedN("GUIModule::preViewportUpdate");
preview(evt);
}
void buttons_panel()
{
ZoneScoped;
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 (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;
}
if (ImGui::Checkbox("Enable physics debug",
&enableDebugRender)) {
ECS::get_mut<EngineData>().enableDbgDraw =
enableDebugRender;
ECS::modified<EngineData>();
PhysicsModule::setDebugDraw(enableDebugRender);
}
ImGui::Text("Text message...");
ImGui::End();
}
void create_entity_node(const Ogre::String &name, int key)
{
ZoneScoped;
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()
{
ZoneScoped;
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)
{
ZoneScoped;
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)
{
ZoneScoped;
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)
{
ZoneScoped;
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()
{
}
Ogre::Vector2 projectToScreen(const Ogre::Vector3 &worldPoint)
{
ZoneScoped;
ImVec2 size = ImGui::GetMainViewport()->Size;
float width = size.x;
float height = size.y;
Ogre::Camera *camera = ECS::get<Camera>().mCamera;
// 1. Convert to camera space
Ogre::Vector3 eyeSpacePoint =
camera->getViewMatrix() * worldPoint;
// 2. Project to clip space
Ogre::Vector3 clipSpacePoint =
camera->getProjectionMatrix() * eyeSpacePoint;
if (clipSpacePoint.z < 0.0f)
return Ogre::Vector2(-1, -1);
// 3. Convert from clip space (-1 to 1) to screen space (0 to 1)
// Note: Y is usually flipped in API screen coordinates compared to projection
float screenX = (clipSpacePoint.x / 2.0f) + 0.5f;
float screenY = 1.0f - ((clipSpacePoint.y / 2.0f) + 0.5f);
// 4. Map to actual pixel dimensions
return Ogre::Vector2(screenX * width, screenY * height);
}
void preview(const Ogre::RenderTargetViewportEvent &evt)
{
ZoneScoped;
int i;
Ogre::ImGuiOverlay::NewFrame();
if (ECS::get().get<EngineData>().startupDelay > 0.0f &&
ECS::get().has<GameState>()) {
ImVec2 size = ImGui::GetMainViewport()->Size;
ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_Always);
ImGui::SetNextWindowSize(ImVec2(size.x, size.y),
ImGuiCond_Always);
ImVec4 solidColor = ImVec4(0.0f, 0.0f, 0.0f, 1.0f);
ImGui::PushStyleColor(ImGuiCol_WindowBg, solidColor);
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();
ImGui::PopStyleColor();
} else if (ECS::get<GUI>().narrationHandlers.size() > 0) {
ECS::get_mut<GUI>().grab = false;
ECS::get_mut<GUI>().grabChanged = true;
ECS::get_mut<GUI>().enabled = true;
ECS::get_mut<GUI>().narrationBox = true;
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();
GUI::NarrationHandler *narration =
ECS::get<GUI>().narrationHandlers.front();
if (!narration->is_active())
narration->_event("narration_activate");
ImGui::TextWrapped(
"%s", narration->getNarrationText().c_str());
if (narration->getChoices().size() == 0) {
ImGui::SetCursorScreenPos(p);
if (ImGui::InvisibleButton(
"Background",
ImGui::GetWindowSize()))
narration->progress();
} else {
int i;
for (i = 0; i < narration->getChoices().size();
i++) {
if (ImGui::Button(
narration->getChoices()[i]
.c_str())) {
narration->setNarrationAnswer(
i + 1);
std::cout << "answer: " << i + 1
<< std::endl;
}
}
}
if (narration->is_complete()) {
ECS::get_mut<GUI>().enabled = false;
ECS::get_mut<GUI>().narrationBox = false;
ECS::get_mut<GUI>().grab = true;
ECS::get_mut<GUI>().grabChanged = true;
ECS::get_mut<GUI>().removeNarrationHandler(
narration);
delete narration;
}
ImGui::Spacing();
ImGui::PopFont();
ImGui::End();
ECS::modified<GUI>();
} else 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>().enabled) {
if (ECS::get().get<GUI>().mainMenu) {
ImGuiViewport *viewport =
ImGui::GetMainViewport();
ImGui::SetNextWindowPos(viewport->WorkPos,
ImGuiCond_Always);
ImGui::SetNextWindowSize(viewport->WorkSize,
ImGuiCond_Always);
ImGui::PushStyleVar(
ImGuiStyleVar_WindowRounding, 0.0f);
ImGui::PushStyleVar(
ImGuiStyleVar_WindowBorderSize, 0.0f);
#if 0
ImGui::SetNextWindowPos(ImVec2(0, 0),
ImGuiCond_Always);
ImGui::SetNextWindowSize(ImVec2(size.x + 4,
size.y + 1),
ImGuiCond_Always);
#endif
ImVec4 solidColor =
ImVec4(0.0f, 0.0f, 0.0f, 1.0f);
ImGui::PushStyleColor(ImGuiCol_WindowBg,
solidColor);
ImGui::Begin(
"MainMenu", nullptr,
ImGuiWindowFlags_NoTitleBar |
ImGuiWindowFlags_NoDecoration |
ImGuiWindowFlags_NoResize |
ImGuiWindowFlags_NoMove |
ImGuiWindowFlags_NoCollapse |
ImGuiWindowFlags_NoFocusOnAppearing |
ImGuiWindowFlags_NoSavedSettings |
ImGuiWindowFlags_NoBringToFrontOnFocus |
0);
struct buttons {
std::string label;
std::function<void(bool)> callback;
};
bool new_game = false, cont = false,
load_game = false, opts = false,
quit = false;
struct buttons buttons_data[] = {
{ "New Game",
[&](bool pressed) {
new_game = true;
} },
{ "Continue",
[&](bool pressed) { cont = true; } },
{ "Load Game",
[&](bool pressed) {
load_game = true;
} },
{ "Options",
[&](bool pressed) { opts = true; } },
{ "Quit###quit",
[&](bool pressed) { quit = true; } },
};
ImVec2 size = ImGui::GetWindowSize();
float window_width = size.x;
float window_height = size.y;
ImGui::PushFont(bigFont);
ImGui::TextWrapped("%s", "Booo!!!!");
float extra_pixels = 20.0f;
float button_width = 0.0f;
float buttons_height = 0.0f;
for (const struct buttons &b : buttons_data) {
ImVec2 text_size = ImGui::CalcTextSize(
b.label.c_str());
float text_width = text_size.x;
float text_height = text_size.y;
float bwidth =
text_width +
(ImGui::GetStyle()
.FramePadding.x *
2.0f) +
extra_pixels;
if (button_width < bwidth)
button_width = bwidth;
buttons_height +=
text_height +
(ImGui::GetStyle()
.FramePadding.y *
2.0f);
}
ImGui::SetCursorPosY(
(window_height - buttons_height) *
0.5f);
for (const struct buttons &b : buttons_data) {
ImGui::SetCursorPosX(
(window_width - button_width) *
0.5f);
if (ImGui::Button(b.label.c_str(),
ImVec2(button_width,
0)))
b.callback(true);
}
bool pressed = false;
pressed = new_game || cont || load_game ||
opts || quit;
ImGui::PopFont();
ImGui::Spacing();
ImGui::End();
ImGui::PopStyleColor();
ImGui::PopStyleVar();
ImGui::PopStyleVar();
if (quit)
Ogre::Root::getSingleton()
.queueEndRendering();
if (pressed)
ECS::get().get<GUI>().finish();
if (new_game) {
ECS::get().set<GameState>({ true });
ECS::get<LuaBase>().mLua->call_handler(
"new_game_selected");
} else if (load_game) {
ECS::get().set<GameState>({ true });
ECS::get<LuaBase>().mLua->call_handler(
"load_game_selected");
}
} 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("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();
}
} else {
ECS::ActionNodeList &list =
ECS::get_mut<ECS::ActionNodeList>();
if (list.dynamicNodes.size() > 0 &&
ECS::get<GUI>().enableActions) {
int j;
Ogre::Vector3 queryPos;
std::vector<size_t> points =
list.getUIData().points;
std::vector<float> distances =
list.getUIData().distances;
Ogre::SceneNode *cameraNode =
ECS::get<Camera>().mCameraNode;
Ogre::Vector3 cameraPos =
cameraNode->_getDerivedPosition();
float minDistance = 25.0f;
int i;
list.setUISelected(-1);
for (i = 0; i < points.size(); i++) {
size_t p = points[i];
float distance = distances[i];
float radius = list.dynamicNodes[p]
.props["radius"]
.get<float>();
float height = list.dynamicNodes[p]
.props["height"]
.get<float>();
float actDistance = radius * radius +
height * height;
float textDistance =
actDistance + 2.0f * 2.0f;
Ogre::Vector2 screenPos =
projectToScreen(
list.dynamicNodes[p]
.position);
if (screenPos.x < 0)
continue;
// FIXME: move this to system to filter points there
Ogre::Vector3 hitPosition;
JPH::BodyID hitBody;
bool hit =
JoltPhysicsWrapper::getSingleton()
.raycastQuery(
list.dynamicNodes[p]
.position,
cameraPos,
hitPosition,
hitBody);
if (hit)
continue;
if (list.getUIData().selected == -1) {
if (distance < actDistance)
list.setUISelected(p);
}
ImDrawList *drawList =
ImGui::GetBackgroundDrawList();
ImVec2 center = ImVec2(screenPos.x,
screenPos.y);
float circleRadius = 8.0f;
ImColor circleColor(
ImVec4(0.3f, 0.3f, 0.3f, 1.0f));
if (p == list.getUIData().selected) {
circleRadius = 16.0f;
circleColor = ImColor(
ImVec4(0, 0, 1, 1));
}
drawList->AddCircleFilled(center,
circleRadius,
circleColor);
drawList->AddCircle(
center, circleRadius,
IM_COL32(64, 64, 255, 255));
ImVec2 textSize = ImGui::CalcTextSize(
list.dynamicNodes[p]
.action_text.c_str());
ImVec2 textPos = ImVec2(
center.x - (textSize.x * 0.5f),
center.y + circleRadius + 4.0f);
if (distance < textDistance) {
drawList->AddText(
ImVec2(textPos.x + 1,
textPos.y + 1),
IM_COL32(0, 0, 0, 200),
list.dynamicNodes[p]
.action_text
.c_str());
drawList->AddText(
ImVec2(textPos.x,
textPos.y),
IM_COL32(255, 32, 64,
255),
list.dynamicNodes[p]
.action_text
.c_str());
}
}
}
}
}
};
GUIModule::GUIModule(flecs::world &ecs)
{
ecs.module<GUIModule>();
ecs.import <AppModule>();
ecs.import <QuestModule>();
ecs.component<GUI>()
.on_add([](GUI &gui) {
gui.enabled = false;
gui.grab = false;
gui.grabChanged = false;
gui.enableActions = true;
})
.add(flecs::Singleton);
ecs.component<GUIData>()
.on_add([](GUIData &priv) {
priv.glb_names.clear();
priv.mGUIListener = nullptr;
priv.mGuiOverlay = nullptr;
})
.add(flecs::Singleton);
}
void GUIModule::configure()
{
ZoneScoped;
ECS::get().set<GUIData>({ nullptr, {}, nullptr });
const RenderWindow &window = ECS::get<RenderWindow>();
GUIData &gui = ECS::get_mut<GUIData>();
const App &app = ECS::get<App>();
if (gui.mGuiOverlay)
return;
float vpScale = window.dpi / 96;
if (vpScale < 1.0f)
vpScale = 1.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<GUIData>();
std::cout << "GUI configure finished\n";
}
}