add fragment.crop, fragment:crop() & fix fragments rotation when width is not equal to depth & fix extra structures placements

This commit is contained in:
MihailRis
2024-10-15 00:03:06 +03:00
parent 44eedadc06
commit 48143c5a2b
13 changed files with 93 additions and 20 deletions
+49 -5
View File
@@ -9,6 +9,7 @@
#include "voxels/ChunksStorage.hpp"
#include "voxels/VoxelsVolume.hpp"
#include "world/Level.hpp"
#include "core_defs.hpp"
std::unique_ptr<VoxelFragment> VoxelFragment::create(
Level* level,
@@ -51,10 +52,10 @@ std::unique_ptr<VoxelFragment> VoxelFragment::create(
level->chunksStorage->getVoxels(&volume);
auto volVoxels = volume.getVoxels();
std::vector<voxel> voxels(size.x*size.y*size.z);
std::vector<voxel> voxels(size.x * size.y * size.z);
std::vector<std::string> blockNames;
std::unordered_map<blockid_t, blockid_t> blocksRegistered;
std::vector<std::string> blockNames {CORE_AIR};
std::unordered_map<blockid_t, blockid_t> blocksRegistered {{0, 0}};
auto contentIndices = level->content->getIndices();
for (size_t i = 0 ; i < voxels.size(); i++) {
blockid_t id = volVoxels[i].id;
@@ -113,6 +114,49 @@ void VoxelFragment::deserialize(const dv::value& src) {
}
}
void VoxelFragment::crop() {
glm::ivec3 min = size;
glm::ivec3 max = {};
blockid_t air;
const auto& found = std::find(blockNames.begin(), blockNames.end(), CORE_AIR);
if (found == blockNames.end()) {
throw std::runtime_error(CORE_AIR+" is not found in fragment");
}
air = found - blockNames.begin();
for (int y = 0; y < size.y; y++) {
for (int z = 0; z < size.z; z++) {
for (int x = 0; x < size.x; x++) {
if (voxels[vox_index(x, y, z, size.x, size.z)].id != air) {
min = glm::min(min, {x, y, z});
max = glm::max(max, {x+1, y+1, z+1});
}
}
}
}
if (glm::min(min, max) == min) {
auto newSize = max - min;
std::vector<voxel> newVoxels(newSize.x * newSize.y * newSize.z);
for (int y = 0; y < newSize.y; y++) {
for (int z = 0; z < newSize.z; z++) {
for (int x = 0; x < newSize.x; x++) {
newVoxels[vox_index(x, y, z, newSize.x, newSize.z)] =
voxels[vox_index(
x + min.x,
y + min.y,
z + min.z,
size.x,
size.z
)];
}
}
}
voxels = std::move(newVoxels);
size = newSize;
}
}
void VoxelFragment::prepare(const Content& content) {
auto volume = size.x*size.y*size.z;
voxelsRuntime.resize(volume);
@@ -129,8 +173,8 @@ std::unique_ptr<VoxelFragment> VoxelFragment::rotated(const Content& content) co
for (int y = 0; y < size.y; y++) {
for (int z = 0; z < size.z; z++) {
for (int x = 0; x < size.x; x++) {
auto& voxel = newVoxels[vox_index(x, y, z, size.x, size.z)];
voxel = voxels[vox_index(size.z-z-1, y, x, size.z, size.x)];
auto& voxel = newVoxels[vox_index(size.z-z-1, y, x, size.z, size.x)];
voxel = voxels[vox_index(x, y, z, size.x, size.z)];
// swap X and Z segment bits
voxel.state.segment = ((voxel.state.segment & 0b001) << 2)
| (voxel.state.segment & 0b010)
+1
View File
@@ -35,6 +35,7 @@ public:
dv::value serialize() const override;
void deserialize(const dv::value& src) override;
void crop();
/// @brief Build runtime voxel indices
/// @param content world content
+1 -3
View File
@@ -272,9 +272,6 @@ void WorldGenerator::generateStructures(
glm::ivec3 position {x, height, z};
position.x -= structure.getSize().x / 2;
position.z -= structure.getSize().z / 2;
prototype.placements.emplace_back(
1, StructurePlacement {structureId, position, rotation}
);
placeStructure(
StructurePlacement {
structureId,
@@ -486,6 +483,7 @@ void WorldGenerator::generateStructure(
auto& structVoxels = structure.getRuntimeVoxels();
const auto& offset = placement.position;
const auto& size = structure.getSize();
for (int y = 0; y < size.y; y++) {
int sy = y + offset.y;
if (sy < 0 || sy >= CHUNK_H) {
+5 -5
View File
@@ -66,10 +66,6 @@ class WorldGenerator {
void generateStructures(ChunkPrototype& prototype, int x, int z);
void generatePlacements(
const ChunkPrototype& prototype, voxel* voxels, int x, int z
);
void generateBiomes(ChunkPrototype& prototype, int x, int z);
void generateHeightmap(ChunkPrototype& prototype, int x, int z);
@@ -81,6 +77,9 @@ class WorldGenerator {
void placeLine(const LinePlacement& line, int priority);
void generatePlacements(
const ChunkPrototype& prototype, voxel* voxels, int x, int z
);
void generateLine(
const ChunkPrototype& prototype,
const LinePlacement& placement,
@@ -113,7 +112,8 @@ class WorldGenerator {
void placeStructures(
const std::vector<Placement>& placements,
ChunkPrototype& prototype,
int x, int z);
int x, int z
);
public:
WorldGenerator(
const GeneratorDef& def,