Started implementing deficated editor GUI
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
cmake_minimum_required(VERSION 3.13.0)
|
||||
project(world2)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(BLENDER "${CMAKE_SOURCE_DIR}/../../blender-bin/bin/blender" CACHE STRING "Blender path")
|
||||
set(CREATE_DIRECTORIES
|
||||
${CMAKE_BINARY_DIR}/assets/blender/shapes/male
|
||||
@@ -75,6 +75,7 @@ add_subdirectory(morph)
|
||||
add_subdirectory(src/world)
|
||||
add_subdirectory(src/tests)
|
||||
add_subdirectory(src/physics)
|
||||
add_subdirectory(src/editor)
|
||||
|
||||
add_executable(Game Game.cpp ${WATER_SRC})
|
||||
target_include_directories(Game PRIVATE src/gamedata)
|
||||
@@ -384,4 +385,5 @@ add_custom_target(import_vrm DEPENDS ${CHARACTER_GLBS})
|
||||
target_compile_definitions(Game PRIVATE FLECS_CPP_NO_AUTO_REGISTRATION)
|
||||
|
||||
install(TARGETS Game DESTINATION bin)
|
||||
install(TARGETS Editor DESTINATION bin)
|
||||
|
||||
|
||||
1
Game.cpp
1
Game.cpp
@@ -16,6 +16,7 @@
|
||||
#include "CharacterModule.h"
|
||||
#include "TerrainModule.h"
|
||||
#include "GUIModule.h"
|
||||
#include "AppModule.h"
|
||||
#include "sound.h"
|
||||
class App;
|
||||
class SkyRenderer : public Ogre::SceneManager::Listener {
|
||||
|
||||
15
src/gamedata/AppModule.cpp
Normal file
15
src/gamedata/AppModule.cpp
Normal file
@@ -0,0 +1,15 @@
|
||||
#include "AppModule.h"
|
||||
namespace ECS
|
||||
{
|
||||
AppModule::AppModule(flecs::world &ecs)
|
||||
{
|
||||
ecs.module<AppModule>();
|
||||
ecs.component<App>()
|
||||
.on_add([](App &app) {
|
||||
app.mInput = nullptr;
|
||||
app.mGuiOverlay = nullptr;
|
||||
app.listeners.clear();
|
||||
})
|
||||
.add(flecs::Singleton);
|
||||
}
|
||||
}
|
||||
25
src/gamedata/AppModule.h
Normal file
25
src/gamedata/AppModule.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#ifndef _APP_MODULE_H_
|
||||
#define _APP_MODULE_H_
|
||||
#include <flecs.h>
|
||||
#include <vector>
|
||||
namespace Ogre
|
||||
{
|
||||
class ImGuiOverlay;
|
||||
}
|
||||
namespace OgreBites
|
||||
{
|
||||
class InputListenerChain;
|
||||
class InputListener;
|
||||
}
|
||||
namespace ECS
|
||||
{
|
||||
struct App {
|
||||
Ogre::ImGuiOverlay *mGuiOverlay;
|
||||
OgreBites::InputListenerChain *mInput;
|
||||
std::vector<OgreBites::InputListener *> listeners;
|
||||
};
|
||||
struct AppModule {
|
||||
AppModule(flecs::world &ecs);
|
||||
};
|
||||
}
|
||||
#endif
|
||||
@@ -2,8 +2,10 @@ project(gamedata)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
find_package(OGRE REQUIRED COMPONENTS Bites Bullet Paging Terrain Overlay CONFIG)
|
||||
find_package(Bullet REQUIRED)
|
||||
add_library(GameData STATIC GameData.cpp CharacterModule.cpp WaterModule.cpp SunModule.cpp TerrainModule.cpp GUIModule.cpp LuaData.cpp WorldMapModule.cpp
|
||||
BoatModule.cpp EventTriggerModule.cpp CharacterAnimationModule.cpp PhysicsModule.cpp EventModule.cpp CharacterManagerModule.cpp SmartObject.cpp SlotsModule.cpp goap.cpp)
|
||||
add_library(GameData STATIC GameData.cpp CharacterModule.cpp WaterModule.cpp SunModule.cpp TerrainModule.cpp
|
||||
GUIModule.cpp LuaData.cpp WorldMapModule.cpp BoatModule.cpp EventTriggerModule.cpp
|
||||
CharacterAnimationModule.cpp PhysicsModule.cpp EventModule.cpp CharacterManagerModule.cpp
|
||||
VehicleManagerModule.cpp AppModule.cpp SmartObject.cpp SlotsModule.cpp goap.cpp)
|
||||
target_link_libraries(GameData PUBLIC lua flecs::flecs_static OgreMain OgreBites
|
||||
OgrePaging OgreTerrain OgreOverlay
|
||||
PRIVATE sceneloader world-build physics)
|
||||
|
||||
@@ -67,11 +67,6 @@ struct RenderWindow {
|
||||
Ogre::RenderWindow *window;
|
||||
float dpi;
|
||||
};
|
||||
struct App {
|
||||
Ogre::ImGuiOverlay *mGuiOverlay;
|
||||
OgreBites::InputListenerChain *mInput;
|
||||
std::vector<OgreBites::InputListener *> listeners;
|
||||
};
|
||||
struct CollisionShape {
|
||||
void *shape;
|
||||
};
|
||||
|
||||
@@ -11,15 +11,22 @@
|
||||
#include "GameData.h"
|
||||
#include "Components.h"
|
||||
#include "LuaData.h"
|
||||
#include "AppModule.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;
|
||||
@@ -459,8 +466,537 @@ struct GUIListener : public Ogre::RenderTargetListener {
|
||||
}
|
||||
};
|
||||
|
||||
struct EditorGUIListener : public Ogre::RenderTargetListener {
|
||||
float panel_width;
|
||||
bool enableEditor;
|
||||
bool enableMapEditor;
|
||||
ImFont *smallFont, *midFont, *bigFont;
|
||||
Ogre::FontPtr _smallFont, _midFont, _bigFont;
|
||||
EditorGUIListener(Ogre::ImGuiOverlay *overlay)
|
||||
: Ogre::RenderTargetListener()
|
||||
{
|
||||
std::cout << "WAAAAAAA!!!!!" << std::endl;
|
||||
_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");
|
||||
#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<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();
|
||||
}
|
||||
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();
|
||||
std::cout << "GUI enabled: " << ECS::get().get<GUI>().enabled
|
||||
<< std::endl;
|
||||
if (ECS::get().get<GUI>().enabled) {
|
||||
buttons_panel();
|
||||
buildings_editor();
|
||||
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();
|
||||
#if 0
|
||||
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();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
};
|
||||
GUIModule::GUIModule(flecs::world &ecs)
|
||||
{
|
||||
ecs.module<GUIModule>();
|
||||
ecs.import <AppModule>();
|
||||
ecs.component<GUI>()
|
||||
.on_add([](GUI &gui) {
|
||||
gui.enabled = false;
|
||||
@@ -522,4 +1058,46 @@ GUIModule::GUIModule(flecs::world &ecs)
|
||||
}
|
||||
});
|
||||
}
|
||||
EditorGUIModule::EditorGUIModule(flecs::world &ecs)
|
||||
{
|
||||
ecs.module<EditorGUIModule>();
|
||||
ecs.import <AppModule>();
|
||||
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";
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -17,11 +17,11 @@ struct GUI {
|
||||
int narration_answer;
|
||||
static void setWindowGrab(bool g = true)
|
||||
{
|
||||
ECS::GUI &gui = ECS::get().get_mut<ECS::GUI>();
|
||||
ECS::GUI &gui = ECS::get().get_mut<GUI>();
|
||||
if (gui.grab != g) {
|
||||
gui.grab = g;
|
||||
gui.grabChanged = true;
|
||||
ECS::get().modified<ECS::GUI>();
|
||||
ECS::get().modified<GUI>();
|
||||
}
|
||||
}
|
||||
static void finish()
|
||||
@@ -38,5 +38,8 @@ struct GUIModule {
|
||||
flecs::entity ui_wait;
|
||||
GUIModule(flecs::world &ecs);
|
||||
};
|
||||
struct EditorGUIModule {
|
||||
EditorGUIModule(flecs::world &ecs);
|
||||
};
|
||||
}
|
||||
#endif
|
||||
@@ -15,6 +15,8 @@
|
||||
#include "PhysicsModule.h"
|
||||
#include "EventModule.h"
|
||||
#include "CharacterManagerModule.h"
|
||||
#include "VehicleManagerModule.h"
|
||||
#include "AppModule.h"
|
||||
#include "world-build.h"
|
||||
|
||||
namespace ECS
|
||||
@@ -30,18 +32,9 @@ void setup_minimal()
|
||||
ecs.import <GameWorldModule>();
|
||||
ecs.import <EventModule>();
|
||||
ecs.import <CharacterManagerModule>();
|
||||
ecs.import <VehicleManagerModule>();
|
||||
ecs.import <WaterModule>();
|
||||
ecs.component<InWater>();
|
||||
ecs.component<WaterReady>().add(flecs::Singleton);
|
||||
ecs.component<WaterAlmostReady>().add(flecs::Singleton);
|
||||
ecs.component<GroundCheckReady>().add(flecs::Singleton);
|
||||
ecs.component<App>()
|
||||
.on_add([](App &app) {
|
||||
app.mInput = nullptr;
|
||||
app.mGuiOverlay = nullptr;
|
||||
app.listeners.clear();
|
||||
})
|
||||
.add(flecs::Singleton);
|
||||
ecs.import <AppModule>();
|
||||
/* lots of things depend on it */
|
||||
ecs.component<Body2Entity>().add(flecs::Singleton);
|
||||
}
|
||||
@@ -108,6 +101,11 @@ void setup(Ogre::SceneManager *scnMgr, Ogre::SceneNode *cameraNode,
|
||||
nullptr,
|
||||
false,
|
||||
{ 0, 0, 0 } });
|
||||
if (!ecs.has<LuaBase>())
|
||||
ecs.add<LuaBase>();
|
||||
if (!ecs.has<LuaEvent>())
|
||||
ecs.set<LuaEvent>({});
|
||||
|
||||
// ecs.set<Body2Entity>({});
|
||||
std::cout << "Setup GameData done\n";
|
||||
|
||||
@@ -116,6 +114,79 @@ void setup(Ogre::SceneManager *scnMgr, Ogre::SceneNode *cameraNode,
|
||||
{ 0, 0, 4 }, Ogre::Quaternion(Ogre::Radian(Ogre::Math::PI),
|
||||
Ogre::Vector3::UNIT_Y));
|
||||
}
|
||||
void setupEditor(Ogre::SceneManager *scnMgr, Ogre::SceneNode *cameraNode,
|
||||
Ogre::Camera *camera, Ogre::RenderWindow *window)
|
||||
{
|
||||
std::cout << "Setup Editor\n";
|
||||
setup_minimal();
|
||||
ecs.component<RenderWindow>().add(flecs::Singleton);
|
||||
ecs.import <CharacterModule>();
|
||||
ecs.import <BoatModule>();
|
||||
ecs.import <PhysicsModule>();
|
||||
ecs.import <WaterModule>();
|
||||
ecs.import <SunModule>();
|
||||
ecs.import <TerrainModule>();
|
||||
ecs.import <EditorGUIModule>();
|
||||
ecs.import <EventTriggerModule>();
|
||||
ecs.import <LuaModule>();
|
||||
// ecs.import <WorldMapModule>();
|
||||
ecs.import <CharacterAnimationModule>();
|
||||
|
||||
ecs.system<EngineData>("UpdateDelta")
|
||||
.kind(flecs::OnUpdate)
|
||||
.each([](EngineData &eng) {
|
||||
eng.delta = ECS::get().delta_time();
|
||||
});
|
||||
ecs.system<EngineData>("UpdateDelay")
|
||||
.kind(flecs::OnUpdate)
|
||||
.with<TerrainReady>()
|
||||
.with<WaterReady>()
|
||||
.with<GroundCheckReady>()
|
||||
.each([](EngineData &eng) {
|
||||
if (eng.startupDelay >= 0.0f)
|
||||
eng.startupDelay -= eng.delta;
|
||||
#ifdef VDEBUG
|
||||
if (ECS::get().has<GroundCheckReady>())
|
||||
std::cout << "ground check ready\n";
|
||||
#endif
|
||||
});
|
||||
ecs.system<EngineData>("CheckStatus")
|
||||
.kind(flecs::OnUpdate)
|
||||
.run([](flecs::iter &it) {
|
||||
#ifdef VDEBUG
|
||||
if (ECS::get().has<WaterReady>())
|
||||
std::cout << "water ready\n";
|
||||
if (ECS::get().has<TerrainReady>())
|
||||
std::cout << "terrain ready\n";
|
||||
if (ECS::get().has<GroundCheckReady>())
|
||||
std::cout << "ground check ready\n";
|
||||
#endif
|
||||
});
|
||||
ecs.set<EngineData>({ scnMgr, 0.0f, 5.0f, (int)window->getWidth(),
|
||||
(int)window->getHeight(), false });
|
||||
ecs.set<Camera>({ cameraNode, camera, false });
|
||||
ecs.add<GameData>();
|
||||
ecs.add<Input>();
|
||||
ecs.add<WaterSurface>();
|
||||
ecs.set<Sun>({ nullptr, nullptr, nullptr, nullptr });
|
||||
ecs.set<Terrain>({ nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
false,
|
||||
{ 0, 0, 0 } });
|
||||
ecs.set<GUI>({ true, true, true, false, false, "", {}, -1 });
|
||||
ecs.get_mut<GUI>().enabled = true;
|
||||
ecs.get_mut<GUI>().setWindowGrab(false);
|
||||
ecs.modified<GUI>();
|
||||
ecs.get_mut<GUI>().setWindowGrab(true);
|
||||
ecs.modified<GUI>();
|
||||
ecs.get_mut<GUI>().enabled = true;
|
||||
ecs.modified<GUI>();
|
||||
}
|
||||
|
||||
void update(float delta)
|
||||
{
|
||||
ecs.progress(delta);
|
||||
|
||||
@@ -7,6 +7,8 @@ extern flecs::entity player;
|
||||
void setup_minimal();
|
||||
void setup(Ogre::SceneManager *scnMgr, Ogre::SceneNode *cameraNode,
|
||||
Ogre::Camera *camera, Ogre::RenderWindow *window);
|
||||
void setupEditor(Ogre::SceneManager *scnMgr, Ogre::SceneNode *cameraNode,
|
||||
Ogre::Camera *camera, Ogre::RenderWindow *window);
|
||||
void update(float delta);
|
||||
flecs::world get();
|
||||
template <class T> const T &get()
|
||||
@@ -22,4 +24,4 @@ template <class T> void modified()
|
||||
ECS::get().modified<T>();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "CharacterModule.h"
|
||||
#include "CharacterAnimationModule.h"
|
||||
#include "CharacterManagerModule.h"
|
||||
#include "VehicleManagerModule.h"
|
||||
#include "BoatModule.h"
|
||||
#include "EventTriggerModule.h"
|
||||
#include "SlotsModule.h"
|
||||
@@ -365,12 +366,14 @@ LuaData::LuaData()
|
||||
float x = lua_tonumber(L, 2);
|
||||
float y = lua_tonumber(L, 3);
|
||||
float z = lua_tonumber(L, 4);
|
||||
flecs::entity e = ECS::get().entity();
|
||||
Ogre::Quaternion orientation(Ogre::Radian(yaw),
|
||||
Ogre::Vector3(0, 1, 0));
|
||||
Ogre::Vector3 position(x, y, z);
|
||||
e.set<BoatType>(
|
||||
{ "boat.scene", position, orientation });
|
||||
flecs::entity e =
|
||||
ECS::get_mut<VehicleManagerModule>()
|
||||
.createVehicleAtPosition(
|
||||
"boat", position, orientation);
|
||||
ECS::modified<VehicleManagerModule>();
|
||||
int ret = idmap.add_entity(e);
|
||||
lua_pushinteger(L, ret);
|
||||
std::cout << "boat created: " << ret << std::endl;
|
||||
@@ -380,12 +383,14 @@ LuaData::LuaData()
|
||||
float x = lua_tonumber(L, 2);
|
||||
float y = lua_tonumber(L, 3);
|
||||
float z = lua_tonumber(L, 4);
|
||||
flecs::entity e = ECS::get().entity();
|
||||
Ogre::Quaternion orientation(Ogre::Radian(yaw),
|
||||
Ogre::Vector3(0, 1, 0));
|
||||
Ogre::Vector3 position(x, y, z);
|
||||
e.set<BoatType>(
|
||||
{ "raft.scene", position, orientation });
|
||||
flecs::entity e =
|
||||
ECS::get_mut<VehicleManagerModule>()
|
||||
.createVehicleAtPosition(
|
||||
"raft", position, orientation);
|
||||
ECS::modified<VehicleManagerModule>();
|
||||
int ret = idmap.add_entity(e);
|
||||
lua_pushinteger(L, ret);
|
||||
std::cout << "raft created: " << ret << std::endl;
|
||||
@@ -840,6 +845,7 @@ LuaModule::LuaModule(flecs::world &ecs)
|
||||
{
|
||||
ecs.module<LuaModule>();
|
||||
ecs.import <SlotsModule>();
|
||||
ecs.import <VehicleManagerModule>();
|
||||
ecs.component<LuaChildEventTrigger>();
|
||||
ecs.component<LuaBase>()
|
||||
.on_add([](LuaBase &lua) {
|
||||
@@ -849,11 +855,6 @@ LuaModule::LuaModule(flecs::world &ecs)
|
||||
})
|
||||
.add(flecs::Singleton);
|
||||
ecs.component<LuaEvent>().add(flecs::Singleton);
|
||||
if (!ecs.has<LuaBase>())
|
||||
ecs.add<LuaBase>();
|
||||
if (!ecs.has<LuaEvent>())
|
||||
ecs.set<LuaEvent>({});
|
||||
|
||||
ecs.system<const EngineData, LuaBase>("LuaUpdate")
|
||||
.kind(flecs::OnUpdate)
|
||||
.each([](const EngineData &eng, LuaBase &lua) {
|
||||
|
||||
24
src/gamedata/VehicleManagerModule.cpp
Normal file
24
src/gamedata/VehicleManagerModule.cpp
Normal file
@@ -0,0 +1,24 @@
|
||||
#include "Components.h"
|
||||
#include "GameData.h"
|
||||
#include "BoatModule.h"
|
||||
#include "VehicleManagerModule.h"
|
||||
namespace ECS
|
||||
{
|
||||
VehicleManagerModule::VehicleManagerModule(flecs::world &ecs)
|
||||
{
|
||||
ecs.module<VehicleManagerModule>();
|
||||
ecs.import <BoatModule>();
|
||||
}
|
||||
flecs::entity VehicleManagerModule::createVehicleAtPosition(
|
||||
const Ogre::String &name, const Ogre::Vector3 &position,
|
||||
const Ogre::Quaternion &orientation)
|
||||
{
|
||||
flecs::entity vehicle = ECS::get().entity();
|
||||
if (name == "boat")
|
||||
vehicle.set<BoatType>(
|
||||
{ name + ".scene", position, orientation });
|
||||
else
|
||||
OgreAssert(false, "unsupported type: " + name);
|
||||
return vehicle;
|
||||
}
|
||||
}
|
||||
15
src/gamedata/VehicleManagerModule.h
Normal file
15
src/gamedata/VehicleManagerModule.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifndef _VEHICLE_MANAGER_MODULE_H_
|
||||
#define _VEHICLE_MANAGE_MODULE_H_
|
||||
#include <flecs.h>
|
||||
#include <Ogre.h>
|
||||
namespace ECS
|
||||
{
|
||||
struct VehicleManagerModule {
|
||||
VehicleManagerModule(flecs::world &ecs);
|
||||
flecs::entity
|
||||
createVehicleAtPosition(const Ogre::String &name,
|
||||
const Ogre::Vector3 &position,
|
||||
const Ogre::Quaternion &orientation);
|
||||
};
|
||||
}
|
||||
#endif
|
||||
@@ -1,4 +1,5 @@
|
||||
project(world)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
find_package(Bullet)
|
||||
find_package(OGRE REQUIRED COMPONENTS Bites Bullet Paging Terrain Overlay CONFIG)
|
||||
add_library(action STATIC action.cpp)
|
||||
|
||||
Reference in New Issue
Block a user