X-Git-Url: http://git.localhorst.tv/?a=blobdiff_plain;f=src%2Fworld%2FWorld.cpp;h=3d3eb6c3d9ba11a6aebc685e01480dca6b6e773f;hb=5e8eee742138f2578e83e710ffc41408abd3073f;hp=cb8186d5f1f10ce27e337030215d060fbe1ee931;hpb=32909aa3224ec0ed5656721178eb6ad31cd047df;p=blank.git diff --git a/src/world/World.cpp b/src/world/World.cpp index cb8186d..3d3eb6c 100644 --- a/src/world/World.cpp +++ b/src/world/World.cpp @@ -1,114 +1,33 @@ #include "World.hpp" #include "WorldCollision.hpp" -#include "../graphics/BlockLighting.hpp" -#include "../graphics/DirectionalLighting.hpp" +#include "../app/Assets.hpp" +#include "../app/TextureIndex.hpp" +#include "../graphics/Format.hpp" +#include "../graphics/Viewport.hpp" -#include #include +#include #include namespace blank { -World::World(const Config &config) -: blockType() -, blockShape({{ -0.5f, -0.5f, -0.5f }, { 0.5f, 0.5f, 0.5f }}) -, stairShape({{ -0.5f, -0.5f, -0.5f }, { 0.5f, 0.5f, 0.5f }}, { 0.0f, 0.0f }) -, slabShape({{ -0.5f, -0.5f, -0.5f }, { 0.5f, 0.0f, 0.5f }}) +World::World(const Assets &assets, const Config &config, const WorldSave &save) +: block_type() +, block_tex() , generate(config.gen) -, chunks(config.load, blockType, generate) +, chunks(config.load, block_type, generate, save) , player() , entities() , light_direction(config.light_direction) , fog_density(config.fog_density) { - BlockType::Faces block_fill = { true, true, true, true, true, true }; - BlockType::Faces slab_fill = { false, true, false, false, false, false }; - BlockType::Faces stair_fill = { false, true, false, false, false, true }; - - { // white block - BlockType type(true, { 1.0f, 1.0f, 1.0f }, &blockShape); - type.block_light = true; - type.fill = block_fill; - blockType.Add(type); - } - { // white slab - BlockType type(true, { 1.0f, 1.0f, 1.0f }, &slabShape); - type.block_light = true; - type.fill = slab_fill; - blockType.Add(type); - } - { // white stair - BlockType type(true, { 1.0f, 1.0f, 1.0f }, &stairShape); - type.block_light = true; - type.fill = stair_fill; - blockType.Add(type); - } - - { // red block - BlockType type(true, { 1.0f, 0.0f, 0.0f }, &blockShape); - type.block_light = true; - type.fill = block_fill; - blockType.Add(type); - } - { // red slab - BlockType type(true, { 1.0f, 0.0f, 0.0f }, &slabShape); - type.block_light = true; - type.fill = slab_fill; - blockType.Add(type); - } - { // red stair - BlockType type(true, { 1.0f, 0.0f, 0.0f }, &stairShape); - type.block_light = true; - type.fill = stair_fill; - blockType.Add(type); - } - - { // green block - BlockType type(true, { 0.0f, 1.0f, 0.0f }, &blockShape); - type.block_light = true; - type.fill = block_fill; - blockType.Add(type); - } - { // green slab - BlockType type(true, { 0.0f, 1.0f, 0.0f }, &slabShape); - type.block_light = true; - type.fill = slab_fill; - blockType.Add(type); - } - { // green stair - BlockType type(true, { 0.0f, 1.0f, 0.0f }, &stairShape); - type.block_light = true; - type.fill = stair_fill; - blockType.Add(type); - } - - { // blue block - BlockType type(true, { 0.0f, 0.0f, 1.0f }, &blockShape); - type.block_light = true; - type.fill = block_fill; - blockType.Add(type); - } - { // blue slab - BlockType type(true, { 0.0f, 0.0f, 1.0f }, &slabShape); - type.block_light = true; - type.fill = slab_fill; - blockType.Add(type); - } - { // blue stair - BlockType type(true, { 0.0f, 0.0f, 1.0f }, &stairShape); - type.block_light = true; - type.fill = stair_fill; - blockType.Add(type); - } + TextureIndex tex_index; + assets.LoadBlockTypes("default", block_type, tex_index); - { // glowing yellow block - BlockType type(true, { 1.0f, 1.0f, 0.0f }, &blockShape); - type.luminosity = 15; - type.block_light = true; - type.fill = block_fill; - blockType.Add(type); - } + block_tex.Bind(); + assets.LoadTextures(tex_index, block_tex); + block_tex.FilterNearest(); generate.Space(0); generate.Light(13); @@ -120,7 +39,7 @@ World::World(const Config &config) player->WorldCollidable(true); player->Position(config.spawn); - chunks.GenerateSurrounding(player->ChunkCoords()); + chunks.QueueSurrounding(player->ChunkCoords()); } @@ -179,14 +98,15 @@ bool World::Intersection( bool World::Intersection(const Entity &e, std::vector &col) { AABB box = e.Bounds(); glm::mat4 M = e.Transform(player->ChunkCoords()); + bool any = false; // TODO: this only needs to check the chunks surrounding the entity's chunk position // need find out if that is quicker than the rough chunk bounds test for (Chunk &cur_chunk : chunks.Loaded()) { if (cur_chunk.Intersection(box, M, cur_chunk.Transform(player->ChunkCoords()), col)) { - return true; + any = true; } } - return false; + return any; } @@ -194,7 +114,7 @@ Chunk &World::PlayerChunk() { return chunks.ForceLoad(player->ChunkCoords()); } -Chunk &World::Next(const Chunk &to, const glm::tvec3 &dir) { +Chunk &World::Next(const Chunk &to, const glm::ivec3 &dir) { const Chunk::Pos tgt_pos = to.Position() + dir; return chunks.ForceLoad(tgt_pos); } @@ -217,19 +137,56 @@ void World::Update(int dt) { Resolve(entity, col); } } + for (auto iter = entities.begin(), end = entities.end(); iter != end;) { + if (iter->CanRemove()) { + iter = entities.erase(iter); + } else { + ++iter; + } + } chunks.Rebase(player->ChunkCoords()); chunks.Update(dt); } -void World::Resolve(const Entity &e, std::vector &col) { - std::cout << e.Name() << " entity intersects world at " << col.size() << " blocks" << std::endl; +void World::Resolve(Entity &e, std::vector &col) { + // determine displacement for each cardinal axis and move entity accordingly + glm::vec3 min_disp(0.0f); + glm::vec3 max_disp(0.0f); + for (const WorldCollision &c : col) { + if (!c.Blocks()) continue; + glm::vec3 local_disp(c.normal * c.depth); + // swap if neccessary (normal may point away from the entity) + if (dot(c.normal, e.Position() - c.BlockCoords()) < 0) { + local_disp *= -1; + } + min_disp = min(min_disp, local_disp); + max_disp = max(max_disp, local_disp); + } + // for each axis + // if only one direction is set, use that as the final + // if both directions are set, use average + glm::vec3 final_disp(0.0f); + for (int axis = 0; axis < 3; ++axis) { + if (std::abs(min_disp[axis]) > std::numeric_limits::epsilon()) { + if (std::abs(max_disp[axis]) > std::numeric_limits::epsilon()) { + final_disp[axis] = (min_disp[axis] + max_disp[axis]) * 0.5f; + } else { + final_disp[axis] = min_disp[axis]; + } + } else if (std::abs(max_disp[axis]) > std::numeric_limits::epsilon()) { + final_disp[axis] = max_disp[axis]; + } + } + e.Move(final_disp); } -void World::Render(BlockLighting &chunk_prog, DirectionalLighting &entity_prog) { - chunk_prog.Activate(); +void World::Render(Viewport &viewport) { + viewport.WorldPosition(player->Transform(player->ChunkCoords())); + + BlockLighting &chunk_prog = viewport.ChunkProgram(); + chunk_prog.SetTexture(block_tex); chunk_prog.SetFogDensity(fog_density); - chunk_prog.SetView(glm::inverse(player->Transform(player->ChunkCoords()))); for (Chunk &chunk : chunks.Loaded()) { glm::mat4 m(chunk.Transform(player->ChunkCoords())); @@ -240,16 +197,12 @@ void World::Render(BlockLighting &chunk_prog, DirectionalLighting &entity_prog) } } - entity_prog.Activate(); + DirectionalLighting &entity_prog = viewport.EntityProgram(); entity_prog.SetLightDirection(light_direction); entity_prog.SetFogDensity(fog_density); - entity_prog.SetView(glm::inverse(player->Transform(player->ChunkCoords()))); for (Entity &entity : entities) { - if (entity.HasShape()) { - entity_prog.SetM(entity.Transform(player->ChunkCoords())); - entity.Draw(); - } + entity.Render(entity.ChunkTransform(player->ChunkCoords()), entity_prog); } }