add fragment.crop, fragment:crop() & fix fragments rotation when width is not equal to depth & fix extra structures placements
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user