From: Daniel Karbach Date: Fri, 20 Nov 2015 15:30:33 +0000 (+0100) Subject: ignore obscured faces in collision response X-Git-Url: http://git.localhorst.tv/?a=commitdiff_plain;h=da355888d84cba0a712e1b8227156c1f08327bba;hp=d1c5d306f2a968c0b7b08e24991cfb956f103755;p=blank.git ignore obscured faces in collision response --- diff --git a/src/world/BlockLookup.hpp b/src/world/BlockLookup.hpp index 3d7aa04..214608e 100644 --- a/src/world/BlockLookup.hpp +++ b/src/world/BlockLookup.hpp @@ -2,6 +2,7 @@ #define BLANK_WORLD_BLOCKLOOKUP_HPP_ #include "Block.hpp" +#include "BlockType.hpp" #include "Chunk.hpp" @@ -28,6 +29,8 @@ public: const BlockType &GetType() const noexcept { return GetChunk().Type(GetBlock()); } int GetLight() const noexcept { return GetChunk().GetLight(GetBlockPos()); } + bool FaceFilled(Block::Face f) const noexcept { return GetType().FaceFilled(GetBlock(), f); } + void SetBlock(const Block &b) noexcept { GetChunk().SetBlock(GetBlockPos(), b); } // traverse in given direction diff --git a/src/world/world.cpp b/src/world/world.cpp index d2b05d6..199343c 100644 --- a/src/world/world.cpp +++ b/src/world/world.cpp @@ -699,11 +699,19 @@ glm::vec3 World::CombinedInterpenetration( glm::vec3 max_pen(0.0f); for (const WorldCollision &c : col) { if (!c.Blocks()) continue; - glm::vec3 local_pen(c.normal * c.depth); + glm::vec3 normal(c.normal); // swap if neccessary (normal may point away from the entity) - if (dot(c.normal, state.RelativePosition(c.ChunkPos()) - c.BlockCoords()) > 0) { - local_pen *= -1; + if (dot(normal, state.RelativePosition(c.ChunkPos()) - c.BlockCoords()) < 0) { + normal = -normal; } + // check if block surface is "inside" + Block::Face coll_face = Block::NormalFace(normal); + BlockLookup neighbor(c.chunk, c.BlockPos(), coll_face); + if (neighbor && neighbor.FaceFilled(Block::Opposite(coll_face))) { + // yep, so ignore this contact + continue; + } + glm::vec3 local_pen(normal * c.depth); min_pen = min(min_pen, local_pen); max_pen = max(max_pen, local_pen); }