X-Git-Url: http://git.localhorst.tv/?a=blobdiff_plain;f=src%2Fworld%2Fworld.cpp;h=0daadfc430afe9e56e6be35a2aba9876d4dcd03d;hb=ab0ba4313c473378b4516e3702d524dc1d1fc5d4;hp=920313653ac1104ee91073a2d55df97462e2a4ed;hpb=ba93deae894a7e35d95aee32c548ac4e7400c771;p=blank.git diff --git a/src/world/world.cpp b/src/world/world.cpp index 9203136..0daadfc 100644 --- a/src/world/world.cpp +++ b/src/world/world.cpp @@ -133,7 +133,9 @@ glm::mat4 Entity::ViewTransform(const glm::ivec3 &reference) const noexcept { Ray Entity::Aim(const ExactLocation::Coarse &chunk_offset) const noexcept { glm::mat4 transform = ViewTransform(chunk_offset); - return Ray{ glm::vec3(transform[3]), -glm::vec3(transform[2]) }; + Ray ray{ glm::vec3(transform[3]), -glm::vec3(transform[2]) }; + ray.Update(); + return ray; } void Entity::Update(World &world, float dt) { @@ -779,12 +781,25 @@ bool World::Intersection( const ExactLocation::Coarse &reference, WorldCollision &coll ) { + // only consider chunks of the idex closest to reference + // this makes the ray not be infinite anymore (which means it's + // actually a line segment), but oh well + ChunkIndex *index = chunks.ClosestIndex(reference); + if (!index) { + return false; + } + candidates.clear(); - for (Chunk &cur_chunk : chunks) { + // TODO: change this so the test starts at the chunk of the ray's + // origin and "walks" forward until it hits (actually casting + // the ray, so to say). if this performs well (at least, better + // than now), this could also qualify for the chunk test itself + // see Bresenham's line algo or something similar + for (Chunk *cur_chunk : *index) { float cur_dist; - if (cur_chunk.Intersection(ray, reference, cur_dist)) { - candidates.push_back({ &cur_chunk, cur_dist }); + if (cur_chunk && cur_chunk->Intersection(ray, reference, cur_dist)) { + candidates.push_back({ cur_chunk, cur_dist }); } } @@ -859,16 +874,19 @@ bool World::Intersection( const glm::ivec3 &reference, std::vector &col ) { + // this only works if box's diameter is < than 16 + ExactLocation::Coarse begin(reference - 1); + ExactLocation::Coarse end(reference + 2); + bool any = false; - for (Chunk &cur_chunk : chunks) { - if (manhattan_radius(cur_chunk.Position() - reference) > 1) { - // chunk is not one of the 3x3x3 surrounding the entity - // since there's no entity which can extent over 16 blocks, they can be skipped - // TODO: change to indexed (like with entity) - continue; - } - if (cur_chunk.Intersection(box, M, cur_chunk.Transform(reference), col)) { - any = true; + for (ExactLocation::Coarse pos(begin); pos.z < end.z; ++pos.z) { + for (pos.y = begin.y; pos.y < end.y; ++pos.y) { + for (pos.x = begin.x; pos.x < end.x; ++pos.x) { + Chunk *chunk = chunks.Get(pos); + if (chunk && chunk->Intersection(box, M, chunk->Transform(reference), col)) { + any = true; + } + } } } return any; @@ -1059,7 +1077,7 @@ void World::RenderDebug(Viewport &viewport) { PrimitiveMesh debug_mesh; PlainColor &prog = viewport.WorldColorProgram(); for (const Entity &entity : entities) { - debug_buf.OutlineBox(entity.Bounds(), glm::vec4(1.0f, 0.0f, 0.0f, 1.0f)); + debug_buf.OutlineBox(entity.Bounds(), glm::tvec4(255, 0, 0, 255)); debug_mesh.Update(debug_buf); prog.SetM(entity.Transform(players.front().GetEntity().ChunkCoords())); debug_mesh.DrawLines();