summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/GameState.cpp13
-rw-r--r--src/GameState.hpp1
-rw-r--r--src/Render.cpp8
-rw-r--r--src/World.cpp87
-rw-r--r--src/World.hpp2
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);