glm::vec3 pos = Chunk::ToCoords(blkid);
outline_visible = true;
outline.Clear();
- chunk->BlockAt(blkid).type->FillOutlineModel(outline);
+ chunk->Type(chunk->BlockAt(blkid)).FillOutlineModel(outline);
outline_transform = glm::translate(chunk->Transform(world.Player().ChunkCoords()), pos);
outline_transform = glm::scale(outline_transform, glm::vec3(1.0001f));
} else {
if (pick) {
if (chunk) {
- place_id = chunk->BlockAt(blkid).type->id;
+ place_id = chunk->BlockAt(blkid).type;
hud.Display(*world.BlockTypes()[place_id]);
}
pick = false;
}
if (remove) {
if (chunk) {
- chunk->BlockAt(blkid).type = world.BlockTypes()[remove_id];
+ chunk->BlockAt(blkid).type = remove_id;
chunk->Invalidate();
}
remove = false;
mod_chunk = &world.Next(*chunk, normal);
next_pos -= normal * glm::vec3(Chunk::Extent());
}
- mod_chunk->BlockAt(next_pos).type = world.BlockTypes()[place_id];
+ mod_chunk->BlockAt(next_pos).type = place_id;
mod_chunk->Invalidate();
}
place = false;
namespace blank {
-const BlockType BlockType::DEFAULT;
const NullShape BlockType::DEFAULT_SHAPE;
void BlockType::FillVBO(
BlockTypeRegistry::BlockTypeRegistry() {
- Add(BlockType::DEFAULT);
+ Add(BlockType());
}
int BlockTypeRegistry::Add(const BlockType &t) {
const glm::vec3 &outline_color = { -1, -1, -1 })
: id(-1), visible(v), shape(shape), color(color), outline_color(outline_color) { }
- static const BlockType DEFAULT;
static const NullShape DEFAULT_SHAPE;
using Pos = glm::vec3;
- const BlockType *type;
+ int type;
- constexpr explicit Block(const BlockType *t = &BlockType::DEFAULT)
- : type(t) { }
+ constexpr explicit Block(int type = 0)
+ : type(type) { }
};
namespace blank {
-Chunk::Chunk()
-: blocks()
+Chunk::Chunk(const BlockTypeRegistry &types)
+: types(&types)
+, blocks()
, model()
, position(0, 0, 0)
, dirty(false) {
}
Chunk::Chunk(Chunk &&other)
-: blocks(std::move(other.blocks))
+: types(other.types)
+, blocks(std::move(other.blocks))
, model(std::move(other.model))
, dirty(other.dirty) {
}
Chunk &Chunk::operator =(Chunk &&other) {
+ types = other.types;
blocks = std::move(other.blocks);
model = std::move(other.model);
dirty = other.dirty;
for (int z = 0; z < Depth(); ++z) {
for (int y = 0; y < Height(); ++y) {
for (int x = 0; x < Width(); ++x, ++id) {
- if (!blocks[id].type->visible) {
+ if (!Type(blocks[id]).visible) {
continue;
}
float cur_dist;
glm::vec3 cur_norm;
Block::Pos pos(float(x) + 0.5f, float(y) + 0.5f, float(z) + 0.5f);
- if (blocks[id].type->shape->Intersects(ray, glm::translate(M, pos), cur_dist, cur_norm)) {
+ if (Type(blocks[id]).shape->Intersects(ray, glm::translate(M, pos), cur_dist, cur_norm)) {
if (cur_dist < closest_dist) {
closest_id = id;
closest_dist = cur_dist;
int Chunk::VertexCount() const {
int count = 0;
for (const auto &block : blocks) {
- count += block.type->shape->VertexCount();
+ count += Type(block).shape->VertexCount();
}
return count;
}
model.Reserve(VertexCount());
for (size_t i = 0; i < Size(); ++i) {
- blocks[i].type->FillModel(ToCoords(i), model);
+ Type(blocks[i]).FillModel(ToCoords(i), model);
}
model.Invalidate();
using Pos = glm::tvec3<int>;
public:
- Chunk();
+ explicit Chunk(const BlockTypeRegistry &);
Chunk(Chunk &&);
Chunk &operator =(Chunk &&);
Block &BlockAt(const Block::Pos &pos) { return BlockAt(ToIndex(pos)); }
const Block &BlockAt(const Block::Pos &pos) const { return BlockAt(ToIndex(pos)); }
+ const BlockType &Type(const Block &b) const { return *types->Get(b.type); }
+
bool Intersection(
const Ray &,
const glm::mat4 &M,
void Update();
private:
+ const BlockTypeRegistry *types;
std::vector<Block> blocks;
Model model;
Pos position;
if (ChunkAvailable(pos)) {
continue;
} else if (x == 0 && y == 0 && z == 0) {
- loaded.emplace_back();
+ loaded.emplace_back(blockType);
loaded.back().Position(pos);
Generate(loaded.back());
} else {
- to_generate.emplace_back();
+ to_generate.emplace_back(blockType);
to_generate.back().Position(pos);
}
}
glm::vec3 coords(pos * Chunk::Extent());
if (pos.x == 0 && pos.y == 0 && pos.z == 0) {
for (size_t i = 1; i < blockType.Size(); ++i) {
- chunk.BlockAt(i) = Block(blockType[i]);
- chunk.BlockAt(i + 257) = Block(blockType[i]);
- chunk.BlockAt(i + 514) = Block(blockType[i]);
+ chunk.BlockAt(i) = Block(i);
+ chunk.BlockAt(i + 257) = Block(i);
+ chunk.BlockAt(i + 514) = Block(i);
}
} else {
for (int z = 0; z < Chunk::Depth(); ++z) {
float val = blockNoise(gen_pos);
if (val > 0.8f) {
int col_val = int((colorNoise(gen_pos) + 1.0f) * 2.0f) % 4;
- chunk.BlockAt(block_pos) = Block(blockType[col_val * 3 + 1]);
+ chunk.BlockAt(block_pos) = Block(col_val * 3 + 1);
}
}
}
return *chunk;
}
- loaded.emplace_back();
+ loaded.emplace_back(blockType);
loaded.back().Position(tgt_pos);
Generate(loaded.back());
return loaded.back();