Furniture placement
This commit is contained in:
@@ -1372,8 +1372,81 @@ struct EditorGUIListener : public Ogre::RenderTargetListener {
|
||||
cursorPosition);
|
||||
modified = false;
|
||||
}
|
||||
}
|
||||
ImGui::EndMenuBar();
|
||||
}
|
||||
if (ImGui::BeginMenu("Furniture")) {
|
||||
if (ImGui::BeginMenu("Create New Furniture")) {
|
||||
static char nameBuffer[32];
|
||||
static int current_mesh = 0;
|
||||
static std::vector<Ogre::String>
|
||||
glb_names;
|
||||
const std::vector<Ogre::String> &groups =
|
||||
Ogre::ResourceGroupManager::
|
||||
getSingleton()
|
||||
.getResourceGroups();
|
||||
if (glb_names.size() == 0) {
|
||||
int i;
|
||||
glb_names.push_back("");
|
||||
for (i = 0; i < groups.size();
|
||||
i++) {
|
||||
std::vector<Ogre::String> names =
|
||||
*Ogre::ResourceGroupManager::getSingleton()
|
||||
.findResourceNames(
|
||||
groups[i],
|
||||
"furniture-*.glb");
|
||||
glb_names.insert(
|
||||
glb_names.end(),
|
||||
names.begin(),
|
||||
names.end());
|
||||
}
|
||||
}
|
||||
ImGui::InputText(
|
||||
"Furniture Name", nameBuffer,
|
||||
IM_ARRAYSIZE(nameBuffer));
|
||||
if (glb_names.size() > 0) {
|
||||
if (ImGui::BeginCombo(
|
||||
"Furniture Mesh",
|
||||
glb_names[current_mesh]
|
||||
.c_str())) {
|
||||
int i;
|
||||
for (i = 0;
|
||||
i <
|
||||
glb_names.size();
|
||||
i++) {
|
||||
bool isSelected =
|
||||
i ==
|
||||
current_mesh;
|
||||
if (ImGui::Selectable(
|
||||
(glb_names[i] +
|
||||
"##select" +
|
||||
Ogre::StringConverter::
|
||||
toString(
|
||||
i))
|
||||
.c_str(),
|
||||
isSelected)) {
|
||||
current_mesh =
|
||||
i;
|
||||
}
|
||||
if (isSelected)
|
||||
ImGui::SetItemDefaultFocus();
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
} else
|
||||
ImGui::Text(
|
||||
"No furniture meshes found");
|
||||
if (ImGui::MenuItem(
|
||||
"Create Furniture")) {
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
if (ImGui::BeginMenu("Edit Furniture")) {
|
||||
if (ImGui::MenuItem("Edit Furniture")) {
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
ImGui::EndMenuBar();
|
||||
}
|
||||
ImGui::Spacing();
|
||||
ImGui::BeginChild("WorldMap...", ImVec2(480, 480),
|
||||
|
||||
@@ -19,13 +19,15 @@ namespace ECS
|
||||
{
|
||||
|
||||
static bool itemsLoaded = false;
|
||||
static bool furnitureLoaded = false;
|
||||
static std::list<std::pair<long, long> > addQueue;
|
||||
StaticGeometryModule::StaticGeometryModule(flecs::world &ecs)
|
||||
{
|
||||
ecs.module<StaticGeometryModule>();
|
||||
ecs.component<TerrainSlotParent>();
|
||||
ecs.component<TerrainItem>();
|
||||
ecs.component<TerrainItemNode>().on_remove([](flecs::entity e,
|
||||
ecs.component<FurnitureItem>();
|
||||
ecs.component<TerrainItemNode>().on_remove([](flecs::entity e,
|
||||
TerrainItemNode &item) {
|
||||
if (item.itemNode) {
|
||||
item.itemNode->destroyAllChildrenAndObjects();
|
||||
@@ -60,6 +62,10 @@ StaticGeometryModule::StaticGeometryModule(flecs::world &ecs)
|
||||
itemsLoaded = true;
|
||||
return;
|
||||
}
|
||||
if (!furnitureLoaded) {
|
||||
loadFurniture();
|
||||
furnitureLoaded = true;
|
||||
}
|
||||
std::list<std::pair<long, long> > output;
|
||||
while (!addQueue.empty()) {
|
||||
std::pair<long, long> item = addQueue.front();
|
||||
@@ -271,93 +277,141 @@ void StaticGeometryModule::loadItems()
|
||||
<< std::endl;
|
||||
std::cout << "position: " << item.id() << " " << position
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StaticGeometryModule::saveFurniture()
|
||||
{
|
||||
/* No saving - furniture is generated by blender */
|
||||
}
|
||||
|
||||
void StaticGeometryModule::loadFurniture()
|
||||
{
|
||||
ECS::get().delete_with<FurnitureItem>();
|
||||
static std::vector<Ogre::String> glb_names;
|
||||
const std::vector<Ogre::String> &groups =
|
||||
Ogre::ResourceGroupManager::getSingleton().getResourceGroups();
|
||||
if (glb_names.size() == 0) {
|
||||
int i;
|
||||
for (i = 0; i < groups.size(); i++) {
|
||||
std::vector<Ogre::String> names =
|
||||
*Ogre::ResourceGroupManager::getSingleton()
|
||||
.findResourceNames(
|
||||
groups[i],
|
||||
"furniture-*.glb.json");
|
||||
glb_names.insert(glb_names.end(), names.begin(),
|
||||
names.end());
|
||||
}
|
||||
}
|
||||
for (auto &g : glb_names) {
|
||||
Ogre::String group = Ogre::ResourceGroupManager::getSingleton()
|
||||
.findGroupContainingResource(g);
|
||||
Ogre::DataStreamPtr stream =
|
||||
Ogre::ResourceGroupManager::getSingleton().openResource(
|
||||
g, group);
|
||||
Ogre::String json = stream->getAsString();
|
||||
nlohmann::json jdata = nlohmann::json::parse(json);
|
||||
std::vector<Ogre::String> tags;
|
||||
for (auto &tag : jdata["tags"]) {
|
||||
Ogre::String stag = tag.get<Ogre::String>();
|
||||
tags.push_back(stag);
|
||||
}
|
||||
Ogre::String meshName = jdata["mesh"].get<Ogre::String>();
|
||||
Ogre::MeshPtr mesh =
|
||||
Ogre::MeshManager::getSingleton().getByName(meshName);
|
||||
if (mesh) {
|
||||
Ogre::LodConfig meshconf(mesh);
|
||||
Geometry::setupLods(meshconf);
|
||||
}
|
||||
ECS::get().entity().set<FurnitureItem>({ json, tags });
|
||||
std::cout << "path: " << g << std::endl;
|
||||
}
|
||||
}
|
||||
void StaticGeometryModule::getItemPositionPerSlot(
|
||||
long x, long y, std::list<Ogre::Vector3> *positions)
|
||||
long x, long y, std::list<Ogre::Vector3> *positions)
|
||||
{
|
||||
std::pair<long, long> pos{ x, y };
|
||||
if (!positions)
|
||||
return;
|
||||
flecs::entity slot =
|
||||
ECS::get().query_builder<const TerrainSlotParent>().build().find(
|
||||
[&](const TerrainSlotParent &slot) -> bool {
|
||||
return slot.slot == pos;
|
||||
std::pair<long, long> pos{ x, y };
|
||||
if (!positions)
|
||||
return;
|
||||
flecs::entity slot =
|
||||
ECS::get().query_builder<const TerrainSlotParent>().build().find(
|
||||
[&](const TerrainSlotParent &slot) -> bool {
|
||||
return slot.slot == pos;
|
||||
});
|
||||
if (!slot.is_valid())
|
||||
return;
|
||||
ECS::get()
|
||||
.query_builder<const TerrainItem>()
|
||||
.with(flecs::ChildOf, slot)
|
||||
.build()
|
||||
.each([&](flecs::entity e, const TerrainItem &item) {
|
||||
positions->push_back(item.position);
|
||||
});
|
||||
if (!slot.is_valid())
|
||||
return;
|
||||
ECS::get()
|
||||
.query_builder<const TerrainItem>()
|
||||
.with(flecs::ChildOf, slot)
|
||||
.build()
|
||||
.each([&](flecs::entity e, const TerrainItem &item) {
|
||||
positions->push_back(item.position);
|
||||
});
|
||||
}
|
||||
void StaticGeometryModule::getItemPositions(std::list<Ogre::Vector3> *positions)
|
||||
{
|
||||
ECS::get().query_builder<const TerrainItem>().build().each(
|
||||
[&](flecs::entity e, const TerrainItem &item) {
|
||||
positions->push_back(item.position);
|
||||
});
|
||||
ECS::get().query_builder<const TerrainItem>().build().each(
|
||||
[&](flecs::entity e, const TerrainItem &item) {
|
||||
positions->push_back(item.position);
|
||||
});
|
||||
}
|
||||
void StaticGeometryModule::getItemPositionAndRotation(
|
||||
flecs::entity e, Ogre::Vector3 &position, Ogre::Quaternion &orientation)
|
||||
flecs::entity e, Ogre::Vector3 &position, Ogre::Quaternion &orientation)
|
||||
{
|
||||
position = e.get<TerrainItem>().position;
|
||||
orientation = e.get<TerrainItem>().orientation;
|
||||
position = e.get<TerrainItem>().position;
|
||||
orientation = e.get<TerrainItem>().orientation;
|
||||
}
|
||||
void StaticGeometryModule::getItemsProperties(
|
||||
std::list<std::pair<flecs::entity, Ogre::String> > *items)
|
||||
std::list<std::pair<flecs::entity, Ogre::String> > *items)
|
||||
{
|
||||
ECS::get().query_builder<const TerrainItem>().build().each(
|
||||
[&](flecs::entity e, const TerrainItem &item) {
|
||||
items->push_back({ e, item.properties });
|
||||
});
|
||||
ECS::get().query_builder<const TerrainItem>().build().each(
|
||||
[&](flecs::entity e, const TerrainItem &item) {
|
||||
items->push_back({ e, item.properties });
|
||||
});
|
||||
}
|
||||
void StaticGeometryModule::createItemGeometry(flecs::entity e)
|
||||
{
|
||||
Geometry::createItemGeometry(e);
|
||||
Geometry::createItemGeometry(e);
|
||||
}
|
||||
|
||||
void StaticGeometryModule::destroyItemGeometry(flecs::entity e)
|
||||
{
|
||||
Geometry::destroyItemGeometry(e);
|
||||
Geometry::destroyItemGeometry(e);
|
||||
}
|
||||
struct TiledMeshes {
|
||||
struct Tile {
|
||||
Ogre::String materialName;
|
||||
std::shared_ptr<Ogre::VertexData> vertexData;
|
||||
std::shared_ptr<Ogre::IndexData> indexData;
|
||||
std::set<uint32_t> positions;
|
||||
};
|
||||
std::map<Ogre::String, Tile> tiles;
|
||||
uint32_t packKey(const Ogre::Vector3i &position)
|
||||
struct Tile {
|
||||
Ogre::String materialName;
|
||||
std::shared_ptr<Ogre::VertexData> vertexData;
|
||||
std::shared_ptr<Ogre::IndexData> indexData;
|
||||
std::set<uint32_t> positions;
|
||||
};
|
||||
std::map<Ogre::String, Tile> tiles;
|
||||
uint32_t packKey(const Ogre::Vector3i &position)
|
||||
{
|
||||
uint32_t key = 0;
|
||||
key |= (uint32_t)(position[2] + 512) << 20;
|
||||
key |= (uint32_t)(position[1] + 512) << 10;
|
||||
key |= (uint32_t)(position[0] + 512) << 0;
|
||||
return key;
|
||||
uint32_t key = 0;
|
||||
key |= (uint32_t)(position[2] + 512) << 20;
|
||||
key |= (uint32_t)(position[1] + 512) << 10;
|
||||
key |= (uint32_t)(position[0] + 512) << 0;
|
||||
return key;
|
||||
}
|
||||
void unpackKey(uint32_t key, Ogre::Vector3i &position)
|
||||
void unpackKey(uint32_t key, Ogre::Vector3i &position)
|
||||
{
|
||||
uint32_t mask = 0x3ff;
|
||||
position[0] = (int)(key & mask) - 512;
|
||||
position[1] = (int)((key >> 10) & mask) - 512;
|
||||
position[2] = (int)((key >> 20) & mask) - 512;
|
||||
uint32_t mask = 0x3ff;
|
||||
position[0] = (int)(key & mask) - 512;
|
||||
position[1] = (int)((key >> 10) & mask) - 512;
|
||||
position[2] = (int)((key >> 20) & mask) - 512;
|
||||
}
|
||||
void setTile(const Ogre::String &name, const Ogre::Vector3i &position)
|
||||
void setTile(const Ogre::String &name, const Ogre::Vector3i &position)
|
||||
{
|
||||
if (tiles.find(name) == tiles.end())
|
||||
return;
|
||||
tiles[name].positions.insert(packKey(position));
|
||||
if (tiles.find(name) == tiles.end())
|
||||
return;
|
||||
tiles[name].positions.insert(packKey(position));
|
||||
}
|
||||
void clearTile(const Ogre::String &name, const Ogre::Vector3i &position)
|
||||
void clearTile(const Ogre::String &name, const Ogre::Vector3i &position)
|
||||
{
|
||||
if (tiles.find(name) == tiles.end())
|
||||
return;
|
||||
tiles[name].positions.erase(packKey(position));
|
||||
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(),
|
||||
@@ -365,22 +419,22 @@ struct TiledMeshes {
|
||||
if (pos != tiles[name].positions.end())
|
||||
tiles[name].positions.erase(pos);
|
||||
#endif
|
||||
}
|
||||
void addTile(const Ogre::String &name, Ogre::MeshPtr mesh)
|
||||
{
|
||||
if (mesh->getSubMeshes().size() != 1)
|
||||
return;
|
||||
Ogre::SubMesh *submesh = mesh->getSubMesh(0);
|
||||
Ogre::VertexData *vertexData;
|
||||
if (submesh->useSharedVertices)
|
||||
vertexData = mesh->sharedVertexData->clone();
|
||||
else
|
||||
vertexData = submesh->vertexData->clone();
|
||||
tiles[name] = { submesh->getMaterialName(),
|
||||
std::shared_ptr<Ogre::VertexData>(vertexData),
|
||||
std::shared_ptr<Ogre::IndexData>(
|
||||
submesh->indexData->clone()),
|
||||
{} };
|
||||
}
|
||||
void addTile(const Ogre::String &name, Ogre::MeshPtr mesh)
|
||||
{
|
||||
if (mesh->getSubMeshes().size() != 1)
|
||||
return;
|
||||
Ogre::SubMesh *submesh = mesh->getSubMesh(0);
|
||||
Ogre::VertexData *vertexData;
|
||||
if (submesh->useSharedVertices)
|
||||
vertexData = mesh->sharedVertexData->clone();
|
||||
else
|
||||
vertexData = submesh->vertexData->clone();
|
||||
tiles[name] = { submesh->getMaterialName(),
|
||||
std::shared_ptr<Ogre::VertexData>(vertexData),
|
||||
std::shared_ptr<Ogre::IndexData>(
|
||||
submesh->indexData->clone()),
|
||||
{} };
|
||||
#if 0
|
||||
std::vector<Ogre::Vector3> vertices;
|
||||
std::vector<uint32_t> indices;
|
||||
@@ -477,257 +531,256 @@ struct TiledMeshes {
|
||||
currentVertexOffset = vertices.size();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
struct buildSettings {
|
||||
Ogre::String meshName;
|
||||
Ogre::String materialName;
|
||||
Ogre::MeshPtr mesh;
|
||||
Ogre::SubMesh *sm;
|
||||
int vertexCount, vertexOffset;
|
||||
int indexCount, indexOffset;
|
||||
Ogre::VertexDeclaration *vdecl;
|
||||
Ogre::HardwareVertexBufferSharedPtr vbuf;
|
||||
Ogre::AxisAlignedBox bounds;
|
||||
bool setBounds;
|
||||
};
|
||||
void configureSettings(struct buildSettings &settings)
|
||||
{
|
||||
settings.mesh = Ogre::MeshManager::getSingleton().createManual(
|
||||
settings.meshName,
|
||||
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
|
||||
settings.mesh->createVertexData();
|
||||
settings.sm = settings.mesh->createSubMesh();
|
||||
settings.vertexCount = 0;
|
||||
settings.indexCount = 0;
|
||||
settings.vdecl = nullptr;
|
||||
for (const auto &tile : tiles) {
|
||||
settings.vertexCount +=
|
||||
tile.second.vertexData->vertexCount *
|
||||
tile.second.positions.size();
|
||||
settings.indexCount +=
|
||||
tile.second.indexData->indexCount *
|
||||
tile.second.positions.size();
|
||||
if (!settings.vdecl) {
|
||||
settings.vdecl =
|
||||
tile.second.vertexData
|
||||
->vertexDeclaration->clone();
|
||||
settings.materialName =
|
||||
tile.second.materialName;
|
||||
}
|
||||
struct buildSettings {
|
||||
Ogre::String meshName;
|
||||
Ogre::String materialName;
|
||||
Ogre::MeshPtr mesh;
|
||||
Ogre::SubMesh *sm;
|
||||
int vertexCount, vertexOffset;
|
||||
int indexCount, indexOffset;
|
||||
Ogre::VertexDeclaration *vdecl;
|
||||
Ogre::HardwareVertexBufferSharedPtr vbuf;
|
||||
Ogre::AxisAlignedBox bounds;
|
||||
bool setBounds;
|
||||
};
|
||||
void configureSettings(struct buildSettings &settings)
|
||||
{
|
||||
settings.mesh = Ogre::MeshManager::getSingleton().createManual(
|
||||
settings.meshName,
|
||||
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
|
||||
settings.mesh->createVertexData();
|
||||
settings.sm = settings.mesh->createSubMesh();
|
||||
settings.vertexCount = 0;
|
||||
settings.indexCount = 0;
|
||||
settings.vdecl = nullptr;
|
||||
for (const auto &tile : tiles) {
|
||||
settings.vertexCount +=
|
||||
tile.second.vertexData->vertexCount *
|
||||
tile.second.positions.size();
|
||||
settings.indexCount +=
|
||||
tile.second.indexData->indexCount *
|
||||
tile.second.positions.size();
|
||||
if (!settings.vdecl) {
|
||||
settings.vdecl =
|
||||
tile.second.vertexData
|
||||
->vertexDeclaration->clone();
|
||||
settings.materialName =
|
||||
tile.second.materialName;
|
||||
}
|
||||
}
|
||||
settings.mesh->sharedVertexData->vertexStart = 0;
|
||||
settings.mesh->sharedVertexData->vertexCount =
|
||||
settings.vertexCount;
|
||||
settings.mesh->sharedVertexData->vertexDeclaration =
|
||||
settings.vdecl;
|
||||
settings.vbuf =
|
||||
Ogre::HardwareBufferManager::getSingleton()
|
||||
.createVertexBuffer(
|
||||
settings.vdecl->getVertexSize(0),
|
||||
settings.vertexCount,
|
||||
Ogre::HBU_GPU_ONLY);
|
||||
settings.mesh->sharedVertexData->vertexBufferBinding->setBinding(
|
||||
0, settings.vbuf);
|
||||
settings.sm->indexData->indexStart = 0;
|
||||
settings.sm->indexData->indexCount = settings.indexCount;
|
||||
settings.sm->indexData->indexBuffer =
|
||||
Ogre::HardwareBufferManager::getSingleton()
|
||||
.createIndexBuffer(
|
||||
Ogre::HardwareIndexBuffer::IT_32BIT,
|
||||
settings.sm->indexData->indexCount * 8,
|
||||
Ogre::HBU_GPU_ONLY);
|
||||
settings.sm->setMaterialName(settings.materialName);
|
||||
settings.setBounds = true;
|
||||
}
|
||||
void processIndex(struct buildSettings &settings,
|
||||
const struct Tile &tile, unsigned int *dstIndices)
|
||||
{
|
||||
int j;
|
||||
std::shared_ptr<Ogre::IndexData> srcIndexData = tile.indexData;
|
||||
int srcIndexCount = srcIndexData->indexCount;
|
||||
std::shared_ptr<Ogre::VertexData> srcVertexData =
|
||||
tile.vertexData;
|
||||
int srcVertexCount = srcVertexData->vertexCount;
|
||||
Ogre::HardwareIndexBufferSharedPtr srcIbuf =
|
||||
srcIndexData->indexBuffer;
|
||||
Ogre::HardwareBufferLockGuard srcIndexLock(
|
||||
srcIbuf, Ogre::HardwareBuffer::HBL_READ_ONLY);
|
||||
if (srcIndexData->indexBuffer->getType() ==
|
||||
Ogre::HardwareIndexBuffer::IT_32BIT) {
|
||||
unsigned int *indices =
|
||||
static_cast<unsigned int *>(srcIndexLock.pData);
|
||||
for (j = 0; j < srcIndexCount; j++)
|
||||
dstIndices[settings.indexOffset + j] =
|
||||
indices[j] + settings.vertexOffset;
|
||||
} else if (srcIndexData->indexBuffer->getType() ==
|
||||
Ogre::HardwareIndexBuffer::IT_16BIT) {
|
||||
unsigned short *indices = static_cast<unsigned short *>(
|
||||
srcIndexLock.pData);
|
||||
for (j = 0; j < srcIndexCount; j++)
|
||||
dstIndices[settings.indexOffset + j] =
|
||||
indices[j] + settings.vertexOffset;
|
||||
}
|
||||
}
|
||||
void processSingleVertex(
|
||||
struct buildSettings &settings,
|
||||
const Ogre::VertexDeclaration::VertexElementList &srcElements,
|
||||
uint32_t offset, unsigned char *srcData, unsigned char *dstData)
|
||||
{
|
||||
for (const auto &srcElement : srcElements) {
|
||||
unsigned char *srcPtr, *dstPtr;
|
||||
const Ogre::VertexElement *destElement =
|
||||
settings.vdecl->findElementBySemantic(
|
||||
srcElement.getSemantic(),
|
||||
srcElement.getIndex());
|
||||
if (!destElement)
|
||||
goto out;
|
||||
if (srcElement.getType() != destElement->getType() ||
|
||||
srcElement.getSize() != destElement->getSize())
|
||||
goto out;
|
||||
srcPtr = srcData + srcElement.getOffset();
|
||||
dstPtr = dstData + destElement->getOffset();
|
||||
if (destElement->getSemantic() == Ogre::VES_POSITION) {
|
||||
float *srcPositionData =
|
||||
reinterpret_cast<float *>(srcPtr);
|
||||
float *dstPositionData =
|
||||
reinterpret_cast<float *>(dstPtr);
|
||||
Ogre::Vector3 position(srcPositionData[0],
|
||||
srcPositionData[1],
|
||||
srcPositionData[2]);
|
||||
Ogre::Vector3i offsetv;
|
||||
unpackKey(offset, offsetv);
|
||||
position.x += (float)offsetv[0];
|
||||
position.y += (float)offsetv[1];
|
||||
position.z += (float)offsetv[2];
|
||||
dstPositionData[0] = position.x;
|
||||
dstPositionData[1] = position.y;
|
||||
dstPositionData[2] = position.z;
|
||||
if (settings.setBounds) {
|
||||
settings.bounds.setMinimum(position);
|
||||
settings.bounds.setMaximum(position);
|
||||
settings.setBounds = false;
|
||||
settings.mesh->sharedVertexData->vertexStart = 0;
|
||||
settings.mesh->sharedVertexData->vertexCount =
|
||||
settings.vertexCount;
|
||||
settings.mesh->sharedVertexData->vertexDeclaration =
|
||||
settings.vdecl;
|
||||
settings.vbuf =
|
||||
Ogre::HardwareBufferManager::getSingleton()
|
||||
.createVertexBuffer(
|
||||
settings.vdecl->getVertexSize(0),
|
||||
settings.vertexCount,
|
||||
Ogre::HBU_GPU_ONLY);
|
||||
settings.mesh->sharedVertexData->vertexBufferBinding->setBinding(
|
||||
0, settings.vbuf);
|
||||
settings.sm->indexData->indexStart = 0;
|
||||
settings.sm->indexData->indexCount = settings.indexCount;
|
||||
settings.sm->indexData->indexBuffer =
|
||||
Ogre::HardwareBufferManager::getSingleton()
|
||||
.createIndexBuffer(
|
||||
Ogre::HardwareIndexBuffer::IT_32BIT,
|
||||
settings.sm->indexData->indexCount * 8,
|
||||
Ogre::HBU_GPU_ONLY);
|
||||
settings.sm->setMaterialName(settings.materialName);
|
||||
settings.setBounds = true;
|
||||
}
|
||||
void processIndex(struct buildSettings &settings,
|
||||
const struct Tile &tile, unsigned int *dstIndices)
|
||||
{
|
||||
int j;
|
||||
std::shared_ptr<Ogre::IndexData> srcIndexData = tile.indexData;
|
||||
int srcIndexCount = srcIndexData->indexCount;
|
||||
std::shared_ptr<Ogre::VertexData> srcVertexData =
|
||||
tile.vertexData;
|
||||
int srcVertexCount = srcVertexData->vertexCount;
|
||||
Ogre::HardwareIndexBufferSharedPtr srcIbuf =
|
||||
srcIndexData->indexBuffer;
|
||||
Ogre::HardwareBufferLockGuard srcIndexLock(
|
||||
srcIbuf, Ogre::HardwareBuffer::HBL_READ_ONLY);
|
||||
if (srcIndexData->indexBuffer->getType() ==
|
||||
Ogre::HardwareIndexBuffer::IT_32BIT) {
|
||||
unsigned int *indices =
|
||||
static_cast<unsigned int *>(srcIndexLock.pData);
|
||||
for (j = 0; j < srcIndexCount; j++)
|
||||
dstIndices[settings.indexOffset + j] =
|
||||
indices[j] + settings.vertexOffset;
|
||||
} else if (srcIndexData->indexBuffer->getType() ==
|
||||
Ogre::HardwareIndexBuffer::IT_16BIT) {
|
||||
unsigned short *indices = static_cast<unsigned short *>(
|
||||
srcIndexLock.pData);
|
||||
for (j = 0; j < srcIndexCount; j++)
|
||||
dstIndices[settings.indexOffset + j] =
|
||||
indices[j] + settings.vertexOffset;
|
||||
}
|
||||
}
|
||||
void processSingleVertex(
|
||||
struct buildSettings &settings,
|
||||
const Ogre::VertexDeclaration::VertexElementList &srcElements,
|
||||
uint32_t offset, unsigned char *srcData, unsigned char *dstData)
|
||||
{
|
||||
for (const auto &srcElement : srcElements) {
|
||||
unsigned char *srcPtr, *dstPtr;
|
||||
const Ogre::VertexElement *destElement =
|
||||
settings.vdecl->findElementBySemantic(
|
||||
srcElement.getSemantic(),
|
||||
srcElement.getIndex());
|
||||
if (!destElement)
|
||||
goto out;
|
||||
if (srcElement.getType() != destElement->getType() ||
|
||||
srcElement.getSize() != destElement->getSize())
|
||||
goto out;
|
||||
srcPtr = srcData + srcElement.getOffset();
|
||||
dstPtr = dstData + destElement->getOffset();
|
||||
if (destElement->getSemantic() == Ogre::VES_POSITION) {
|
||||
float *srcPositionData =
|
||||
reinterpret_cast<float *>(srcPtr);
|
||||
float *dstPositionData =
|
||||
reinterpret_cast<float *>(dstPtr);
|
||||
Ogre::Vector3 position(srcPositionData[0],
|
||||
srcPositionData[1],
|
||||
srcPositionData[2]);
|
||||
Ogre::Vector3i offsetv;
|
||||
unpackKey(offset, offsetv);
|
||||
position.x += (float)offsetv[0];
|
||||
position.y += (float)offsetv[1];
|
||||
position.z += (float)offsetv[2];
|
||||
dstPositionData[0] = position.x;
|
||||
dstPositionData[1] = position.y;
|
||||
dstPositionData[2] = position.z;
|
||||
if (settings.setBounds) {
|
||||
settings.bounds.setMinimum(position);
|
||||
settings.bounds.setMaximum(position);
|
||||
settings.setBounds = false;
|
||||
} else
|
||||
settings.bounds.merge(position);
|
||||
} else if (destElement->getSemantic() ==
|
||||
Ogre::VES_NORMAL) {
|
||||
float *srcNormalData =
|
||||
reinterpret_cast<float *>(srcPtr);
|
||||
float *dstNormalData =
|
||||
reinterpret_cast<float *>(dstPtr);
|
||||
Ogre::Vector3 normal(srcNormalData[0],
|
||||
srcNormalData[1],
|
||||
srcNormalData[2]);
|
||||
dstNormalData[0] = normal.x;
|
||||
dstNormalData[1] = normal.y;
|
||||
dstNormalData[2] = normal.z;
|
||||
} else
|
||||
memcpy(dstPtr, srcPtr, srcElement.getSize());
|
||||
settings.bounds.merge(position);
|
||||
} else if (destElement->getSemantic() ==
|
||||
Ogre::VES_NORMAL) {
|
||||
float *srcNormalData =
|
||||
reinterpret_cast<float *>(srcPtr);
|
||||
float *dstNormalData =
|
||||
reinterpret_cast<float *>(dstPtr);
|
||||
Ogre::Vector3 normal(srcNormalData[0],
|
||||
srcNormalData[1],
|
||||
srcNormalData[2]);
|
||||
dstNormalData[0] = normal.x;
|
||||
dstNormalData[1] = normal.y;
|
||||
dstNormalData[2] = normal.z;
|
||||
} else
|
||||
memcpy(dstPtr, srcPtr, srcElement.getSize());
|
||||
out:;
|
||||
}
|
||||
}
|
||||
void processTile(struct buildSettings &settings,
|
||||
const struct Tile &tile, uint32_t position,
|
||||
unsigned char *dstpData)
|
||||
{
|
||||
std::shared_ptr<Ogre::VertexData> srcVertexData =
|
||||
tile.vertexData;
|
||||
const Ogre::VertexDeclaration *srcDecl =
|
||||
srcVertexData->vertexDeclaration;
|
||||
const Ogre::VertexBufferBinding *srcBind =
|
||||
srcVertexData->vertexBufferBinding;
|
||||
int srcVertexCount = srcVertexData->vertexCount;
|
||||
Ogre::HardwareVertexBufferSharedPtr srcVbuf =
|
||||
srcBind->getBuffer(0);
|
||||
std::shared_ptr<Ogre::IndexData> srcIndexData = tile.indexData;
|
||||
int srcIndexCount = srcIndexData->indexCount;
|
||||
}
|
||||
}
|
||||
void processTile(struct buildSettings &settings,
|
||||
const struct Tile &tile, uint32_t position,
|
||||
unsigned char *dstpData)
|
||||
{
|
||||
std::shared_ptr<Ogre::VertexData> srcVertexData =
|
||||
tile.vertexData;
|
||||
const Ogre::VertexDeclaration *srcDecl =
|
||||
srcVertexData->vertexDeclaration;
|
||||
const Ogre::VertexBufferBinding *srcBind =
|
||||
srcVertexData->vertexBufferBinding;
|
||||
int srcVertexCount = srcVertexData->vertexCount;
|
||||
Ogre::HardwareVertexBufferSharedPtr srcVbuf =
|
||||
srcBind->getBuffer(0);
|
||||
std::shared_ptr<Ogre::IndexData> srcIndexData = tile.indexData;
|
||||
int srcIndexCount = srcIndexData->indexCount;
|
||||
|
||||
Ogre::HardwareBufferLockGuard srcVertexLock(
|
||||
srcVbuf, 0, srcVertexCount * srcDecl->getVertexSize(0),
|
||||
Ogre::HardwareBuffer::HBL_READ_ONLY);
|
||||
const Ogre::VertexDeclaration::VertexElementList &srcElements =
|
||||
srcDecl->getElements();
|
||||
int j;
|
||||
unsigned char *srcpData =
|
||||
static_cast<unsigned char *>(srcVertexLock.pData);
|
||||
Ogre::HardwareBufferLockGuard srcVertexLock(
|
||||
srcVbuf, 0, srcVertexCount * srcDecl->getVertexSize(0),
|
||||
Ogre::HardwareBuffer::HBL_READ_ONLY);
|
||||
const Ogre::VertexDeclaration::VertexElementList &srcElements =
|
||||
srcDecl->getElements();
|
||||
int j;
|
||||
unsigned char *srcpData =
|
||||
static_cast<unsigned char *>(srcVertexLock.pData);
|
||||
|
||||
for (j = 0; j < srcVertexCount; j++) {
|
||||
unsigned char *srcData =
|
||||
srcpData + j * srcVbuf->getVertexSize();
|
||||
unsigned char *dstData =
|
||||
dstpData + (settings.vertexOffset +
|
||||
j) * settings.vbuf->getVertexSize();
|
||||
processSingleVertex(settings, srcElements, position,
|
||||
srcData, dstData);
|
||||
for (j = 0; j < srcVertexCount; j++) {
|
||||
unsigned char *srcData =
|
||||
srcpData + j * srcVbuf->getVertexSize();
|
||||
unsigned char *dstData =
|
||||
dstpData + (settings.vertexOffset +
|
||||
j) * settings.vbuf->getVertexSize();
|
||||
processSingleVertex(settings, srcElements, position,
|
||||
srcData, dstData);
|
||||
}
|
||||
}
|
||||
Ogre::MeshPtr build(const Ogre::String &meshName)
|
||||
{
|
||||
buildSettings settings;
|
||||
settings.meshName = meshName;
|
||||
configureSettings(settings);
|
||||
}
|
||||
Ogre::MeshPtr build(const Ogre::String &meshName)
|
||||
{
|
||||
buildSettings settings;
|
||||
settings.meshName = meshName;
|
||||
configureSettings(settings);
|
||||
{
|
||||
Ogre::HardwareBufferLockGuard vertexLock(
|
||||
settings.vbuf, 0,
|
||||
settings.vertexCount *
|
||||
settings.vdecl->getVertexSize(0),
|
||||
Ogre::HardwareBuffer::HBL_NO_OVERWRITE);
|
||||
Ogre::HardwareBufferLockGuard indexLock(
|
||||
settings.sm->indexData->indexBuffer,
|
||||
Ogre::HardwareBuffer::HBL_NO_OVERWRITE);
|
||||
settings.vertexOffset = 0;
|
||||
settings.indexOffset = 0;
|
||||
unsigned char *dstpData =
|
||||
static_cast<unsigned char *>(vertexLock.pData);
|
||||
unsigned int *dstIndices =
|
||||
static_cast<unsigned int *>(indexLock.pData);
|
||||
Ogre::HardwareBufferLockGuard vertexLock(
|
||||
settings.vbuf, 0,
|
||||
settings.vertexCount *
|
||||
settings.vdecl->getVertexSize(0),
|
||||
Ogre::HardwareBuffer::HBL_NO_OVERWRITE);
|
||||
Ogre::HardwareBufferLockGuard indexLock(
|
||||
settings.sm->indexData->indexBuffer,
|
||||
Ogre::HardwareBuffer::HBL_NO_OVERWRITE);
|
||||
settings.vertexOffset = 0;
|
||||
settings.indexOffset = 0;
|
||||
unsigned char *dstpData =
|
||||
static_cast<unsigned char *>(vertexLock.pData);
|
||||
unsigned int *dstIndices =
|
||||
static_cast<unsigned int *>(indexLock.pData);
|
||||
|
||||
for (const auto &tile : tiles) {
|
||||
std::shared_ptr<Ogre::IndexData> srcIndexData =
|
||||
tile.second.indexData;
|
||||
int srcIndexCount = srcIndexData->indexCount;
|
||||
std::shared_ptr<Ogre::VertexData> srcVertexData =
|
||||
tile.second.vertexData;
|
||||
int srcVertexCount = srcVertexData->vertexCount;
|
||||
for (const auto &position :
|
||||
tile.second.positions) {
|
||||
processTile(settings, tile.second,
|
||||
position, dstpData);
|
||||
processIndex(settings, tile.second,
|
||||
dstIndices);
|
||||
settings.vertexOffset += srcVertexCount;
|
||||
settings.indexOffset += srcIndexCount;
|
||||
Ogre::Vector3i vposition;
|
||||
unpackKey(position, vposition);
|
||||
std::cout << "position: " << position
|
||||
<< " " << vposition
|
||||
<< std::endl;
|
||||
for (const auto &tile : tiles) {
|
||||
std::shared_ptr<Ogre::IndexData> srcIndexData =
|
||||
tile.second.indexData;
|
||||
int srcIndexCount = srcIndexData->indexCount;
|
||||
std::shared_ptr<Ogre::VertexData> srcVertexData =
|
||||
tile.second.vertexData;
|
||||
int srcVertexCount = srcVertexData->vertexCount;
|
||||
for (const auto &position :
|
||||
tile.second.positions) {
|
||||
processTile(settings, tile.second,
|
||||
position, dstpData);
|
||||
processIndex(settings, tile.second,
|
||||
dstIndices);
|
||||
settings.vertexOffset += srcVertexCount;
|
||||
settings.indexOffset += srcIndexCount;
|
||||
Ogre::Vector3i vposition;
|
||||
unpackKey(position, vposition);
|
||||
std::cout << "position: " << position
|
||||
<< " " << vposition
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
settings.mesh->_setBounds(settings.bounds);
|
||||
}
|
||||
Ogre::LodConfig config(settings.mesh);
|
||||
// config.advanced.useCompression = false;
|
||||
// config.advanced.useVertexNormals = true;
|
||||
config.advanced.preventPunchingHoles = true;
|
||||
config.advanced.preventBreakingLines = true;
|
||||
config.createGeneratedLodLevel(2, 0.15f);
|
||||
config.createGeneratedLodLevel(20, 0.49f);
|
||||
}
|
||||
settings.mesh->_setBounds(settings.bounds);
|
||||
}
|
||||
Ogre::LodConfig config(settings.mesh);
|
||||
// config.advanced.useCompression = false;
|
||||
// config.advanced.useVertexNormals = true;
|
||||
config.advanced.preventPunchingHoles = true;
|
||||
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);
|
||||
return settings.mesh;
|
||||
}
|
||||
void removeTile(const Ogre::String &name)
|
||||
{
|
||||
tiles.erase(name);
|
||||
}
|
||||
TiledMeshes()
|
||||
{
|
||||
}
|
||||
config.advanced.useBackgroundQueue = false;
|
||||
Ogre::MeshLodGenerator::getSingleton().generateLodLevels(
|
||||
config);
|
||||
return settings.mesh;
|
||||
}
|
||||
void removeTile(const Ogre::String &name)
|
||||
{
|
||||
tiles.erase(name);
|
||||
}
|
||||
TiledMeshes()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -25,6 +25,11 @@ struct TerrainItemMeshNode {
|
||||
Ogre::SceneNode *itemNode;
|
||||
Ogre::StaticGeometry *geo;
|
||||
};
|
||||
struct FurnitureItem {
|
||||
Ogre::String properties;
|
||||
std::vector<Ogre::String> tags;
|
||||
};
|
||||
|
||||
struct TownCollider {};
|
||||
|
||||
struct StaticGeometryModule {
|
||||
@@ -39,6 +44,8 @@ struct StaticGeometryModule {
|
||||
static const Ogre::String &getItemProperties(flecs::entity id);
|
||||
static void saveItems();
|
||||
static void loadItems();
|
||||
static void saveFurniture();
|
||||
static void loadFurniture();
|
||||
static void getItemPositionPerSlot(long x, long y,
|
||||
std::list<Ogre::Vector3> *positions);
|
||||
static void getItemPositions(std::list<Ogre::Vector3> *positions);
|
||||
|
||||
@@ -199,9 +199,9 @@ void setupLods(Ogre::LodConfig &config)
|
||||
config.advanced.preventPunchingHoles = true;
|
||||
config.advanced.preventBreakingLines = true;
|
||||
config.createGeneratedLodLevel(10, 0.15f);
|
||||
config.createGeneratedLodLevel(50, 0.25f);
|
||||
config.createGeneratedLodLevel(100, 0.36f);
|
||||
config.createGeneratedLodLevel(200, 0.50f);
|
||||
// config.createGeneratedLodLevel(50, 0.25f);
|
||||
// config.createGeneratedLodLevel(100, 0.36f);
|
||||
// config.createGeneratedLodLevel(200, 0.50f);
|
||||
config.createGeneratedLodLevel(500, 0.85f);
|
||||
config.advanced.useBackgroundQueue = false;
|
||||
Ogre::MeshLodGenerator::getSingleton().generateLodLevels(config);
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#include "items.h"
|
||||
#include "town.h"
|
||||
|
||||
/* TODO: Create roofs with the same Lua script as tiles.
|
||||
/*
|
||||
* TODO: Create doors and handle them via script.
|
||||
* TODO: Handle doors direction.
|
||||
* TODO: Hide hero mesh if camera is too close.
|
||||
@@ -174,6 +174,7 @@ struct CellsScript {
|
||||
Ogre::String cellScript;
|
||||
nlohmann::json &lot;
|
||||
nlohmann::json &cells;
|
||||
nlohmann::json &fucells;
|
||||
CellsScript(const Ogre::String &cellScript, nlohmann::json &lot)
|
||||
: L(luaL_newstate())
|
||||
, currentX(0)
|
||||
@@ -182,6 +183,7 @@ struct CellsScript {
|
||||
, cellScript(cellScript)
|
||||
, lot(lot)
|
||||
, cells(lot["cells"])
|
||||
, fucells(lot["furniture_cells"])
|
||||
{
|
||||
lua_pushlightuserdata(L, this);
|
||||
lua_pushcclosure(
|
||||
@@ -277,6 +279,19 @@ struct CellsScript {
|
||||
1);
|
||||
lua_setglobal(L, "roof");
|
||||
lua_pushlightuserdata(L, this);
|
||||
lua_pushcclosure(
|
||||
L,
|
||||
[](lua_State *L) -> int {
|
||||
CellsScript *_this = static_cast<CellsScript *>(
|
||||
lua_touserdata(L, lua_upvalueindex(1)));
|
||||
int room = lua_tointeger(L, 1);
|
||||
Ogre::String tags = lua_tostring(L, 2);
|
||||
_this->place_furniture(room, tags);
|
||||
return 0;
|
||||
},
|
||||
1);
|
||||
lua_setglobal(L, "place_furniture");
|
||||
lua_pushlightuserdata(L, this);
|
||||
lua_pushcclosure(
|
||||
L,
|
||||
[](lua_State *L) -> int {
|
||||
@@ -292,6 +307,22 @@ struct CellsScript {
|
||||
1);
|
||||
lua_setglobal(L, "clear_area");
|
||||
lua_pushlightuserdata(L, this);
|
||||
lua_pushcclosure(
|
||||
L,
|
||||
[](lua_State *L) -> int {
|
||||
CellsScript *_this = static_cast<CellsScript *>(
|
||||
lua_touserdata(L, lua_upvalueindex(1)));
|
||||
int minX = lua_tointeger(L, 1);
|
||||
int minZ = lua_tointeger(L, 2);
|
||||
int sizeX = lua_tointeger(L, 3);
|
||||
int sizeZ = lua_tointeger(L, 4);
|
||||
_this->clear_furniture_area(minX, minZ, sizeX,
|
||||
sizeZ);
|
||||
return 0;
|
||||
},
|
||||
1);
|
||||
lua_setglobal(L, "clear_furniture_area");
|
||||
lua_pushlightuserdata(L, this);
|
||||
lua_pushcclosure(
|
||||
L,
|
||||
[](lua_State *L) -> int {
|
||||
@@ -430,6 +461,11 @@ struct CellsScript {
|
||||
for (auto &cell : cells)
|
||||
cell["id"] = makeCellKey(cell);
|
||||
}
|
||||
void buildFCellIndex()
|
||||
{
|
||||
for (auto &fucell : fucells)
|
||||
fucell["id"] = makeCellKey(fucell);
|
||||
}
|
||||
int findCell(int X, int Y, int Z)
|
||||
{
|
||||
int64_t key = makeCellKey(X, Y, Z);
|
||||
@@ -444,6 +480,20 @@ struct CellsScript {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
int findFCell(int X, int Y, int Z)
|
||||
{
|
||||
int64_t key = makeCellKey(X, Y, Z);
|
||||
int result = -1;
|
||||
int i;
|
||||
for (i = 0; i < fucells.size(); i++) {
|
||||
int64_t ckey = makeCellKey(fucells[i]);
|
||||
if (key == ckey) {
|
||||
result = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
void bitCmd(const Ogre::String &cmd, const Ogre::String &bit)
|
||||
{
|
||||
uint64_t flags = 0;
|
||||
@@ -560,6 +610,22 @@ struct CellsScript {
|
||||
clear();
|
||||
}
|
||||
}
|
||||
void clear_furniture()
|
||||
{
|
||||
int index = findFCell(currentX, currentY, currentZ);
|
||||
if (index >= 0)
|
||||
fucells.erase(index);
|
||||
}
|
||||
void clear_furniture_area(int minX, int minZ, int sizeX, int sizeZ)
|
||||
{
|
||||
int i, j;
|
||||
for (i = 0; i < sizeZ; i++)
|
||||
for (j = 0; j < sizeX; j++) {
|
||||
currentX = minX + j;
|
||||
currentZ = minZ + i;
|
||||
clear_furniture();
|
||||
}
|
||||
}
|
||||
int room(int minX, int minZ, int sizeX, int sizeZ)
|
||||
{
|
||||
int i, j, ret;
|
||||
@@ -621,6 +687,250 @@ struct CellsScript {
|
||||
{
|
||||
lot["roofs"] = nlohmann::json::array();
|
||||
}
|
||||
void fcell(const std::vector<Ogre::String> &tags,
|
||||
nlohmann::json furniture, int rotation)
|
||||
{
|
||||
nlohmann::json jtags = nlohmann::json::array();
|
||||
for (const auto &tag : tags)
|
||||
jtags.push_back(tag);
|
||||
if (findFCell(currentX, currentY, currentZ) == -1) {
|
||||
nlohmann::json fucell;
|
||||
buildFCellIndex();
|
||||
fucell["x"] = currentX;
|
||||
fucell["y"] = currentY;
|
||||
fucell["z"] = currentZ;
|
||||
fucell["tags"] = jtags;
|
||||
fucell["id"] = makeCellKey(fucell);
|
||||
fucell["furniture"] = furniture;
|
||||
fucell["rotation"] = rotation;
|
||||
fucells.push_back(fucell);
|
||||
} else {
|
||||
int index = findFCell(currentX, currentY, currentZ);
|
||||
if (index >= 0) {
|
||||
fucells[index]["tags"] = jtags;
|
||||
fucells[index]["furniture"] = furniture;
|
||||
fucells[index]["rotation"] = rotation;
|
||||
}
|
||||
}
|
||||
}
|
||||
nlohmann::json select_furniture(const std::vector<Ogre::String> &tags)
|
||||
{
|
||||
nlohmann::json adata = nlohmann::json::array();
|
||||
ECS::get().query_builder<const FurnitureItem>().build().each(
|
||||
[&](flecs::entity e, const FurnitureItem &item) {
|
||||
bool apply = true;
|
||||
for (auto &t : tags) {
|
||||
if (std::find(item.tags.begin(),
|
||||
item.tags.end(),
|
||||
t) == item.tags.end()) {
|
||||
apply = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (apply) {
|
||||
nlohmann::json jdata =
|
||||
nlohmann::json::parse(
|
||||
item.properties);
|
||||
adata.push_back(jdata);
|
||||
}
|
||||
});
|
||||
// FIXME: use noise function
|
||||
return adata[0];
|
||||
}
|
||||
void place_furniture(int room, Ogre::String tags)
|
||||
{
|
||||
std::vector<Ogre::String> atags = split_and_trim(tags, ',');
|
||||
int i, j;
|
||||
int minX = rooms[room].minX;
|
||||
int minZ = rooms[room].minZ;
|
||||
int sizeX = rooms[room].sizeX;
|
||||
int sizeZ = rooms[room].sizeZ;
|
||||
int midX = minX + sizeX / 2;
|
||||
int midZ = minZ + sizeZ / 2;
|
||||
std::cout << "room: " << room << " " << minX << " " << minZ
|
||||
<< " " << sizeX << " " << sizeZ << std::endl;
|
||||
clear_furniture_area(minX, minZ, sizeX, sizeZ);
|
||||
currentX = midX;
|
||||
currentZ = minZ;
|
||||
bool placed = false;
|
||||
if (isBit("iwallz-") && !isBit("idoorz+") &&
|
||||
!isBit("idoorz-") && !isBit("idoorx+") &&
|
||||
!isBit("idoorx-") && !placed) {
|
||||
std::vector<Ogre::String> ptags = atags;
|
||||
ptags.push_back("essential");
|
||||
nlohmann::json furniture = select_furniture(ptags);
|
||||
std::cout << currentX << " " << currentY << " "
|
||||
<< currentZ << std::endl;
|
||||
fcell(ptags, furniture, 2);
|
||||
placed = true;
|
||||
}
|
||||
currentX = midX;
|
||||
currentZ = minZ + sizeZ - 1;
|
||||
if (isBit("iwallz+") && !isBit("idoorz+") &&
|
||||
!isBit("idoorz-") && !isBit("idoorx+") &&
|
||||
!isBit("idoorx-") && !placed) {
|
||||
std::vector<Ogre::String> ptags = atags;
|
||||
ptags.push_back("essential");
|
||||
nlohmann::json furniture = select_furniture(ptags);
|
||||
std::cout << currentX << " " << currentY << " "
|
||||
<< currentZ << std::endl;
|
||||
fcell(ptags, furniture, 0);
|
||||
placed = true;
|
||||
}
|
||||
currentX = midX;
|
||||
currentZ = midZ;
|
||||
if (isBit("iwallx-") && !isBit("idoorz+") &&
|
||||
!isBit("idoorz-") && !isBit("idoorx+") &&
|
||||
!isBit("idoorx-") && !placed) {
|
||||
std::vector<Ogre::String> ptags = atags;
|
||||
ptags.push_back("essential");
|
||||
nlohmann::json furniture = select_furniture(ptags);
|
||||
std::cout << currentX << " " << currentY << " "
|
||||
<< currentZ << std::endl;
|
||||
fcell(ptags, furniture, 1);
|
||||
placed = true;
|
||||
}
|
||||
currentX = midX + sizeX - 1;
|
||||
currentZ = midZ;
|
||||
if (isBit("iwallx+") && !isBit("idoorz+") &&
|
||||
!isBit("idoorz-") && !isBit("idoorx+") &&
|
||||
!isBit("idoorx-") && !placed) {
|
||||
std::vector<Ogre::String> ptags = atags;
|
||||
ptags.push_back("essential");
|
||||
nlohmann::json furniture = select_furniture(ptags);
|
||||
std::cout << currentX << " " << currentY << " "
|
||||
<< currentZ << std::endl;
|
||||
fcell(ptags, furniture, 3);
|
||||
placed = true;
|
||||
}
|
||||
if (placed)
|
||||
return;
|
||||
if (isBit("windowz-") && !isBit("idoorz+") &&
|
||||
!isBit("idoorz-") && !isBit("idoorx+") &&
|
||||
!isBit("idoorx-") && !placed) {
|
||||
std::vector<Ogre::String> ptags = atags;
|
||||
ptags.push_back("essential");
|
||||
nlohmann::json furniture = select_furniture(ptags);
|
||||
std::cout << currentX << " " << currentY << " "
|
||||
<< currentZ << std::endl;
|
||||
fcell(ptags, furniture, 2);
|
||||
placed = true;
|
||||
}
|
||||
currentX = midX;
|
||||
currentZ = minZ + sizeZ - 1;
|
||||
if (isBit("windowz+") && !isBit("idoorz+") &&
|
||||
!isBit("idoorz-") && !isBit("idoorx+") &&
|
||||
!isBit("idoorx-") && !placed) {
|
||||
std::vector<Ogre::String> ptags = atags;
|
||||
ptags.push_back("essential");
|
||||
nlohmann::json furniture = select_furniture(ptags);
|
||||
std::cout << currentX << " " << currentY << " "
|
||||
<< currentZ << std::endl;
|
||||
fcell(ptags, furniture, 0);
|
||||
placed = true;
|
||||
}
|
||||
currentX = midX;
|
||||
currentZ = midZ;
|
||||
if (isBit("windowx-") && !isBit("idoorz+") &&
|
||||
!isBit("idoorz-") && !isBit("idoorx+") &&
|
||||
!isBit("idoorx-") && !placed) {
|
||||
std::vector<Ogre::String> ptags = atags;
|
||||
ptags.push_back("essential");
|
||||
nlohmann::json furniture = select_furniture(ptags);
|
||||
std::cout << currentX << " " << currentY << " "
|
||||
<< currentZ << std::endl;
|
||||
fcell(ptags, furniture, 1);
|
||||
placed = true;
|
||||
}
|
||||
currentX = midX + sizeX - 1;
|
||||
currentZ = midZ;
|
||||
if (isBit("windowx+") && !isBit("idoorz+") &&
|
||||
!isBit("idoorz-") && !isBit("idoorx+") &&
|
||||
!isBit("idoorx-") && !placed) {
|
||||
std::vector<Ogre::String> ptags = atags;
|
||||
ptags.push_back("essential");
|
||||
nlohmann::json furniture = select_furniture(ptags);
|
||||
std::cout << currentX << " " << currentY << " "
|
||||
<< currentZ << std::endl;
|
||||
fcell(ptags, furniture, 3);
|
||||
placed = true;
|
||||
}
|
||||
if (placed)
|
||||
return;
|
||||
for (i = 1; i < sizeX - 1; i++) {
|
||||
currentX = minX + i;
|
||||
currentZ = minZ;
|
||||
if (isBit("iwallz-") && !isBit("idoorz+") &&
|
||||
!isBit("idoorz-") && !isBit("idoorx+") &&
|
||||
!isBit("idoorx-") && !placed) {
|
||||
std::vector<Ogre::String> ptags = atags;
|
||||
ptags.push_back("essential");
|
||||
nlohmann::json furniture =
|
||||
select_furniture(ptags);
|
||||
std::cout << currentX << " " << currentY << " "
|
||||
<< currentZ << std::endl;
|
||||
fcell(ptags, furniture, 2);
|
||||
placed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (placed)
|
||||
return;
|
||||
for (i = 1; i < sizeX - 1; i++) {
|
||||
currentX = minX + i;
|
||||
currentZ = minZ + sizeZ - 1;
|
||||
if (isBit("iwallz+") && !isBit("idoorz+") &&
|
||||
!isBit("idoorz-") && !isBit("idoorx+") &&
|
||||
!isBit("idoorx-") && !placed) {
|
||||
std::vector<Ogre::String> ptags = atags;
|
||||
ptags.push_back("essential");
|
||||
nlohmann::json furniture =
|
||||
select_furniture(ptags);
|
||||
std::cout << currentX << " " << currentY << " "
|
||||
<< currentZ << std::endl;
|
||||
fcell(ptags, furniture, 0);
|
||||
placed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (placed)
|
||||
return;
|
||||
for (i = 1; i < sizeZ - 1; i++) {
|
||||
currentX = minX;
|
||||
currentZ = minZ + i;
|
||||
if (isBit("iwallx-") && !isBit("idoorz+") &&
|
||||
!isBit("idoorz-") && !isBit("idoorx+") &&
|
||||
!isBit("idoorx-") && !placed) {
|
||||
std::vector<Ogre::String> ptags = atags;
|
||||
ptags.push_back("essential");
|
||||
nlohmann::json furniture =
|
||||
select_furniture(ptags);
|
||||
std::cout << currentX << " " << currentY << " "
|
||||
<< currentZ << std::endl;
|
||||
fcell(ptags, furniture, 1);
|
||||
placed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (i = 1; i < sizeZ - 1; i++) {
|
||||
currentX = minX + sizeX - 1;
|
||||
currentZ = minZ + i;
|
||||
if (isBit("iwallx+") && !isBit("idoorz+") &&
|
||||
!isBit("idoorz-") && !isBit("idoorx+") &&
|
||||
!isBit("idoorx-") && !placed) {
|
||||
std::vector<Ogre::String> ptags = atags;
|
||||
ptags.push_back("essential");
|
||||
nlohmann::json furniture =
|
||||
select_furniture(ptags);
|
||||
std::cout << currentX << " " << currentY << " "
|
||||
<< currentZ << std::endl;
|
||||
fcell(ptags, furniture, 3);
|
||||
placed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::pair<int, int> > roomEdge(int room)
|
||||
{
|
||||
std::vector<std::pair<int, int> > seg;
|
||||
@@ -1235,16 +1545,21 @@ bool editLot(const Ogre::String &lotLabel, nlohmann::json &lot)
|
||||
nlohmann::json cells = nlohmann::json::array();
|
||||
static char text_buffer[16384];
|
||||
strcpy(text_buffer, "");
|
||||
/* copy script data from json to a buffer */
|
||||
if (lot.find("cellScript") != lot.end()) {
|
||||
Ogre::String script = lot["cellScript"].get<Ogre::String>();
|
||||
strncpy(text_buffer, script.c_str(), sizeof(text_buffer));
|
||||
}
|
||||
/* edit a buffer and if changed, copy a buffer back to json */
|
||||
if (ImGui::InputTextMultiline(("Cells Script##" + lotLabel).c_str(),
|
||||
text_buffer, IM_ARRAYSIZE(text_buffer),
|
||||
ImVec2(1000,
|
||||
ImGui::GetTextLineHeight() * 20),
|
||||
ImGuiInputTextFlags_AllowTabInput)) {
|
||||
lot["cellScript"] = Ogre::String(text_buffer);
|
||||
}
|
||||
if (ImGui::IsItemDeactivatedAfterEdit()) {
|
||||
lot["cellScript"] = Ogre::String(text_buffer);
|
||||
changed = true;
|
||||
}
|
||||
if (ImGui::SmallButton(("Execute script...##" + lotLabel).c_str())) {
|
||||
@@ -1252,6 +1567,7 @@ bool editLot(const Ogre::String &lotLabel, nlohmann::json &lot)
|
||||
script.run();
|
||||
changed = true;
|
||||
}
|
||||
|
||||
for (const auto &cell : lot["cells"])
|
||||
cells.push_back(cell);
|
||||
if (ImGui::CollapsingHeader(("Cells...##" + lotLabel).c_str())) {
|
||||
@@ -1380,11 +1696,15 @@ bool editDistrict(const Ogre::String &districtLabel, nlohmann::json &district)
|
||||
districtLabel + "_lot" +
|
||||
Ogre::StringConverter::toString(lotCount);
|
||||
ImGui::Text("%s", lotLabel.c_str());
|
||||
changed = changed || editLot(lotLabel, lot);
|
||||
ImGui::Separator();
|
||||
if (ImGui::SmallButton(("Lot Delete##" + lotLabel).c_str())) {
|
||||
lots.erase(lotCount);
|
||||
break;
|
||||
if (ImGui::CollapsingHeader(
|
||||
("Edit lot... ##" + lotLabel).c_str())) {
|
||||
changed = changed || editLot(lotLabel, lot);
|
||||
ImGui::Separator();
|
||||
if (ImGui::SmallButton(
|
||||
("Lot Delete##" + lotLabel).c_str())) {
|
||||
lots.erase(lotCount);
|
||||
break;
|
||||
}
|
||||
}
|
||||
lotCount++;
|
||||
}
|
||||
@@ -1400,9 +1720,12 @@ bool editDistrict(const Ogre::String &districtLabel, nlohmann::json &district)
|
||||
changed = true;
|
||||
}
|
||||
district["lots"] = lots;
|
||||
float radius = 50.0f;
|
||||
bool plazza = false;
|
||||
if (district.find("plazza") != district.end())
|
||||
plazza = district["plazza"].get<bool>();
|
||||
if (district.find("radius") != district.end())
|
||||
radius = district["radius"].get<float>();
|
||||
if (ImGui::Checkbox("Plazza", &plazza)) {
|
||||
changed = true;
|
||||
district["plazza"] = plazza;
|
||||
@@ -1412,6 +1735,10 @@ bool editDistrict(const Ogre::String &districtLabel, nlohmann::json &district)
|
||||
elevation = district["elevation"].get<float>();
|
||||
if (district.find("height") != district.end())
|
||||
height = district["height"].get<float>();
|
||||
if (ImGui::SliderFloat("Radius", &radius, 20.0f, 100.0f)) {
|
||||
district["radius"] = radius;
|
||||
changed = true;
|
||||
}
|
||||
if (ImGui::SliderFloat("Height", &height, 0.1f, 10.0f)) {
|
||||
district["height"] = height;
|
||||
changed = true;
|
||||
@@ -1535,8 +1862,10 @@ void createTownPopup(const std::pair<flecs::entity, Ogre::String> item)
|
||||
nlohmann::json colorRects = nlohmann::json::object();
|
||||
if (j.find("colorRects") != j.end())
|
||||
colorRects = j["colorRects"];
|
||||
changed = changed || editColorRects(colorRects);
|
||||
ImGui::Separator();
|
||||
if (ImGui::CollapsingHeader("Edit Color Rects")) {
|
||||
changed = changed || editColorRects(colorRects);
|
||||
ImGui::Separator();
|
||||
}
|
||||
nlohmann::json districts = nlohmann::json::array();
|
||||
for (auto &district : j["districts"])
|
||||
districts.push_back(district);
|
||||
@@ -2565,6 +2894,122 @@ void createTownDoors(flecs::entity e)
|
||||
}
|
||||
}
|
||||
}
|
||||
void createDecorateFurniture(flecs::entity e, const nlohmann::json &jdistrict,
|
||||
int index, Ogre::SceneNode *sceneNode,
|
||||
Ogre::StaticGeometry *geo)
|
||||
{
|
||||
Ogre::MaterialPtr townMaterial = createTownMaterial(e);
|
||||
const nlohmann::json &jp = jdistrict;
|
||||
nlohmann::json jlots = nlohmann::json::array();
|
||||
float baseHeight = 4.0f;
|
||||
Ogre::Vector3 localPosition(0, 0, 0);
|
||||
Ogre::Quaternion localRotation = Ogre::Quaternion::IDENTITY;
|
||||
Ogre::Vector3 centerPosition = sceneNode->_getDerivedPosition();
|
||||
Ogre::Quaternion centerOrientation =
|
||||
sceneNode->_getDerivedOrientation();
|
||||
float delevation = 0.0f;
|
||||
float radius = 50.0f;
|
||||
if (jp.find("elevation") != jp.end())
|
||||
delevation = jp["elevation"].get<float>();
|
||||
if (jp.find("radius") != jp.end())
|
||||
radius = jp["radius"].get<float>();
|
||||
from_json(jp["position"], localPosition);
|
||||
from_json(jp["rotation"], localRotation);
|
||||
centerPosition = centerPosition + localPosition +
|
||||
Ogre::Vector3(0, delevation, 0);
|
||||
centerOrientation = centerOrientation * localRotation;
|
||||
if (jdistrict.find("lots") != jdistrict.end())
|
||||
jlots = jdistrict["lots"];
|
||||
for (const auto &jb : jlots) {
|
||||
float angle = 0.0f;
|
||||
int depth = 10;
|
||||
int width = 10;
|
||||
float distance = radius;
|
||||
float elevation = 0.0f;
|
||||
std::cout << jb.dump() << std::endl;
|
||||
if (jb.find("angle") != jb.end())
|
||||
angle = jb["angle"].get<float>();
|
||||
if (jb.find("depth") != jb.end())
|
||||
depth = jb["depth"].get<int>();
|
||||
if (jb.find("width") != jb.end())
|
||||
width = jb["width"].get<int>();
|
||||
if (jb.find("elevation") != jb.end())
|
||||
elevation = jb["elevation"].get<float>();
|
||||
|
||||
OgreAssert(width > 1 && depth > 1 && baseHeight > 1,
|
||||
"Bad stuff happen");
|
||||
|
||||
Ogre::Quaternion rotation = Ogre::Quaternion(
|
||||
Ogre::Degree(angle), Ogre::Vector3::UNIT_Y);
|
||||
Ogre::Vector3 offset = centerOrientation * rotation *
|
||||
(Ogre::Vector3::UNIT_Z * distance);
|
||||
Ogre::Vector3 worldCenterPosition =
|
||||
centerPosition + offset +
|
||||
Ogre::Vector3(0, elevation, 0);
|
||||
Ogre::Quaternion worldCenterOrientation =
|
||||
centerOrientation * rotation;
|
||||
float outOffset = 1.05f;
|
||||
if (jb.find("furniture_cells") != jb.end()) {
|
||||
for (auto &jfcell : jb["furniture_cells"]) {
|
||||
int x = jfcell["x"].get<int>();
|
||||
int y = jfcell["y"].get<int>();
|
||||
int z = jfcell["z"].get<int>();
|
||||
nlohmann::json furniture = jfcell["furniture"];
|
||||
Ogre::Vector3 cellOffset(x * 2.0f, y * 4.0f,
|
||||
z * 2.0f);
|
||||
Ogre::Vector3 offsetX = worldCenterOrientation *
|
||||
Ogre::Vector3::UNIT_X *
|
||||
(float)x * 2.0f;
|
||||
Ogre::Vector3 offsetZ = worldCenterOrientation *
|
||||
Ogre::Vector3::UNIT_Z *
|
||||
(float)z * 2.0f;
|
||||
Ogre::Vector3 offsetY(0, y * 4.0f, 0);
|
||||
if (furniture.find("mesh") != furniture.end()) {
|
||||
Ogre::String meshName =
|
||||
furniture["mesh"]
|
||||
.get<Ogre::String>();
|
||||
Ogre::MeshPtr mesh =
|
||||
Ogre::MeshManager::getSingleton()
|
||||
.getByName(meshName);
|
||||
if (!mesh) {
|
||||
mesh = Ogre::MeshManager::getSingleton()
|
||||
.load(meshName,
|
||||
"General");
|
||||
Ogre::LodConfig meshconf(mesh);
|
||||
setupLods(meshconf);
|
||||
}
|
||||
int rotation = 2;
|
||||
if (jfcell.find("rotation") !=
|
||||
jfcell.end())
|
||||
rotation = jfcell["rotation"]
|
||||
.get<int>();
|
||||
|
||||
Ogre::Vector3 offset =
|
||||
worldCenterOrientation *
|
||||
Ogre::Vector3::UNIT_Z * 0.0f;
|
||||
Ogre::Entity *ent =
|
||||
ECS::get<EngineData>()
|
||||
.mScnMgr->createEntity(
|
||||
meshName);
|
||||
geo->addEntity(
|
||||
ent,
|
||||
worldCenterPosition + offsetX +
|
||||
offsetZ + offsetY +
|
||||
offset,
|
||||
worldCenterOrientation *
|
||||
Ogre::Quaternion(
|
||||
Ogre::Degree(
|
||||
90.0f *
|
||||
(float)rotation),
|
||||
Ogre::Vector3::
|
||||
UNIT_Y));
|
||||
ECS::get<EngineData>()
|
||||
.mScnMgr->destroyEntity(ent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void createDecorateDoors(flecs::entity e, const nlohmann::json &jdistrict,
|
||||
int index, Ogre::SceneNode *sceneNode,
|
||||
@@ -3049,6 +3494,8 @@ void createTown(flecs::entity e, Ogre::SceneNode *sceneNode,
|
||||
geo);
|
||||
createDecorateDoors(e, jdistrict, index, sceneNode,
|
||||
geo);
|
||||
createDecorateFurniture(e, jdistrict, index, sceneNode,
|
||||
geo);
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user