diff options
-rw-r--r-- | src/GameState.cpp | 13 | ||||
-rw-r--r-- | src/GameState.hpp | 1 | ||||
-rw-r--r-- | src/Render.cpp | 8 | ||||
-rw-r--r-- | src/World.cpp | 87 | ||||
-rw-r--r-- | src/World.hpp | 2 |
5 files changed, 103 insertions, 8 deletions
diff --git a/src/GameState.cpp b/src/GameState.cpp index 20926e0..650cd6f 100644 --- a/src/GameState.cpp +++ b/src/GameState.cpp @@ -27,7 +27,16 @@ void GameState::Update(float deltaTime) { PUSH_EVENT("SendPacket",packet); } - selectedBlock = Vector(Vector(player->pos.x,player->pos.y,player->pos.z) - Vector(-1,0,0)); + + double playerYaw = Entity::DecodeYaw(player->yaw); + double playerPitch = Entity::DecodePitch(player->pitch); + + glm::vec3 direction; + direction.x = cos(glm::radians(playerYaw)) * cos(glm::radians(playerPitch)); + direction.y = sin(glm::radians(playerPitch)); + direction.z = sin(glm::radians(playerYaw)) * cos(glm::radians(playerPitch)); + + selectedBlock = world.Raycast(player->pos + player->EyeOffset, direction, distanceToSelectedBlock); } } @@ -404,7 +413,7 @@ void GameState::HandleMovement(GameState::Direction direction, float deltaTime) const double playerSpeed = 43; float velocity = playerSpeed * deltaTime; - + double playerYaw = Entity::DecodeYaw(player->yaw); double playerPitch = Entity::DecodePitch(player->pitch); diff --git a/src/GameState.hpp b/src/GameState.hpp index 0bc8cfd..5d3d36a 100644 --- a/src/GameState.hpp +++ b/src/GameState.hpp @@ -62,4 +62,5 @@ public: std::vector<Window> openedWindows; Vector selectedBlock; + float distanceToSelectedBlock; }; diff --git a/src/Render.cpp b/src/Render.cpp index f53cc91..534782e 100644 --- a/src/Render.cpp +++ b/src/Render.cpp @@ -291,7 +291,7 @@ void Render::RenderGui() { ImGui::Text("Player pos: %.1f %.1f %.1f OnGround=%d", world->GameStatePtr()->player->pos.x, world->GameStatePtr()->player->pos.y, world->GameStatePtr()->player->pos.z, world->GameStatePtr()->player->onGround); ImGui::Text("Player vel: %.1f %.1f %.1f", world->GameStatePtr()->player->vel.x, world->GameStatePtr()->player->vel.y, world->GameStatePtr()->player->vel.z); ImGui::Text("Player health: %.1f/%.1f", world->GameStatePtr()->g_PlayerHealth, 20.0f); - ImGui::Text("Selected block: %d %d %d",world->GameStatePtr()->selectedBlock.x,world->GameStatePtr()->selectedBlock.y,world->GameStatePtr()->selectedBlock.z); + ImGui::Text("Selected block: %d %d %d : %.1f",world->GameStatePtr()->selectedBlock.x,world->GameStatePtr()->selectedBlock.y,world->GameStatePtr()->selectedBlock.z,world->GameStatePtr()->distanceToSelectedBlock); } ImGui::End(); @@ -476,6 +476,12 @@ void Render::RenderGui() { } case State::InitialLoading: break; + case State::Playing: { + ImGui::SetNextWindowPosCenter(); + ImGui::Begin("",0,windowFlags); + ImGui::End(); + break; + } } ImGui::Render(); diff --git a/src/World.cpp b/src/World.cpp index 9df8889..e4c2a1b 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -1,6 +1,7 @@ #include "World.hpp" #include <bitset> +#include <glm/glm.hpp> #include "Section.hpp" #include "Event.hpp" @@ -134,8 +135,86 @@ const Section &World::GetSection(Vector sectionPos) { } } -glm::vec3 World::Raycast(glm::vec3 position, glm::vec3 direction, float maxLength, float minPrecision) { - return glm::vec3(position * direction / maxLength * minPrecision); +Vector World::Raycast(glm::vec3 position, glm::vec3 direction, float &distance) { + auto triangle_intersection = [&] (const glm::vec3 &v0, const glm::vec3 &v1, const glm::vec3 &v2) -> bool { + glm::vec3 e1 = v1 - v0; + glm::vec3 e2 = v2 - v0; + + glm::vec3 pvec = glm::cross(direction, e2); + + float det = glm::dot(e1, pvec); + if (det < 1e-8 && det > -1e-8) { + return 0; + } + + float inv_det = 1 / det; + glm::vec3 tvec = position - v0; + float u = dot(tvec, pvec) * inv_det; + if (u < 0 || u > 1) { + return 0; + } + + glm::vec3 qvec = cross(tvec, e1); + float v = dot(direction, qvec) * inv_det; + if (v < 0 || u + v > 1) { + return 0; + } + return dot(e2, qvec) * inv_det; + }; + + float minDistance = 1000000; + Vector minBlock; + + for (int y = position.y-5; y<position.y+5;y++) { + for (int z = position.z-5;z<position.z+5;z++) { + for (int x = position.x-5;x<position.x+5;x++) { + if (GetBlockId(Vector(x,y,z)) == BlockId{0,0}) + continue; + + //Z- north + //Z+ south + //X+ east + //X- west + //Y+ top + //Y- bottom + glm::vec3 vNNN {x,y,z}; + glm::vec3 vNNP {x,y,z+1}; + glm::vec3 vNPN {x,y+1,z}; + glm::vec3 vNPP {x,y+1,z+1}; + glm::vec3 vPNN {x+1,y,z}; + glm::vec3 vPNP {x+1,y,z+1}; + glm::vec3 vPPN {x+1,y+1,z}; + glm::vec3 vPPP {x+1,y+1,z+1}; + + float west = triangle_intersection(vNNN,vNPN,vNPP); + float east = triangle_intersection(vPPN,vPNP,vPNN); + float north = triangle_intersection(vNPN,vPNN,vNNN); + float south = triangle_intersection(vNNP,vNPP,vPNP); + float top = triangle_intersection(vNPN,vNPP,vPPN); + float bottom = triangle_intersection(vNNN,vNNP,vPNN); + + if (west || east || north || south || top || bottom) { + float len = (Vector(position.x,position.y,position.z) - Vector(x,y,z)).GetLength(); + if (len <= minDistance) { + float we = west < east && west != 0 ? west : east; + float ns = north < south && north != 0 ? north : south; + float tb = top < bottom && top != 0 ? top : bottom; + float wens = we < ns && we != 0 ? we : ns; + minDistance = wens < tb && wens != 0? wens : tb; + minBlock = Vector(x,y,z); + } + } + } + } + } + + if (minDistance == 1000000) { + distance = 0; + return Vector(0,0,0); + } + + distance = minDistance; + return minBlock; } void World::UpdatePhysics(float delta) @@ -148,7 +227,7 @@ void World::UpdatePhysics(float delta) }; auto testCollision = [this](double width, double height, VectorF pos)->CollisionResult { - + int blockXBegin = pos.x - width - 1.0; int blockXEnd = pos.x + width + 0.5; int blockYBegin = pos.y - 0.5; @@ -324,9 +403,9 @@ BlockId World::GetBlockId(Vector pos) { void World::SetBlockId(Vector pos, BlockId block) { Vector sectionPos(std::floor(pos.x / 16.0), std::floor(pos.y / 16.0), std::floor(pos.z / 16.0)); - Section* section = GetSectionPtr(sectionPos); section->SetBlockId(pos - (sectionPos * 16), block); + PUSH_EVENT("ChunkChanged",sectionPos); } void World::SetBlockLight(Vector pos, unsigned char light) { diff --git a/src/World.hpp b/src/World.hpp index 6d10491..50dfa31 100644 --- a/src/World.hpp +++ b/src/World.hpp @@ -55,7 +55,7 @@ public: const Section &GetSection(Vector sectionPos); - glm::vec3 Raycast(glm::vec3 position, glm::vec3 direction, float maxLength = 1000.0f, float minPrecision = 0.01f); + Vector Raycast(glm::vec3 position, glm::vec3 direction, float &distance); void UpdatePhysics(float delta); |