Action nodes support and lots of other updates
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user