implement structures rotation
This commit is contained in:
@@ -77,7 +77,8 @@ function place_structures(x, z, w, d, seed, hmap)
|
|||||||
if py <= sea_level then
|
if py <= sea_level then
|
||||||
goto continue
|
goto continue
|
||||||
end
|
end
|
||||||
table.insert(placements, {math.floor(math.random() * 3), {px-8, py, pz-8}})
|
table.insert(placements,
|
||||||
|
{math.floor(math.random() * 3), {px-8, py, pz-8}, math.floor(math.random()*4)})
|
||||||
::continue::
|
::continue::
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -85,7 +86,7 @@ function place_structures(x, z, w, d, seed, hmap)
|
|||||||
local px = math.random() * w
|
local px = math.random() * w
|
||||||
local pz = math.random() * d
|
local pz = math.random() * d
|
||||||
local py = hmap:at(px, pz) * 256
|
local py = hmap:at(px, pz) * 256
|
||||||
table.insert(placements, {3, {px-8, py, pz-8}})
|
table.insert(placements, {3, {px-8, py, pz-8}, 0})
|
||||||
end
|
end
|
||||||
return placements
|
return placements
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -127,9 +127,13 @@ public:
|
|||||||
glm::ivec3 pos = lua::tovec3(L, -1);
|
glm::ivec3 pos = lua::tovec3(L, -1);
|
||||||
lua::pop(L);
|
lua::pop(L);
|
||||||
|
|
||||||
|
lua::rawgeti(L, 3);
|
||||||
|
int rotation = lua::tointeger(L, -1) & 0b11;
|
||||||
lua::pop(L);
|
lua::pop(L);
|
||||||
|
|
||||||
placements.emplace_back(structIndex, pos);
|
lua::pop(L);
|
||||||
|
|
||||||
|
placements.emplace_back(structIndex, pos, rotation);
|
||||||
}
|
}
|
||||||
lua::pop(L);
|
lua::pop(L);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,16 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
struct StructurePlacement {
|
struct StructurePlacement {
|
||||||
int structure;
|
int structure;
|
||||||
|
|
||||||
glm::ivec3 position;
|
glm::ivec3 position;
|
||||||
|
uint8_t rotation;
|
||||||
|
|
||||||
StructurePlacement(int structure, glm::ivec3 position)
|
StructurePlacement(int structure, glm::ivec3 position, uint8_t rotation)
|
||||||
: structure(structure), position(std::move(position)) {}
|
: structure(structure),
|
||||||
|
position(std::move(position)),
|
||||||
|
rotation(rotation) {
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -92,3 +92,35 @@ void VoxelStructure::prepare(const Content& content) {
|
|||||||
voxelsRuntime[i].state = voxels[i].state;
|
voxelsRuntime[i].state = voxels[i].state;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<VoxelStructure> VoxelStructure::rotated(const Content& content) const {
|
||||||
|
std::vector<voxel> newVoxels(voxels.size());
|
||||||
|
|
||||||
|
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)];
|
||||||
|
// swap X and Z segment bits
|
||||||
|
voxel.state.segment = ((voxel.state.segment & 0b001) << 2)
|
||||||
|
| (voxel.state.segment & 0b010)
|
||||||
|
| ((voxel.state.segment & 0b100) >> 2);
|
||||||
|
auto& def = content.blocks.require(blockNames[voxel.id]);
|
||||||
|
if (def.rotations.name == BlockRotProfile::PANE_NAME ||
|
||||||
|
def.rotations.name == BlockRotProfile::PIPE_NAME){
|
||||||
|
if (voxel.state.rotation < 4) {
|
||||||
|
voxel.state.rotation = (voxel.state.rotation + 3) & 0b11;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
auto newStructure = std::make_unique<VoxelStructure>(
|
||||||
|
// swap X and Z on 90 deg. rotation
|
||||||
|
glm::ivec3(size.z, size.y, size.x),
|
||||||
|
std::move(newVoxels),
|
||||||
|
blockNames
|
||||||
|
);
|
||||||
|
newStructure->prepare(content);
|
||||||
|
return newStructure;
|
||||||
|
}
|
||||||
|
|||||||
@@ -40,6 +40,9 @@ public:
|
|||||||
/// @param content world content
|
/// @param content world content
|
||||||
void prepare(const Content& content);
|
void prepare(const Content& content);
|
||||||
|
|
||||||
|
/// @brief Create structure copy rotated 90 deg. clockwise
|
||||||
|
std::unique_ptr<VoxelStructure> rotated(const Content& content) const;
|
||||||
|
|
||||||
static std::unique_ptr<VoxelStructure> create(
|
static std::unique_ptr<VoxelStructure> create(
|
||||||
Level* level, const glm::ivec3& a, const glm::ivec3& b, bool entities);
|
Level* level, const glm::ivec3& a, const glm::ivec3& b, bool entities);
|
||||||
|
|
||||||
@@ -47,6 +50,7 @@ public:
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @return Voxels with indices valid to current world content
|
||||||
const std::vector<voxel>& getRuntimeVoxels() {
|
const std::vector<voxel>& getRuntimeVoxels() {
|
||||||
assert(!voxelsRuntime.empty());
|
assert(!voxelsRuntime.empty());
|
||||||
return voxelsRuntime;
|
return voxelsRuntime;
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
#include "WorldGenerator.hpp"
|
#include "WorldGenerator.hpp"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include "maths/util.hpp"
|
#include "maths/util.hpp"
|
||||||
#include "content/Content.hpp"
|
#include "content/Content.hpp"
|
||||||
@@ -50,9 +49,16 @@ WorldGenerator::WorldGenerator(
|
|||||||
generateStructures(requirePrototype(x, z), x, z);
|
generateStructures(requirePrototype(x, z), x, z);
|
||||||
});
|
});
|
||||||
|
|
||||||
structures = def.script->loadStructures();
|
auto rawStructures = def.script->loadStructures();
|
||||||
for (auto& structure : structures) {
|
structures.resize(rawStructures.size());
|
||||||
structure->prepare(*content);
|
|
||||||
|
for (int i = 0; i < rawStructures.size(); i++) {
|
||||||
|
structures[i][0] = std::move(rawStructures[i]);
|
||||||
|
structures[i][0]->prepare(*content);
|
||||||
|
// pre-calculate rotated structure variants
|
||||||
|
for (int j = 1; j < 4; j++) {
|
||||||
|
structures[i][j] = structures[i][j-1]->rotated(*content);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,7 +156,7 @@ void WorldGenerator::generateStructures(
|
|||||||
logger.error() << "invalid structure index " << placement.structure;
|
logger.error() << "invalid structure index " << placement.structure;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
auto& structure = *structures[placement.structure];
|
auto& structure = *structures[placement.structure][placement.rotation];
|
||||||
auto position = glm::ivec3(chunkX * CHUNK_W, 0, chunkZ * CHUNK_D)+offset;
|
auto position = glm::ivec3(chunkX * CHUNK_W, 0, chunkZ * CHUNK_D)+offset;
|
||||||
auto size = structure.getSize() + glm::ivec3(0, CHUNK_H, 0);
|
auto size = structure.getSize() + glm::ivec3(0, CHUNK_H, 0);
|
||||||
AABB aabb(position, position + size);
|
AABB aabb(position, position + size);
|
||||||
@@ -167,7 +173,8 @@ void WorldGenerator::generateStructures(
|
|||||||
otherPrototype.structures.emplace_back(
|
otherPrototype.structures.emplace_back(
|
||||||
placement.structure,
|
placement.structure,
|
||||||
placement.position -
|
placement.position -
|
||||||
glm::ivec3(lcx * CHUNK_W, 0, lcz * CHUNK_D)
|
glm::ivec3(lcx * CHUNK_W, 0, lcz * CHUNK_D),
|
||||||
|
placement.rotation
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -258,7 +265,7 @@ void WorldGenerator::generate(voxel* voxels, int chunkX, int chunkZ) {
|
|||||||
logger.error() << "invalid structure index " << placement.structure;
|
logger.error() << "invalid structure index " << placement.structure;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
auto& structure = *structures[placement.structure];
|
auto& structure = *structures[placement.structure][placement.rotation];
|
||||||
auto& structVoxels = structure.getRuntimeVoxels();
|
auto& structVoxels = structure.getRuntimeVoxels();
|
||||||
const auto& offset = placement.position;
|
const auto& offset = placement.position;
|
||||||
const auto& size = structure.getSize();
|
const auto& size = structure.getSize();
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -46,7 +47,7 @@ class WorldGenerator {
|
|||||||
/// @brief Chunk prototypes loading surround map
|
/// @brief Chunk prototypes loading surround map
|
||||||
SurroundMap surroundMap;
|
SurroundMap surroundMap;
|
||||||
|
|
||||||
std::vector<std::shared_ptr<VoxelStructure>> structures;
|
std::vector<std::array<std::shared_ptr<VoxelStructure>, 4>> structures;
|
||||||
|
|
||||||
/// @brief Generate chunk prototype (see ChunkPrototype)
|
/// @brief Generate chunk prototype (see ChunkPrototype)
|
||||||
/// @param x chunk position X divided by CHUNK_W
|
/// @param x chunk position X divided by CHUNK_W
|
||||||
|
|||||||
Reference in New Issue
Block a user