From c149d9ac2492cecbd1ba336f231157f69413942b Mon Sep 17 00:00:00 2001 From: LaG1924 <12997935+LaG1924@users.noreply.github.com> Date: Sat, 30 Sep 2017 21:00:09 +0500 Subject: 2017-09-30 --- cwd/shaders/face.vs | 7 +- src/Entity.cpp | 22 ++++- src/Entity.hpp | 18 +++- src/GameState.cpp | 227 +++++++++++++++++++++----------------------------- src/GameState.hpp | 13 +-- src/Render.cpp | 17 ++-- src/RendererWorld.cpp | 155 +++++++++++++++++----------------- src/Utility.hpp | 2 - src/World.cpp | 84 ++++++++++++++++++- src/World.hpp | 4 +- src/main.cpp | 3 + 11 files changed, 320 insertions(+), 232 deletions(-) diff --git a/cwd/shaders/face.vs b/cwd/shaders/face.vs index 9bf2639..2d3b4b5 100644 --- a/cwd/shaders/face.vs +++ b/cwd/shaders/face.vs @@ -13,13 +13,14 @@ out VS_OUT { vec2 Light; } vs_out; -uniform mat4 view; -uniform mat4 projection; +//uniform mat4 view; +//uniform mat4 projection; +uniform mat4 projView; void main() { vec4 sourcePosition = vec4(position,1.0f); - gl_Position = projection * view * model * sourcePosition; + gl_Position = projView * model * sourcePosition; vs_out.UvPosition = vec2(UvCoordinates.x,UvCoordinates.y); vs_out.Texture = Texture; diff --git a/src/Entity.cpp b/src/Entity.cpp index cdfd85d..d91e78d 100644 --- a/src/Entity.cpp +++ b/src/Entity.cpp @@ -13,10 +13,26 @@ VectorF Entity::DecodeDeltaPos(short deltaX, short deltaY, short deltaZ) return VectorF(deltaX / posMod, deltaY / posMod, deltaZ / posMod); } +double Entity::DecodeYaw(double yaw) { + return yaw + 90.0; +} + +double Entity::DecodePitch(double pitch) { + return -pitch; +} + +double Entity::EncodeYaw(double yaw) { + return yaw - 90.0; +} + +double Entity::EncodePitch(double pitch) { + return -pitch; +} + Entity CreateObject(ObjectType type) { Entity entity; - entity.isMob = false; + entity.type = EntityType::Object; switch (type) { case ObjectType::Boat: break; @@ -82,5 +98,7 @@ Entity CreateObject(ObjectType type) Entity CreateMob(MobType type) { - return Entity(); + Entity entity; + entity.type = EntityType::Mob; + return entity; } diff --git a/src/Entity.hpp b/src/Entity.hpp index c818abe..cc9f6fa 100644 --- a/src/Entity.hpp +++ b/src/Entity.hpp @@ -3,6 +3,11 @@ #include "Utility.hpp" #include "Vector.hpp" +enum class EntityType { + Object, + Mob, +}; + enum class ObjectType{ Boat=1, ItemStack, @@ -130,9 +135,20 @@ struct Entity { double height = 1.0; glm::vec3 renderColor; int entityType=0; - bool isMob=false; + EntityType type; + bool isSolid = true; + double gravity = 32.0; // in m/s^2 + double drag = 0.4; + double terminalVelocity = 78.4; + bool onGround = true; + VectorF EyeOffset = VectorF(0,1.62,0); + static VectorF DecodeVelocity(short x, short y, short z); static VectorF DecodeDeltaPos(short deltaX, short deltaY, short deltaZ); + static double DecodeYaw(double yaw); + static double DecodePitch(double pitch); + static double EncodeYaw(double yaw); + static double EncodePitch(double pitch); }; Entity CreateObject(ObjectType type); diff --git a/src/GameState.cpp b/src/GameState.cpp index 98b49f7..08b29b4 100644 --- a/src/GameState.cpp +++ b/src/GameState.cpp @@ -3,9 +3,9 @@ #include GameState::GameState(std::shared_ptr networkClient) : nc(networkClient) { - Front = glm::vec3(0.0f, 0.0f, -1.0f); - this->SetPosition(glm::vec3(0.0f, 0.0f, 3.0f)); - this->WorldUp = glm::vec3(0.0f, 1.0f, 0.0f); + //Front = glm::vec3(0.0f, 0.0f, -1.0f); + //this->SetPosition(glm::vec3(0.0f, 0.0f, 3.0f)); + //this->WorldUp = glm::vec3(0.0f, 1.0f, 0.0f); } void GameState::Update(float deltaTime) { @@ -14,46 +14,19 @@ void GameState::Update(float deltaTime) { static auto timeOfPreviousSendedPacket(clock.now()); auto delta = clock.now() - timeOfPreviousSendedPacket; using namespace std::chrono_literals; - if (delta >= 50ms) { - auto packetToSend = std::make_shared(g_PlayerX, g_PlayerY, g_PlayerZ, - g_PlayerYaw, - g_PlayerPitch, g_OnGround); - nc->SendPacket(packetToSend); - timeOfPreviousSendedPacket = clock.now(); - } - - const float gravity = -9.8f; - g_PlayerVelocityY += gravity * deltaTime; - - bool isCollides = world.isPlayerCollides(g_PlayerX, g_PlayerY + g_PlayerVelocityY * deltaTime, - g_PlayerZ); - if (!isCollides) { - g_PlayerY += g_PlayerVelocityY * deltaTime; - g_OnGround = false; - } else { - g_PlayerVelocityY = 0; - if (g_OnGround == false) { - auto updatePacket = std::make_shared(g_PlayerX, g_PlayerY, g_PlayerZ, true); - nc->SendPacket(updatePacket); - } - g_OnGround = true; - } - - isCollides = world.isPlayerCollides(g_PlayerX + g_PlayerVelocityX * deltaTime, g_PlayerY, - g_PlayerZ + g_PlayerVelocityZ * deltaTime); - if (!isCollides) { - g_PlayerX += g_PlayerVelocityX * deltaTime; - g_PlayerZ += g_PlayerVelocityZ * deltaTime; + if (delta >= 50ms) { + auto packetToSend = std::make_shared(player->pos.x, player->pos.y, player->pos.z, player->yaw, player->pitch, player->onGround); + nc->SendPacket(packetToSend); + timeOfPreviousSendedPacket = clock.now(); } - const float AirResistance = 10.0f; - glm::vec3 vel(g_PlayerVelocityX, 0, g_PlayerVelocityZ); - glm::vec3 resistForce = -vel * AirResistance * deltaTime; - vel += resistForce; - g_PlayerVelocityX = vel.x; - g_PlayerVelocityZ = vel.z; - + bool prevOnGround = player->onGround; world.UpdatePhysics(deltaTime); + if (player->onGround != prevOnGround) { + auto updatePacket = std::make_shared(player->pos.x, player->pos.y, player->pos.z, player->onGround); + nc->SendPacket(updatePacket); + } + } } @@ -213,6 +186,13 @@ void GameState::UpdatePacket() break; case JoinGame: { auto packet = std::static_pointer_cast(ptr); + Entity entity; + entity.entityId = packet->EntityId; + entity.width = 0.6; + entity.height = 1.8; + world.AddEntity(entity); + player = world.GetEntityPtr(entity.entityId); + g_PlayerEid = packet->EntityId; g_Gamemode = (packet->Gamemode & 0b11111011); g_Dimension = packet->Dimension; @@ -266,43 +246,42 @@ void GameState::UpdatePacket() case PlayerPositionAndLookCB: { auto packet = std::static_pointer_cast(ptr); if ((packet->Flags & 0x10) != 0) { - g_PlayerPitch += packet->Pitch; + player->pitch += packet->Pitch; } else { - g_PlayerPitch = packet->Pitch; + player->pitch = packet->Pitch; }; if ((packet->Flags & 0x08) != 0) { - g_PlayerYaw += packet->Yaw; + player->yaw += packet->Yaw; } else { - g_PlayerYaw = packet->Yaw; + player->yaw = packet->Yaw; } if ((packet->Flags & 0x01) != 0) { - g_PlayerX += packet->X; + player->pos.x += packet->X; } else { - g_PlayerX = packet->X; + player->pos.x = packet->X; } if ((packet->Flags & 0x02) != 0) { - g_PlayerY += packet->Y; + player->pos.y += packet->Y; } else { - g_PlayerY = packet->Y; + player->pos.y = packet->Y; } if ((packet->Flags & 0x04) != 0) { - g_PlayerZ += packet->Z; + player->pos.z += packet->Z; } else { - g_PlayerZ = packet->Z; + player->pos.z = packet->Z; } - EventAgregator::PushEvent(EventType::PlayerPosChanged, PlayerPosChangedData{ VectorF(g_PlayerX,g_PlayerY,g_PlayerZ) }); - LOG(INFO) << "PlayerPos is " << g_PlayerX << ", " << g_PlayerY << ", " << g_PlayerZ << "\t\tAngle: " - << g_PlayerYaw << "," << g_PlayerPitch; + EventAgregator::PushEvent(EventType::PlayerPosChanged, PlayerPosChangedData{ player->pos }); + LOG(INFO) << "PlayerPos is " << player->pos << "\t\tAngle: " << player->yaw << "," << player->pitch;; if (!g_IsGameStarted) { LOG(INFO) << "Game is started"; @@ -425,92 +404,74 @@ void GameState::UpdatePacket() void GameState::HandleMovement(GameState::Direction direction, float deltaTime) { if (!g_IsGameStarted) return; - const float PlayerSpeed = 40.0; - float velocity = PlayerSpeed * deltaTime; - glm::vec3 vel(g_PlayerVelocityX, g_PlayerVelocityY, g_PlayerVelocityZ); - glm::vec3 front(cos(glm::radians(this->Yaw())) * cos(glm::radians(this->Pitch())), 0, - sin(glm::radians(this->Yaw())) * cos(glm::radians(this->Pitch()))); - front = glm::normalize(front); - glm::vec3 right = glm::normalize(glm::cross(front, this->WorldUp)); - switch (direction) { - case FORWARD: - vel += front * velocity; - break; - case BACKWARD: - vel -= front * velocity; - break; - case RIGHT: - vel += right * velocity; - break; - case LEFT: - vel -= right * velocity; - break; - case JUMP: - if (g_OnGround) { - vel.y += 5; - g_OnGround = false; - } - break; - } - g_PlayerVelocityX = vel.x; - g_PlayerVelocityY = vel.y; - g_PlayerVelocityZ = vel.z; + const double playerSpeed = 43; + + float velocity = playerSpeed * deltaTime; + + double playerYaw = Entity::DecodeYaw(player->yaw); + double playerPitch = Entity::DecodePitch(player->pitch); + + glm::vec3 front, right, worldUp, up; + worldUp = glm::vec3(0.0f, 1.0f, 0.0f); + front.x = cos(glm::radians(playerYaw)) * cos(glm::radians(playerPitch)); + front.y = 0; + front.z = sin(glm::radians(playerYaw)) * cos(glm::radians(playerPitch)); + front = glm::normalize(front); + right = glm::normalize(glm::cross(front, worldUp)); + up = glm::normalize(glm::cross(right, front)); + + glm::vec3 vel = player->vel.glm(); + switch (direction) { + case FORWARD: + vel += front * velocity; + break; + case BACKWARD: + vel -= front * velocity; + break; + case RIGHT: + vel += right * velocity; + break; + case LEFT: + vel -= right * velocity; + break; + case JUMP: + if (player->onGround) { + vel.y += 10; + player->onGround = false; + } + break; + } + player->vel = VectorF(vel.x, vel.y, vel.z); } void GameState::HandleRotation(double yaw, double pitch) { if (!g_IsGameStarted) return; - this->SetYaw(Yaw() + yaw); - this->SetPitch(Pitch() + pitch); - if (this->Pitch() > 89.0f) - this->SetPitch(89.0f); - if (this->Pitch() < -89.0f) - this->SetPitch(-89.0f); - this->updateCameraVectors(); - - auto updatePacket = std::make_shared(g_PlayerYaw, g_PlayerPitch, g_OnGround); - nc->SendPacket(updatePacket); + double playerYaw = Entity::DecodeYaw(player->yaw); + double playerPitch = Entity::DecodePitch(player->pitch); + playerYaw += yaw; + playerPitch += pitch; + if (playerPitch > 89.0) + playerPitch = 89.0; + if (playerPitch < -89.0) + playerPitch = -89.0; + player->yaw = Entity::EncodeYaw(playerYaw); + player->pitch = Entity::EncodePitch(playerPitch); } glm::mat4 GameState::GetViewMatrix() { - updateCameraVectors(); - auto pos = this->Position(); - pos.y += 1.62; - return glm::lookAt(pos, pos + this->Front, this->Up); -} - -void GameState::updateCameraVectors() { - glm::vec3 front; - front.x = cos(glm::radians(this->Yaw())) * cos(glm::radians(this->Pitch())); - front.y = sin(glm::radians(this->Pitch())); - front.z = sin(glm::radians(this->Yaw())) * cos(glm::radians(this->Pitch())); - this->Front = glm::normalize(front); - this->Right = glm::normalize(glm::cross(this->Front, this->WorldUp)); - this->Up = glm::normalize(glm::cross(this->Right, this->Front)); -} - -float GameState::Yaw() { - return g_PlayerYaw + 90; -} - -float GameState::Pitch() { - return -g_PlayerPitch; -} - -void GameState::SetYaw(float yaw) { - g_PlayerYaw = yaw - 90; -} - -void GameState::SetPitch(float pitch) { - g_PlayerPitch = -pitch; -} - -glm::vec3 GameState::Position() { - return glm::vec3(g_PlayerX, g_PlayerY, g_PlayerZ); -} + double playerYaw = Entity::DecodeYaw(player->yaw); + double playerPitch = Entity::DecodePitch(player->pitch); + glm::vec3 front, right, worldUp, up; + worldUp = glm::vec3(0.0f, 1.0f, 0.0f); + front.x = cos(glm::radians(playerYaw)) * cos(glm::radians(playerPitch)); + front.y = sin(glm::radians(playerPitch)); + front.z = sin(glm::radians(playerYaw)) * cos(glm::radians(playerPitch)); + front = glm::normalize(front); + right = glm::normalize(glm::cross(front, worldUp)); + up = glm::normalize(glm::cross(right, front)); -void GameState::SetPosition(glm::vec3 Position) { - g_PlayerX = Position.x; - g_PlayerY = Position.y; - g_PlayerZ = Position.z; -} + glm::vec3 eyePos = player->pos.glm(); + eyePos += player->EyeOffset.glm(); + return glm::lookAt(eyePos, eyePos + front, up); +} \ No newline at end of file diff --git a/src/GameState.hpp b/src/GameState.hpp index 659f829..31ec928 100644 --- a/src/GameState.hpp +++ b/src/GameState.hpp @@ -25,7 +25,8 @@ public: void HandleMovement(GameState::Direction direction, float deltaTime); void HandleRotation(double yaw, double pitch); glm::mat4 GetViewMatrix(); - void updateCameraVectors(); + Entity* player; + /*void updateCameraVectors(); float Yaw(); float Pitch(); @@ -37,7 +38,7 @@ public: glm::vec3 Front; glm::vec3 Up; glm::vec3 Right; - glm::vec3 WorldUp; + glm::vec3 WorldUp;*/ World world; @@ -58,17 +59,17 @@ public: bool g_PlayerCreativeMode = false; float g_PlayerFlyingSpeed = 0; float g_PlayerFovModifier = 0; - float g_PlayerPitch = 0; + /*float g_PlayerPitch = 0; float g_PlayerYaw = 0; double g_PlayerX = 0; double g_PlayerY = 0; - double g_PlayerZ = 0; + double g_PlayerZ = 0;*/ float g_PlayerHealth = 0; - bool g_OnGround = true; + /*bool g_OnGround = true; double g_PlayerVelocityX = 0; double g_PlayerVelocityY = 0; - double g_PlayerVelocityZ = 0; + double g_PlayerVelocityZ = 0;*/ long long WorldAge = 0; long long TimeOfDay = 0; diff --git a/src/Render.cpp b/src/Render.cpp index ffa219a..c607a2d 100644 --- a/src/Render.cpp +++ b/src/Render.cpp @@ -9,7 +9,7 @@ #include #include "imgui_impl_sdl_gl3.h" -Render::Render(unsigned int windowWidth, unsigned int windowHeight, std::string windowTitle) : timer(std::chrono::milliseconds(0)) { +Render::Render(unsigned int windowWidth, unsigned int windowHeight, std::string windowTitle) : timer(std::chrono::milliseconds(16)) { InitSfml(windowWidth, windowHeight, windowTitle); glCheckError(); InitGlew(); @@ -297,12 +297,13 @@ void Render::RenderGui() { ImGui::Separator(); ImGui::Text("State: %s", stateString.c_str()); ImGui::Text("FPS: %.1f (%.3fms)", ImGui::GetIO().Framerate, 1000.0f / ImGui::GetIO().Framerate); - float gameTime = DebugInfo::gameThreadTime / 100.0f; - ImGui::Text("TPS: %.1f (%.2fms)", 1000.0f/gameTime, gameTime); - ImGui::Text("Sections loaded: %d", (int)DebugInfo::totalSections); - ImGui::Text("SectionsRenderer: %d (%d)", (int)DebugInfo::renderSections, (int)DebugInfo::readyRenderer); + float gameTime = DebugInfo::gameThreadTime / 100.0f; if (world) { - ImGui::Text("Player pos: %.1f %.1f %.1f", world->GameStatePtr()->g_PlayerX, world->GameStatePtr()->g_PlayerY, world->GameStatePtr()->g_PlayerZ); + ImGui::Text("TPS: %.1f (%.2fms)", 1000.0f / gameTime, gameTime); + ImGui::Text("Sections loaded: %d", (int)DebugInfo::totalSections); + ImGui::Text("SectionsRenderer: %d (%d)", (int)DebugInfo::renderSections, (int)DebugInfo::readyRenderer); + 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::End(); @@ -431,6 +432,9 @@ void Render::RenderGui() { static float sense = sensetivity; ImGui::SliderFloat("Sensetivity", &sense, 0.01f, 1.0f); + static float frameTime = 16.0f; + ImGui::SliderFloat("Frame time", &frameTime, 0.0f, 32.0f); + static bool wireframe = isWireframe; ImGui::Checkbox("Wireframe", &wireframe); @@ -445,6 +449,7 @@ void Render::RenderGui() { sensetivity = sense; isWireframe = wireframe; + timer.SetDelayLength(std::chrono::duration(frameTime)); } ImGui::Separator(); diff --git a/src/RendererWorld.cpp b/src/RendererWorld.cpp index 62fb243..0661b9a 100644 --- a/src/RendererWorld.cpp +++ b/src/RendererWorld.cpp @@ -50,7 +50,7 @@ void RendererWorld::WorkerFunction(size_t workerId) { void RendererWorld::UpdateAllSections(VectorF playerPos) { - Vector playerChunk(std::floor(gs->g_PlayerX / 16), 0, std::floor(gs->g_PlayerZ / 16)); + Vector playerChunk(std::floor(gs->player->pos.x / 16), 0, std::floor(gs->player->pos.z / 16)); std::vector suitableChunks; auto chunks = gs->world.GetSectionsList(); @@ -74,7 +74,7 @@ void RendererWorld::UpdateAllSections(VectorF playerPos) EventAgregator::PushEvent(EventType::DeleteSectionRender, DeleteSectionRenderData{ it }); } - playerChunk.y = std::floor(gs->g_PlayerY / 16.0); + playerChunk.y = std::floor(gs->player->pos.y / 16.0); std::sort(suitableChunks.begin(), suitableChunks.end(), [playerChunk](Vector lhs, Vector rhs) { double leftLengthToPlayer = (playerChunk - lhs).GetLength(); double rightLengthToPlayer = (playerChunk - rhs).GetLength(); @@ -146,7 +146,7 @@ RendererWorld::RendererWorld(std::shared_ptr ptr):gs(ptr) { listener.RegisterHandler(EventType::ChunkChanged, [this](EventData eventData) { auto vec = std::get(eventData).chunkPosition; - Vector playerChunk(std::floor(gs->g_PlayerX / 16), 0, std::floor(gs->g_PlayerZ / 16)); + Vector playerChunk(std::floor(gs->player->pos.x / 16), 0, std::floor(gs->player->pos.z / 16)); double distanceToChunk = (Vector(vec.x, 0, vec.z) - playerChunk).GetLength(); if (MaxRenderingDistance != 1000 && distanceToChunk > MaxRenderingDistance) { @@ -169,7 +169,7 @@ RendererWorld::RendererWorld(std::shared_ptr ptr):gs(ptr) { }); listener.RegisterHandler(EventType::UpdateSectionsRender, [this](EventData eventData) { - UpdateAllSections(VectorF(gs->g_PlayerX,gs->g_PlayerY,gs->g_PlayerZ)); + UpdateAllSections(gs->player->pos); }); listener.RegisterHandler(EventType::PlayerPosChanged, [this](EventData eventData) { @@ -211,84 +211,21 @@ RendererWorld::~RendererWorld() { } void RendererWorld::Render(RenderState & renderState) { - renderState.TimeOfDay = gs->TimeOfDay; - renderState.SetActiveShader(blockShader->Program); - glCheckError(); - - GLint projectionLoc = glGetUniformLocation(blockShader->Program, "projection"); - GLint viewLoc = glGetUniformLocation(blockShader->Program, "view"); - GLint windowSizeLoc = glGetUniformLocation(blockShader->Program, "windowSize"); + //Common + GLint projectionLoc, viewLoc, modelLoc, pvLoc, windowSizeLoc, colorLoc; glm::mat4 projection = glm::perspective(45.0f, (float)renderState.WindowWidth / (float)renderState.WindowHeight, 0.1f, 10000000.0f); glm::mat4 view = gs->GetViewMatrix(); - glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, glm::value_ptr(projection)); - glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view)); - glUniform2f(windowSizeLoc, renderState.WindowWidth, renderState.WindowHeight); - glCheckError(); - - sectionsMutex.lock(); - for (auto& section : sections) { - sectionsMutex.unlock(); - std::vector sectionCorners = { - Vector(0, 0, 0), - Vector(0, 0, 16), - Vector(0, 16, 0), - Vector(0, 16, 16), - Vector(16, 0, 0), - Vector(16, 0, 16), - Vector(16, 16, 0), - Vector(16, 16, 16), - }; - bool isBreak = true; - glm::mat4 vp = projection * view; - for (auto &it : sectionCorners) { - glm::vec3 point(section.second.GetPosition().x * 16 + it.x, - section.second.GetPosition().y * 16 + it.y, - section.second.GetPosition().z * 16 + it.z); - glm::vec4 p = vp * glm::vec4(point, 1); - glm::vec3 res = glm::vec3(p) / p.w; - if (res.x < 1 && res.x > -1 && res.y < 1 && res.y > -1 && res.z > 0) { - isBreak = false; - break; - } - } - double lengthToSection = (VectorF(gs->g_PlayerX, gs->g_PlayerY, gs->g_PlayerZ) - VectorF(section.first.x*16,section.first.y*16,section.first.z*16)).GetLength(); - - if (isBreak && lengthToSection > 30.0f) { - sectionsMutex.lock(); - continue; - } - section.second.Render(renderState); - sectionsMutex.lock(); - } - sectionsMutex.unlock(); - glCheckError(); - - glLineWidth(3.0); - renderState.SetActiveShader(entityShader->Program); - glCheckError(); - projectionLoc = glGetUniformLocation(entityShader->Program, "projection"); - viewLoc = glGetUniformLocation(entityShader->Program, "view"); - glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, glm::value_ptr(projection)); - glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view)); - glCheckError(); - GLint modelLoc = glGetUniformLocation(entityShader->Program, "model"); - GLint colorLoc = glGetUniformLocation(entityShader->Program, "color"); - for (auto& it : entities) { - it.modelLoc = modelLoc; - it.colorLoc = colorLoc; - it.Render(renderState); - } - glLineWidth(1.0); - - + glm::mat4 projView = projection * view; + //Render sky + renderState.TimeOfDay = gs->TimeOfDay; renderState.SetActiveShader(skyShader->Program); projectionLoc = glGetUniformLocation(skyShader->Program, "projection"); viewLoc = glGetUniformLocation(skyShader->Program, "view"); glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, glm::value_ptr(projection)); glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view)); glm::mat4 model = glm::mat4(); - model = glm::translate(model, gs->Position()); + model = glm::translate(model, gs->player->pos.glm()); const float scale = 1000000.0f; model = glm::scale(model, glm::vec3(scale, scale, scale)); float shift = gs->TimeOfDay / 24000.0f; @@ -308,7 +245,7 @@ void RendererWorld::Render(RenderState & renderState) { const float sunriseLength = sunriseMax - sunriseMin; const float moonriseLength = moonriseMax - moonriseMin; - float mixLevel=0; + float mixLevel = 0; int dayTime = gs->TimeOfDay; if (dayTime < 0) dayTime *= -1; @@ -325,10 +262,78 @@ void RendererWorld::Render(RenderState & renderState) { mixLevel = 1.0 - (timePassed / moonriseLength); } - glUniform1f(glGetUniformLocation(skyShader->Program,"DayTime"), mixLevel); + glUniform1f(glGetUniformLocation(skyShader->Program, "DayTime"), mixLevel); rendererSky.Render(renderState); glCheckError(); + + //Render Entities + glLineWidth(3.0); + renderState.SetActiveShader(entityShader->Program); + glCheckError(); + projectionLoc = glGetUniformLocation(entityShader->Program, "projection"); + viewLoc = glGetUniformLocation(entityShader->Program, "view"); + glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, glm::value_ptr(projection)); + glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view)); + glCheckError(); + modelLoc = glGetUniformLocation(entityShader->Program, "model"); + colorLoc = glGetUniformLocation(entityShader->Program, "color"); + for (auto& it : entities) { + it.modelLoc = modelLoc; + it.colorLoc = colorLoc; + it.Render(renderState); + } + glLineWidth(1.0); + glCheckError(); + + //Render sections + renderState.SetActiveShader(blockShader->Program); + projectionLoc = glGetUniformLocation(blockShader->Program, "projection"); + viewLoc = glGetUniformLocation(blockShader->Program, "view"); + windowSizeLoc = glGetUniformLocation(blockShader->Program, "windowSize"); + pvLoc = glGetUniformLocation(blockShader->Program, "projView"); + + glUniformMatrix4fv(pvLoc, 1, GL_FALSE, glm::value_ptr(projView)); + glUniform2f(windowSizeLoc, renderState.WindowWidth, renderState.WindowHeight); + glCheckError(); + + sectionsMutex.lock(); + for (auto& section : sections) { + sectionsMutex.unlock(); + std::vector sectionCorners = { + Vector(0, 0, 0), + Vector(0, 0, 16), + Vector(0, 16, 0), + Vector(0, 16, 16), + Vector(16, 0, 0), + Vector(16, 0, 16), + Vector(16, 16, 0), + Vector(16, 16, 16), + }; + bool isBreak = true; + glm::mat4 vp = projection * view; + for (auto &it : sectionCorners) { + glm::vec3 point(section.second.GetPosition().x * 16 + it.x, + section.second.GetPosition().y * 16 + it.y, + section.second.GetPosition().z * 16 + it.z); + glm::vec4 p = vp * glm::vec4(point, 1); + glm::vec3 res = glm::vec3(p) / p.w; + if (res.x < 1 && res.x > -1 && res.y < 1 && res.y > -1 && res.z > 0) { + isBreak = false; + break; + } + } + double lengthToSection = (gs->player->pos - VectorF(section.first.x*16,section.first.y*16,section.first.z*16)).GetLength(); + + if (isBreak && lengthToSection > 30.0f) { + sectionsMutex.lock(); + continue; + } + section.second.Render(renderState); + sectionsMutex.lock(); + } + sectionsMutex.unlock(); + glCheckError(); } void RendererWorld::PrepareRender() { diff --git a/src/Utility.hpp b/src/Utility.hpp index 064f4dd..8333052 100644 --- a/src/Utility.hpp +++ b/src/Utility.hpp @@ -7,8 +7,6 @@ #include #include -//using Uuid = std::array; -//using Uuid = unsigned char[16]; using Uuid = std::vector; template diff --git a/src/World.cpp b/src/World.cpp index 0176a91..7b150b7 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -134,10 +134,76 @@ glm::vec3 World::Raycast(glm::vec3 position, glm::vec3 direction, float maxLengt void World::UpdatePhysics(float delta) { - delta /= 5; + struct CollisionResult { + bool isCollide; + //Vector block; + //VectorF pos; + //VectorF dir; + }; + + 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; + int blockYEnd = pos.y + height + 0.5; + int blockZBegin = pos.z - width - 0.5; + int blockZEnd = pos.z + width + 0.5; + + AABB entityCollBox; + entityCollBox.x = pos.x - width / 2.0; + entityCollBox.y = pos.y; + entityCollBox.z = pos.z - width / 2.0; + + entityCollBox.w = width; + entityCollBox.h = height; + entityCollBox.l = width; + + for (int y = blockYBegin; y <= blockYEnd; y++) { + for (int z = blockZBegin; z <= blockZEnd; z++) { + for (int x = blockXBegin; x <= blockXEnd; x++) { + BlockId block = this->GetBlockId(Vector(x, y, z)); + if (block.id == 0 || block.id == 31) + continue; + AABB blockColl{ x,y,z,1.0,1.0,1.0 }; + if (TestCollision(entityCollBox, blockColl)) { + return { true }; + } + } + } + } + return { false }; + }; + entitiesMutex.lock(); for (auto& it : entities) { - it.pos = it.pos + it.vel * delta; + { //Vertical velocity + it.vel.y -= it.gravity * delta; + VectorF newPos = it.pos + VectorF(0, it.vel.y, 0) * delta; + auto coll = testCollision(it.width, it.height, newPos); + if (coll.isCollide) { + it.vel = VectorF(it.vel.x, 0, it.vel.z); + it.onGround = true; + } + else { + it.pos = newPos; + } + } + { //Horizontal velocity + VectorF newPos = it.pos + VectorF(it.vel.x, 0, it.vel.z) * delta; + auto coll = testCollision(it.width, it.height, newPos); + if (coll.isCollide) { + it.vel = VectorF(0, it.vel.y, 0); + } + else { + it.pos = newPos; + } + + const float AirResistance = 10.0f; + VectorF resistForce = it.vel * AirResistance * delta * -1.0; + resistForce.y = 0.0; + it.vel = it.vel + resistForce; + } } entitiesMutex.unlock(); DebugInfo::totalSections = sections.size(); @@ -247,7 +313,7 @@ BlockId World::GetBlockId(Vector pos) { Vector sectionPos(std::floor(pos.x / 16.0), std::floor(pos.y / 16.0), std::floor(pos.z / 16.0)); Section* section = GetSectionPtr(sectionPos); - return section->GetBlockId(pos - (sectionPos * 16)); + return !section ? BlockId{0, 0} : section->GetBlockId(pos - (sectionPos * 16)); } void World::SetBlockId(Vector pos, BlockId block) { @@ -272,4 +338,16 @@ Section *World::GetSectionPtr(Vector position) { return nullptr; return it->second.get(); +} + +Entity* World::GetEntityPtr(unsigned int EntityId) { + entitiesMutex.lock(); + for (auto& it : entities) { + if (it.entityId == EntityId) { + entitiesMutex.unlock(); + return ⁢ + } + } + entitiesMutex.unlock(); + return nullptr; } \ No newline at end of file diff --git a/src/World.hpp b/src/World.hpp index 6b8b5d1..31290c8 100644 --- a/src/World.hpp +++ b/src/World.hpp @@ -22,7 +22,7 @@ class World { Section ParseSection(StreamInput *data, Vector position); - std::vector entities; + std::list entities; std::mutex entitiesMutex; @@ -57,6 +57,8 @@ public: Entity& GetEntity(unsigned int EntityId); + Entity* GetEntityPtr(unsigned int EntityId); + std::vector GetEntitiesList(); void AddEntity(Entity entity); diff --git a/src/main.cpp b/src/main.cpp index 4130bf3..aa7383d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,6 +4,8 @@ #include "ThreadRender.hpp" #include "ThreadNetwork.hpp" +#include + const char *getTimeSinceProgramStart(void) { static auto initialTime = std::chrono::steady_clock().now(); auto now = std::chrono::steady_clock().now(); @@ -18,6 +20,7 @@ INITIALIZE_EASYLOGGINGPP #undef main int main(int argc, char** argv) { + srand(time(0)); el::Configurations loggerConfiguration; el::Helpers::installCustomFormatSpecifier( el::CustomFormatSpecifier("%startTime", std::bind(getTimeSinceProgramStart))); -- cgit v1.2.3