Furniture placement
This commit is contained in:
@@ -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()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user