Action nodes support and lots of other updates
This commit is contained in:
2586
src/FastNoiseLite/FastNoiseLite.h
Normal file
2586
src/FastNoiseLite/FastNoiseLite.h
Normal file
File diff suppressed because it is too large
Load Diff
22
src/FastNoiseLite/LICENSE
Normal file
22
src/FastNoiseLite/LICENSE
Normal file
@@ -0,0 +1,22 @@
|
||||
MIT License
|
||||
|
||||
Copyright(c) 2020 Jordan Peck (jordan.me2@gmail.com)
|
||||
Copyright(c) 2020 Contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
23
src/FastNoiseLite/README.md
Normal file
23
src/FastNoiseLite/README.md
Normal file
@@ -0,0 +1,23 @@
|
||||
## Getting Started
|
||||
|
||||
Here's an example for creating a 128x128 array of OpenSimplex2 noise
|
||||
|
||||
```cpp
|
||||
// Create and configure FastNoise object
|
||||
FastNoiseLite noise;
|
||||
noise.SetNoiseType(FastNoiseLite::NoiseType_OpenSimplex2);
|
||||
|
||||
// Gather noise data
|
||||
std::vector<float> noiseData(128 * 128);
|
||||
int index = 0;
|
||||
|
||||
for (int y = 0; y < 128; y++)
|
||||
{
|
||||
for (int x = 0; x < 128; x++)
|
||||
{
|
||||
noiseData[index++] = noise.GetNoise((float)x, (float)y);
|
||||
}
|
||||
}
|
||||
|
||||
// Do something with this data...
|
||||
```
|
||||
@@ -16,7 +16,7 @@
|
||||
#include "Components.h"
|
||||
#include "CharacterModule.h"
|
||||
#include "TerrainModule.h"
|
||||
#include "GUIModule.h"
|
||||
#include "GUIModuleCommon.h"
|
||||
#include "AppModule.h"
|
||||
#include "EditorGizmoModule.h"
|
||||
#include "EditorInputModule.h"
|
||||
|
||||
@@ -6,9 +6,10 @@ find_package(nlohmann_json REQUIRED)
|
||||
find_package(OgreProcedural REQUIRED CONFIG)
|
||||
add_subdirectory(items)
|
||||
add_library(GameData STATIC GameData.cpp CharacterModule.cpp WaterModule.cpp SunModule.cpp TerrainModule.cpp
|
||||
GUIModule.cpp LuaData.cpp WorldMapModule.cpp BoatModule.cpp EventTriggerModule.cpp
|
||||
GUIModule.cpp EditorGUIModule.cpp LuaData.cpp WorldMapModule.cpp BoatModule.cpp EventTriggerModule.cpp
|
||||
CharacterAnimationModule.cpp PhysicsModule.cpp EventModule.cpp CharacterManagerModule.cpp
|
||||
VehicleManagerModule.cpp AppModule.cpp StaticGeometryModule.cpp SmartObject.cpp SlotsModule.cpp goap.cpp)
|
||||
VehicleManagerModule.cpp AppModule.cpp StaticGeometryModule.cpp SmartObject.cpp SlotsModule.cpp
|
||||
PlayerActionModule.cpp goap.cpp)
|
||||
target_link_libraries(GameData PUBLIC
|
||||
lua
|
||||
flecs::flecs_static
|
||||
|
||||
1421
src/gamedata/EditorGUIModule.cpp
Normal file
1421
src/gamedata/EditorGUIModule.cpp
Normal file
File diff suppressed because it is too large
Load Diff
9
src/gamedata/EditorGUIModule.h
Normal file
9
src/gamedata/EditorGUIModule.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#ifndef __EDITORGUIMODULE_H__
|
||||
#define __EDITORGUIMODULE_H__
|
||||
|
||||
namespace ECS {
|
||||
struct EditorGUIModule {
|
||||
EditorGUIModule(flecs::world &ecs);
|
||||
};
|
||||
}
|
||||
#endif // EDITORGUIMODULE_H
|
||||
@@ -26,4 +26,4 @@ struct EventModule {
|
||||
flecs::entity to);
|
||||
};
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -6,40 +6,9 @@ namespace OgreBites
|
||||
}
|
||||
namespace ECS
|
||||
{
|
||||
struct GUI {
|
||||
bool enabled;
|
||||
bool grab;
|
||||
bool grabChanged;
|
||||
bool narrationBox;
|
||||
bool mainMenu;
|
||||
Ogre::String narrationText;
|
||||
std::vector<Ogre::String> choices;
|
||||
int narration_answer;
|
||||
static void setWindowGrab(bool g = true)
|
||||
{
|
||||
ECS::GUI &gui = ECS::get().get_mut<GUI>();
|
||||
if (gui.grab != g) {
|
||||
gui.grab = g;
|
||||
gui.grabChanged = true;
|
||||
ECS::get().modified<GUI>();
|
||||
}
|
||||
}
|
||||
static void finish()
|
||||
{
|
||||
ECS::GUI &gui = ECS::get().get_mut<ECS::GUI>();
|
||||
gui.enabled = false;
|
||||
gui.mainMenu = false;
|
||||
gui.narrationBox = false;
|
||||
ECS::get().modified<ECS::GUI>();
|
||||
setWindowGrab(true);
|
||||
}
|
||||
};
|
||||
struct GUIModule {
|
||||
flecs::entity ui_wait;
|
||||
GUIModule(flecs::world &ecs);
|
||||
};
|
||||
struct EditorGUIModule {
|
||||
EditorGUIModule(flecs::world &ecs);
|
||||
};
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
36
src/gamedata/GUIModuleCommon.h
Normal file
36
src/gamedata/GUIModuleCommon.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#ifndef __GUIMODULECOMMON_H__
|
||||
#define __GUIMODULECOMMON_H__
|
||||
namespace ECS
|
||||
{
|
||||
|
||||
struct GUI {
|
||||
bool enabled;
|
||||
bool grab;
|
||||
bool grabChanged;
|
||||
bool narrationBox;
|
||||
bool mainMenu;
|
||||
Ogre::String narrationText;
|
||||
std::vector<Ogre::String> choices;
|
||||
int narration_answer;
|
||||
static void setWindowGrab(bool g = true)
|
||||
{
|
||||
ECS::GUI &gui = ECS::get().get_mut<GUI>();
|
||||
if (gui.grab != g) {
|
||||
gui.grab = g;
|
||||
gui.grabChanged = true;
|
||||
ECS::get().modified<GUI>();
|
||||
}
|
||||
}
|
||||
static void finish()
|
||||
{
|
||||
ECS::GUI &gui = ECS::get().get_mut<ECS::GUI>();
|
||||
gui.enabled = false;
|
||||
gui.mainMenu = false;
|
||||
gui.narrationBox = false;
|
||||
ECS::get().modified<ECS::GUI>();
|
||||
setWindowGrab(true);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif // GUIMODULECOMMON_H
|
||||
@@ -10,7 +10,9 @@
|
||||
#include "WaterModule.h"
|
||||
#include "TerrainModule.h"
|
||||
#include "SunModule.h"
|
||||
#include "GUIModuleCommon.h"
|
||||
#include "GUIModule.h"
|
||||
#include "EditorGUIModule.h"
|
||||
#include "LuaData.h"
|
||||
#include "WorldMapModule.h"
|
||||
#include "BoatModule.h"
|
||||
@@ -20,6 +22,7 @@
|
||||
#include "EventModule.h"
|
||||
#include "CharacterManagerModule.h"
|
||||
#include "VehicleManagerModule.h"
|
||||
#include "PlayerActionModule.h"
|
||||
#include "AppModule.h"
|
||||
#include "world-build.h"
|
||||
|
||||
@@ -42,7 +45,7 @@ void setup_minimal()
|
||||
ecs.component<Body2Entity>().add(flecs::Singleton);
|
||||
}
|
||||
void setupExteriorScene(Ogre::SceneManager *scnMgr, Ogre::SceneNode *cameraNode,
|
||||
Ogre::Camera *camera, Ogre::RenderWindow *window)
|
||||
Ogre::Camera *camera, Ogre::RenderWindow *window)
|
||||
{
|
||||
std::cout << "Setup GameData\n";
|
||||
setup_minimal();
|
||||
@@ -53,11 +56,13 @@ void setupExteriorScene(Ogre::SceneManager *scnMgr, Ogre::SceneNode *cameraNode,
|
||||
ecs.import <WaterModule>();
|
||||
ecs.import <SunModule>();
|
||||
ecs.import <TerrainModule>();
|
||||
ecs.import <GUIModule>();
|
||||
ecs.import <GUIModule>();
|
||||
ecs.import <EventTriggerModule>();
|
||||
ecs.import <LuaModule>();
|
||||
ecs.import <WorldMapModule>();
|
||||
ecs.import <CharacterAnimationModule>();
|
||||
ecs.import <PlayerActionModule>();
|
||||
ecs.add<ActionNodeList>();
|
||||
|
||||
ecs.system<EngineData>("UpdateDelta")
|
||||
.kind(flecs::OnUpdate)
|
||||
@@ -90,7 +95,7 @@ void setupExteriorScene(Ogre::SceneManager *scnMgr, Ogre::SceneNode *cameraNode,
|
||||
#endif
|
||||
});
|
||||
ecs.set<EngineData>({ scnMgr, 0.0f, 5.0f, (int)window->getWidth(),
|
||||
(int)window->getHeight(), false });
|
||||
(int)window->getHeight(), false });
|
||||
ecs.set<Camera>({ cameraNode, camera, false });
|
||||
ecs.add<GameData>();
|
||||
ecs.add<Input>();
|
||||
@@ -168,7 +173,7 @@ void setupInventoryScene(Ogre::SceneManager *scnMgr,
|
||||
}
|
||||
|
||||
void setupEditor(Ogre::SceneManager *scnMgr, Ogre::SceneNode *cameraNode,
|
||||
Ogre::Camera *camera, Ogre::RenderWindow *window)
|
||||
Ogre::Camera *camera, Ogre::RenderWindow *window)
|
||||
{
|
||||
std::cout << "Setup Editor\n";
|
||||
setup_minimal();
|
||||
@@ -217,7 +222,7 @@ void setupEditor(Ogre::SceneManager *scnMgr, Ogre::SceneNode *cameraNode,
|
||||
#endif
|
||||
});
|
||||
ecs.set<EngineData>({ scnMgr, 0.0f, 5.0f, (int)window->getWidth(),
|
||||
(int)window->getHeight(), false });
|
||||
(int)window->getHeight(), false });
|
||||
ecs.set<Camera>({ cameraNode, camera, false });
|
||||
#if 0
|
||||
ecs.set<EditorSceneSwitch>({ 0 });
|
||||
|
||||
@@ -6,13 +6,13 @@ namespace ECS
|
||||
extern flecs::entity player;
|
||||
void setup_minimal();
|
||||
void setupExteriorScene(Ogre::SceneManager *scnMgr, Ogre::SceneNode *cameraNode,
|
||||
Ogre::Camera *camera, Ogre::RenderWindow *window);
|
||||
Ogre::Camera *camera, Ogre::RenderWindow *window);
|
||||
void setupInteriorScene(Ogre::SceneManager *scnMgr, Ogre::SceneNode *cameraNode,
|
||||
Ogre::Camera *camera, Ogre::RenderWindow *window);
|
||||
void setupInventoryScene(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);
|
||||
Ogre::Camera *camera, Ogre::RenderWindow *window);
|
||||
void setupEditorAlt(Ogre::SceneManager *scnMgr, Ogre::SceneNode *cameraNode,
|
||||
Ogre::Camera *camera, Ogre::RenderWindow *window);
|
||||
void update(float delta);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <OgreFileSystemLayer.h>
|
||||
#include "GameData.h"
|
||||
#include "Components.h"
|
||||
#include "GUIModule.h"
|
||||
#include "GUIModuleCommon.h"
|
||||
#include "PhysicsModule.h"
|
||||
#include "CharacterModule.h"
|
||||
#include "CharacterAnimationModule.h"
|
||||
@@ -911,4 +911,4 @@ LuaModule::LuaModule(flecs::world &ecs)
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
114
src/gamedata/PlayerActionModule.cpp
Normal file
114
src/gamedata/PlayerActionModule.cpp
Normal file
@@ -0,0 +1,114 @@
|
||||
#include <nanoflann.hpp>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include "Components.h"
|
||||
#include "GameData.h"
|
||||
#include "PlayerActionModule.h"
|
||||
|
||||
namespace ECS
|
||||
{
|
||||
struct OgreVector3Adaptor {
|
||||
const std::vector<ActionNodeList::ActionNode> &nodes;
|
||||
|
||||
OgreVector3Adaptor(const std::vector<ActionNodeList::ActionNode> &nodes)
|
||||
: nodes(nodes)
|
||||
{
|
||||
}
|
||||
|
||||
// Required by nanoflann: Number of data points
|
||||
inline size_t kdtree_get_point_count() const
|
||||
{
|
||||
return nodes.size();
|
||||
}
|
||||
|
||||
// Required by nanoflann: Returns the distance between the vector and a point
|
||||
// Using squared distance is standard for performance
|
||||
inline float kdtree_get_pt(const size_t idx, const size_t dim) const
|
||||
{
|
||||
return nodes[idx].position[dim];
|
||||
}
|
||||
|
||||
// Optional: bounding box optimization (return false if not implemented)
|
||||
template <class BBOX> bool kdtree_get_bbox(BBOX & /*bb*/) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
typedef nanoflann::KDTreeSingleIndexAdaptor<
|
||||
nanoflann::L2_Simple_Adaptor<float, OgreVector3Adaptor>,
|
||||
OgreVector3Adaptor, 3 /* dimensionality */
|
||||
>
|
||||
OgreKDTree;
|
||||
struct ActionNodeList::indexObject {
|
||||
OgreVector3Adaptor adaptor;
|
||||
OgreKDTree index;
|
||||
indexObject(const std::vector<ActionNodeList::ActionNode> &nodes)
|
||||
: adaptor(nodes)
|
||||
, index(3, adaptor,
|
||||
nanoflann::KDTreeSingleIndexAdaptorParams(10))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
PlayerActionModule::PlayerActionModule(flecs::world &ecs)
|
||||
{
|
||||
ecs.module<PlayerActionModule>();
|
||||
ecs.component<ActionNodeList>()
|
||||
.on_add([](flecs::entity e, ActionNodeList &alist) {
|
||||
alist.dirty = true;
|
||||
alist.nodes.reserve(1000);
|
||||
})
|
||||
.add(flecs::Singleton);
|
||||
#if 0
|
||||
ecs.system<ActionNodeList>("testNodeList")
|
||||
.kind(flecs::OnUpdate)
|
||||
.each([](ActionNodeList &list) {
|
||||
if (list.nodes.size() > 0) {
|
||||
Ogre::Vector3 queryPos =
|
||||
ECS::get<Camera>()
|
||||
.mCameraNode
|
||||
->_getDerivedPosition();
|
||||
std::vector<size_t> points;
|
||||
list.query(queryPos, points);
|
||||
for (auto &p : points)
|
||||
std::cout << p << std::endl
|
||||
<< list.nodes[p].props.dump()
|
||||
<< std::endl;
|
||||
OgreAssert(points.size() == 0, "got result");
|
||||
}
|
||||
});
|
||||
#endif
|
||||
}
|
||||
|
||||
void ActionNodeList::build()
|
||||
{
|
||||
indexObj = std::make_shared<ActionNodeList::indexObject>(nodes);
|
||||
indexObj->index.buildIndex();
|
||||
dirty = false;
|
||||
std::cout << "index built" << std::endl;
|
||||
}
|
||||
|
||||
bool ActionNodeList::query(const Ogre::Vector3 &position,
|
||||
std::vector<size_t> &points)
|
||||
{
|
||||
if (dirty)
|
||||
build();
|
||||
std::vector<size_t> tmppoints;
|
||||
std::vector<float> tmpdistances;
|
||||
points.clear();
|
||||
points.reserve(4);
|
||||
tmppoints.resize(4);
|
||||
tmpdistances.resize(4);
|
||||
nanoflann::KNNResultSet<float> resultSet(4);
|
||||
resultSet.init(tmppoints.data(), tmpdistances.data());
|
||||
bool ret = indexObj->index.findNeighbors(resultSet, &position.x,
|
||||
nanoflann::SearchParameters());
|
||||
int i;
|
||||
for (i = 0; i < resultSet.size(); i++)
|
||||
if (tmpdistances[i] < 25.0f)
|
||||
points.push_back(tmppoints[i]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
42
src/gamedata/PlayerActionModule.h
Normal file
42
src/gamedata/PlayerActionModule.h
Normal file
@@ -0,0 +1,42 @@
|
||||
#ifndef PLAYERACTIONMODULE_H
|
||||
#define PLAYERACTIONMODULE_H
|
||||
#include <flecs.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <Ogre.h>
|
||||
|
||||
namespace ECS {
|
||||
|
||||
struct ActionNodeList {
|
||||
struct indexObject;
|
||||
struct ActionNode {
|
||||
Ogre::String action;
|
||||
Ogre::String action_text;
|
||||
Ogre::Vector3 position;
|
||||
Ogre::Quaternion rotation;
|
||||
nlohmann::json props;
|
||||
};
|
||||
std::vector<ActionNode> nodes;
|
||||
std::shared_ptr<indexObject> indexObj;
|
||||
bool dirty;
|
||||
void build();
|
||||
bool query(const Ogre::Vector3 &position, std::vector<size_t> &points);
|
||||
int addNode(struct ActionNodeList::ActionNode &node)
|
||||
{
|
||||
int index = nodes.size();
|
||||
nodes.push_back(node);
|
||||
dirty = true;
|
||||
return index;
|
||||
}
|
||||
void removeNode(int index)
|
||||
{
|
||||
nodes.erase(nodes.begin() + index);
|
||||
}
|
||||
};
|
||||
|
||||
struct PlayerActionModule
|
||||
{
|
||||
PlayerActionModule(flecs::world &ecs);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // PLAYERACTIONMODULE_H
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <OgreRTShaderSystem.h>
|
||||
#include <OgreStaticGeometry.h>
|
||||
#include <OgreMeshLodGenerator.h>
|
||||
#include <OgreWorkQueue.h>
|
||||
#include <Procedural.h>
|
||||
#include "Components.h"
|
||||
#include "GameData.h"
|
||||
@@ -20,6 +21,7 @@ namespace ECS
|
||||
|
||||
static bool itemsLoaded = false;
|
||||
static bool furnitureLoaded = false;
|
||||
static bool templatesLoaded = false;
|
||||
static std::list<std::pair<long, long> > addQueue;
|
||||
StaticGeometryModule::StaticGeometryModule(flecs::world &ecs)
|
||||
{
|
||||
@@ -27,6 +29,32 @@ StaticGeometryModule::StaticGeometryModule(flecs::world &ecs)
|
||||
ecs.component<TerrainSlotParent>();
|
||||
ecs.component<TerrainItem>();
|
||||
ecs.component<FurnitureItem>();
|
||||
ecs.component<FurnitureInstance>()
|
||||
.on_remove([](flecs::entity e, FurnitureInstance &instance) {
|
||||
if (instance.furniture) {
|
||||
instance.furniture
|
||||
->destroyAllChildrenAndObjects();
|
||||
instance.furniture->getCreator()
|
||||
->destroySceneNode(instance.furniture);
|
||||
instance.furniture = nullptr;
|
||||
}
|
||||
})
|
||||
.on_set([](flecs::entity e, FurnitureInstance &instance) {
|
||||
if (instance.furniture !=
|
||||
e.get<FurnitureInstance>().furniture) {
|
||||
FurnitureInstance &f =
|
||||
e.get_mut<FurnitureInstance>();
|
||||
if (f.furniture) {
|
||||
f.furniture
|
||||
->destroyAllChildrenAndObjects();
|
||||
f.furniture->getCreator()
|
||||
->destroySceneNode(f.furniture);
|
||||
}
|
||||
}
|
||||
})
|
||||
.on_add([](flecs::entity e, FurnitureInstance &instance) {
|
||||
instance.furniture = nullptr;
|
||||
});
|
||||
ecs.component<TerrainItemNode>().on_remove([](flecs::entity e,
|
||||
TerrainItemNode &item) {
|
||||
if (item.itemNode) {
|
||||
@@ -42,6 +70,7 @@ StaticGeometryModule::StaticGeometryModule(flecs::world &ecs)
|
||||
}
|
||||
});
|
||||
ecs.component<TerrainItemMeshNode>();
|
||||
ecs.component<GeometryUpdateItem>();
|
||||
ecs.import <TerrainModule>();
|
||||
ecs.observer<const Terrain>("LoadTerrainItems")
|
||||
.event(flecs::OnSet)
|
||||
@@ -65,6 +94,10 @@ StaticGeometryModule::StaticGeometryModule(flecs::world &ecs)
|
||||
if (!furnitureLoaded) {
|
||||
loadFurniture();
|
||||
furnitureLoaded = true;
|
||||
}
|
||||
if (!templatesLoaded) {
|
||||
loadTemplates();
|
||||
templatesLoaded = true;
|
||||
}
|
||||
std::list<std::pair<long, long> > output;
|
||||
while (!addQueue.empty()) {
|
||||
@@ -163,8 +196,48 @@ void StaticGeometryModule::setItemProperties(flecs::entity id,
|
||||
const Ogre::String &StaticGeometryModule::getItemProperties(flecs::entity id)
|
||||
{
|
||||
OgreAssert(id.is_valid(), "bad id");
|
||||
return id.get<TerrainItem>().properties;
|
||||
return id.get<TerrainItem>().properties;
|
||||
}
|
||||
|
||||
nlohmann::json templates;
|
||||
void StaticGeometryModule::loadTemplates()
|
||||
{
|
||||
if (!Ogre::ResourceGroupManager::getSingleton().resourceExistsInAnyGroup(
|
||||
"templates.list"))
|
||||
return;
|
||||
Ogre::String group =
|
||||
Ogre::ResourceGroupManager::getSingleton()
|
||||
.findGroupContainingResource("templates.list");
|
||||
Ogre::DataStreamPtr stream =
|
||||
Ogre::ResourceGroupManager::getSingleton().openResource(
|
||||
"templates.list", group);
|
||||
Ogre::String json = stream->getAsString();
|
||||
nlohmann::json jtemplates = nlohmann::json::parse(json);
|
||||
templates = jtemplates;
|
||||
}
|
||||
|
||||
void StaticGeometryModule::saveTemplates()
|
||||
{
|
||||
Ogre::String path = "resources/buildings/templates.list";
|
||||
if (Ogre::ResourceGroupManager::getSingleton().resourceExistsInAnyGroup(
|
||||
"templates.list")) {
|
||||
Ogre::String group =
|
||||
Ogre::ResourceGroupManager::getSingleton()
|
||||
.findGroupContainingResource("templates.list");
|
||||
Ogre::FileInfoListPtr fileInfoList(
|
||||
Ogre::ResourceGroupManager::getSingleton()
|
||||
.findResourceFileInfo(group, "templates.list"));
|
||||
OgreAssert(fileInfoList->size() == 1,
|
||||
"templates.list should be there and only once");
|
||||
path = fileInfoList->at(0).archive->getName() + "/" +
|
||||
"templates.list";
|
||||
Ogre::FileSystemLayer::removeFile(path);
|
||||
}
|
||||
std::fstream fout(path.c_str(), std::ios::out);
|
||||
fout << templates.dump();
|
||||
fout.close();
|
||||
}
|
||||
|
||||
void StaticGeometryModule::saveItems()
|
||||
{
|
||||
Ogre::String path = "resources/buildings/items.list";
|
||||
@@ -378,6 +451,58 @@ void StaticGeometryModule::destroyItemGeometry(flecs::entity e)
|
||||
{
|
||||
Geometry::destroyItemGeometry(e);
|
||||
}
|
||||
|
||||
nlohmann::json &StaticGeometryModule::getTemplates()
|
||||
{
|
||||
return templates;
|
||||
}
|
||||
|
||||
void StaticGeometryModule::updateItemGeometry(flecs::entity e)
|
||||
{
|
||||
if (e.has<GeometryUpdateItem>())
|
||||
return;
|
||||
e.add<GeometryUpdateItem>();
|
||||
Ogre::Root::getSingleton().getWorkQueue()->addTask([e]() {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
Ogre::Root::getSingleton().getWorkQueue()->addMainThreadTask(
|
||||
[e]() {
|
||||
Geometry::updateItemGeometry(e);
|
||||
e.remove<GeometryUpdateItem>();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void StaticGeometryModule::addTriangleBufferWork(
|
||||
const Ogre::String &meshName, Ogre::StaticGeometry *geo,
|
||||
const Ogre::Vector3 &position, const Ogre::Quaternion &rotation,
|
||||
const Procedural::TriangleBuffer &tb)
|
||||
{
|
||||
struct WorkData {
|
||||
Ogre::String meshName;
|
||||
Ogre::StaticGeometry *geo;
|
||||
Ogre::Vector3 position;
|
||||
Ogre::Quaternion rotation;
|
||||
Procedural::TriangleBuffer tb;
|
||||
};
|
||||
WorkData data = { meshName, geo, position, rotation, tb };
|
||||
|
||||
Ogre::Root::getSingleton().getWorkQueue()->addTask([captData = std::move(
|
||||
data)]() {
|
||||
Ogre::Root::getSingleton().getWorkQueue()->addMainThreadTask(
|
||||
[captData]() {
|
||||
Ogre::MeshPtr mesh =
|
||||
captData.tb.transformToMesh(
|
||||
captData.meshName);
|
||||
Ogre::Entity *ent =
|
||||
ECS::get<EngineData>()
|
||||
.mScnMgr->createEntity(mesh);
|
||||
captData.geo->addEntity(ent, captData.position,
|
||||
captData.rotation);
|
||||
ECS::get<EngineData>().mScnMgr->destroyEntity(
|
||||
ent);
|
||||
});
|
||||
});
|
||||
}
|
||||
struct TiledMeshes {
|
||||
struct Tile {
|
||||
Ogre::String materialName;
|
||||
@@ -412,13 +537,6 @@ struct TiledMeshes {
|
||||
if (tiles.find(name) == tiles.end())
|
||||
return;
|
||||
tiles[name].positions.erase(packKey(position));
|
||||
#if 0
|
||||
auto pos = std::find(tiles[name].positions.begin(),
|
||||
tiles[name].positions.end(),
|
||||
packKey(position));
|
||||
if (pos != tiles[name].positions.end())
|
||||
tiles[name].positions.erase(pos);
|
||||
#endif
|
||||
}
|
||||
void addTile(const Ogre::String &name, Ogre::MeshPtr mesh)
|
||||
{
|
||||
@@ -435,102 +553,6 @@ struct TiledMeshes {
|
||||
std::shared_ptr<Ogre::IndexData>(
|
||||
submesh->indexData->clone()),
|
||||
{} };
|
||||
#if 0
|
||||
std::vector<Ogre::Vector3> vertices;
|
||||
std::vector<uint32_t> indices;
|
||||
int count = mesh->getNumSubMeshes();
|
||||
int i, j;
|
||||
int indexCount = 0;
|
||||
int vertexCount = 0;
|
||||
int sharedVertexOffset = 0;
|
||||
for (i = 0; i < count; i++) {
|
||||
Ogre::SubMesh *submesh = mesh->getSubMesh(i);
|
||||
indexCount += submesh->indexData->indexCount;
|
||||
if (submesh->useSharedVertices)
|
||||
vertexCount +=
|
||||
mesh->sharedVertexData->vertexCount;
|
||||
else
|
||||
vertexCount += submesh->vertexData->vertexCount;
|
||||
}
|
||||
indices.reserve(indexCount);
|
||||
vertices.reserve(vertexCount);
|
||||
size_t currentVertexOffset = 0;
|
||||
bool added_shared = false;
|
||||
for (i = 0; i < count; i++) {
|
||||
Ogre::SubMesh *submesh = mesh->getSubMesh(i);
|
||||
Ogre::VertexData *vertex_data =
|
||||
submesh->useSharedVertices ?
|
||||
mesh->sharedVertexData :
|
||||
submesh->vertexData;
|
||||
bool add_vertices =
|
||||
(submesh->useSharedVertices && !added_shared) ||
|
||||
!submesh->useSharedVertices;
|
||||
if (add_vertices) {
|
||||
if (submesh->useSharedVertices)
|
||||
sharedVertexOffset = vertices.size();
|
||||
const Ogre::VertexDeclaration *decl =
|
||||
vertex_data->vertexDeclaration;
|
||||
const Ogre::VertexBufferBinding *bind =
|
||||
vertex_data->vertexBufferBinding;
|
||||
const Ogre::VertexElement *position_element =
|
||||
decl->findElementBySemantic(
|
||||
Ogre::VES_POSITION);
|
||||
if (!position_element)
|
||||
continue;
|
||||
Ogre::HardwareVertexBufferSharedPtr vbuf =
|
||||
bind->getBuffer(
|
||||
position_element->getSource());
|
||||
unsigned char *vertex_buffer = static_cast<
|
||||
unsigned char *>(vbuf->lock(
|
||||
Ogre::HardwareBuffer::HBL_READ_ONLY));
|
||||
int vertexSize = vbuf->getVertexSize();
|
||||
for (j = 0; j < vertex_data->vertexCount; j++) {
|
||||
float *position_data;
|
||||
position_element
|
||||
->baseVertexPointerToElement(
|
||||
vertex_buffer,
|
||||
&position_data);
|
||||
vertices.push_back(
|
||||
{ position_data[0],
|
||||
position_data[1],
|
||||
position_data[2] });
|
||||
vertex_buffer += vertexSize;
|
||||
}
|
||||
if (submesh->useSharedVertices)
|
||||
added_shared = true;
|
||||
vbuf->unlock();
|
||||
}
|
||||
Ogre::HardwareIndexBufferSharedPtr ibuf =
|
||||
submesh->indexData->indexBuffer;
|
||||
size_t numIndices = submesh->indexData->indexCount;
|
||||
size_t vertexOffset = submesh->useSharedVertices ?
|
||||
sharedVertexOffset :
|
||||
currentVertexOffset;
|
||||
if (ibuf->getType() ==
|
||||
Ogre::HardwareIndexBuffer::IT_32BIT) {
|
||||
unsigned int *pIndices = static_cast<
|
||||
unsigned int *>(ibuf->lock(
|
||||
Ogre::HardwareBuffer::HBL_READ_ONLY));
|
||||
for (j = 0; j < numIndices; j++) {
|
||||
indices.push_back(
|
||||
(uint32_t)pIndices[j] +
|
||||
vertexOffset);
|
||||
}
|
||||
ibuf->unlock();
|
||||
} else {
|
||||
unsigned short *pIndices = static_cast<
|
||||
unsigned short *>(ibuf->lock(
|
||||
Ogre::HardwareBuffer::HBL_READ_ONLY));
|
||||
for (j = 0; j < numIndices; j++) {
|
||||
indices.push_back(
|
||||
(uint32_t)pIndices[j] +
|
||||
vertexOffset);
|
||||
}
|
||||
ibuf->unlock();
|
||||
}
|
||||
currentVertexOffset = vertices.size();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
struct buildSettings {
|
||||
Ogre::String meshName;
|
||||
@@ -766,10 +788,8 @@ out:;
|
||||
config.advanced.preventBreakingLines = true;
|
||||
config.createGeneratedLodLevel(2, 0.15f);
|
||||
config.createGeneratedLodLevel(20, 0.49f);
|
||||
#if 0
|
||||
config.createGeneratedLodLevel(15, 0.49f);
|
||||
config.createGeneratedLodLevel(150, 0.75f);
|
||||
#endif
|
||||
config.advanced.useBackgroundQueue = false;
|
||||
Ogre::MeshLodGenerator::getSingleton().generateLodLevels(
|
||||
config);
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
#include <flecs.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <Ogre.h>
|
||||
namespace Procedural
|
||||
{
|
||||
class TriangleBuffer;
|
||||
}
|
||||
namespace Ogre
|
||||
{
|
||||
struct LodConfig;
|
||||
@@ -29,6 +33,10 @@ struct FurnitureItem {
|
||||
Ogre::String properties;
|
||||
std::vector<Ogre::String> tags;
|
||||
};
|
||||
struct FurnitureInstance {
|
||||
Ogre::SceneNode *furniture;
|
||||
};
|
||||
struct GeometryUpdateItem {};
|
||||
|
||||
struct TownCollider {};
|
||||
|
||||
@@ -42,7 +50,9 @@ struct StaticGeometryModule {
|
||||
static void setItemProperties(flecs::entity id,
|
||||
Ogre::String properties);
|
||||
static const Ogre::String &getItemProperties(flecs::entity id);
|
||||
static void saveItems();
|
||||
static void loadTemplates();
|
||||
static void saveTemplates();
|
||||
static void saveItems();
|
||||
static void loadItems();
|
||||
static void saveFurniture();
|
||||
static void loadFurniture();
|
||||
@@ -56,6 +66,13 @@ struct StaticGeometryModule {
|
||||
std::list<std::pair<flecs::entity, Ogre::String> > *items);
|
||||
static void createItemGeometry(flecs::entity e);
|
||||
static void destroyItemGeometry(flecs::entity e);
|
||||
static nlohmann::json &getTemplates();
|
||||
static void updateItemGeometry(flecs::entity e);
|
||||
static void addTriangleBufferWork(const Ogre::String &meshName,
|
||||
Ogre::StaticGeometry *geo,
|
||||
const Ogre::Vector3 &position,
|
||||
const Ogre::Quaternion &rotation,
|
||||
const Procedural::TriangleBuffer &tb);
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -4,7 +4,7 @@ find_package(Bullet REQUIRED)
|
||||
find_package(nlohmann_json REQUIRED)
|
||||
find_package(OgreProcedural REQUIRED CONFIG)
|
||||
add_library(items STATIC items.cpp harbour.cpp temple.cpp town.cpp)
|
||||
target_include_directories(items PUBLIC .)
|
||||
target_include_directories(items PUBLIC . ${CMAKE_SOURCE_DIR}/src/FastNoiseLite)
|
||||
target_link_libraries(items PRIVATE
|
||||
flecs::flecs_static
|
||||
nlohmann_json::nlohmann_json
|
||||
@@ -13,4 +13,4 @@ target_link_libraries(items PRIVATE
|
||||
OgreBites
|
||||
editor
|
||||
physics
|
||||
)
|
||||
)
|
||||
|
||||
@@ -22,6 +22,22 @@ namespace ECS
|
||||
{
|
||||
namespace Items
|
||||
{
|
||||
void runScriptsForAllTowns()
|
||||
{
|
||||
std::pair<flecs::entity, Ogre::String> selected_item;
|
||||
std::list<std::pair<flecs::entity, Ogre::String> > items;
|
||||
StaticGeometryModule::getItemsProperties(&items);
|
||||
for (const auto &item : items) {
|
||||
nlohmann::json j = nlohmann::json::parse(item.second);
|
||||
Ogre::String itemType = j["type"].get<Ogre::String>();
|
||||
if (itemType == "town") {
|
||||
Items::runAllScriptsForTown(item.first);
|
||||
if (item.first.has<TerrainItemNode>())
|
||||
Geometry::updateItemGeometry(item.first);
|
||||
}
|
||||
}
|
||||
StaticGeometryModule::saveItems();
|
||||
}
|
||||
void showItemPopup(const std::pair<flecs::entity, Ogre::String> &item)
|
||||
{
|
||||
Ogre::String popupLabel =
|
||||
@@ -131,8 +147,7 @@ void showItemPopup(const std::pair<flecs::entity, Ogre::String> &item)
|
||||
orientation;
|
||||
item.first.modified<TerrainItem>();
|
||||
StaticGeometryModule::saveItems();
|
||||
StaticGeometryModule::destroyItemGeometry(item.first);
|
||||
StaticGeometryModule::createItemGeometry(item.first);
|
||||
StaticGeometryModule::updateItemGeometry(item.first);
|
||||
}
|
||||
if (itemType == "harbour")
|
||||
createHarbourPopup(item);
|
||||
@@ -194,6 +209,7 @@ namespace Geometry
|
||||
{
|
||||
void setupLods(Ogre::LodConfig &config)
|
||||
{
|
||||
int count = 0;
|
||||
// config.advanced.useCompression = false;
|
||||
config.advanced.useVertexNormals = true;
|
||||
config.advanced.preventPunchingHoles = true;
|
||||
@@ -204,7 +220,28 @@ void setupLods(Ogre::LodConfig &config)
|
||||
// config.createGeneratedLodLevel(200, 0.50f);
|
||||
config.createGeneratedLodLevel(500, 0.85f);
|
||||
config.advanced.useBackgroundQueue = false;
|
||||
Ogre::MeshLodGenerator::getSingleton().generateLodLevels(config);
|
||||
std::cout << "mesh name: " << config.mesh->getName() << std::endl;
|
||||
bool crash = false;
|
||||
for (count = 0; count < config.mesh->getSubMeshes().size(); count++) {
|
||||
Ogre::SubMesh *submesh = config.mesh->getSubMeshes()[count];
|
||||
std::cout << "unprocessed submesh: " << count << " " << submesh
|
||||
<< std::endl;
|
||||
if (submesh)
|
||||
submesh->parent = config.mesh.get();
|
||||
else
|
||||
crash = true;
|
||||
}
|
||||
Ogre::MeshLodGenerator::getSingleton().generateLodLevels(config);
|
||||
for (count = 0; count < config.mesh->getSubMeshes().size(); count++) {
|
||||
Ogre::SubMesh *submesh = config.mesh->getSubMeshes()[count];
|
||||
std::cout << "submesh: " << count << " " << submesh
|
||||
<< std::endl;
|
||||
if (submesh)
|
||||
submesh->parent = config.mesh.get();
|
||||
else
|
||||
crash = true;
|
||||
}
|
||||
OgreAssert(!crash, "no submesh");
|
||||
}
|
||||
|
||||
Ogre::StaticGeometry *createStaticGeometry(flecs::entity e)
|
||||
@@ -294,6 +331,14 @@ void destroyItemGeometry(flecs::entity e)
|
||||
#endif
|
||||
e.remove<TerrainItemNode>();
|
||||
}
|
||||
void updateItemGeometry(flecs::entity e)
|
||||
{
|
||||
OgreAssert(e.has<TerrainItem>(), "not terrain item");
|
||||
if (e.has<TerrainItemNode>())
|
||||
destroyItemGeometry(e);
|
||||
createItemGeometry(e);
|
||||
}
|
||||
|
||||
flecs::entity createMeshGeometry(const Ogre::String &meshName,
|
||||
flecs::entity parente,
|
||||
Ogre::SceneNode *sceneNode,
|
||||
@@ -322,7 +367,7 @@ flecs::entity createMeshGeometry(const Ogre::String &meshName,
|
||||
.set<TerrainItemMeshNode>({ sceneNode, geo });
|
||||
JoltPhysicsWrapper::getSingleton().addBody(id,
|
||||
JPH::EActivation::Activate);
|
||||
return e;
|
||||
return e;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ namespace Items
|
||||
void showItemPopup(const std::pair<flecs::entity, Ogre::String> &item);
|
||||
void showItemButtons(const std::pair<flecs::entity, Ogre::String> &item);
|
||||
void createItemsMenu();
|
||||
void runScriptsForAllTowns();
|
||||
}
|
||||
namespace Geometry
|
||||
{
|
||||
@@ -53,6 +54,7 @@ struct harbourMaker {
|
||||
};
|
||||
void createItemGeometry(flecs::entity e);
|
||||
void destroyItemGeometry(flecs::entity e);
|
||||
void updateItemGeometry(flecs::entity e);
|
||||
flecs::entity createMeshGeometry(const Ogre::String &meshName,
|
||||
flecs::entity parente,
|
||||
Ogre::SceneNode *sceneNode,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -12,25 +12,15 @@ namespace Items
|
||||
void createTownItem();
|
||||
void createTownMenu();
|
||||
void createTownPopup(const std::pair<flecs::entity, Ogre::String> item);
|
||||
void runAllScriptsForTown(flecs::entity e);
|
||||
}
|
||||
namespace Geometry
|
||||
{
|
||||
void clampUV(flecs::entity e, Procedural::TriangleBuffer &tb,
|
||||
const Ogre::String &rectKey);
|
||||
Ogre::MaterialPtr createTownMaterial(flecs::entity e, bool force = false);
|
||||
void createCells(flecs::entity e, const nlohmann::json &jdistrict, int index,
|
||||
Ogre::SceneNode *sceneNode, Ogre::StaticGeometry *geo);
|
||||
void createTown(flecs::entity e, Ogre::SceneNode *sceneNode,
|
||||
Ogre::StaticGeometry *geo);
|
||||
void createTownPlazza(flecs::entity e, const nlohmann::json &jdistrict,
|
||||
int index, Ogre::SceneNode *sceneNode,
|
||||
Ogre::StaticGeometry *geo);
|
||||
void createTownLots(flecs::entity e, const nlohmann::json &jdistrict,
|
||||
int index, Ogre::SceneNode *sceneNode,
|
||||
Ogre::StaticGeometry *geo);
|
||||
void createTownRoofs(flecs::entity e, const nlohmann::json &jdistrict,
|
||||
int index, Ogre::SceneNode *sceneNode,
|
||||
Ogre::StaticGeometry *geo);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -90,7 +90,10 @@ public:
|
||||
Layers::MOVING; // Non moving only collides with moving
|
||||
case Layers::MOVING:
|
||||
return true; // Moving collides with everything
|
||||
default:
|
||||
case Layers::SENSORS:
|
||||
return inObject2 ==
|
||||
Layers::MOVING; // Non moving only collides with moving
|
||||
default:
|
||||
JPH_ASSERT(false);
|
||||
return false;
|
||||
}
|
||||
@@ -107,7 +110,8 @@ public:
|
||||
mObjectToBroadPhase[Layers::NON_MOVING] =
|
||||
BroadPhaseLayers::NON_MOVING;
|
||||
mObjectToBroadPhase[Layers::MOVING] = BroadPhaseLayers::MOVING;
|
||||
}
|
||||
mObjectToBroadPhase[Layers::SENSORS] = BroadPhaseLayers::MOVING;
|
||||
}
|
||||
|
||||
virtual uint GetNumBroadPhaseLayers() const override
|
||||
{
|
||||
@@ -1330,7 +1334,18 @@ public:
|
||||
OgreAssert(result.Get(), "Can not create com offset shape");
|
||||
return result.Get();
|
||||
}
|
||||
void applyBuoyancyImpulse(JPH::BodyID id,
|
||||
JPH::ShapeRefC
|
||||
createRotatedTranslatedShape(const Ogre::Vector3 &offset,
|
||||
const Ogre::Quaternion rotation,
|
||||
JPH::ShapeRefC shape)
|
||||
{
|
||||
return JPH::RotatedTranslatedShapeSettings(
|
||||
JoltPhysics::convert(offset),
|
||||
JoltPhysics::convert(rotation), shape)
|
||||
.Create()
|
||||
.Get();
|
||||
}
|
||||
void applyBuoyancyImpulse(JPH::BodyID id,
|
||||
const Ogre::Vector3 &surfacePosition,
|
||||
const Ogre::Vector3 &surfaceNormal,
|
||||
float buoyancy, float linearDrag,
|
||||
@@ -1597,7 +1612,14 @@ JPH::ShapeRefC
|
||||
JoltPhysicsWrapper::createOffsetCenterOfMassShape(const Ogre::Vector3 &offset,
|
||||
JPH::ShapeRefC shape)
|
||||
{
|
||||
return phys->createOffsetCenterOfMassShape(offset, shape);
|
||||
return phys->createOffsetCenterOfMassShape(offset, shape);
|
||||
}
|
||||
|
||||
JPH::ShapeRefC JoltPhysicsWrapper::createRotatedTranslatedShape(
|
||||
const Ogre::Vector3 &offset, const Ogre::Quaternion rotation,
|
||||
JPH::ShapeRefC shape)
|
||||
{
|
||||
return phys->createRotatedTranslatedShape(offset, rotation, shape);
|
||||
}
|
||||
|
||||
JPH::BodyID
|
||||
|
||||
@@ -26,7 +26,8 @@ namespace Layers
|
||||
{
|
||||
static constexpr JPH::ObjectLayer NON_MOVING = 0;
|
||||
static constexpr JPH::ObjectLayer MOVING = 1;
|
||||
static constexpr JPH::ObjectLayer NUM_LAYERS = 2;
|
||||
static constexpr JPH::ObjectLayer SENSORS = 2;
|
||||
static constexpr JPH::ObjectLayer NUM_LAYERS = 3;
|
||||
};
|
||||
|
||||
// Each broadphase layer results in a separate bounding volume tree in the broad phase. You at least want to have
|
||||
@@ -134,7 +135,10 @@ public:
|
||||
JPH::ShapeRefC
|
||||
createOffsetCenterOfMassShape(const Ogre::Vector3 &offset,
|
||||
JPH::ShapeRefC shape);
|
||||
JPH::BodyID createBody(const JPH::BodyCreationSettings &settings);
|
||||
JPH::ShapeRefC
|
||||
createRotatedTranslatedShape(const Ogre::Vector3 &offset, const Ogre::Quaternion rotation,
|
||||
JPH::ShapeRefC shape);
|
||||
JPH::BodyID createBody(const JPH::BodyCreationSettings &settings);
|
||||
JPH::BodyID createBody(const JPH::Shape *shape, float mass,
|
||||
const Ogre::Vector3 &position,
|
||||
const Ogre::Quaternion &rotation,
|
||||
|
||||
Reference in New Issue
Block a user