Merge branch 'main' of https://github.com/MihailRis/VoxelEngine-Cpp
This commit is contained in:
commit
d11f4b7348
@ -12,6 +12,7 @@
|
||||
#include "../voxels/Chunk.h"
|
||||
#include "../typedefs.h"
|
||||
#include "../maths/voxmaths.h"
|
||||
#include "../world/World.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
@ -201,12 +202,12 @@ ubyte* WorldFiles::readChunkData(int x, int y, uint32_t& length){
|
||||
return data;
|
||||
}
|
||||
|
||||
void WorldFiles::write(const WorldInfo info, const Content* content) {
|
||||
void WorldFiles::write(const World* world, const Content* content) {
|
||||
path directory = getRegionsFolder();
|
||||
if (!std::filesystem::is_directory(directory)) {
|
||||
std::filesystem::create_directories(directory);
|
||||
}
|
||||
writeWorldInfo(info);
|
||||
writeWorldInfo(world);
|
||||
if (generatorTestMode)
|
||||
return;
|
||||
writeIndices(content->indices);
|
||||
@ -232,23 +233,23 @@ void WorldFiles::writeIndices(const ContentIndices* indices) {
|
||||
}
|
||||
}
|
||||
|
||||
void WorldFiles::writeWorldInfo(const WorldInfo& info) {
|
||||
void WorldFiles::writeWorldInfo(const World* world) {
|
||||
BinaryWriter out;
|
||||
out.putCStr(WORLD_FORMAT_MAGIC);
|
||||
out.put(WORLD_FORMAT_VERSION);
|
||||
|
||||
out.put(WORLD_SECTION_MAIN);
|
||||
out.putInt64(info.seed);
|
||||
out.put(info.name);
|
||||
out.putInt64(world->seed);
|
||||
out.put(world->name);
|
||||
|
||||
out.put(WORLD_SECTION_DAYNIGHT);
|
||||
out.putFloat32(info.daytime);
|
||||
out.putFloat32(info.daytimeSpeed);
|
||||
out.putFloat32(world->daytime);
|
||||
out.putFloat32(world->daytimeSpeed);
|
||||
|
||||
files::write_bytes(getWorldFile(), (const char*)out.data(), out.size());
|
||||
}
|
||||
|
||||
bool WorldFiles::readWorldInfo(WorldInfo& info) {
|
||||
bool WorldFiles::readWorldInfo(World* world) {
|
||||
size_t length = 0;
|
||||
ubyte* data = (ubyte*)files::read_bytes(getWorldFile(), length);
|
||||
if (data == nullptr){
|
||||
@ -262,12 +263,12 @@ bool WorldFiles::readWorldInfo(WorldInfo& info) {
|
||||
ubyte section = inp.get();
|
||||
switch (section) {
|
||||
case WORLD_SECTION_MAIN:
|
||||
info.seed = inp.getInt64();
|
||||
info.name = inp.getString();
|
||||
world->seed = inp.getInt64();
|
||||
world->name = inp.getString();
|
||||
break;
|
||||
case WORLD_SECTION_DAYNIGHT:
|
||||
info.daytime = inp.getFloat32();
|
||||
info.daytimeSpeed = inp.getFloat32();
|
||||
world->daytime = inp.getFloat32();
|
||||
world->daytimeSpeed = inp.getFloat32();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,6 +25,7 @@ class Player;
|
||||
class Chunk;
|
||||
class Content;
|
||||
class ContentIndices;
|
||||
class World;
|
||||
|
||||
struct WorldRegion {
|
||||
ubyte** chunksData;
|
||||
@ -32,16 +33,8 @@ struct WorldRegion {
|
||||
bool unsaved;
|
||||
};
|
||||
|
||||
struct WorldInfo {
|
||||
std::string name;
|
||||
std::filesystem::path directory;
|
||||
uint64_t seed;
|
||||
float daytime;
|
||||
float daytimeSpeed;
|
||||
};
|
||||
|
||||
class WorldFiles {
|
||||
void writeWorldInfo(const WorldInfo& info);
|
||||
void writeWorldInfo(const World* world);
|
||||
std::filesystem::path getRegionsFolder() const;
|
||||
std::filesystem::path getRegionFile(int x, int y) const;
|
||||
std::filesystem::path getPlayerFile() const;
|
||||
@ -58,13 +51,13 @@ public:
|
||||
|
||||
void put(Chunk* chunk);
|
||||
|
||||
bool readWorldInfo(WorldInfo& info);
|
||||
bool readWorldInfo(World* world);
|
||||
bool readPlayer(Player* player);
|
||||
ubyte* readChunkData(int x, int y, uint32_t& length);
|
||||
ubyte* getChunk(int x, int y);
|
||||
void writeRegion(int x, int y, WorldRegion& entry);
|
||||
void writePlayer(Player* player);
|
||||
void write(const WorldInfo info, const Content* content);
|
||||
void write(const World* world, const Content* content);
|
||||
void writeIndices(const ContentIndices* indices);
|
||||
};
|
||||
|
||||
|
||||
@ -30,6 +30,7 @@ toml::Wrapper create_wrapper(EngineSettings& settings) {
|
||||
toml::Section& graphics = wrapper.add("graphics");
|
||||
graphics.add("fog-curve", &settings.graphics.fogCurve);
|
||||
graphics.add("backlight", &settings.graphics.backlight);
|
||||
graphics.add("frustum-culling", &settings.graphics.frustumCulling);
|
||||
|
||||
toml::Section& debug = wrapper.add("debug");
|
||||
debug.add("generator-test-mode", &settings.debug.generatorTestMode);
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
#include "world_render.h"
|
||||
#include "WorldRenderer.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <GL/glew.h>
|
||||
@ -22,7 +22,7 @@
|
||||
#include "../world/LevelEvents.h"
|
||||
#include "../objects/Player.h"
|
||||
#include "../assets/Assets.h"
|
||||
#include "../objects/player_control.h"
|
||||
#include "../logic/PlayerController.h"
|
||||
#include "../maths/FrustumCulling.h"
|
||||
#include "../maths/voxmaths.h"
|
||||
#include "../settings.h"
|
||||
@ -32,20 +32,26 @@
|
||||
|
||||
using glm::vec3;
|
||||
using glm::vec4;
|
||||
using glm::mat4;
|
||||
using std::string;
|
||||
using std::shared_ptr;
|
||||
|
||||
WorldRenderer::WorldRenderer(Engine* engine, Level* level, const ContentGfxCache* cache)
|
||||
: engine(engine), level(level) {
|
||||
EngineSettings& settings = engine->getSettings();
|
||||
WorldRenderer::WorldRenderer(Engine* engine,
|
||||
Level* level,
|
||||
const ContentGfxCache* cache)
|
||||
: engine(engine),
|
||||
level(level),
|
||||
frustumCulling(new Frustum()),
|
||||
lineBatch(new LineBatch()),
|
||||
renderer( new ChunksRenderer(level, cache, engine->getSettings())) {
|
||||
|
||||
lineBatch = new LineBatch(4096);
|
||||
renderer = new ChunksRenderer(level, cache, settings);
|
||||
frustumCulling = new Frustum();
|
||||
level->events->listen(EVT_CHUNK_HIDDEN, [this](lvl_event_type type, Chunk* chunk) {
|
||||
renderer->unload(chunk);
|
||||
});
|
||||
skybox = new Skybox(64, engine->getAssets()->getShader("skybox_gen"));
|
||||
level->events->listen(EVT_CHUNK_HIDDEN,
|
||||
[this](lvl_event_type type, Chunk* chunk) {
|
||||
renderer->unload(chunk);
|
||||
}
|
||||
);
|
||||
auto assets = engine->getAssets();
|
||||
skybox = new Skybox(64, assets->getShader("skybox_gen"));
|
||||
}
|
||||
|
||||
WorldRenderer::~WorldRenderer() {
|
||||
@ -55,22 +61,30 @@ WorldRenderer::~WorldRenderer() {
|
||||
delete frustumCulling;
|
||||
}
|
||||
|
||||
bool WorldRenderer::drawChunk(size_t index, Camera* camera, Shader* shader, bool occlusion){
|
||||
shared_ptr<Chunk> chunk = level->chunks->chunks[index];
|
||||
if (!chunk->isLighted())
|
||||
bool WorldRenderer::drawChunk(size_t index,
|
||||
Camera* camera,
|
||||
Shader* shader,
|
||||
bool culling){
|
||||
auto chunk = level->chunks->chunks[index];
|
||||
if (!chunk->isLighted()) {
|
||||
return false;
|
||||
}
|
||||
shared_ptr<Mesh> mesh = renderer->getOrRender(chunk.get());
|
||||
if (mesh == nullptr)
|
||||
if (mesh == nullptr) {
|
||||
return false;
|
||||
|
||||
// Simple frustum culling
|
||||
if (occlusion){
|
||||
vec3 min(chunk->x * CHUNK_W, chunk->bottom, chunk->z * CHUNK_D);
|
||||
vec3 max(chunk->x * CHUNK_W + CHUNK_W, chunk->top, chunk->z * CHUNK_D + CHUNK_D);
|
||||
}
|
||||
if (culling){
|
||||
vec3 min(chunk->x * CHUNK_W,
|
||||
chunk->bottom,
|
||||
chunk->z * CHUNK_D);
|
||||
vec3 max(chunk->x * CHUNK_W + CHUNK_W,
|
||||
chunk->top,
|
||||
chunk->z * CHUNK_D + CHUNK_D);
|
||||
|
||||
if (!frustumCulling->IsBoxVisible(min, max)) return false;
|
||||
}
|
||||
mat4 model = glm::translate(mat4(1.0f), vec3(chunk->x*CHUNK_W, 0.0f, chunk->z*CHUNK_D+1));
|
||||
vec3 coord = vec3(chunk->x*CHUNK_W, 0.0f, chunk->z*CHUNK_D+1);
|
||||
mat4 model = glm::translate(mat4(1.0f), coord);
|
||||
shader->uniformMatrix("u_model", model);
|
||||
mesh->draw();
|
||||
return true;
|
||||
@ -78,8 +92,7 @@ bool WorldRenderer::drawChunk(size_t index, Camera* camera, Shader* shader, bool
|
||||
|
||||
void WorldRenderer::drawChunks(Chunks* chunks,
|
||||
Camera* camera,
|
||||
Shader* shader,
|
||||
bool occlusion) {
|
||||
Shader* shader) {
|
||||
std::vector<size_t> indices;
|
||||
for (size_t i = 0; i < chunks->volume; i++){
|
||||
shared_ptr<Chunk> chunk = chunks->chunks[i];
|
||||
@ -87,25 +100,30 @@ void WorldRenderer::drawChunks(Chunks* chunks,
|
||||
continue;
|
||||
indices.push_back(i);
|
||||
}
|
||||
|
||||
float px = camera->position.x / (float)CHUNK_W;
|
||||
float pz = camera->position.z / (float)CHUNK_D;
|
||||
std::sort(indices.begin(), indices.end(), [this, chunks, px, pz](size_t i, size_t j) {
|
||||
shared_ptr<Chunk> a = chunks->chunks[i];
|
||||
shared_ptr<Chunk> b = chunks->chunks[j];
|
||||
return ((a->x + 0.5f - px)*(a->x + 0.5f - px) + (a->z + 0.5f - pz)*(a->z + 0.5f - pz) >
|
||||
(b->x + 0.5f - px)*(b->x + 0.5f - px) + (b->z + 0.5f - pz)*(b->z + 0.5f - pz));
|
||||
return ((a->x + 0.5f - px)*(a->x + 0.5f - px) +
|
||||
(a->z + 0.5f - pz)*(a->z + 0.5f - pz)
|
||||
>
|
||||
(b->x + 0.5f - px)*(b->x + 0.5f - px) +
|
||||
(b->z + 0.5f - pz)*(b->z + 0.5f - pz));
|
||||
});
|
||||
|
||||
if (occlusion) frustumCulling->update(camera->getProjView());
|
||||
bool culling = engine->getSettings().graphics.frustumCulling;
|
||||
if (culling) {
|
||||
frustumCulling->update(camera->getProjView());
|
||||
}
|
||||
chunks->visible = 0;
|
||||
for (size_t i = 0; i < indices.size(); i++){
|
||||
chunks->visible += drawChunk(indices[i], camera, shader, occlusion);
|
||||
chunks->visible += drawChunk(indices[i], camera, shader, culling);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void WorldRenderer::draw(const GfxContext& pctx, Camera* camera, bool occlusion){
|
||||
void WorldRenderer::draw(const GfxContext& pctx, Camera* camera){
|
||||
EngineSettings& settings = engine->getSettings();
|
||||
skybox->refresh(level->world->daytime,
|
||||
fmax(1.0f, 18.0f/settings.chunks.loadDistance), 4);
|
||||
@ -123,6 +141,7 @@ void WorldRenderer::draw(const GfxContext& pctx, Camera* camera, bool occlusion)
|
||||
Window::clearDepth();
|
||||
Window::viewport(0, 0, displayWidth, displayHeight);
|
||||
|
||||
// Drawing background sky plane
|
||||
Shader* backShader = assets->getShader("background");
|
||||
backShader->use();
|
||||
backShader->uniformMatrix("u_view", camera->getView(false));
|
||||
@ -137,8 +156,8 @@ void WorldRenderer::draw(const GfxContext& pctx, Camera* camera, bool occlusion)
|
||||
|
||||
float fogFactor = 18.0f / (float)settings.chunks.loadDistance;
|
||||
|
||||
// Setting up main shader
|
||||
shader->use();
|
||||
skybox->bind();
|
||||
shader->uniformMatrix("u_proj", camera->getProjection());
|
||||
shader->uniformMatrix("u_view", camera->getView());
|
||||
shader->uniform1f("u_gamma", 1.0f);
|
||||
@ -146,34 +165,37 @@ void WorldRenderer::draw(const GfxContext& pctx, Camera* camera, bool occlusion)
|
||||
shader->uniform1f("u_fogCurve", settings.graphics.fogCurve);
|
||||
shader->uniform3f("u_cameraPos", camera->position);
|
||||
shader->uniform1i("u_cubemap", 1);
|
||||
{
|
||||
blockid_t id = level->player->choosenBlock;
|
||||
Block* block = contentIds->getBlockDef(id);
|
||||
assert(block != nullptr);
|
||||
float multiplier = 0.5f;
|
||||
shader->uniform3f("u_torchlightColor",
|
||||
block->emission[0] / 15.0f * multiplier,
|
||||
block->emission[1] / 15.0f * multiplier,
|
||||
block->emission[2] / 15.0f * multiplier);
|
||||
shader->uniform1f("u_torchlightDistance", 6.0f);
|
||||
}
|
||||
|
||||
Block* cblock = contentIds->getBlockDef(level->player->choosenBlock);
|
||||
assert(cblock != nullptr);
|
||||
float multiplier = 0.5f;
|
||||
shader->uniform3f("u_torchlightColor",
|
||||
cblock->emission[0] / 15.0f * multiplier,
|
||||
cblock->emission[1] / 15.0f * multiplier,
|
||||
cblock->emission[2] / 15.0f * multiplier);
|
||||
shader->uniform1f("u_torchlightDistance", 6.0f);
|
||||
// Binding main shader textures
|
||||
skybox->bind();
|
||||
atlas->getTexture()->bind();
|
||||
|
||||
Chunks* chunks = level->chunks;
|
||||
drawChunks(chunks, camera, shader, occlusion);
|
||||
drawChunks(level->chunks, camera, shader);
|
||||
|
||||
shader->uniformMatrix("u_model", mat4(1.0f));
|
||||
|
||||
if (level->playerController->selectedBlockId != -1){
|
||||
Block* block = contentIds->getBlockDef(level->playerController->selectedBlockId);
|
||||
// Selected block
|
||||
if (PlayerController::selectedBlockId != -1){
|
||||
blockid_t id = PlayerController::selectedBlockId;
|
||||
Block* block = contentIds->getBlockDef(id);
|
||||
assert(block != nullptr);
|
||||
vec3 pos = level->playerController->selectedBlockPosition;
|
||||
linesShader->use();
|
||||
linesShader->uniformMatrix("u_projview", camera->getProjView());
|
||||
lineBatch->lineWidth(2.0f);
|
||||
|
||||
const vec3 pos = PlayerController::selectedBlockPosition;
|
||||
const AABB& hitbox = block->hitbox;
|
||||
const vec3 center = pos + hitbox.center();
|
||||
const vec3 size = hitbox.size();
|
||||
lineBatch->box(center, size + vec3(0.02), vec4(0.0f, 0.0f, 0.0f, 0.5f));
|
||||
linesShader->use();
|
||||
linesShader->uniformMatrix("u_projview", camera->getProjView());
|
||||
lineBatch->lineWidth(2.0f);
|
||||
lineBatch->box(center, size + vec3(0.02), vec4(0.f, 0.f, 0.f, 0.5f));
|
||||
lineBatch->render();
|
||||
}
|
||||
skybox->unbind();
|
||||
@ -191,44 +213,12 @@ void WorldRenderer::draw(const GfxContext& pctx, Camera* camera, bool occlusion)
|
||||
if (coord.z < 0) coord.z--;
|
||||
int cx = floordiv((int)coord.x, CHUNK_W);
|
||||
int cz = floordiv((int)coord.z, CHUNK_D);
|
||||
/*corner*/ {
|
||||
lineBatch->line( cx * CHUNK_W, 0, cz * CHUNK_D,
|
||||
cx * CHUNK_W, CHUNK_H, cz * CHUNK_D, 0.8f, 0, 0.8f, 1);
|
||||
lineBatch->line( cx * CHUNK_W, 0, (cz+1) * CHUNK_D,
|
||||
cx * CHUNK_W, CHUNK_H, (cz+1) * CHUNK_D, 0.8f, 0, 0.8f, 1);
|
||||
lineBatch->line((cx+1) * CHUNK_W, 0, cz * CHUNK_D,
|
||||
(cx+1) * CHUNK_W, CHUNK_H, cz * CHUNK_D, 0.8f, 0, 0.8f, 1);
|
||||
lineBatch->line((cx+1) * CHUNK_W, 0, (cz+1) * CHUNK_D,
|
||||
(cx+1) * CHUNK_W, CHUNK_H, (cz+1) * CHUNK_D, 0.8f, 0, 0.8f, 1);
|
||||
}
|
||||
for (int i = 2; i < CHUNK_W; i+=2) {
|
||||
lineBatch->line( cx * CHUNK_W + i, 0, cz * CHUNK_D,
|
||||
cx * CHUNK_W + i, CHUNK_H, cz * CHUNK_D, 0, 0, 0.8f, 1);
|
||||
lineBatch->line( cx * CHUNK_W + i, 0, (cz+1) * CHUNK_D,
|
||||
cx * CHUNK_W + i, CHUNK_H, (cz+1) * CHUNK_D, 0, 0, 0.8f, 1);
|
||||
}
|
||||
for (int i = 2; i < CHUNK_D; i+=2) {
|
||||
lineBatch->line( cx * CHUNK_W, 0, cz * CHUNK_D + i,
|
||||
cx * CHUNK_W, CHUNK_H, cz * CHUNK_D + i, 0.8f, 0, 0, 1);
|
||||
lineBatch->line((cx+1) * CHUNK_W, 0, cz * CHUNK_D + i,
|
||||
(cx+1) * CHUNK_W, CHUNK_H, cz * CHUNK_D + i, 0.8f, 0, 0, 1);
|
||||
}
|
||||
for (int i=0; i < CHUNK_H; i+=2){
|
||||
lineBatch->line( cx * CHUNK_W, i, cz * CHUNK_D,
|
||||
cx * CHUNK_W, i, (cz+1) * CHUNK_D, 0, 0.8f, 0, 1);
|
||||
lineBatch->line( cx * CHUNK_W, i, (cz+1) * CHUNK_D,
|
||||
(cx+1) * CHUNK_W, i, (cz+1) * CHUNK_D, 0, 0.8f, 0, 1);
|
||||
lineBatch->line((cx+1) * CHUNK_W, i, (cz+1) * CHUNK_D,
|
||||
(cx+1) * CHUNK_W, i, cz * CHUNK_D, 0, 0.8f, 0, 1);
|
||||
lineBatch->line((cx+1) * CHUNK_W, i, cz * CHUNK_D,
|
||||
cx * CHUNK_W, i, cz * CHUNK_D, 0, 0.8f, 0, 1);
|
||||
|
||||
}
|
||||
lineBatch->render();
|
||||
drawBorders(cx * CHUNK_W, 0, cz * CHUNK_D,
|
||||
(cx + 1) * CHUNK_W, CHUNK_H, (cz + 1) * CHUNK_D);
|
||||
}
|
||||
|
||||
float length = 40.f;
|
||||
// top-right: vec3 tsl = vec3(displayWidth - length - 4, -length - 4, 0.f);
|
||||
vec3 tsl = vec3(displayWidth/2, displayHeight/2, 0.f);
|
||||
glm::mat4 model(glm::translate(glm::mat4(1.f), tsl));
|
||||
linesShader->uniformMatrix("u_projview", glm::ortho(
|
||||
@ -251,3 +241,41 @@ void WorldRenderer::draw(const GfxContext& pctx, Camera* camera, bool occlusion)
|
||||
lineBatch->render();
|
||||
}
|
||||
}
|
||||
|
||||
void WorldRenderer::drawBorders(int sx, int sy, int sz, int ex, int ey, int ez) {
|
||||
int ww = ex-sx;
|
||||
int dd = ez-sz;
|
||||
/*corner*/ {
|
||||
lineBatch->line(sx, sy, sz,
|
||||
sx, ey, sz, 0.8f, 0, 0.8f, 1);
|
||||
lineBatch->line(sx, sy, ez,
|
||||
sx, ey, ez, 0.8f, 0, 0.8f, 1);
|
||||
lineBatch->line(ex, sy, sz,
|
||||
ex, ey, sz, 0.8f, 0, 0.8f, 1);
|
||||
lineBatch->line(ex, sy, ez,
|
||||
ex, ey, ez, 0.8f, 0, 0.8f, 1);
|
||||
}
|
||||
for (int i = 2; i < ww; i+=2) {
|
||||
lineBatch->line(sx + i, sy, sz,
|
||||
sx + i, ey, sz, 0, 0, 0.8f, 1);
|
||||
lineBatch->line(sx + i, sy, ez,
|
||||
sx + i, ey, ez, 0, 0, 0.8f, 1);
|
||||
}
|
||||
for (int i = 2; i < dd; i+=2) {
|
||||
lineBatch->line(sx, sy, sz + i,
|
||||
sx, ey, sz + i, 0.8f, 0, 0, 1);
|
||||
lineBatch->line(ex, sy, sz + i,
|
||||
ex, ey, sz + i, 0.8f, 0, 0, 1);
|
||||
}
|
||||
for (int i = sy; i < ey; i+=2){
|
||||
lineBatch->line(sx, i, sz,
|
||||
sx, i, ez, 0, 0.8f, 0, 1);
|
||||
lineBatch->line(sx, i, ez,
|
||||
ex, i, ez, 0, 0.8f, 0, 1);
|
||||
lineBatch->line(ex, i, ez,
|
||||
ex, i, sz, 0, 0.8f, 0, 1);
|
||||
lineBatch->line(ex, i, sz,
|
||||
sx, i, sz, 0, 0.8f, 0, 1);
|
||||
}
|
||||
lineBatch->render();
|
||||
}
|
||||
@ -31,14 +31,15 @@ class WorldRenderer {
|
||||
LineBatch* lineBatch;
|
||||
ChunksRenderer* renderer;
|
||||
Skybox* skybox;
|
||||
bool drawChunk(size_t index, Camera* camera, Shader* shader, bool occlusion);
|
||||
void drawChunks(Chunks* chunks, Camera* camera, Shader* shader, bool occlusion);
|
||||
bool drawChunk(size_t index, Camera* camera, Shader* shader, bool culling);
|
||||
void drawChunks(Chunks* chunks, Camera* camera, Shader* shader);
|
||||
public:
|
||||
WorldRenderer(Engine* engine, Level* level, const ContentGfxCache* cache);
|
||||
~WorldRenderer();
|
||||
|
||||
void draw(const GfxContext& context, Camera* camera, bool occlusion);
|
||||
void draw(const GfxContext& context, Camera* camera);
|
||||
void drawDebug(const GfxContext& context, Camera* camera);
|
||||
void drawBorders(int sx, int sy, int sz, int ex, int ey, int ez);
|
||||
};
|
||||
|
||||
|
||||
@ -35,7 +35,7 @@
|
||||
#include "gui/GUI.h"
|
||||
#include "ContentGfxCache.h"
|
||||
#include "screens.h"
|
||||
#include "world_render.h"
|
||||
#include "WorldRenderer.h"
|
||||
#include "../engine.h"
|
||||
#include "../core_defs.h"
|
||||
|
||||
@ -81,8 +81,10 @@ HudRenderer::HudRenderer(Engine* engine,
|
||||
panel->add(shared_ptr<Label>(create_label([this](){
|
||||
return L"meshes: " + std::to_wstring(Mesh::meshesCount);
|
||||
})));
|
||||
panel->add(shared_ptr<Label>(create_label([this](){
|
||||
return L"occlusion: "+wstring(this->occlusion ? L"on" : L"off");
|
||||
panel->add(shared_ptr<Label>(create_label([=](){
|
||||
auto& settings = engine->getSettings();
|
||||
bool culling = settings.graphics.frustumCulling;
|
||||
return L"frustum-culling: "+wstring(culling ? L"on" : L"off");
|
||||
})));
|
||||
panel->add(shared_ptr<Label>(create_label([this, level]() {
|
||||
return L"chunks: "+std::to_wstring(this->level->chunks->chunksCount)+
|
||||
@ -178,8 +180,7 @@ HudRenderer::~HudRenderer() {
|
||||
delete uicamera;
|
||||
}
|
||||
|
||||
void HudRenderer::drawDebug(int fps, bool occlusion){
|
||||
this->occlusion = occlusion;
|
||||
void HudRenderer::drawDebug(int fps){
|
||||
this->fps = fps;
|
||||
fpsMin = min(fps, fpsMin);
|
||||
fpsMax = max(fps, fpsMax);
|
||||
|
||||
@ -31,7 +31,6 @@ class HudRenderer {
|
||||
int fpsMin = 60;
|
||||
int fpsMax = 60;
|
||||
std::wstring fpsString;
|
||||
bool occlusion;
|
||||
bool inventoryOpen = false;
|
||||
bool pause = false;
|
||||
|
||||
@ -49,7 +48,7 @@ public:
|
||||
void update();
|
||||
void drawContentAccess(const GfxContext& ctx, Player* player);
|
||||
void draw(const GfxContext& context);
|
||||
void drawDebug(int fps, bool occlusion);
|
||||
void drawDebug(int fps);
|
||||
|
||||
bool isInventoryOpen() const;
|
||||
bool isPause() const;
|
||||
|
||||
@ -18,18 +18,18 @@
|
||||
#include "../world/Level.h"
|
||||
#include "../world/World.h"
|
||||
#include "../objects/Player.h"
|
||||
#include "../voxels/ChunksController.h"
|
||||
#include "../logic/ChunksController.h"
|
||||
#include "../logic/LevelController.h"
|
||||
#include "../voxels/Chunks.h"
|
||||
#include "../voxels/Chunk.h"
|
||||
#include "world_render.h"
|
||||
#include "../engine.h"
|
||||
#include "../util/stringutil.h"
|
||||
#include "../core_defs.h"
|
||||
#include "WorldRenderer.h"
|
||||
#include "hud.h"
|
||||
#include "ContentGfxCache.h"
|
||||
#include "gui/GUI.h"
|
||||
#include "gui/panels.h"
|
||||
#include "../engine.h"
|
||||
#include "../util/stringutil.h"
|
||||
#include "../core_defs.h"
|
||||
|
||||
#include "menu.h"
|
||||
|
||||
using std::string;
|
||||
@ -71,7 +71,7 @@ void MenuScreen::update(float delta) {
|
||||
|
||||
void MenuScreen::draw(float delta) {
|
||||
Window::clear();
|
||||
Window::setBgColor(vec3(0.2f, 0.2f, 0.2f));
|
||||
Window::setBgColor(vec3(0.2f));
|
||||
|
||||
uicamera->fov = Window::height;
|
||||
Shader* uishader = engine->getAssets()->getShader("ui");
|
||||
@ -88,16 +88,20 @@ void MenuScreen::draw(float delta) {
|
||||
}
|
||||
|
||||
static bool backlight;
|
||||
|
||||
LevelScreen::LevelScreen(Engine* engine, Level* level)
|
||||
: Screen(engine),
|
||||
level(level) {
|
||||
auto& settings = engine->getSettings();
|
||||
controller = new LevelController(settings, level);
|
||||
cache = new ContentGfxCache(level->content, engine->getAssets());
|
||||
worldRenderer = new WorldRenderer(engine, level, cache);
|
||||
hud = new HudRenderer(engine, level, cache, worldRenderer);
|
||||
backlight = engine->getSettings().graphics.backlight;
|
||||
backlight = settings.graphics.backlight;
|
||||
}
|
||||
|
||||
LevelScreen::~LevelScreen() {
|
||||
delete controller;
|
||||
delete hud;
|
||||
delete worldRenderer;
|
||||
delete cache;
|
||||
@ -111,8 +115,9 @@ LevelScreen::~LevelScreen() {
|
||||
}
|
||||
|
||||
void LevelScreen::updateHotkeys() {
|
||||
auto& settings = engine->getSettings();
|
||||
if (Events::jpressed(keycode::O)) {
|
||||
occlusion = !occlusion;
|
||||
settings.graphics.frustumCulling = !settings.graphics.frustumCulling;
|
||||
}
|
||||
if (Events::jpressed(keycode::F3)) {
|
||||
level->player->debug = !level->player->debug;
|
||||
@ -124,14 +129,15 @@ void LevelScreen::updateHotkeys() {
|
||||
|
||||
void LevelScreen::update(float delta) {
|
||||
gui::GUI* gui = engine->getGUI();
|
||||
EngineSettings& settings = engine->getSettings();
|
||||
|
||||
|
||||
bool inputLocked = hud->isPause() ||
|
||||
hud->isInventoryOpen() ||
|
||||
gui->isFocusCaught();
|
||||
if (!gui->isFocusCaught()) {
|
||||
updateHotkeys();
|
||||
}
|
||||
// TODO: subscribe for setting change
|
||||
EngineSettings& settings = engine->getSettings();
|
||||
if (settings.graphics.backlight != backlight) {
|
||||
level->chunks->saveAndClear();
|
||||
backlight = settings.graphics.backlight;
|
||||
@ -139,11 +145,7 @@ void LevelScreen::update(float delta) {
|
||||
if (!hud->isPause()) {
|
||||
level->world->updateTimers(delta);
|
||||
}
|
||||
level->updatePlayer(delta, !inputLocked, hud->isPause(), !inputLocked);
|
||||
level->update();
|
||||
|
||||
level->chunksController->update(settings.chunks.loadSpeed);
|
||||
|
||||
controller->update(delta, !inputLocked, hud->isPause());
|
||||
hud->update();
|
||||
}
|
||||
|
||||
@ -153,9 +155,9 @@ void LevelScreen::draw(float delta) {
|
||||
Viewport viewport(Window::width, Window::height);
|
||||
GfxContext ctx(nullptr, viewport, nullptr);
|
||||
|
||||
worldRenderer->draw(ctx, camera, occlusion);
|
||||
worldRenderer->draw(ctx, camera);
|
||||
hud->draw(ctx);
|
||||
if (level->player->debug) {
|
||||
hud->drawDebug( 1 / delta, occlusion);
|
||||
hud->drawDebug(1 / delta);
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@ class Engine;
|
||||
class Camera;
|
||||
class Batch2D;
|
||||
class ContentGfxCache;
|
||||
class LevelController;
|
||||
|
||||
/* Screen is a mainloop state */
|
||||
class Screen {
|
||||
@ -37,10 +38,10 @@ public:
|
||||
|
||||
class LevelScreen : public Screen {
|
||||
Level* level;
|
||||
LevelController* controller;
|
||||
WorldRenderer* worldRenderer;
|
||||
HudRenderer* hud;
|
||||
ContentGfxCache* cache;
|
||||
bool occlusion = true;
|
||||
void updateHotkeys();
|
||||
public:
|
||||
LevelScreen(Engine* engine, Level* level);
|
||||
|
||||
@ -307,7 +307,8 @@ vec4 BlocksRenderer::pickLight(int x, int y, int z) const {
|
||||
}
|
||||
}
|
||||
|
||||
vec4 BlocksRenderer::pickSoftLight(int x, int y, int z, const ivec3& right, const ivec3& up) const {
|
||||
vec4 BlocksRenderer::pickSoftLight(int x, int y, int z,
|
||||
const ivec3& right, const ivec3& up) const {
|
||||
return (pickLight(x - right.x - up.x, y - right.y - up.y, z - right.z - up.z) +
|
||||
pickLight(x - up.x, y - up.y, z - up.z) +
|
||||
pickLight(x, y, z) +
|
||||
@ -332,15 +333,15 @@ void BlocksRenderer::render(const voxel* voxels, int atlas_size) {
|
||||
int z = (i / CHUNK_D) % CHUNK_W;
|
||||
switch (def.model) {
|
||||
case BlockModel::block:
|
||||
if (*((uint32_t*)&def.emission)) {
|
||||
blockCube(x, y, z, vec3(1, 1, 1), texfaces, def.drawGroup);
|
||||
if (def.rt.emissive) {
|
||||
blockCube(x, y, z, vec3(1.0f), texfaces, def.drawGroup);
|
||||
}
|
||||
else {
|
||||
blockCubeShaded(x, y, z, vec3(1, 1, 1), texfaces, &def, vox.states);
|
||||
blockCubeShaded(x, y, z, vec3(1.0f), texfaces, &def, vox.states);
|
||||
}
|
||||
break;
|
||||
case BlockModel::xsprite: {
|
||||
blockXSprite(x, y, z, vec3(1, 1, 1), texfaces[FACE_MX], texfaces[FACE_MZ], 1.0f);
|
||||
blockXSprite(x, y, z, vec3(1.0f), texfaces[FACE_MX], texfaces[FACE_MZ], 1.0f);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
||||
@ -12,7 +12,7 @@ class LineBatch {
|
||||
size_t index;
|
||||
size_t capacity;
|
||||
public:
|
||||
LineBatch(size_t capacity);
|
||||
LineBatch(size_t capacity=4096);
|
||||
~LineBatch();
|
||||
|
||||
void line(float x1, float y1, float z1, float x2, float y2, float z2,
|
||||
|
||||
@ -1,9 +1,15 @@
|
||||
#include "ChunksController.h"
|
||||
#include "Block.h"
|
||||
#include "Chunk.h"
|
||||
#include "Chunks.h"
|
||||
#include "ChunksStorage.h"
|
||||
#include "WorldGenerator.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <limits.h>
|
||||
#include <memory>
|
||||
#include <chrono>
|
||||
|
||||
#include "../voxels/Block.h"
|
||||
#include "../voxels/Chunk.h"
|
||||
#include "../voxels/Chunks.h"
|
||||
#include "../voxels/ChunksStorage.h"
|
||||
#include "../voxels/WorldGenerator.h"
|
||||
#include "../content/Content.h"
|
||||
#include "../graphics/Mesh.h"
|
||||
#include "../lighting/Lighting.h"
|
||||
@ -11,10 +17,6 @@
|
||||
#include "../world/Level.h"
|
||||
#include "../world/World.h"
|
||||
#include "../maths/voxmaths.h"
|
||||
#include <iostream>
|
||||
#include <limits.h>
|
||||
#include <memory>
|
||||
#include <chrono>
|
||||
|
||||
#define MAX_WORK_PER_FRAME 16
|
||||
#define MIN_SURROUNDING 9
|
||||
@ -26,7 +28,11 @@ using std::chrono::duration_cast;
|
||||
using std::chrono::microseconds;
|
||||
|
||||
|
||||
ChunksController::ChunksController(Level* level, Chunks* chunks, Lighting* lighting, uint padding)
|
||||
ChunksController::ChunksController(
|
||||
Level* level,
|
||||
Chunks* chunks,
|
||||
Lighting* lighting,
|
||||
uint padding)
|
||||
: level(level),
|
||||
chunks(chunks),
|
||||
lighting(lighting),
|
||||
@ -11,20 +11,26 @@ class VoxelRenderer;
|
||||
class ChunksLoader;
|
||||
class WorldGenerator;
|
||||
|
||||
/* ChunksController manages chunks dynamic loading/unloading */
|
||||
class ChunksController {
|
||||
private:
|
||||
Level* level;
|
||||
Chunks* chunks;
|
||||
Lighting* lighting;
|
||||
int64_t avgDurationMcs = 1000;
|
||||
uint padding;
|
||||
WorldGenerator* generator;
|
||||
|
||||
/* Average measured microseconds duration of loadVisible call */
|
||||
int64_t avgDurationMcs = 1000;
|
||||
|
||||
/* Process one chunk: load it or calculate lights for it */
|
||||
bool loadVisible();
|
||||
public:
|
||||
ChunksController(Level* level, Chunks* chunks, Lighting* lighting, uint padding);
|
||||
~ChunksController();
|
||||
|
||||
/* @param maxDuration milliseconds reserved for chunks loading */
|
||||
void update(int64_t maxDuration);
|
||||
bool loadVisible();
|
||||
};
|
||||
|
||||
#endif /* VOXELS_CHUNKSCONTROLLER_H_ */
|
||||
29
src/logic/LevelController.cpp
Normal file
29
src/logic/LevelController.cpp
Normal file
@ -0,0 +1,29 @@
|
||||
#include "LevelController.h"
|
||||
#include "../world/Level.h"
|
||||
|
||||
#include "PlayerController.h"
|
||||
#include "ChunksController.h"
|
||||
|
||||
LevelController::LevelController(EngineSettings& settings, Level* level)
|
||||
: settings(settings), level(level) {
|
||||
chunks = new ChunksController(
|
||||
level,
|
||||
level->chunks,
|
||||
level->lighting,
|
||||
settings.chunks.padding);
|
||||
player = new PlayerController(level, settings);
|
||||
}
|
||||
|
||||
LevelController::~LevelController() {
|
||||
delete player;
|
||||
delete chunks;
|
||||
}
|
||||
|
||||
void LevelController::update(
|
||||
float delta,
|
||||
bool input,
|
||||
bool pause) {
|
||||
player->update(delta, input, pause);
|
||||
level->update();
|
||||
chunks->update(settings.chunks.loadSpeed);
|
||||
}
|
||||
31
src/logic/LevelController.h
Normal file
31
src/logic/LevelController.h
Normal file
@ -0,0 +1,31 @@
|
||||
#ifndef LOGIC_LEVEL_CONTROLLER_H_
|
||||
#define LOGIC_LEVEL_CONTROLLER_H_
|
||||
|
||||
#include "../settings.h"
|
||||
|
||||
class Level;
|
||||
class ChunksController;
|
||||
class PlayerController;
|
||||
|
||||
/* LevelController manages other controllers */
|
||||
class LevelController {
|
||||
EngineSettings& settings;
|
||||
Level* level;
|
||||
// Sub-controllers
|
||||
ChunksController* chunks;
|
||||
PlayerController* player;
|
||||
public:
|
||||
LevelController(EngineSettings& settings, Level* level);
|
||||
~LevelController();
|
||||
|
||||
/*
|
||||
@param delta time elapsed since the last update
|
||||
@param input is user input allowed to be handled
|
||||
@param pause is world and player simulation paused
|
||||
*/
|
||||
void update(float delta,
|
||||
bool input,
|
||||
bool pause);
|
||||
};
|
||||
|
||||
#endif // LOGIC_LEVEL_CONTROLLER_H_
|
||||
@ -1,6 +1,6 @@
|
||||
#include "player_control.h"
|
||||
#include "PlayerController.h"
|
||||
|
||||
#include "Player.h"
|
||||
#include "../objects/Player.h"
|
||||
#include "../physics/PhysicsSolver.h"
|
||||
#include "../physics/Hitbox.h"
|
||||
#include "../lighting/Lighting.h"
|
||||
@ -15,29 +15,123 @@
|
||||
|
||||
#include "../core_defs.h"
|
||||
|
||||
#define CROUCH_SPEED_MUL 0.25f
|
||||
#define CROUCH_SHIFT_Y -0.2f
|
||||
#define RUN_SPEED_MUL 1.5f
|
||||
#define CAM_SHAKE_OFFSET 0.025f
|
||||
#define CAM_SHAKE_OFFSET_Y 0.031f
|
||||
#define CAM_SHAKE_SPEED 1.6f
|
||||
#define CAM_SHAKE_DELTA_K 10.0f
|
||||
#define ZOOM_SPEED 16.0f
|
||||
#define CROUCH_ZOOM 0.9f
|
||||
#define RUN_ZOOM 1.1f
|
||||
#define C_ZOOM 0.1f
|
||||
#define ZOOM_SPEED 16.0f
|
||||
#define PLAYER_GROUND_DAMPING 10.0f
|
||||
#define PLAYER_AIR_DAMPING 7.0f
|
||||
#define CAMERA_SHAKING_OFFSET 0.025f
|
||||
#define CAMERA_SHAKING_OFFSET_Y 0.031f
|
||||
#define CAMERA_SHAKING_SPEED 1.6f
|
||||
#define CAMERA_SHAKING_DELTA_K 10.0f
|
||||
#define FLIGHT_SPEED_MUL 4.0f
|
||||
#define CHEAT_SPEED_MUL 5.0f
|
||||
#define JUMP_FORCE 7.0f
|
||||
#define CROUCH_SHIFT_Y -0.2f
|
||||
|
||||
PlayerController::PlayerController(Level* level, const EngineSettings& settings)
|
||||
: level(level), player(level->player), camSettings(settings.camera) {
|
||||
using glm::vec2;
|
||||
using glm::vec3;
|
||||
|
||||
CameraControl::CameraControl(Player* player, const CameraSettings& settings)
|
||||
: player(player),
|
||||
camera(player->camera),
|
||||
settings(settings),
|
||||
offset(0.0f, 0.7f, 0.0f) {
|
||||
}
|
||||
|
||||
void PlayerController::refreshCamera() {
|
||||
level->player->camera->position = level->player->hitbox->position + cameraOffset;
|
||||
void CameraControl::refresh() {
|
||||
camera->position = player->hitbox->position + offset;
|
||||
}
|
||||
|
||||
void CameraControl::updateMouse(PlayerInput& input) {
|
||||
float rotX = -Events::deltaX / Window::height * 2;
|
||||
float rotY = -Events::deltaY / Window::height * 2;
|
||||
|
||||
if (input.zoom){
|
||||
rotX /= 4;
|
||||
rotY /= 4;
|
||||
}
|
||||
|
||||
float& camX = player->camX;
|
||||
float& camY = player->camY;
|
||||
camX += rotX;
|
||||
camY += rotY;
|
||||
if (camY < -radians(89.9f)){
|
||||
camY = -radians(89.9f);
|
||||
}
|
||||
if (camY > radians(89.9f)){
|
||||
camY = radians(89.9f);
|
||||
}
|
||||
|
||||
camera->rotation = mat4(1.0f);
|
||||
camera->rotate(camY, camX, 0);
|
||||
}
|
||||
|
||||
void CameraControl::update(PlayerInput& input, float delta) {
|
||||
Hitbox* hitbox = player->hitbox;
|
||||
|
||||
offset = vec3(0.0f, 0.7f, 0.0f);
|
||||
|
||||
if (settings.shaking && !input.cheat) {
|
||||
const float k = CAM_SHAKE_DELTA_K;
|
||||
const float oh = CAM_SHAKE_OFFSET;
|
||||
const float ov = CAM_SHAKE_OFFSET_Y;
|
||||
const vec3& vel = hitbox->velocity;
|
||||
|
||||
interpVel = interpVel * (1.0f - delta * 5) + vel * delta * 0.1f;
|
||||
if (hitbox->grounded && interpVel.y < 0.0f){
|
||||
interpVel.y *= -30.0f;
|
||||
}
|
||||
shake = shake * (1.0f - delta * k);
|
||||
if (hitbox->grounded) {
|
||||
float f = length(vec2(vel.x, vel.z));
|
||||
shakeTimer += delta * f * CAM_SHAKE_SPEED;
|
||||
shake += f * delta * k;
|
||||
}
|
||||
offset += camera->right * sin(shakeTimer) * oh * shake;
|
||||
offset += camera->up * abs(cos(shakeTimer)) * ov * shake;
|
||||
offset -= glm::min(interpVel * 0.05f, 1.0f);
|
||||
}
|
||||
|
||||
if (settings.fovEvents){
|
||||
bool crouch = input.shift && hitbox->grounded && !input.sprint;
|
||||
|
||||
float dt = fmin(1.0f, delta * ZOOM_SPEED);
|
||||
float zoomValue = 1.0f;
|
||||
if (crouch){
|
||||
offset += vec3(0.f, CROUCH_SHIFT_Y, 0.f);
|
||||
zoomValue = CROUCH_ZOOM;
|
||||
} else if (input.sprint){
|
||||
zoomValue = RUN_ZOOM;
|
||||
}
|
||||
if (input.zoom)
|
||||
zoomValue *= C_ZOOM;
|
||||
camera->zoom = zoomValue * dt + camera->zoom * (1.0f - dt);
|
||||
}
|
||||
}
|
||||
|
||||
vec3 PlayerController::selectedBlockPosition;
|
||||
int PlayerController::selectedBlockId = -1;
|
||||
|
||||
PlayerController::PlayerController(Level* level, const EngineSettings& settings)
|
||||
: level(level),
|
||||
player(level->player),
|
||||
camControl(level->player, settings.camera) {
|
||||
}
|
||||
|
||||
void PlayerController::update(float delta, bool input, bool pause) {
|
||||
if (!pause) {
|
||||
if (input) {
|
||||
updateKeyboard();
|
||||
} else {
|
||||
resetKeyboard();
|
||||
}
|
||||
updateCamera(delta, input);
|
||||
updateControls(delta);
|
||||
|
||||
}
|
||||
camControl.refresh();
|
||||
if (input) {
|
||||
updateInteraction();
|
||||
} else {
|
||||
selectedBlockId = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerController::updateKeyboard() {
|
||||
@ -62,6 +156,13 @@ void PlayerController::updateKeyboard() {
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerController::updateCamera(float delta, bool movement) {
|
||||
if (movement) {
|
||||
camControl.updateMouse(input);
|
||||
}
|
||||
camControl.update(input, delta);
|
||||
}
|
||||
|
||||
void PlayerController::resetKeyboard() {
|
||||
input.zoom = false;
|
||||
input.moveForward = false;
|
||||
@ -75,142 +176,7 @@ void PlayerController::resetKeyboard() {
|
||||
}
|
||||
|
||||
void PlayerController::updateControls(float delta){
|
||||
Player* player = level->player;
|
||||
Camera* camera = player->camera;
|
||||
Hitbox* hitbox = player->hitbox;
|
||||
bool cameraShaking = camSettings.shaking;
|
||||
|
||||
bool crouch = input.shift && hitbox->grounded && !input.sprint;
|
||||
float speed = player->speed;
|
||||
|
||||
if (player->flight){
|
||||
speed *= FLIGHT_SPEED_MUL;
|
||||
}
|
||||
if (input.cheat){
|
||||
speed *= CHEAT_SPEED_MUL;
|
||||
cameraShaking = false;
|
||||
}
|
||||
|
||||
if (crouch) {
|
||||
speed *= CROUCH_SPEED_MUL;
|
||||
} else if (input.sprint) {
|
||||
speed *= RUN_SPEED_MUL;
|
||||
}
|
||||
|
||||
vec3 dir(0,0,0);
|
||||
if (input.moveForward){
|
||||
dir.x += camera->dir.x;
|
||||
dir.z += camera->dir.z;
|
||||
}
|
||||
if (input.moveBack){
|
||||
dir.x -= camera->dir.x;
|
||||
dir.z -= camera->dir.z;
|
||||
}
|
||||
if (input.moveRight){
|
||||
dir.x += camera->right.x;
|
||||
dir.z += camera->right.z;
|
||||
}
|
||||
if (input.moveLeft){
|
||||
dir.x -= camera->right.x;
|
||||
dir.z -= camera->right.z;
|
||||
}
|
||||
if (length(dir) > 0.0f){
|
||||
dir = normalize(dir);
|
||||
hitbox->velocity.x += dir.x * speed * delta * 9;
|
||||
hitbox->velocity.z += dir.z * speed * delta * 9;
|
||||
}
|
||||
|
||||
int substeps = (int)(delta * 1000);
|
||||
substeps = (substeps <= 0 ? 1 : (substeps > 100 ? 100 : substeps));
|
||||
level->physics->step(level->chunks, hitbox, delta, substeps, crouch, player->flight ? 0.0f : 1.0f, !player->noclip);
|
||||
if (player->flight && hitbox->grounded) {
|
||||
player->flight = false;
|
||||
}
|
||||
|
||||
if (input.jump && hitbox->grounded){
|
||||
hitbox->velocity.y = JUMP_FORCE;
|
||||
}
|
||||
|
||||
cameraOffset = vec3(0.0f, 0.7f, 0.0f);
|
||||
|
||||
if (cameraShaking) {
|
||||
player->interpVel = player->interpVel * (1.0f - delta * 5) + hitbox->velocity * delta * 0.1f;
|
||||
if (hitbox->grounded && player->interpVel.y < 0.0f){
|
||||
player->interpVel.y *= -30.0f;
|
||||
}
|
||||
float factor = hitbox->grounded ? length(vec2(hitbox->velocity.x, hitbox->velocity.z)) : 0.0f;
|
||||
player->cameraShakingTimer += delta * factor * CAMERA_SHAKING_SPEED;
|
||||
float shakeTimer = player->cameraShakingTimer;
|
||||
player->cameraShaking = player->cameraShaking * (1.0f - delta * CAMERA_SHAKING_DELTA_K) + factor * delta * CAMERA_SHAKING_DELTA_K;
|
||||
cameraOffset += camera->right * sin(shakeTimer) * CAMERA_SHAKING_OFFSET * player->cameraShaking;
|
||||
cameraOffset += camera->up * abs(cos(shakeTimer)) * CAMERA_SHAKING_OFFSET_Y * player->cameraShaking;
|
||||
cameraOffset -= min(player->interpVel * 0.05f, 1.0f);
|
||||
}
|
||||
|
||||
if ((input.flight && !player->noclip) ||
|
||||
(input.noclip && player->flight == player->noclip)){
|
||||
player->flight = !player->flight;
|
||||
if (player->flight){
|
||||
hitbox->grounded = false;
|
||||
}
|
||||
}
|
||||
if (input.noclip) {
|
||||
player->noclip = !player->noclip;
|
||||
}
|
||||
|
||||
if (camSettings.fovEvents){
|
||||
float dt = min(1.0f, delta * ZOOM_SPEED);
|
||||
float zoomValue = 1.0f;
|
||||
if (crouch){
|
||||
cameraOffset += vec3(0.f, CROUCH_SHIFT_Y, 0.f);
|
||||
zoomValue = CROUCH_ZOOM;
|
||||
} else if (input.sprint){
|
||||
zoomValue = RUN_ZOOM;
|
||||
}
|
||||
if (input.zoom)
|
||||
zoomValue *= C_ZOOM;
|
||||
camera->zoom = zoomValue * dt + camera->zoom * (1.0f - dt);
|
||||
}
|
||||
|
||||
hitbox->linear_damping = PLAYER_GROUND_DAMPING;
|
||||
if (player->flight){
|
||||
hitbox->linear_damping = PLAYER_AIR_DAMPING;
|
||||
hitbox->velocity.y *= 1.0f - delta * 9;
|
||||
if (input.jump){
|
||||
hitbox->velocity.y += speed * delta * 9;
|
||||
}
|
||||
if (input.shift){
|
||||
hitbox->velocity.y -= speed * delta * 9;
|
||||
}
|
||||
}
|
||||
if (!hitbox->grounded) {
|
||||
hitbox->linear_damping = PLAYER_AIR_DAMPING;
|
||||
}
|
||||
|
||||
input.noclip = false;
|
||||
input.flight = false;
|
||||
}
|
||||
|
||||
void PlayerController::updateCameraControl() {
|
||||
Camera* camera = player->camera;
|
||||
float rotX = -Events::deltaX / Window::height * 2;
|
||||
float rotY = -Events::deltaY / Window::height * 2;
|
||||
if (input.zoom){
|
||||
rotX /= 4;
|
||||
rotY /= 4;
|
||||
}
|
||||
player->camX += rotX;
|
||||
player->camY += rotY;
|
||||
|
||||
if (player->camY < -radians(89.9f)){
|
||||
player->camY = -radians(89.9f);
|
||||
}
|
||||
if (player->camY > radians(89.9f)){
|
||||
player->camY = radians(89.9f);
|
||||
}
|
||||
|
||||
camera->rotation = mat4(1.0f);
|
||||
camera->rotate(player->camY, player->camX, 0);
|
||||
player->update(level, input, delta);
|
||||
}
|
||||
|
||||
void PlayerController::updateInteraction(){
|
||||
@ -278,4 +244,4 @@ void PlayerController::updateInteraction(){
|
||||
} else {
|
||||
selectedBlockId = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
46
src/logic/PlayerController.h
Normal file
46
src/logic/PlayerController.h
Normal file
@ -0,0 +1,46 @@
|
||||
#ifndef PLAYER_CONTROL_H_
|
||||
#define PLAYER_CONTROL_H_
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include "../settings.h"
|
||||
#include "../objects/Player.h"
|
||||
|
||||
class Camera;
|
||||
class Level;
|
||||
|
||||
class CameraControl {
|
||||
Player* player;
|
||||
Camera* camera;
|
||||
const CameraSettings& settings;
|
||||
glm::vec3 offset;
|
||||
float shake = 0.0f;
|
||||
float shakeTimer = 0.0f;
|
||||
glm::vec3 interpVel {0.0f};
|
||||
public:
|
||||
CameraControl(Player* player, const CameraSettings& settings);
|
||||
void updateMouse(PlayerInput& input);
|
||||
void update(PlayerInput& input, float delta);
|
||||
void refresh();
|
||||
};
|
||||
|
||||
class PlayerController {
|
||||
Level* level;
|
||||
Player* player;
|
||||
PlayerInput input;
|
||||
CameraControl camControl;
|
||||
|
||||
void updateKeyboard();
|
||||
void updateCamera(float delta, bool movement);
|
||||
void resetKeyboard();
|
||||
void updateControls(float delta);
|
||||
void updateInteraction();
|
||||
public:
|
||||
static glm::vec3 selectedBlockPosition;
|
||||
static int selectedBlockId;
|
||||
|
||||
PlayerController(Level* level, const EngineSettings& settings);
|
||||
void update(float delta, bool input, bool pause);
|
||||
};
|
||||
|
||||
#endif /* PLAYER_CONTROL_H_ */
|
||||
@ -2,15 +2,24 @@
|
||||
#include "../physics/Hitbox.h"
|
||||
#include "../physics/PhysicsSolver.h"
|
||||
#include "../voxels/Chunks.h"
|
||||
#include "../world/Level.h"
|
||||
#include "../window/Events.h"
|
||||
#include "../window/Camera.h"
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#define CROUCH_SPEED_MUL 0.35f
|
||||
#define RUN_SPEED_MUL 1.5f
|
||||
#define PLAYER_GROUND_DAMPING 10.0f
|
||||
#define PLAYER_AIR_DAMPING 7.0f
|
||||
#define FLIGHT_SPEED_MUL 4.0f
|
||||
#define CHEAT_SPEED_MUL 5.0f
|
||||
#define JUMP_FORCE 7.0f
|
||||
|
||||
Player::Player(glm::vec3 position, float speed, Camera* camera) :
|
||||
speed(speed),
|
||||
camera(camera),
|
||||
choosenBlock(1),
|
||||
camX(0.0f), camY(0.0f){
|
||||
choosenBlock(1) {
|
||||
hitbox = new Hitbox(position, vec3(0.3f,0.9f,0.3f));
|
||||
}
|
||||
|
||||
@ -18,6 +27,96 @@ Player::~Player(){
|
||||
delete hitbox;
|
||||
}
|
||||
|
||||
void Player::update(
|
||||
Level* level,
|
||||
PlayerInput& input,
|
||||
float delta) {
|
||||
bool crouch = input.shift && hitbox->grounded && !input.sprint;
|
||||
float speed = this->speed;
|
||||
if (flight){
|
||||
speed *= FLIGHT_SPEED_MUL;
|
||||
}
|
||||
if (input.cheat){
|
||||
speed *= CHEAT_SPEED_MUL;
|
||||
}
|
||||
|
||||
if (crouch) {
|
||||
speed *= CROUCH_SPEED_MUL;
|
||||
} else if (input.sprint) {
|
||||
speed *= RUN_SPEED_MUL;
|
||||
}
|
||||
|
||||
vec3 dir(0,0,0);
|
||||
if (input.moveForward){
|
||||
dir.x += camera->dir.x;
|
||||
dir.z += camera->dir.z;
|
||||
}
|
||||
if (input.moveBack){
|
||||
dir.x -= camera->dir.x;
|
||||
dir.z -= camera->dir.z;
|
||||
}
|
||||
if (input.moveRight){
|
||||
dir.x += camera->right.x;
|
||||
dir.z += camera->right.z;
|
||||
}
|
||||
if (input.moveLeft){
|
||||
dir.x -= camera->right.x;
|
||||
dir.z -= camera->right.z;
|
||||
}
|
||||
if (length(dir) > 0.0f){
|
||||
dir = normalize(dir);
|
||||
hitbox->velocity.x += dir.x * speed * delta * 9;
|
||||
hitbox->velocity.z += dir.z * speed * delta * 9;
|
||||
}
|
||||
|
||||
int substeps = (int)(delta * 1000);
|
||||
substeps = std::min(100, std::max(0, substeps));
|
||||
level->physics->step(level->chunks, hitbox,
|
||||
delta, substeps,
|
||||
crouch, flight ? 0.0f : 1.0f,
|
||||
!noclip);
|
||||
if (flight && hitbox->grounded) {
|
||||
flight = false;
|
||||
}
|
||||
|
||||
if (input.jump && hitbox->grounded){
|
||||
hitbox->velocity.y = JUMP_FORCE;
|
||||
}
|
||||
|
||||
if ((input.flight && !noclip) ||
|
||||
(input.noclip && flight == noclip)){
|
||||
flight = !flight;
|
||||
if (flight){
|
||||
hitbox->grounded = false;
|
||||
}
|
||||
}
|
||||
if (input.noclip) {
|
||||
noclip = !noclip;
|
||||
}
|
||||
|
||||
hitbox->linear_damping = PLAYER_GROUND_DAMPING;
|
||||
if (flight){
|
||||
hitbox->linear_damping = PLAYER_AIR_DAMPING;
|
||||
hitbox->velocity.y *= 1.0f - delta * 9;
|
||||
if (input.jump){
|
||||
hitbox->velocity.y += speed * delta * 9;
|
||||
}
|
||||
if (input.shift){
|
||||
hitbox->velocity.y -= speed * delta * 9;
|
||||
}
|
||||
}
|
||||
if (!hitbox->grounded) {
|
||||
hitbox->linear_damping = PLAYER_AIR_DAMPING;
|
||||
}
|
||||
|
||||
input.noclip = false;
|
||||
input.flight = false;
|
||||
}
|
||||
|
||||
void Player::teleport(glm::vec3 position) {
|
||||
hitbox->position = position;
|
||||
}
|
||||
|
||||
float Player::getSpeed() const {
|
||||
return speed;
|
||||
}
|
||||
|
||||
@ -4,30 +4,49 @@
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include "../voxels/voxel.h"
|
||||
#include "../settings.h"
|
||||
|
||||
class Camera;
|
||||
class Hitbox;
|
||||
class PhysicsSolver;
|
||||
class Chunks;
|
||||
class Level;
|
||||
|
||||
struct PlayerInput {
|
||||
bool zoom;
|
||||
bool moveForward;
|
||||
bool moveBack;
|
||||
bool moveRight;
|
||||
bool moveLeft;
|
||||
bool sprint;
|
||||
bool shift;
|
||||
bool cheat;
|
||||
bool jump;
|
||||
bool noclip;
|
||||
bool flight;
|
||||
};
|
||||
|
||||
class Player {
|
||||
public:
|
||||
float speed;
|
||||
public:
|
||||
Camera* camera;
|
||||
Hitbox* hitbox;
|
||||
bool flight = false;
|
||||
bool noclip = false;
|
||||
bool debug = false;
|
||||
int choosenBlock;
|
||||
float camX, camY;
|
||||
float cameraShaking = 0.0f;
|
||||
float cameraShakingTimer = 0.0f;
|
||||
glm::vec3 interpVel {0.0f, 0.0f, 0.0f};
|
||||
voxel selectedVoxel {0, 0};
|
||||
|
||||
float camX = 0.0f;
|
||||
float camY = 0.0f;
|
||||
|
||||
Player(glm::vec3 position, float speed, Camera* camera);
|
||||
~Player();
|
||||
|
||||
void teleport(glm::vec3 position);
|
||||
|
||||
float getSpeed() const;
|
||||
void update(Level* level, PlayerInput& input, float delta);
|
||||
};
|
||||
|
||||
#endif /* SRC_OBJECTS_PLAYER_H_ */
|
||||
|
||||
@ -1,47 +0,0 @@
|
||||
#ifndef PLAYER_CONTROL_H_
|
||||
#define PLAYER_CONTROL_H_
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include "../settings.h"
|
||||
|
||||
class PhysicsSolver;
|
||||
class Chunks;
|
||||
class Player;
|
||||
class Level;
|
||||
|
||||
struct PlayerInput {
|
||||
bool zoom;
|
||||
bool moveForward;
|
||||
bool moveBack;
|
||||
bool moveRight;
|
||||
bool moveLeft;
|
||||
bool sprint;
|
||||
bool shift;
|
||||
bool cheat;
|
||||
bool jump;
|
||||
bool noclip;
|
||||
bool flight;
|
||||
};
|
||||
|
||||
class PlayerController {
|
||||
Level* level;
|
||||
Player* player;
|
||||
|
||||
PlayerInput input;
|
||||
|
||||
const CameraSettings& camSettings;
|
||||
public:
|
||||
glm::vec3 selectedBlockPosition;
|
||||
glm::vec3 cameraOffset {0.0f, 0.7f, 0.0f};
|
||||
int selectedBlockId = -1;
|
||||
PlayerController(Level* level, const EngineSettings& settings);
|
||||
void updateKeyboard();
|
||||
void resetKeyboard();
|
||||
void updateCameraControl();
|
||||
void updateControls(float delta);
|
||||
void updateInteraction();
|
||||
void refreshCamera();
|
||||
};
|
||||
|
||||
#endif /* PLAYER_CONTROL_H_ */
|
||||
@ -2,8 +2,6 @@
|
||||
#define PHYSICS_HITBOX_H_
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/ext.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
|
||||
using namespace glm;
|
||||
|
||||
|
||||
@ -7,41 +7,42 @@
|
||||
|
||||
#define E 0.03
|
||||
|
||||
using glm::vec3;
|
||||
|
||||
PhysicsSolver::PhysicsSolver(vec3 gravity) : gravity(gravity) {
|
||||
}
|
||||
|
||||
void PhysicsSolver::step(Chunks* chunks, Hitbox* hitbox, float delta, unsigned substeps, bool shifting,
|
||||
void PhysicsSolver::step(
|
||||
Chunks* chunks,
|
||||
Hitbox* hitbox,
|
||||
float delta,
|
||||
uint substeps,
|
||||
bool shifting,
|
||||
float gravityScale,
|
||||
bool collisions) {
|
||||
float s = 2.0/BLOCK_AABB_GRID;
|
||||
bool collisions)
|
||||
{
|
||||
float dt = delta / float(substeps);
|
||||
float linear_damping = hitbox->linear_damping;
|
||||
float s = 2.0f/BLOCK_AABB_GRID;
|
||||
|
||||
hitbox->grounded = false;
|
||||
for (unsigned i = 0; i < substeps; i++){
|
||||
float dt = delta / (float)substeps;
|
||||
float linear_damping = hitbox->linear_damping;
|
||||
for (uint i = 0; i < substeps; i++) {
|
||||
vec3& pos = hitbox->position;
|
||||
vec3& half = hitbox->halfsize;
|
||||
vec3& vel = hitbox->velocity;
|
||||
vel.x += gravity.x*dt * gravityScale;
|
||||
vel.y += gravity.y*dt * gravityScale;
|
||||
vel.z += gravity.z*dt * gravityScale;
|
||||
|
||||
float px = pos.x;
|
||||
float pz = pos.z;
|
||||
|
||||
|
||||
vel += gravity * dt * gravityScale;
|
||||
if (collisions) {
|
||||
colisionCalc(chunks, hitbox, &vel, &pos, half);
|
||||
colisionCalc(chunks, hitbox, vel, pos, half);
|
||||
}
|
||||
|
||||
vel.x *= max(0.0, 1.0 - dt * linear_damping);
|
||||
vel.z *= max(0.0, 1.0 - dt * linear_damping);
|
||||
|
||||
pos.x += vel.x * dt;
|
||||
pos.y += vel.y * dt;
|
||||
pos.z += vel.z * dt;
|
||||
vel.x *= glm::max(0.0f, 1.0f - dt * linear_damping);
|
||||
vel.z *= glm::max(0.0f, 1.0f - dt * linear_damping);
|
||||
pos += vel * dt;
|
||||
|
||||
if (shifting && hitbox->grounded){
|
||||
float y = (pos.y-half.y-E);
|
||||
|
||||
hitbox->grounded = false;
|
||||
for (float x = (px-half.x+E); x <= (px+half.x-E); x+=s){
|
||||
for (float z = (pos.z-half.z+E); z <= (pos.z+half.z-E); z+=s){
|
||||
@ -51,10 +52,10 @@ void PhysicsSolver::step(Chunks* chunks, Hitbox* hitbox, float delta, unsigned s
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!hitbox->grounded)
|
||||
if (!hitbox->grounded) {
|
||||
pos.z = pz;
|
||||
}
|
||||
hitbox->grounded = false;
|
||||
|
||||
for (float x = (pos.x-half.x+E); x <= (pos.x+half.x-E); x+=s){
|
||||
for (float z = (pz-half.z+E); z <= (pz+half.z-E); z+=s){
|
||||
if (chunks->isObstacle(x,y,z)){
|
||||
@ -63,91 +64,97 @@ void PhysicsSolver::step(Chunks* chunks, Hitbox* hitbox, float delta, unsigned s
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!hitbox->grounded)
|
||||
if (!hitbox->grounded) {
|
||||
pos.x = px;
|
||||
|
||||
}
|
||||
hitbox->grounded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsSolver::colisionCalc(Chunks* chunks, Hitbox* hitbox, vec3* vel, vec3* pos, vec3 half){
|
||||
void PhysicsSolver::colisionCalc(
|
||||
Chunks* chunks,
|
||||
Hitbox* hitbox,
|
||||
vec3& vel,
|
||||
vec3& pos,
|
||||
const vec3 half)
|
||||
{
|
||||
// step size (smaller - more accurate, but slower)
|
||||
float s = 2.0/BLOCK_AABB_GRID;
|
||||
float s = 2.0f/BLOCK_AABB_GRID;
|
||||
|
||||
const AABB* aabb;
|
||||
|
||||
if (vel->x < 0.0){
|
||||
for (float y = (pos->y-half.y+E); y <= (pos->y+half.y-E); y+=s){
|
||||
for (float z = (pos->z-half.z+E); z <= (pos->z+half.z-E); z+=s){
|
||||
float x = (pos->x-half.x-E);
|
||||
if (vel.x < 0.0f){
|
||||
for (float y = (pos.y-half.y+E); y <= (pos.y+half.y-E); y+=s){
|
||||
for (float z = (pos.z-half.z+E); z <= (pos.z+half.z-E); z+=s){
|
||||
float x = (pos.x-half.x-E);
|
||||
if ((aabb = chunks->isObstacle(x,y,z))){
|
||||
vel->x *= 0.0;
|
||||
pos->x = floor(x) + aabb->max().x + half.x + E;
|
||||
vel.x *= 0.0f;
|
||||
pos.x = floor(x) + aabb->max().x + half.x + E;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (vel->x > 0.0){
|
||||
for (float y = (pos->y-half.y+E); y <= (pos->y+half.y-E); y+=s){
|
||||
for (float z = (pos->z-half.z+E); z <= (pos->z+half.z-E); z+=s){
|
||||
float x = (pos->x+half.x+E);
|
||||
if (vel.x > 0.0f){
|
||||
for (float y = (pos.y-half.y+E); y <= (pos.y+half.y-E); y+=s){
|
||||
for (float z = (pos.z-half.z+E); z <= (pos.z+half.z-E); z+=s){
|
||||
float x = (pos.x+half.x+E);
|
||||
if ((aabb = chunks->isObstacle(x,y,z))){
|
||||
vel->x *= 0.0;
|
||||
pos->x = floor(x) - half.x + aabb->min().x - E;
|
||||
vel.x *= 0.0f;
|
||||
pos.x = floor(x) - half.x + aabb->min().x - E;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (vel->z < 0.0){
|
||||
for (float y = (pos->y-half.y+E); y <= (pos->y+half.y-E); y+=s){
|
||||
for (float x = (pos->x-half.x+E); x <= (pos->x+half.x-E); x+=s){
|
||||
float z = (pos->z-half.z-E);
|
||||
if (vel.z < 0.0f){
|
||||
for (float y = (pos.y-half.y+E); y <= (pos.y+half.y-E); y+=s){
|
||||
for (float x = (pos.x-half.x+E); x <= (pos.x+half.x-E); x+=s){
|
||||
float z = (pos.z-half.z-E);
|
||||
if ((aabb = chunks->isObstacle(x,y,z))){
|
||||
vel->z *= 0.0;
|
||||
pos->z = floor(z) + aabb->max().z + half.z + E;
|
||||
vel.z *= 0.0f;
|
||||
pos.z = floor(z) + aabb->max().z + half.z + E;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (vel->z > 0.0){
|
||||
for (float y = (pos->y-half.y+E); y <= (pos->y+half.y-E); y+=s){
|
||||
for (float x = (pos->x-half.x+E); x <= (pos->x+half.x-E); x+=s){
|
||||
float z = (pos->z+half.z+E);
|
||||
if (vel.z > 0.0f){
|
||||
for (float y = (pos.y-half.y+E); y <= (pos.y+half.y-E); y+=s){
|
||||
for (float x = (pos.x-half.x+E); x <= (pos.x+half.x-E); x+=s){
|
||||
float z = (pos.z+half.z+E);
|
||||
if ((aabb = chunks->isObstacle(x,y,z))){
|
||||
vel->z *= 0.0;
|
||||
pos->z = floor(z) - half.z + aabb->min().z - E;
|
||||
vel.z *= 0.0f;
|
||||
pos.z = floor(z) - half.z + aabb->min().z - E;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (vel->y < 0.0){
|
||||
for (float x = (pos->x-half.x+E); x <= (pos->x+half.x-E); x+=s){
|
||||
for (float z = (pos->z-half.z+E); z <= (pos->z+half.z-E); z+=s){
|
||||
float y = (pos->y-half.y-E);
|
||||
if (vel.y < 0.0f){
|
||||
for (float x = (pos.x-half.x+E); x <= (pos.x+half.x-E); x+=s){
|
||||
for (float z = (pos.z-half.z+E); z <= (pos.z+half.z-E); z+=s){
|
||||
float y = (pos.y-half.y-E);
|
||||
if ((aabb = chunks->isObstacle(x,y,z))){
|
||||
vel->y *= 0.0;
|
||||
pos->y = floor(y) + aabb->max().y + half.y;
|
||||
vel.y *= 0.0f;
|
||||
pos.y = floor(y) + aabb->max().y + half.y;
|
||||
hitbox->grounded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (vel->y > 0.0){
|
||||
for (float x = (pos->x-half.x+E); x <= (pos->x+half.x-E); x+=s){
|
||||
for (float z = (pos->z-half.z+E); z <= (pos->z+half.z-E); z+=s){
|
||||
float y = (pos->y+half.y+E);
|
||||
if (vel.y > 0.0f){
|
||||
for (float x = (pos.x-half.x+E); x <= (pos.x+half.x-E); x+=s){
|
||||
for (float z = (pos.z-half.z+E); z <= (pos.z+half.z-E); z+=s){
|
||||
float y = (pos.y+half.y+E);
|
||||
if ((aabb = chunks->isObstacle(x,y,z))){
|
||||
vel->y *= 0.0;
|
||||
pos->y = floor(y) - half.y + aabb->min().y - E;
|
||||
vel.y *= 0.0f;
|
||||
pos.y = floor(y) - half.y + aabb->min().y - E;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,8 +2,7 @@
|
||||
#define PHYSICS_PHYSICSSOLVER_H_
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/ext.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include "../typedefs.h"
|
||||
|
||||
class Hitbox;
|
||||
class Chunks;
|
||||
@ -15,11 +14,11 @@ public:
|
||||
void step(Chunks* chunks,
|
||||
Hitbox* hitbox,
|
||||
float delta,
|
||||
unsigned substeps,
|
||||
uint substeps,
|
||||
bool shifting,
|
||||
float gravityScale,
|
||||
bool collisions);
|
||||
void colisionCalc(Chunks* chunks, Hitbox* hitbox, glm::vec3* vel, glm::vec3* pos, glm::vec3 half);
|
||||
void colisionCalc(Chunks* chunks, Hitbox* hitbox, glm::vec3& vel, glm::vec3& pos, const glm::vec3 half);
|
||||
bool isBlockInside(int x, int y, int z, Hitbox* hitbox);
|
||||
};
|
||||
|
||||
|
||||
@ -43,6 +43,8 @@ struct GraphicsSettings {
|
||||
float fogCurve = 1.6f;
|
||||
/* Enable blocks backlight to prevent complete darkness */
|
||||
bool backlight = true;
|
||||
/* Enable chunks frustum culling */
|
||||
bool frustumCulling = true;
|
||||
};
|
||||
|
||||
struct DebugSettings {
|
||||
|
||||
@ -3,6 +3,10 @@
|
||||
|
||||
#include <glm/ext.hpp>
|
||||
|
||||
using glm::vec3;
|
||||
using glm::vec4;
|
||||
using glm::mat4;
|
||||
|
||||
Camera::Camera(vec3 position, float fov) : position(position), fov(fov), zoom(1.0f), rotation(1.0f) {
|
||||
updateVectors();
|
||||
}
|
||||
|
||||
@ -2,30 +2,29 @@
|
||||
#define WINDOW_CAMERA_H_
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
using namespace glm;
|
||||
|
||||
class Camera {
|
||||
void updateVectors();
|
||||
public:
|
||||
vec3 front;
|
||||
vec3 up;
|
||||
vec3 right;
|
||||
vec3 dir;
|
||||
glm::vec3 front;
|
||||
glm::vec3 up;
|
||||
glm::vec3 right;
|
||||
glm::vec3 dir;
|
||||
|
||||
vec3 position;
|
||||
glm::vec3 position;
|
||||
float fov;
|
||||
float zoom;
|
||||
mat4 rotation;
|
||||
glm::mat4 rotation;
|
||||
bool perspective = true;
|
||||
bool flipped = false;
|
||||
float aspect = 0.0f;
|
||||
Camera(vec3 position, float fov);
|
||||
Camera(glm::vec3 position, float fov);
|
||||
|
||||
void rotate(float x, float y, float z);
|
||||
|
||||
mat4 getProjection();
|
||||
mat4 getView(bool position=true);
|
||||
mat4 getProjView();
|
||||
glm::mat4 getProjection();
|
||||
glm::mat4 getView(bool position=true);
|
||||
glm::mat4 getProjView();
|
||||
};
|
||||
|
||||
#endif /* WINDOW_CAMERA_H_ */
|
||||
|
||||
@ -5,12 +5,10 @@
|
||||
#include "../lighting/Lighting.h"
|
||||
#include "../voxels/Chunk.h"
|
||||
#include "../voxels/Chunks.h"
|
||||
#include "../voxels/ChunksController.h"
|
||||
#include "../voxels/ChunksStorage.h"
|
||||
#include "../physics/Hitbox.h"
|
||||
#include "../physics/PhysicsSolver.h"
|
||||
#include "../objects/Player.h"
|
||||
#include "../objects/player_control.h"
|
||||
|
||||
Level::Level(World* world, const Content* content, Player* player, EngineSettings& settings)
|
||||
: world(world),
|
||||
@ -30,9 +28,6 @@ Level::Level(World* world, const Content* content, Player* player, EngineSetting
|
||||
events,
|
||||
content);
|
||||
lighting = new Lighting(content, chunks);
|
||||
chunksController = new ChunksController(this, chunks, lighting,
|
||||
settings.chunks.padding);
|
||||
playerController = new PlayerController(this, settings);
|
||||
|
||||
events->listen(EVT_CHUNK_HIDDEN, [this](lvl_event_type type, Chunk* chunk) {
|
||||
this->chunksStorage->remove(chunk->x, chunk->z);
|
||||
@ -45,31 +40,7 @@ Level::~Level(){
|
||||
delete physics;
|
||||
delete player;
|
||||
delete lighting;
|
||||
delete chunksController;
|
||||
delete chunksStorage;
|
||||
delete playerController;
|
||||
}
|
||||
|
||||
void Level::updatePlayer(float delta,
|
||||
bool input,
|
||||
bool pause,
|
||||
bool interactions) {
|
||||
if (!pause) {
|
||||
if (input) {
|
||||
playerController->updateKeyboard();
|
||||
playerController->updateCameraControl();
|
||||
} else {
|
||||
playerController->resetKeyboard();
|
||||
}
|
||||
playerController->updateControls(delta);
|
||||
|
||||
}
|
||||
playerController->refreshCamera();
|
||||
if (interactions) {
|
||||
playerController->updateInteraction();
|
||||
} else {
|
||||
playerController->selectedBlockId = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void Level::update() {
|
||||
@ -77,7 +48,7 @@ void Level::update() {
|
||||
chunks->setCenter(position.x, position.z);
|
||||
|
||||
int matrixSize = (settings.chunks.loadDistance+
|
||||
settings.chunks.padding) * 2;
|
||||
settings.chunks.padding) * 2;
|
||||
if (chunks->w != matrixSize) {
|
||||
chunks->resize(matrixSize, matrixSize);
|
||||
}
|
||||
|
||||
@ -24,11 +24,11 @@ public:
|
||||
Player* player;
|
||||
Chunks* chunks;
|
||||
ChunksStorage* chunksStorage;
|
||||
|
||||
PhysicsSolver* physics;
|
||||
Lighting* lighting;
|
||||
ChunksController* chunksController;
|
||||
PlayerController* playerController;
|
||||
LevelEvents* events;
|
||||
|
||||
const EngineSettings& settings;
|
||||
|
||||
Level(World* world,
|
||||
@ -37,11 +37,6 @@ public:
|
||||
EngineSettings& settings);
|
||||
~Level();
|
||||
|
||||
void updatePlayer(float delta,
|
||||
bool input,
|
||||
bool pause,
|
||||
bool interactions);
|
||||
|
||||
void update();
|
||||
};
|
||||
|
||||
|
||||
@ -46,25 +46,21 @@ void World::write(Level* level) {
|
||||
wfile->put(chunk.get());
|
||||
}
|
||||
|
||||
wfile->write(WorldInfo {name, wfile->directory, seed, daytime, daytimeSpeed}, content);
|
||||
wfile->write(this, content);
|
||||
wfile->writePlayer(level->player);
|
||||
}
|
||||
|
||||
Level* World::load(EngineSettings& settings, const Content* content) {
|
||||
WorldInfo info {name, wfile->directory, seed, daytime, daytimeSpeed};
|
||||
wfile->readWorldInfo(info);
|
||||
seed = info.seed;
|
||||
name = info.name;
|
||||
daytime = info.daytime;
|
||||
daytimeSpeed = info.daytimeSpeed;
|
||||
wfile->readWorldInfo(this);
|
||||
|
||||
vec3 playerPosition = vec3(0, 100, 0);
|
||||
Camera* camera = new Camera(playerPosition, glm::radians(90.0f));
|
||||
Player* player = new Player(playerPosition, 4.0f, camera);
|
||||
Level* level = new Level(this, content, player, settings);
|
||||
|
||||
wfile->readPlayer(player);
|
||||
|
||||
camera->rotation = mat4(1.0f);
|
||||
camera->rotation = glm::mat4(1.0f);
|
||||
camera->rotate(player->camY, player->camX, 0);
|
||||
return level;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user