COLORED LIGHTING~
parent
a9a13b73c6
commit
49b45d1b9e
|
@ -4,11 +4,12 @@ layout (location = 0) out vec4 gPosition;
|
|||
layout (location = 1) out vec4 gNormal;
|
||||
layout (location = 2) out vec4 gSpecular;
|
||||
|
||||
in vec2 texCoords;
|
||||
in vec2 blendMaskCoords;
|
||||
in vec3 blend;
|
||||
in vec3 fragPos;
|
||||
in vec3 normal;
|
||||
in vec2 texCoords;
|
||||
in vec2 blendMaskCoords;
|
||||
in vec3 blend;
|
||||
in vec3 fragPos;
|
||||
in vec3 normal;
|
||||
in vec3 light;
|
||||
|
||||
uniform float time;
|
||||
|
||||
|
@ -16,6 +17,7 @@ uniform sampler2D tex;
|
|||
|
||||
void main() {
|
||||
float blendMaskMult = -1;
|
||||
|
||||
if (blendMaskCoords.x >= 0 && blendMaskCoords.y >= 0) blendMaskMult = texture(tex, blendMaskCoords).r;
|
||||
|
||||
vec4 spec = texture(tex, texCoords);
|
||||
|
@ -24,7 +26,7 @@ void main() {
|
|||
blendCol = (vec3(1, 1, 1) * (1 - blendMaskMult)) + (blendCol * blendMaskMult);
|
||||
}
|
||||
|
||||
spec = vec4(spec.xyz * blendCol, spec.w);
|
||||
spec = vec4(spec.xyz * blendCol * light, spec.a);
|
||||
|
||||
if (spec.a < 0.1) discard;
|
||||
|
||||
|
|
|
@ -1,28 +1,31 @@
|
|||
#version 330 core
|
||||
|
||||
#define TAU 6.28318530718
|
||||
#define MAX_BLOCKLIGHT 31
|
||||
#define MAX_SUNLIGHT 15
|
||||
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 1) in vec2 aTexCoords;
|
||||
layout (location = 2) in vec3 aBlend;
|
||||
layout (location = 3) in vec2 aBlendMaskCoords;
|
||||
layout (location = 4) in float aNormal;
|
||||
layout (location = 5) in float aShaderMod;
|
||||
layout (location = 6) in vec3 aModValues;
|
||||
layout (location = 5) in vec4 aLight;
|
||||
layout (location = 6) in float aShaderMod;
|
||||
layout (location = 7) in vec3 aModValues;
|
||||
|
||||
uniform mat4 model;
|
||||
uniform mat4 projection;
|
||||
uniform mat4 view;
|
||||
|
||||
uniform sampler2D swayTex;
|
||||
|
||||
uniform float time;
|
||||
|
||||
out vec2 texCoords;
|
||||
out vec2 blendMaskCoords;
|
||||
out vec3 blend;
|
||||
out vec3 fragPos;
|
||||
out vec3 normal;
|
||||
out vec2 texCoords;
|
||||
out vec2 blendMaskCoords;
|
||||
out vec3 blend;
|
||||
out vec3 fragPos;
|
||||
out vec3 normal;
|
||||
out vec3 light;
|
||||
|
||||
vec3 unpackFloat(float src) {
|
||||
return vec3(fract(src) * 2.0f - 1.0f, fract(src * 256.f) * 2.0f - 1.0f, fract(src * 65536.f) * 2.0f - 1.0f);
|
||||
|
@ -88,6 +91,12 @@ void main() {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
float sunlightIntensity = aLight.w * clamp(sin(time * 10.5) + 0.25, 0, 1) / MAX_SUNLIGHT;
|
||||
vec3 blockLightColor = (aLight.xyz / MAX_BLOCKLIGHT) * vec3(1 + sunlightIntensity / 4);
|
||||
vec3 sunlightColor = clamp(sunlightIntensity * 1.25 * vec3(1, 0.8, 0.9), 0, 1);
|
||||
vec3 resultantLight = vec3(max(sunlightColor.x, blockLightColor.x), max(sunlightColor.y, blockLightColor.y), max(sunlightColor.z, blockLightColor.z));
|
||||
|
||||
vec4 worldPos = model * pos;
|
||||
|
||||
fragPos = (view * worldPos).xyz;
|
||||
|
@ -95,6 +104,6 @@ void main() {
|
|||
blendMaskCoords = aBlendMaskCoords;
|
||||
blend = aBlend;
|
||||
normal = nml.xyz;
|
||||
|
||||
light = resultantLight;
|
||||
gl_Position = projection * view * worldPos;
|
||||
}
|
||||
|
|
|
@ -7,13 +7,13 @@
|
|||
LocalDefinitionAtlas::LocalDefinitionAtlas(TextureAtlas& atlas) {
|
||||
//Invalid Node
|
||||
BlockModel invalidModel = BlockModel::createCube({atlas["_missing"]}, {}, {});
|
||||
BlockDef* invalid = new BlockDef("invalid", 0, "Invalid (you broke the game!)", 1, invalidModel, invalidModel, true, {{}}, {{}});
|
||||
BlockDef* invalid = new BlockDef("invalid", "Invalid (you broke the game!)", 1, invalidModel, invalidModel, true, {}, {{}}, {{}});
|
||||
defs.push_back(invalid);
|
||||
defTable.insert({"invalid", 0});
|
||||
|
||||
//Air Node
|
||||
BlockModel nullModel {};
|
||||
BlockDef* air = new BlockDef("air", 0, "Air", 1, nullModel, nullModel, false, {}, {});
|
||||
BlockDef* air = new BlockDef("air", "Air", 1, nullModel, nullModel, false, {}, {}, {});
|
||||
defs.push_back(air);
|
||||
defTable.insert({"air", 1});
|
||||
}
|
||||
|
|
|
@ -8,12 +8,12 @@ ServerDefinitionAtlas::ServerDefinitionAtlas() {
|
|||
|
||||
//Invalid Node
|
||||
BlockModel invalidModel = BlockModel::createCube({}, {}, {});
|
||||
BlockDef* invalid = new BlockDef("invalid", INVALID, "Invalid (you broke the game!)", 1, invalidModel, invalidModel, true, {{}}, {{}});
|
||||
BlockDef* invalid = new BlockDef("invalid", "Invalid (you broke the game!)", 1, invalidModel, invalidModel, true, {}, {{}}, {{}}, INVALID);
|
||||
registerDef(invalid);
|
||||
|
||||
//Air Node
|
||||
BlockModel nullModel {};
|
||||
BlockDef* air = new BlockDef("air", AIR, "Air (you broke the game!)", 1, nullModel, nullModel, false, {}, {});
|
||||
BlockDef* air = new BlockDef("air", "Air (you broke the game!)", 1, nullModel, nullModel, false, {}, {}, {}, AIR);
|
||||
registerDef(air);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,20 +4,25 @@
|
|||
|
||||
#include "BlockDef.h"
|
||||
|
||||
BlockDef::BlockDef(const std::string &identifier, const std::string& name, unsigned short maxStackSize,
|
||||
const BlockModel &model, const BlockModel& farModel, bool solid, const std::vector<SelectionBox>& sBoxes,
|
||||
const std::vector<SelectionBox>& cBoxes) :
|
||||
BlockDef(identifier, 0, name, maxStackSize, model, farModel, solid, sBoxes, cBoxes) {}
|
||||
|
||||
BlockDef::BlockDef(const std::string& identifier, unsigned int index, const std::string& name,
|
||||
unsigned short maxStackSize, const BlockModel& model, const BlockModel& farModel, bool solid,
|
||||
const std::vector<SelectionBox>& sBoxes, const std::vector<SelectionBox>& cBoxes) :
|
||||
BlockDef::BlockDef(
|
||||
const std::string& identifier,
|
||||
const std::string& name,
|
||||
unsigned short maxStackSize,
|
||||
const BlockModel& model,
|
||||
const BlockModel& farModel,
|
||||
bool solid,
|
||||
glm::ivec3 lightSource,
|
||||
const std::vector<SelectionBox>& sBoxes,
|
||||
const std::vector<SelectionBox>& cBoxes,
|
||||
unsigned int index) :
|
||||
|
||||
ItemDef {identifier, name, index, maxStackSize, ItemDef::Type::BLOCK},
|
||||
|
||||
model(model),
|
||||
farModel(farModel),
|
||||
culls(model.culls),
|
||||
solid(solid),
|
||||
lightSource(lightSource),
|
||||
sBoxes(sBoxes),
|
||||
cBoxes(cBoxes) {}
|
||||
|
||||
|
|
|
@ -15,21 +15,29 @@
|
|||
|
||||
class BlockDef : public ItemDef {
|
||||
public:
|
||||
BlockDef() = default;
|
||||
BlockDef(const std::string& identifier, const std::string& name, unsigned short maxStackSize,
|
||||
const BlockModel& model, const BlockModel& farModel, bool solid, const std::vector<SelectionBox>& sBoxes,
|
||||
const std::vector<SelectionBox>& cBoxes);
|
||||
|
||||
BlockDef(const std::string& identifier, unsigned int index, const std::string& name,
|
||||
unsigned short maxStackSize, const BlockModel& model, const BlockModel& farModel, bool solid,
|
||||
const std::vector<SelectionBox>& sBoxes, const std::vector<SelectionBox>& cBoxes);
|
||||
BlockDef(
|
||||
const std::string& identifier,
|
||||
const std::string& name,
|
||||
unsigned short maxStackSize,
|
||||
const BlockModel& model,
|
||||
const BlockModel& farModel,
|
||||
bool solid,
|
||||
glm::ivec3 lightSource,
|
||||
const std::vector<SelectionBox>& sBoxes,
|
||||
const std::vector<SelectionBox>& cBoxes,
|
||||
unsigned int index = 0
|
||||
);
|
||||
|
||||
void createModel();
|
||||
|
||||
BlockModel model, farModel;
|
||||
BlockModel model;
|
||||
BlockModel farModel;
|
||||
|
||||
bool culls = false;
|
||||
bool solid = false;
|
||||
|
||||
glm::ivec3 lightSource;
|
||||
|
||||
std::vector<SelectionBox> sBoxes;
|
||||
std::vector<SelectionBox> cBoxes;
|
||||
|
||||
|
|
|
@ -2,11 +2,9 @@
|
|||
// Created by aurailus on 25/11/18.
|
||||
//
|
||||
|
||||
#include "ChunkMesh.h"
|
||||
#include <vector>
|
||||
|
||||
ChunkMesh::ChunkMesh(const ChunkMesh &o) {
|
||||
throw "Copy constructor for ChunkMesh is not supported! Throwing.";
|
||||
}
|
||||
#include "ChunkMesh.h"
|
||||
|
||||
void ChunkMesh::create(const std::vector<ChunkVertex>& vertices, const std::vector<unsigned int>& indices) {
|
||||
indCount = static_cast<GLsizei>(indices.size());
|
||||
|
@ -21,6 +19,7 @@ void ChunkMesh::create(const std::vector<ChunkVertex>& vertices, const std::vect
|
|||
createVertexAttrib(idx++, 3, GL_FLOAT, STRIDE_OFFSET_CHUNK(blendColor));
|
||||
createVertexAttrib(idx++, 2, GL_FLOAT, STRIDE_OFFSET_CHUNK(blendMaskCoords));
|
||||
createVertexAttrib(idx++, 1, GL_FLOAT, STRIDE_OFFSET_CHUNK(normal));
|
||||
createVertexAttrib(idx++, 4, GL_FLOAT, STRIDE_OFFSET_CHUNK(light));
|
||||
createVertexAttrib(idx++, 1, GL_FLOAT, STRIDE_OFFSET_CHUNK(shaderMod));
|
||||
createVertexAttrib(idx , 3, GL_FLOAT, STRIDE_OFFSET_CHUNK(modValues));
|
||||
|
||||
|
|
|
@ -4,14 +4,15 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "Mesh.h"
|
||||
#include "ChunkVertex.h"
|
||||
|
||||
class ChunkMesh : public Mesh {
|
||||
public:
|
||||
ChunkMesh() = default;
|
||||
ChunkMesh(const ChunkMesh& o);
|
||||
ChunkMesh(const ChunkMesh& o) { assert(false); };
|
||||
|
||||
void create(const std::vector<ChunkVertex>& vertices, const std::vector<unsigned int>& indices);
|
||||
|
||||
~ChunkMesh() = default;
|
||||
};
|
||||
|
|
|
@ -4,8 +4,9 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <glm/vec3.hpp>
|
||||
#include <glm/vec2.hpp>
|
||||
#include <glm/vec3.hpp>
|
||||
#include <glm/vec4.hpp>
|
||||
|
||||
struct ChunkVertex {
|
||||
glm::vec3 position;
|
||||
|
@ -13,6 +14,7 @@ struct ChunkVertex {
|
|||
glm::vec3 blendColor;
|
||||
glm::vec2 blendMaskCoords;
|
||||
float normal;
|
||||
glm::vec4 light;
|
||||
float shaderMod;
|
||||
glm::vec3 modValues;
|
||||
};
|
||||
|
|
|
@ -64,21 +64,28 @@ ChunkMeshGenerator::ChunkMeshGenerator(ChunkMeshDetails* meshDetails, LocalDefin
|
|||
}
|
||||
}
|
||||
|
||||
if (!getBlockAt({off.x - 1, off.y, off.z}).culls) addFaces(vis, model.parts[static_cast<int>(Dir::XNEG)], biomeTint);
|
||||
if (!getBlockAt({off.x + 1, off.y, off.z}).culls) addFaces(vis, model.parts[static_cast<int>(Dir::XPOS)], biomeTint);
|
||||
if (!getBlockAt({off.x, off.y - 1, off.z}).culls) addFaces(vis, model.parts[static_cast<int>(Dir::YNEG)], biomeTint);
|
||||
if (!getBlockAt({off.x, off.y + 1, off.z}).culls) addFaces(vis, model.parts[static_cast<int>(Dir::YPOS)], biomeTint);
|
||||
if (!getBlockAt({off.x, off.y, off.z - 1}).culls) addFaces(vis, model.parts[static_cast<int>(Dir::ZNEG)], biomeTint);
|
||||
if (!getBlockAt({off.x, off.y, off.z + 1}).culls) addFaces(vis, model.parts[static_cast<int>(Dir::ZPOS)], biomeTint);
|
||||
glm::ivec3 pos {};
|
||||
pos = { off.x - 1, off.y, off.z };
|
||||
if (!getBlockAt(pos).culls) addFaces(vis, model.parts[static_cast<int>(Dir::XNEG)], biomeTint, getLightAt(pos));
|
||||
pos = { off.x + 1, off.y, off.z };
|
||||
if (!getBlockAt(pos).culls) addFaces(vis, model.parts[static_cast<int>(Dir::XPOS)], biomeTint, getLightAt(pos));
|
||||
pos = { off.x, off.y - 1, off.z };
|
||||
if (!getBlockAt(pos).culls) addFaces(vis, model.parts[static_cast<int>(Dir::YNEG)], biomeTint, getLightAt(pos));
|
||||
pos = { off.x, off.y + 1, off.z };
|
||||
if (!getBlockAt(pos).culls) addFaces(vis, model.parts[static_cast<int>(Dir::YPOS)], biomeTint, getLightAt(pos));
|
||||
pos = { off.x, off.y, off.z - 1 };
|
||||
if (!getBlockAt(pos).culls) addFaces(vis, model.parts[static_cast<int>(Dir::ZNEG)], biomeTint, getLightAt(pos));
|
||||
pos = { off.x, off.y, off.z + 1 };
|
||||
if (!getBlockAt(pos).culls) addFaces(vis, model.parts[static_cast<int>(Dir::ZPOS)], biomeTint, getLightAt(pos));
|
||||
|
||||
addFaces(vis, model.parts[static_cast<int>(Dir::NO_CULL)], biomeTint);
|
||||
addFaces(vis, model.parts[static_cast<int>(Dir::NO_CULL)], biomeTint, getLightAt(vis));
|
||||
}
|
||||
|
||||
meshDetails->vertices.shrink_to_fit();
|
||||
meshDetails->indices.shrink_to_fit();
|
||||
}
|
||||
|
||||
BlockDef& ChunkMeshGenerator::getBlockAt(const glm::ivec3 &pos) {
|
||||
BlockDef& ChunkMeshGenerator::getBlockAt(const glm::ivec3& pos) {
|
||||
if (pos.x == 16) return defs.blockFromId(adjacent[0]->getBlock(pos - glm::ivec3 {16, 0, 0}));
|
||||
if (pos.x == -1) return defs.blockFromId(adjacent[1]->getBlock(pos + glm::ivec3 {16, 0, 0}));
|
||||
|
||||
|
@ -91,7 +98,20 @@ BlockDef& ChunkMeshGenerator::getBlockAt(const glm::ivec3 &pos) {
|
|||
return defs.blockFromId(chunk->getBlock(pos));
|
||||
}
|
||||
|
||||
void ChunkMeshGenerator::addFaces(const glm::vec3 &offset, const std::vector<MeshPart> &meshParts, const glm::vec3& tint) {
|
||||
glm::vec4 ChunkMeshGenerator::getLightAt(const glm::ivec3& pos) {
|
||||
if (pos.x == 16) return adjacent[0]->getLightVec(Space::Block::index(pos - glm::ivec3 {16, 0, 0}));
|
||||
if (pos.x == -1) return adjacent[1]->getLightVec(Space::Block::index(pos + glm::ivec3 {16, 0, 0}));
|
||||
|
||||
if (pos.y == 16) return adjacent[2]->getLightVec(Space::Block::index(pos - glm::ivec3 {0, 16, 0}));
|
||||
if (pos.y == -1) return adjacent[3]->getLightVec(Space::Block::index(pos + glm::ivec3 {0, 16, 0}));
|
||||
|
||||
if (pos.z == 16) return adjacent[4]->getLightVec(Space::Block::index(pos - glm::ivec3 {0, 0, 16}));
|
||||
if (pos.z == -1) return adjacent[5]->getLightVec(Space::Block::index(pos + glm::ivec3 {0, 0, 16}));
|
||||
|
||||
return chunk->getLightVec(Space::Block::index(pos));
|
||||
}
|
||||
|
||||
void ChunkMeshGenerator::addFaces(const glm::vec3 &offset, const std::vector<MeshPart> &meshParts, const glm::vec3& tint, glm::vec4 light) {
|
||||
for (const MeshPart& mp : meshParts) {
|
||||
glm::vec3 modData = {};
|
||||
|
||||
|
@ -114,6 +134,7 @@ void ChunkMeshGenerator::addFaces(const glm::vec3 &offset, const std::vector<Mes
|
|||
mp.blendInd ? tint : glm::vec3 {1, 1, 1},
|
||||
mp.blendInd ? vertex.blendMask : glm::vec2 {-1, -1},
|
||||
Util::packFloat(vertex.nml),
|
||||
light,
|
||||
static_cast<float>(mp.shaderMod),
|
||||
modData
|
||||
});
|
||||
|
|
|
@ -21,8 +21,10 @@ public:
|
|||
std::shared_ptr<BlockChunk> chunk, std::array<std::shared_ptr<BlockChunk>, 6> adjacent,
|
||||
std::array<NoiseSample, 3>& blockOffsets);
|
||||
private:
|
||||
BlockDef& getBlockAt(const glm::ivec3 &pos);
|
||||
void addFaces(const glm::vec3 &offset, const std::vector<MeshPart> &meshParts, const glm::vec3& tint);
|
||||
inline BlockDef& getBlockAt(const glm::ivec3& pos);
|
||||
inline glm::vec4 getLightAt(const glm::ivec3& pos);
|
||||
|
||||
void addFaces(const glm::vec3 &offset, const std::vector<MeshPart> &meshParts, const glm::vec3& tint, glm::vec4 light);
|
||||
|
||||
LocalDefinitionAtlas& defs;
|
||||
LocalBiomeAtlas& biomes;
|
||||
|
|
|
@ -265,6 +265,16 @@ namespace RegisterBlocks {
|
|||
bool solid = blockTable.get_or("solid", true);
|
||||
auto maxStack = blockTable.get_or("stack", 64);
|
||||
|
||||
glm::vec3 lightSource {};
|
||||
if (blockTable.get<sol::optional<sol::table>>("light_source")) {
|
||||
auto light = blockTable.get<sol::table>("light_source");
|
||||
lightSource = { light[1], light[2], light[3] };
|
||||
}
|
||||
else if (blockTable.get_or<float>("light_source", -1) != -1) {
|
||||
auto light = blockTable.get<float>("light_source");
|
||||
lightSource = { light, light, light };
|
||||
}
|
||||
|
||||
// Parse through selection boxes and collision boxes
|
||||
auto selectionOpt = blockTable.get<sol::optional<sol::table>>("selection_box");
|
||||
auto collisionOpt = blockTable.get<sol::optional<sol::table>>("collision_box");
|
||||
|
@ -283,14 +293,15 @@ namespace RegisterBlocks {
|
|||
std::pair<BlockModel, BlockModel> models = createBlockModel(blockTable, blockModels, atlas);
|
||||
|
||||
BlockDef *blockDef = new BlockDef(
|
||||
identifier,
|
||||
defs.size(),
|
||||
*nameOpt,
|
||||
maxStack,
|
||||
models.first, models.second,
|
||||
solid,
|
||||
std::move(selectionBoxes),
|
||||
std::move(collisionBoxes)
|
||||
identifier,
|
||||
*nameOpt,
|
||||
maxStack,
|
||||
models.first, models.second,
|
||||
solid,
|
||||
lightSource,
|
||||
std::move(selectionBoxes),
|
||||
std::move(collisionBoxes),
|
||||
defs.size() // Index
|
||||
);
|
||||
|
||||
// Create entity model
|
||||
|
|
|
@ -7,13 +7,14 @@
|
|||
|
||||
#include "ServerWorld.h"
|
||||
|
||||
#include "ServerGenStream.h"
|
||||
#include "../conn/ClientList.h"
|
||||
#include "../conn/ServerClient.h"
|
||||
|
||||
ServerWorld::ServerWorld(unsigned int seed, ServerGame& defs, ClientList& clients) :
|
||||
ServerWorld::ServerWorld(unsigned int seed, ServerGame& game, ClientList& clients) :
|
||||
clientList(clients),
|
||||
dimension(game),
|
||||
seed(seed),
|
||||
defs(defs) {
|
||||
game(game) {
|
||||
|
||||
//Pregenerate chunk generation order
|
||||
generateOrder.reserve(MB_GEN_H * 2 * MB_GEN_H * 2 * MB_GEN_V * 2);
|
||||
|
@ -34,7 +35,7 @@ ServerWorld::ServerWorld(unsigned int seed, ServerGame& defs, ClientList& client
|
|||
}
|
||||
|
||||
void ServerWorld::init() {
|
||||
genStream = std::make_unique<ServerGenStream>(seed, defs);
|
||||
genStream = std::make_unique<ServerGenStream>(seed, game);
|
||||
}
|
||||
|
||||
void ServerWorld::update(double delta) {
|
||||
|
@ -170,26 +171,21 @@ void ServerWorld::setBlock(glm::ivec3 pos, unsigned int block) {
|
|||
auto oldBlock = getBlock(pos);
|
||||
|
||||
if (block == DefinitionAtlas::AIR) {
|
||||
auto def = defs.defs.blockFromId(oldBlock);
|
||||
auto def = game.defs.blockFromId(oldBlock);
|
||||
if (def.callbacks.count(Callback::DESTRUCT)) {
|
||||
def.callbacks[Callback::DESTRUCT](defs.parser.luaVec(pos));
|
||||
def.callbacks[Callback::DESTRUCT](game.parser.luaVec(pos));
|
||||
}
|
||||
}
|
||||
else {
|
||||
auto def = defs.defs.blockFromId(block);
|
||||
auto def = game.defs.blockFromId(block);
|
||||
if (def.callbacks.count(Callback::CONSTRUCT)) {
|
||||
def.callbacks[Callback::CONSTRUCT](defs.parser.luaVec(pos));
|
||||
def.callbacks[Callback::CONSTRUCT](game.parser.luaVec(pos));
|
||||
}
|
||||
}
|
||||
|
||||
dimension.setBlock(pos, block);
|
||||
|
||||
Packet b(PacketType::BLOCK_SET);
|
||||
b.data = Serializer()
|
||||
.append(pos)
|
||||
.append(block)
|
||||
.data;
|
||||
|
||||
Packet b = Serializer().append(pos).append(block).packet(PacketType::BLOCK_SET);
|
||||
auto chunkPos = Space::Chunk::world::fromBlock(pos);
|
||||
|
||||
for (auto &client : clientList.clients) {
|
||||
|
@ -207,15 +203,15 @@ void ServerWorld::setBlock(glm::ivec3 pos, unsigned int block) {
|
|||
}
|
||||
|
||||
if (block == DefinitionAtlas::AIR) {
|
||||
auto def = defs.defs.blockFromId(oldBlock);
|
||||
auto def = game.defs.blockFromId(oldBlock);
|
||||
if (def.callbacks.count(Callback::AFTER_DESTRUCT)) {
|
||||
def.callbacks[Callback::AFTER_DESTRUCT](defs.parser.luaVec(pos));
|
||||
def.callbacks[Callback::AFTER_DESTRUCT](game.parser.luaVec(pos));
|
||||
}
|
||||
}
|
||||
else {
|
||||
auto def = defs.defs.blockFromId(block);
|
||||
auto def = game.defs.blockFromId(block);
|
||||
if (def.callbacks.count(Callback::AFTER_CONSTRUCT)) {
|
||||
def.callbacks[Callback::AFTER_CONSTRUCT](defs.parser.luaVec(pos));
|
||||
def.callbacks[Callback::AFTER_CONSTRUCT](game.parser.luaVec(pos));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
//
|
||||
// World subclass for the server.
|
||||
// Handles blocks, entities, and clients.
|
||||
// Created by aurailus on 05/03/19.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <unordered_set>
|
||||
#include "../../game/scene/world/World.h"
|
||||
|
||||
#include "ServerGenStream.h"
|
||||
#include "../conn/ClientList.h"
|
||||
#include "../../def/ServerGame.h"
|
||||
#include "../../game/scene/world/World.h"
|
||||
#include "../../world/ServerDimension.h"
|
||||
|
||||
class ServerWorld : public World {
|
||||
|
@ -17,7 +16,7 @@ public:
|
|||
const static int MB_GEN_H = 2;
|
||||
const static int MB_GEN_V = 2;
|
||||
|
||||
explicit ServerWorld(unsigned int seed, ServerGame& defs, ClientList& clients);
|
||||
explicit ServerWorld(unsigned int seed, ServerGame& game, ClientList& clients);
|
||||
|
||||
void init();
|
||||
void update(double delta) override;
|
||||
|
@ -25,7 +24,7 @@ public:
|
|||
unsigned int getBlock(glm::ivec3 pos) override;
|
||||
void setBlock(glm::ivec3 pos, unsigned int block) override;
|
||||
|
||||
ServerDimension dimension {};
|
||||
ServerDimension dimension;
|
||||
private:
|
||||
void changedChunks(ServerClient& client);
|
||||
bool generateMapBlock(glm::ivec3 pos);
|
||||
|
@ -39,7 +38,7 @@ private:
|
|||
std::unique_ptr<ServerGenStream> genStream = nullptr;
|
||||
|
||||
unsigned int seed;
|
||||
ServerGame& defs;
|
||||
ServerGame& game;
|
||||
ClientList& clientList;
|
||||
|
||||
unsigned int generatedChunks = 0;
|
||||
|
|
|
@ -41,17 +41,17 @@ namespace Space {
|
|||
|
||||
namespace Region {
|
||||
namespace world {
|
||||
// Get a Region engine position from a MapBlock's engine position.
|
||||
// Get a Region engine position from a MapBlock's world position.
|
||||
static inline glm::ivec3 fromMapBlock(const glm::ivec3& mapBlock) {
|
||||
return sectionFromGlobal(mapBlock, REGION_SIZE);
|
||||
}
|
||||
|
||||
// Get a Region engine position from a Chunk's engine position.
|
||||
// Get a Region engine position from a Chunk's world position.
|
||||
static inline glm::ivec3 fromChunk(const glm::ivec3 &chunk) {
|
||||
return sectionFromGlobal(chunk, REGION_CHUNK_LENGTH);
|
||||
}
|
||||
|
||||
// Get a Region engine position from a Block's engine position.
|
||||
// Get a Region engine position from a Block's world position.
|
||||
static inline glm::ivec3 fromBlock(const glm::ivec3 &chunk) {
|
||||
return sectionFromGlobal(chunk, REGION_BLOCK_LENGTH);
|
||||
}
|
||||
|
@ -60,25 +60,25 @@ namespace Space {
|
|||
|
||||
namespace MapBlock {
|
||||
namespace relative {
|
||||
// Get a MapBlock's relative position in its Region from its engine position.
|
||||
// Get a MapBlock's relative position in its Region from its world position.
|
||||
static inline glm::ivec3 toRegion(const glm::ivec3& pos) {
|
||||
return localFromGlobal(pos, MAPBLOCK_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
namespace world {
|
||||
// Get a MapBlock engine position from a Chunk's engine position.
|
||||
// Get a MapBlock engine position from a Chunk's world position.
|
||||
static inline glm::ivec3 fromChunk(const glm::ivec3 &chunk) {
|
||||
return sectionFromGlobal(chunk, MAPBLOCK_SIZE);
|
||||
}
|
||||
|
||||
// Get a MapBlock engine position from a Block's engine position.
|
||||
// Get a MapBlock engine position from a Block's world position.
|
||||
static inline glm::ivec3 fromBlock(const glm::ivec3 &vec) {
|
||||
return sectionFromGlobal(vec, MAPBLOCK_BLOCK_LENGTH);
|
||||
}
|
||||
}
|
||||
|
||||
// Get the index of a MapBlock within its Region from its local or engine position.
|
||||
// Get the index of a MapBlock within its Region from its local or world position.
|
||||
static inline unsigned int index(const glm::ivec3& vec) {
|
||||
glm::ivec3 local = MapBlock::relative::toRegion(vec);
|
||||
unsigned int ind = static_cast<unsigned int>(local.x + REGION_SIZE * (local.y + REGION_SIZE * local.z));
|
||||
|
@ -88,25 +88,25 @@ namespace Space {
|
|||
|
||||
namespace Chunk {
|
||||
namespace relative {
|
||||
// Get a Chunk's relative position in its MapBlock from its engine position.
|
||||
// Get a Chunk's relative position in its MapBlock from its world position.
|
||||
static inline glm::ivec3 toMapBlock(const glm::ivec3& pos) {
|
||||
return localFromGlobal(pos, MAPBLOCK_CHUNK_LENGTH);
|
||||
}
|
||||
|
||||
// Get a Chunk's relative position in its Region from its engine position.
|
||||
// Get a Chunk's relative position in its Region from its world position.
|
||||
static inline glm::ivec3 toRegion(const glm::ivec3& pos) {
|
||||
return localFromGlobal(pos, REGION_CHUNK_LENGTH);
|
||||
}
|
||||
}
|
||||
|
||||
namespace world {
|
||||
// Get a Chunk engine position from a Block's engine position.
|
||||
// Get a Chunk engine position from a Block's world position.
|
||||
static inline glm::ivec3 fromBlock(const glm::ivec3& pos) {
|
||||
return sectionFromGlobal(pos, CHUNK_BLOCK_LENGTH);
|
||||
}
|
||||
}
|
||||
|
||||
// Get the index of a Chunk within its MapBlock from its local or engine position.
|
||||
// Get the index of a Chunk within its MapBlock from its local or world position.
|
||||
static inline unsigned int index(const glm::ivec3& vec) {
|
||||
glm::ivec3 local = Chunk::relative::toMapBlock(vec);
|
||||
return static_cast<unsigned int>(local.x + MAPBLOCK_SIZE * (local.y + MAPBLOCK_SIZE * local.z));
|
||||
|
@ -115,27 +115,39 @@ namespace Space {
|
|||
|
||||
namespace Block {
|
||||
namespace relative {
|
||||
// Get a Block's relative position to its Chunk from its engine position.
|
||||
// Get a Block's relative position to its Chunk from its world position.
|
||||
static inline glm::ivec3 toChunk(const glm::ivec3& pos) {
|
||||
return localFromGlobal(pos, CHUNK_BLOCK_LENGTH);
|
||||
}
|
||||
|
||||
// Get a Block's relative position to its MapBlock from its engine position.
|
||||
// Get a Block's relative position to its MapBlock from its world position.
|
||||
static inline glm::ivec3 toMapBlock(const glm::ivec3& pos) {
|
||||
return localFromGlobal(pos, MAPBLOCK_BLOCK_LENGTH);
|
||||
}
|
||||
|
||||
// Get a Block's relative position in its Region from its engine position.
|
||||
// Get a Block's relative position in its Region from its world position.
|
||||
static inline glm::ivec3 toRegion(const glm::ivec3& pos) {
|
||||
return localFromGlobal(pos, REGION_BLOCK_LENGTH);
|
||||
}
|
||||
}
|
||||
|
||||
// Get the index of a Block within its Chunk from its local or engine position.
|
||||
// Get the index of a Block within its Chunk from its local or world position.
|
||||
static inline unsigned int index(const glm::ivec3& vec) {
|
||||
glm::ivec3 local = Block::relative::toChunk(vec);
|
||||
return static_cast<unsigned int>(local.x + CHUNK_SIZE * (local.y + CHUNK_SIZE * local.z));
|
||||
}
|
||||
|
||||
// Return a local vector of an index within it's chunk.
|
||||
static inline glm::ivec3 fromIndex(unsigned int ind) {
|
||||
glm::ivec3 vec {};
|
||||
|
||||
vec.z = ind / (CHUNK_SIZE * CHUNK_SIZE);
|
||||
ind -= (static_cast<int>(vec.z) * CHUNK_SIZE * CHUNK_SIZE);
|
||||
vec.y = ind / CHUNK_SIZE;
|
||||
vec.x = ind % CHUNK_SIZE;
|
||||
|
||||
return vec;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -147,6 +147,20 @@ template <> inline std::vector<unsigned short> Deserializer::read<std::vector<un
|
|||
reinterpret_cast<const unsigned short*>(&data[ind + len * 2]));
|
||||
}
|
||||
|
||||
template <> inline std::vector<char> Deserializer::read<std::vector<char>>() {
|
||||
unsigned int len = read<unsigned int>();
|
||||
return std::vector<char>(
|
||||
reinterpret_cast<const char*>(&data[ind]),
|
||||
reinterpret_cast<const char*>(&data[ind + len]));
|
||||
}
|
||||
|
||||
template <> inline std::vector<unsigned char> Deserializer::read<std::vector<unsigned char>>() {
|
||||
unsigned int len = read<unsigned int>();
|
||||
return std::vector<unsigned char>(
|
||||
reinterpret_cast<const unsigned char*>(&data[ind]),
|
||||
reinterpret_cast<const unsigned char*>(&data[ind + len]));
|
||||
}
|
||||
|
||||
template <> inline std::vector<float> Deserializer::read<std::vector<float>>() {
|
||||
unsigned int len = read<unsigned int>();
|
||||
return std::vector<float>(
|
||||
|
|
|
@ -132,6 +132,20 @@ template <> inline Serializer& Serializer::append<std::vector<unsigned short>>(c
|
|||
return *this;
|
||||
}
|
||||
|
||||
template <> inline Serializer& Serializer::append<std::vector<char>>(const std::vector<char>& elem) {
|
||||
data.reserve(data.length() + elem.size() + 4);
|
||||
append<unsigned int>(elem.size());
|
||||
data += std::string { reinterpret_cast<const char*>(&elem[0]), elem.size() };
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <> inline Serializer& Serializer::append<std::vector<unsigned char>>(const std::vector<unsigned char>& elem) {
|
||||
data.reserve(data.length() + elem.size() + 4);
|
||||
append<unsigned int>(elem.size());
|
||||
data += std::string { reinterpret_cast<const char*>(&elem[0]), elem.size() };
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <> inline Serializer& Serializer::append<std::vector<float>>(const std::vector<float>& elem) {
|
||||
data.reserve(data.length() + elem.size() * 4 + 4);
|
||||
append<unsigned int>(elem.size());
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
#include "Dimension.h"
|
||||
|
||||
Dimension::Dimension(DefinitionAtlas &defs) : defs(defs) {}
|
||||
|
||||
std::shared_ptr<Region> Dimension::getRegion(glm::ivec3 regionPosition) {
|
||||
if (!regions.count(regionPosition)) return nullptr;
|
||||
return regions[regionPosition];
|
||||
|
@ -15,13 +17,13 @@ void Dimension::removeRegion(glm::ivec3 pos) {
|
|||
|
||||
std::shared_ptr<MapBlock> Dimension::getMapBlock(glm::ivec3 mapBlockPosition) {
|
||||
auto region = getRegion(Space::Region::world::fromMapBlock(mapBlockPosition));
|
||||
if (region == nullptr) return nullptr;
|
||||
if (!region) return nullptr;
|
||||
return (*region)[Space::MapBlock::index(mapBlockPosition)];
|
||||
}
|
||||
|
||||
void Dimension::removeMapBlock(glm::ivec3 pos) {
|
||||
auto region = getRegion(Space::Region::world::fromMapBlock(pos));
|
||||
if (region == nullptr) return;
|
||||
if (!region) return;
|
||||
auto ind = Space::MapBlock::index(pos);
|
||||
region->remove(ind);
|
||||
if (region->count == 0) removeRegion(Space::Region::world::fromMapBlock(pos));
|
||||
|
@ -29,7 +31,7 @@ void Dimension::removeMapBlock(glm::ivec3 pos) {
|
|||
|
||||
std::shared_ptr<BlockChunk> Dimension::getChunk(glm::ivec3 chunkPosition) {
|
||||
auto mapBlock = getMapBlock(Space::MapBlock::world::fromChunk(chunkPosition));
|
||||
if (mapBlock == nullptr) return nullptr;
|
||||
if (!mapBlock) return nullptr;
|
||||
return (*mapBlock)[Space::Chunk::index(chunkPosition)];
|
||||
}
|
||||
|
||||
|
@ -40,7 +42,7 @@ void Dimension::setChunk(std::shared_ptr<BlockChunk> chunk) {
|
|||
|
||||
void Dimension::removeChunk(glm::ivec3 pos){
|
||||
auto mapBlock = getMapBlock(Space::MapBlock::world::fromChunk(pos));
|
||||
if (mapBlock == nullptr) return;
|
||||
if (!mapBlock) return;
|
||||
auto ind = Space::Chunk::index(pos);
|
||||
mapBlock->remove(ind);
|
||||
if (mapBlock->count == 0) removeMapBlock(Space::MapBlock::world::fromChunk(pos));
|
||||
|
@ -48,20 +50,27 @@ void Dimension::removeChunk(glm::ivec3 pos){
|
|||
|
||||
unsigned int Dimension::getBlock(glm::ivec3 pos) {
|
||||
auto chunk = getChunk(Space::Chunk::world::fromBlock(pos));
|
||||
if (chunk != nullptr) return chunk->getBlock(Space::Block::relative::toChunk(pos));
|
||||
if (chunk) return chunk->getBlock(Space::Block::relative::toChunk(pos));
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool Dimension::setBlock(glm::ivec3 pos, unsigned int block) {
|
||||
auto chunk = getChunk(Space::Chunk::world::fromBlock(pos));
|
||||
if (chunk == nullptr) return false;
|
||||
if (!chunk) return false;
|
||||
|
||||
chunk->setBlock(Space::Block::relative::toChunk(pos), block);
|
||||
|
||||
glm::ivec3 oldLight = chunk->getBlockLight(Space::Block::index(pos));
|
||||
glm::ivec3 newLight = defs.blockFromId(block).lightSource;
|
||||
if (oldLight != newLight) {
|
||||
if (abs(oldLight.x) + abs(oldLight.y) + abs(oldLight.z) != 0) removeLight(pos);
|
||||
if (abs(newLight.x) + abs(newLight.y) + abs(newLight.z) != 0) addLight(pos, newLight);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::shared_ptr<Region> Dimension::getOrCreateRegion(glm::ivec3 pos) {
|
||||
if (regions[pos] != nullptr) return regions[pos];
|
||||
if (regions[pos]) return regions[pos];
|
||||
regions[pos] = std::make_shared<Region>(pos);
|
||||
return regions[pos];
|
||||
}
|
||||
|
@ -74,3 +83,97 @@ std::shared_ptr<MapBlock> Dimension::getOrCreateMapBlock(glm::ivec3 mapBlockPosi
|
|||
(*region).set(index, std::make_shared<MapBlock>(mapBlockPosition));
|
||||
return (*region)[index];
|
||||
}
|
||||
|
||||
// Returns true if the provided pos references a block within chunk, otherwise returns false.
|
||||
bool Dimension::containsWorldPos(BlockChunk *chunk, glm::ivec3 pos) {
|
||||
return chunk && Space::Chunk::world::fromBlock(pos) == chunk->pos;
|
||||
}
|
||||
|
||||
// Get the BlockLight of a block. This function can be accelerated
|
||||
// by providing a chunk that might contain the world position.
|
||||
glm::ivec3 Dimension::getBlockLight(glm::ivec3 worldPos, BlockChunk *chunk) {
|
||||
if (containsWorldPos(chunk, worldPos)) return chunk->getBlockLight(Space::Block::index(worldPos));
|
||||
auto oChunk = getChunk(Space::Chunk::world::fromBlock(worldPos)).get();
|
||||
return (oChunk ? oChunk->getBlockLight(Space::Block::index(worldPos)) : glm::ivec3 {});
|
||||
}
|
||||
|
||||
void Dimension::addLight(glm::ivec3 pos, glm::ivec3 light) {
|
||||
auto startChunk = getChunk(Space::Chunk::world::fromBlock(pos));
|
||||
auto index = Space::Block::index(pos);
|
||||
|
||||
startChunk->setBlockLight(index, light);
|
||||
lightAddQueue[0].emplace(index, startChunk.get());
|
||||
lightAddQueue[1].emplace(index, startChunk.get());
|
||||
lightAddQueue[2].emplace(index, startChunk.get());
|
||||
|
||||
propogateAddNodes(0);
|
||||
propogateAddNodes(1);
|
||||
propogateAddNodes(2);
|
||||
}
|
||||
|
||||
void Dimension::removeLight(glm::ivec3 pos) {
|
||||
auto startChunk = getChunk(Space::Chunk::world::fromBlock(pos));
|
||||
glm::ivec3 val = startChunk->getBlockLight(Space::Block::index(pos));
|
||||
|
||||
startChunk->setBlockLight(Space::Block::index(pos), {});
|
||||
lightRemoveQueue[0].emplace(Space::Block::index(pos), val.r, startChunk.get());
|
||||
lightRemoveQueue[1].emplace(Space::Block::index(pos), val.g, startChunk.get());
|
||||
lightRemoveQueue[2].emplace(Space::Block::index(pos), val.b, startChunk.get());
|
||||
|
||||
propogateRemoveNodes(0);
|
||||
propogateRemoveNodes(1);
|
||||
propogateRemoveNodes(2);
|
||||
}
|
||||
|
||||
void Dimension::propogateAddNodes(unsigned char channel) {
|
||||
while (!lightAddQueue[channel].empty()) {
|
||||
LightAddNode& node = lightAddQueue[channel].front();
|
||||
|
||||
unsigned char lightLevel = node.chunk->getBlockLight(node.index, channel);
|
||||
glm::ivec3 worldPos = node.chunk->pos * 16 + Space::Block::fromIndex(node.index);
|
||||
|
||||
const static std::array<glm::ivec3, 6> checks = { glm::ivec3 {-1, 0, 0}, {1, 0, 0}, {0, -1, 0}, {0, 1, 0}, {0, 0, -1}, {0, 0, 1} };
|
||||
for (const auto& i : checks) {
|
||||
glm::ivec3 check = worldPos + i;
|
||||
if (!defs.blockFromId(getBlock(check)).solid && getBlockLight(check, node.chunk)[channel] + 2 <= lightLevel) {
|
||||
auto chunk = containsWorldPos(node.chunk, check) ? node.chunk : getChunk(Space::Chunk::world::fromBlock(check)).get();
|
||||
if (!chunk) continue;
|
||||
chunk->setBlockLight(Space::Block::index(check), channel, lightLevel - 1);
|
||||
lightAddQueue[channel].emplace(Space::Block::index(check), chunk);
|
||||
}
|
||||
}
|
||||
lightAddQueue[channel].pop();
|
||||
}
|
||||
}
|
||||
|
||||
void Dimension::propogateRemoveNodes(unsigned char channel) {
|
||||
while (!lightRemoveQueue[channel].empty()) {
|
||||
LightRemoveNode& node = lightRemoveQueue[channel].front();
|
||||
|
||||
glm::ivec3 worldPos = node.chunk->pos * 16 + Space::Block::fromIndex(node.index);
|
||||
|
||||
const static std::array<glm::ivec3, 6> checks = { glm::ivec3 {-1, 0, 0}, {1, 0, 0}, {0, -1, 0}, {0, 1, 0}, {0, 0, -1}, {0, 0, 1} };
|
||||
for (const auto& i : checks) {
|
||||
glm::ivec3 check = worldPos + i;
|
||||
unsigned char checkLight = getBlockLight(check, node.chunk)[channel];
|
||||
|
||||
if (checkLight != 0 && checkLight < node.value) {
|
||||
auto chunk = containsWorldPos(node.chunk, check) ? node.chunk : getChunk(Space::Chunk::world::fromBlock(check)).get();
|
||||
if (!chunk) continue;
|
||||
|
||||
auto blockLight = defs.blockFromId(chunk->getBlock(Space::Block::index(check))).lightSource[channel];
|
||||
chunk->setBlockLight(Space::Block::index(check), channel, blockLight);
|
||||
if (blockLight) lightAddQueue[channel].emplace(Space::Block::index(check), chunk);
|
||||
lightRemoveQueue[channel].emplace(Space::Block::index(check), checkLight, chunk);
|
||||
}
|
||||
else if (checkLight >= node.value) {
|
||||
auto chunk = containsWorldPos(node.chunk, check) ? node.chunk : getChunk(Space::Chunk::world::fromBlock(check)).get();
|
||||
if (!chunk) continue;
|
||||
lightAddQueue[channel].emplace(Space::Block::index(check), chunk);
|
||||
}
|
||||
}
|
||||
lightRemoveQueue[channel].pop();
|
||||
}
|
||||
|
||||
propogateAddNodes(channel);
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <queue>
|
||||
#include <array>
|
||||
#include <memory>
|
||||
|
||||
#include "../util/Vec.h"
|
||||
|
@ -11,7 +13,7 @@
|
|||
|
||||
class Dimension {
|
||||
public:
|
||||
Dimension() = default;
|
||||
Dimension(DefinitionAtlas& defs);
|
||||
|
||||
std::shared_ptr<Region> getRegion(glm::ivec3 regionPosition);
|
||||
void removeRegion(glm::ivec3 pos);
|
||||
|
@ -29,8 +31,34 @@ public:
|
|||
protected:
|
||||
typedef std::unordered_map<glm::ivec3, std::shared_ptr<Region>, Vec::ivec3> block_region_map;
|
||||
block_region_map regions;
|
||||
DefinitionAtlas& defs;
|
||||
|
||||
private:
|
||||
inline std::shared_ptr<Region> getOrCreateRegion(glm::ivec3 pos);
|
||||
inline std::shared_ptr<MapBlock> getOrCreateMapBlock(glm::ivec3 mapBlockPosition);
|
||||
|
||||
static inline bool containsWorldPos(BlockChunk* chunk, glm::ivec3 pos);
|
||||
|
||||
inline glm::ivec3 getBlockLight(glm::ivec3 worldPos, BlockChunk* chunk = nullptr);
|
||||
inline void addLight(glm::ivec3 pos, glm::ivec3 light);
|
||||
inline void removeLight(glm::ivec3 pos);
|
||||
|
||||
void propogateAddNodes(unsigned char channel);
|
||||
void propogateRemoveNodes(unsigned char channel);
|
||||
|
||||
struct LightAddNode {
|
||||
LightAddNode(unsigned short index, BlockChunk* chunk) : index(index), chunk(chunk) {};
|
||||
unsigned short index;
|
||||
BlockChunk* chunk;
|
||||
};
|
||||
|
||||
struct LightRemoveNode {
|
||||
LightRemoveNode(unsigned short index, unsigned short value, BlockChunk* chunk) : index(index), value(value), chunk(chunk) {};
|
||||
unsigned short index;
|
||||
unsigned short value;
|
||||
BlockChunk* chunk;
|
||||
};
|
||||
|
||||
std::array<std::queue<LightAddNode>, 3> lightAddQueue;
|
||||
std::array<std::queue<LightRemoveNode>, 3> lightRemoveQueue;
|
||||
};
|
||||
|
|
|
@ -6,7 +6,9 @@
|
|||
|
||||
#include "../game/scene/world/graph/MeshChunk.h"
|
||||
|
||||
LocalDimension::LocalDimension(ClientGame &defs) : defs(defs), meshGenStream(std::make_unique<MeshGenStream>(defs, *this)) {}
|
||||
LocalDimension::LocalDimension(ClientGame &game) : Dimension(game.defs),
|
||||
meshGenStream(std::make_unique<MeshGenStream>(game, *this)),
|
||||
game(game) {}
|
||||
|
||||
void LocalDimension::update(double delta, glm::vec3 playerPos) {
|
||||
finishMeshes();
|
||||
|
@ -182,7 +184,7 @@ void LocalDimension::serverEntityInfo(PacketView& p) {
|
|||
luaEntity.setDisplayType(displayMode, displayArg1, displayArg2);
|
||||
}
|
||||
else {
|
||||
auto entity = std::make_shared<ServerLocalLuaEntity>(id, defs, displayMode, displayArg1, displayArg2);
|
||||
auto entity = std::make_shared<ServerLocalLuaEntity>(id, game, displayMode, displayArg1, displayArg2);
|
||||
entity->entity->setPos(position);
|
||||
entity->entity->setVisualOffset(visualOffset);
|
||||
entity->entity->interpRotateX(rotation.x);
|
||||
|
|
|
@ -5,10 +5,11 @@
|
|||
#pragma once
|
||||
|
||||
#include "Dimension.h"
|
||||
|
||||
#include "../lua/api/class/LocalLuaEntity.h"
|
||||
#include "../lua/api/class/ServerLocalLuaEntity.h"
|
||||
#include "../game/entity/engine/PlayerEntity.h"
|
||||
#include "../game/scene/world/MeshGenStream.h"
|
||||
#include "../game/entity/engine/PlayerEntity.h"
|
||||
#include "../lua/api/class/ServerLocalLuaEntity.h"
|
||||
#include "../game/scene/world/graph/ChunkRenderElem.h"
|
||||
|
||||
class MeshChunk;
|
||||
|
@ -18,7 +19,7 @@ public:
|
|||
const static int MB_STORE_H = 6;
|
||||
const static int MB_STORE_V = 4;
|
||||
|
||||
explicit LocalDimension(ClientGame& defs);
|
||||
explicit LocalDimension(ClientGame& game);
|
||||
void update(double delta, glm::vec3 playerPos);
|
||||
|
||||
void setChunk(std::shared_ptr<BlockChunk> chunk) override;
|
||||
|
@ -50,7 +51,7 @@ private:
|
|||
void attemptMeshChunk(const std::shared_ptr<BlockChunk>& chunk, bool updateAdjacents = true);
|
||||
bool getAdjacentExists(glm::vec3 pos, bool updateAdjacents);
|
||||
|
||||
ClientGame& defs;
|
||||
ClientGame& game;
|
||||
|
||||
std::unique_ptr<MeshGenStream> meshGenStream = nullptr;
|
||||
std::vector<glm::vec3> pendingMesh {};
|
||||
|
|
|
@ -2,10 +2,13 @@
|
|||
// Created by aurailus on 01/10/19.
|
||||
//
|
||||
|
||||
#include "ServerDimension.h"
|
||||
|
||||
#include "../def/gen/MapGen.h"
|
||||
#include "../server/conn/ServerClient.h"
|
||||
#include "../server/world/ServerWorld.h"
|
||||
#include "ServerDimension.h"
|
||||
|
||||
ServerDimension::ServerDimension(ServerGame &game) : Dimension(game.defs), game(game) {}
|
||||
|
||||
void ServerDimension::update(const std::vector<std::shared_ptr<ServerClient>> &clients) {
|
||||
for (const auto& region : regions) {
|
||||
|
@ -79,4 +82,4 @@ const std::list<unsigned int> &ServerDimension::getRemovedEntities() const {
|
|||
|
||||
void ServerDimension::clearRemovedEntities() {
|
||||
removedEntities.clear();
|
||||
}
|
||||
}
|
|
@ -12,7 +12,7 @@ class ServerClient;
|
|||
|
||||
class ServerDimension : public Dimension {
|
||||
public:
|
||||
ServerDimension() = default;
|
||||
ServerDimension(ServerGame& game);
|
||||
|
||||
void update(const std::vector<std::shared_ptr<ServerClient>>& clients);
|
||||
|
||||
|
@ -27,6 +27,8 @@ public:
|
|||
const std::list<unsigned int>& getRemovedEntities() const;
|
||||
void clearRemovedEntities();
|
||||
private:
|
||||
ServerGame& game;
|
||||
|
||||
typedef std::list<std::shared_ptr<ServerLuaEntity>>::iterator luaent_ref;
|
||||
|
||||
std::unordered_map<unsigned int, luaent_ref> luaEntityRefs {};
|
||||
|
|
|
@ -19,6 +19,7 @@ BlockChunk::BlockChunk(const std::vector<unsigned int>& blocks, const std::vecto
|
|||
biomes(std::move(biomes)),
|
||||
pos(pos),
|
||||
generated(true) {
|
||||
memset(light.data(), 0, sizeof(light));
|
||||
calcNonAirBlocks();
|
||||
}
|
||||
|
||||
|
@ -59,6 +60,16 @@ Packet BlockChunk::serialize() {
|
|||
temp = Serializer().append(biomes).data;
|
||||
s.append<std::string>(gzip::compress(temp.data(), temp.size()));
|
||||
|
||||
std::vector<unsigned char> lights {};
|
||||
lights.resize(4096 * 3);
|
||||
for (unsigned short i = 0; i < 4096; i++) {
|
||||
lights[i * 3] = this->light[i].r;
|
||||
lights[i * 3 + 1] = this->light[i].g;
|
||||
lights[i * 3 + 2] = this->light[i].b;
|
||||
}
|
||||
temp = Serializer().append(lights).data;
|
||||
s.append<std::string>(gzip::compress(temp.data(), temp.size()));
|
||||
|
||||
return s.packet(PacketType::CHUNK);
|
||||
}
|
||||
|
||||
|
@ -78,6 +89,18 @@ void BlockChunk::deserialize(PacketView& packet) {
|
|||
gzip = gzip::decompress(gzip.data(), gzip.length());
|
||||
|
||||
biomes = Deserializer(gzip).read<std::vector<unsigned short>>();
|
||||
|
||||
gzip = packet.d.read<std::string>();
|
||||
if (!gzip::is_compressed(gzip.data(), gzip.length())) throw "Invalid Light GZip Data.";
|
||||
gzip = gzip::decompress(gzip.data(), gzip.length());
|
||||
|
||||
auto lightsVec = Deserializer(gzip).read<std::vector<unsigned char>>();
|
||||
for (unsigned int i = 0; i < 4096; i++) {
|
||||
light[i].r = lightsVec[i * 3];
|
||||
light[i].g = lightsVec[i * 3 + 1];
|
||||
light[i].b = lightsVec[i * 3 + 2];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void BlockChunk::calcNonAirBlocks() {
|
||||
|
|
|
@ -35,10 +35,14 @@ public:
|
|||
inline unsigned short getBiome(const glm::ivec3& pos) const;
|
||||
|
||||
inline void setSunlight(unsigned int ind, unsigned char val);
|
||||
inline void setBlocklight(unsigned int ind, unsigned char val);
|
||||
inline void setBlockLight(unsigned int ind, glm::ivec3 light);
|
||||
inline void setBlockLight(unsigned int ind, unsigned char channel, unsigned char light);
|
||||
|
||||
inline int getSunlight(unsigned int ind);
|
||||
inline int getBlocklight(unsigned int ind);
|
||||
inline unsigned char getSunlight(unsigned int ind);
|
||||
inline glm::ivec3 getBlockLight(unsigned int ind);
|
||||
inline unsigned char getBlockLight(unsigned int ind, unsigned char channel);
|
||||
|
||||
inline glm::vec4 getLightVec(unsigned int ind);
|
||||
|
||||
const std::vector<unsigned int>& cGetBlocks() const;
|
||||
const std::vector<unsigned short>& cGetBiomes() const;
|
||||
|
@ -53,9 +57,16 @@ public:
|
|||
|
||||
glm::ivec3 pos;
|
||||
private:
|
||||
struct light_bits {
|
||||
// 16 bits - 1 short
|
||||
unsigned char r: 5;
|
||||
unsigned char g: 5;
|
||||
unsigned char b: 5, :1;
|
||||
};
|
||||
|
||||
std::vector<unsigned int> blocks {};
|
||||
std::vector<unsigned short> biomes {};
|
||||
std::array<unsigned char, 4096> lighting {};
|
||||
std::array <light_bits, 4096> light {};
|
||||
|
||||
bool empty = true;
|
||||
bool partial = false;
|
||||
|
@ -100,17 +111,34 @@ inline unsigned short BlockChunk::getBiome(const glm::ivec3& pos) const {
|
|||
}
|
||||
|
||||
inline void BlockChunk::setSunlight(unsigned int ind, unsigned char val) {
|
||||
lighting[ind] = (lighting[ind] & 0xF) | (val << 4);
|
||||
}
|
||||
|
||||
inline void BlockChunk::setBlocklight(unsigned int ind, unsigned char val) {
|
||||
lighting[ind] = (lighting[ind] & 0xF0) | val;
|
||||
inline void BlockChunk::setBlockLight(unsigned int ind, glm::ivec3 l) {
|
||||
light[ind].r = l.x;
|
||||
light[ind].g = l.y;
|
||||
light[ind].b = l.z;
|
||||
}
|
||||
|
||||
inline int BlockChunk::getSunlight(unsigned int ind) {
|
||||
return (lighting[ind] >> 4) & 0xF;
|
||||
inline void BlockChunk::setBlockLight(unsigned int ind, unsigned char channel, unsigned char l){
|
||||
channel == 0 ? light[ind].r = l :
|
||||
channel == 1 ? light[ind].g = l :
|
||||
light[ind].b = l;
|
||||
}
|
||||
|
||||
inline int BlockChunk::getBlocklight(unsigned int ind) {
|
||||
return (lighting[ind]) & 0xF;
|
||||
inline unsigned char BlockChunk::getSunlight(unsigned int ind) {
|
||||
return 15;
|
||||
}
|
||||
|
||||
inline glm::ivec3 BlockChunk::getBlockLight(unsigned int ind) {
|
||||
return { light[ind].r, light[ind].g, light[ind].b };
|
||||
}
|
||||
|
||||
inline unsigned char BlockChunk::getBlockLight(unsigned int ind, unsigned char channel) {
|
||||
return channel == 0 ? light[ind].r :
|
||||
channel == 1 ? light[ind].g :
|
||||
light[ind].b;
|
||||
}
|
||||
|
||||
inline glm::vec4 BlockChunk::getLightVec(unsigned int ind) {
|
||||
return glm::vec4 { light[ind].r, light[ind].g, light[ind].b, getSunlight(ind) };
|
||||
}
|
|
@ -6,5 +6,6 @@ zepha.register_block("zeus:default:cobblestone", {
|
|||
hand = 14,
|
||||
pick = 3
|
||||
},
|
||||
yields = "zeus:default:cobblestone"
|
||||
yields = "zeus:default:cobblestone",
|
||||
light_source = { 31, 16, 4 },
|
||||
})
|
|
@ -7,5 +7,6 @@ zepha.register_block("zeus:default:dirt", {
|
|||
shovel = 1,
|
||||
pick = 2
|
||||
},
|
||||
light_source = { 0, 15, 31 },
|
||||
yields = "zeus:default:dirt"
|
||||
})
|
|
@ -1,28 +1,31 @@
|
|||
local noise = {
|
||||
heightmap = {
|
||||
module = "add",
|
||||
sources = {{
|
||||
## Elevation
|
||||
module = "scale_bias",
|
||||
source = {
|
||||
module = "perlin",
|
||||
frequency = 0.002,
|
||||
octaves = 8
|
||||
},
|
||||
scale = 250,
|
||||
bias = -32
|
||||
}, {
|
||||
## Features
|
||||
module = "scale_bias",
|
||||
source = {
|
||||
module = "perlin",
|
||||
frequency = 0.2,
|
||||
octaves = 3,
|
||||
},
|
||||
scale = 6,
|
||||
bias = 6
|
||||
}}
|
||||
module = "const"
|
||||
}
|
||||
## heightmap = {
|
||||
## module = "add",
|
||||
## sources = {{
|
||||
## ## Elevation
|
||||
## module = "scale_bias",
|
||||
## source = {
|
||||
## module = "perlin",
|
||||
## frequency = 0.002,
|
||||
## octaves = 8
|
||||
## },
|
||||
## scale = 250,
|
||||
## bias = -32
|
||||
## }, {
|
||||
## ## Features
|
||||
## module = "scale_bias",
|
||||
## source = {
|
||||
## module = "perlin",
|
||||
## frequency = 0.2,
|
||||
## octaves = 3,
|
||||
## },
|
||||
## scale = 6,
|
||||
## bias = 6
|
||||
## }}
|
||||
## }
|
||||
}
|
||||
|
||||
zepha.register_biome("zeus:mapgen:plains", {
|
||||
|
@ -32,7 +35,7 @@ zepha.register_biome("zeus:mapgen:plains", {
|
|||
roughness = 20/100,
|
||||
},
|
||||
blocks = {
|
||||
top = "zeus:default:grass",
|
||||
top = "zeus:default:stone",
|
||||
soil = "zeus:default:dirt",
|
||||
rock = "zeus:default:stone"
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue