From 3ae3001227d1b018df92e8a38d3d00feddad9c12 Mon Sep 17 00:00:00 2001 From: A-lex-Ra Date: Mon, 11 Dec 2023 15:24:36 +0600 Subject: [PATCH 1/2] placing non-obstacle blocks --- src/logic/PlayerController.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/logic/PlayerController.cpp b/src/logic/PlayerController.cpp index f731f9e2..ab28f9fa 100644 --- a/src/logic/PlayerController.cpp +++ b/src/logic/PlayerController.cpp @@ -257,7 +257,8 @@ void PlayerController::updateInteraction(){ } vox = chunks->get(x, y, z); if (vox && (block = contentIds->getBlockDef(vox->id))->replaceable) { - if (!level->physics->isBlockInside(x,y,z, player->hitbox)){ + if (!level->physics->isBlockInside(x,y,z, player->hitbox) + || !def->obstacle){ chunks->set(x, y, z, player->choosenBlock, states); lighting->onBlockSet(x,y,z, player->choosenBlock); } From 20caa4b9802daf199a320c89d9b251720d5d3b85 Mon Sep 17 00:00:00 2001 From: A-lex-Ra Date: Mon, 11 Dec 2023 22:22:52 +0600 Subject: [PATCH 2/2] SP and TP cameras --- src/core_defs.h | 1 + src/definitions.cpp | 1 + src/frontend/screens.cpp | 2 +- src/logic/PlayerController.cpp | 26 ++++++++-- src/logic/PlayerController.h | 4 +- src/objects/Player.cpp | 3 ++ src/objects/Player.h | 3 +- src/voxels/Chunks.cpp | 88 ++++++++++++++++++++++++++++++++++ src/voxels/Chunks.h | 2 + 9 files changed, 123 insertions(+), 7 deletions(-) diff --git a/src/core_defs.h b/src/core_defs.h index def3ce66..78aea0ef 100644 --- a/src/core_defs.h +++ b/src/core_defs.h @@ -16,6 +16,7 @@ const std::string BIND_MOVE_SPRINT = "movement.sprint"; const std::string BIND_MOVE_CROUCH = "movement.crouch"; const std::string BIND_MOVE_CHEAT = "movement.cheat"; const std::string BIND_CAM_ZOOM = "camera.zoom"; +const std::string BIND_CAM_MODE = "camera.mode"; const std::string BIND_PLAYER_NOCLIP = "player.noclip"; const std::string BIND_PLAYER_FLIGHT = "player.flight"; const std::string BIND_PLAYER_ATTACK = "player.attack"; diff --git a/src/definitions.cpp b/src/definitions.cpp index 83553ca8..40dcb105 100644 --- a/src/definitions.cpp +++ b/src/definitions.cpp @@ -33,6 +33,7 @@ void setup_bindings() { Events::bind(BIND_MOVE_CROUCH, inputtype::keyboard, keycode::LEFT_SHIFT); Events::bind(BIND_MOVE_CHEAT, inputtype::keyboard, keycode::R); Events::bind(BIND_CAM_ZOOM, inputtype::keyboard, keycode::C); + Events::bind(BIND_CAM_MODE, inputtype::keyboard, keycode::F4); Events::bind(BIND_PLAYER_NOCLIP, inputtype::keyboard, keycode::N); Events::bind(BIND_PLAYER_FLIGHT, inputtype::keyboard, keycode::F); Events::bind(BIND_PLAYER_ATTACK, inputtype::mouse, mousecode::BUTTON_1); diff --git a/src/frontend/screens.cpp b/src/frontend/screens.cpp index 23235583..5988d992 100644 --- a/src/frontend/screens.cpp +++ b/src/frontend/screens.cpp @@ -180,7 +180,7 @@ void LevelScreen::update(float delta) { } void LevelScreen::draw(float delta) { - Camera* camera = level->player->camera; + Camera* camera = level->player->currentViewCamera; Viewport viewport(Window::width, Window::height); GfxContext ctx(nullptr, viewport, nullptr); diff --git a/src/logic/PlayerController.cpp b/src/logic/PlayerController.cpp index ab28f9fa..da594c15 100644 --- a/src/logic/PlayerController.cpp +++ b/src/logic/PlayerController.cpp @@ -32,6 +32,7 @@ using std::string; CameraControl::CameraControl(Player* player, const CameraSettings& settings) : player(player), camera(player->camera), + currentViewCamera(player->currentViewCamera), //TODO "start view" settings (for custom worlds and minigames, maybe) settings(settings), offset(0.0f, 0.7f, 0.0f) { } @@ -65,7 +66,7 @@ void CameraControl::updateMouse(PlayerInput& input) { camera->rotate(camY, camX, 0); } -void CameraControl::update(PlayerInput& input, float delta) { +void CameraControl::update(PlayerInput& input, float delta, Chunks* chunks) { Hitbox* hitbox = player->hitbox; offset = vec3(0.0f, 0.7f, 0.0f); @@ -106,6 +107,25 @@ void CameraControl::update(PlayerInput& input, float delta) { zoomValue *= C_ZOOM; camera->zoom = zoomValue * dt + camera->zoom * (1.0f - dt); } + + if (input.cameraMode) { //ugly but effective + if (player->currentViewCamera == camera) + player->currentViewCamera = player->SPCamera; + else if (player->currentViewCamera == player->SPCamera) + player->currentViewCamera = player->TPCamera; + else if (player->currentViewCamera == player->TPCamera) + player->currentViewCamera = camera; + } + if (player->currentViewCamera == player->SPCamera) { + player->SPCamera->position = chunks->rayCastToObstacle(camera->position, camera->front, 3.0f); + player->SPCamera->dir = -camera->dir; + player->SPCamera->front = -camera->front; + } + else if (player->currentViewCamera == player->TPCamera) { + player->TPCamera->position = chunks->rayCastToObstacle(camera->position, -camera->front, 3.0f); + player->TPCamera->dir = camera->dir; + player->TPCamera->front = camera->front; + } } vec3 PlayerController::selectedBlockPosition; @@ -150,7 +170,7 @@ void PlayerController::updateKeyboard() { input.cheat = Events::active(BIND_MOVE_CHEAT); input.jump = Events::active(BIND_MOVE_JUMP); input.zoom = Events::active(BIND_CAM_ZOOM); - + input.cameraMode = Events::jactive(BIND_CAM_MODE); input.noclip = Events::jactive(BIND_PLAYER_NOCLIP); input.flight = Events::jactive(BIND_PLAYER_FLIGHT); @@ -166,7 +186,7 @@ void PlayerController::updateCamera(float delta, bool movement) { if (movement) { camControl.updateMouse(input); } - camControl.update(input, delta); + camControl.update(input, delta, level->chunks); } void PlayerController::resetKeyboard() { diff --git a/src/logic/PlayerController.h b/src/logic/PlayerController.h index 158b0b87..6893382b 100644 --- a/src/logic/PlayerController.h +++ b/src/logic/PlayerController.h @@ -11,7 +11,7 @@ class Level; class CameraControl { Player* player; - Camera* camera; + Camera* camera, *currentViewCamera; const CameraSettings& settings; glm::vec3 offset; float shake = 0.0f; @@ -20,7 +20,7 @@ class CameraControl { public: CameraControl(Player* player, const CameraSettings& settings); void updateMouse(PlayerInput& input); - void update(PlayerInput& input, float delta); + void update(PlayerInput& input, float delta, Chunks* chunks); void refresh(); }; diff --git a/src/objects/Player.cpp b/src/objects/Player.cpp index 8b294cb6..df93d2ef 100644 --- a/src/objects/Player.cpp +++ b/src/objects/Player.cpp @@ -20,6 +20,9 @@ Player::Player(glm::vec3 position, float speed) : speed(speed), choosenBlock(1) { camera = new Camera(position, glm::radians(90.0f)); + currentViewCamera = camera; + SPCamera = new Camera(position, glm::radians(90.0f)); + TPCamera = new Camera(position, glm::radians(90.0f)); hitbox = new Hitbox(position, vec3(0.3f,0.9f,0.3f)); } diff --git a/src/objects/Player.h b/src/objects/Player.h index cc2b4b9b..65d3ff40 100644 --- a/src/objects/Player.h +++ b/src/objects/Player.h @@ -14,6 +14,7 @@ class Level; struct PlayerInput { bool zoom; + bool cameraMode; bool moveForward; bool moveBack; bool moveRight; @@ -29,7 +30,7 @@ struct PlayerInput { class Player { float speed; public: - Camera* camera; + Camera* camera, *SPCamera, *TPCamera, *currentViewCamera; Hitbox* hitbox; bool flight = false; bool noclip = false; diff --git a/src/voxels/Chunks.cpp b/src/voxels/Chunks.cpp index 13b4631f..498549bc 100644 --- a/src/voxels/Chunks.cpp +++ b/src/voxels/Chunks.cpp @@ -289,6 +289,94 @@ voxel* Chunks::rayCast(vec3 start, return nullptr; } +vec3 Chunks::rayCastToObstacle(vec3 start, vec3 dir, float maxDist) { + float px = start.x; + float py = start.y; + float pz = start.z; + + float dx = dir.x; + float dy = dir.y; + float dz = dir.z; + + float t = 0.0f; + int ix = floor(px); + int iy = floor(py); + int iz = floor(pz); + + int stepx = (dx > 0.0f) ? 1 : -1; + int stepy = (dy > 0.0f) ? 1 : -1; + int stepz = (dz > 0.0f) ? 1 : -1; + + constexpr float infinity = std::numeric_limits::infinity(); + + float txDelta = (dx == 0.0f) ? infinity : abs(1.0f / dx); + float tyDelta = (dy == 0.0f) ? infinity : abs(1.0f / dy); + float tzDelta = (dz == 0.0f) ? infinity : abs(1.0f / dz); + + float xdist = (stepx > 0) ? (ix + 1 - px) : (px - ix); + float ydist = (stepy > 0) ? (iy + 1 - py) : (py - iy); + float zdist = (stepz > 0) ? (iz + 1 - pz) : (pz - iz); + + float txMax = (txDelta < infinity) ? txDelta * xdist : infinity; + float tyMax = (tyDelta < infinity) ? tyDelta * ydist : infinity; + float tzMax = (tzDelta < infinity) ? tzDelta * zdist : infinity; + + int steppedIndex = -1; + + while (t <= maxDist) { + voxel* voxel = get(ix, iy, iz); + if (!voxel) { return vec3(px + t * dx, py + t * dy, pz + t * dz); } + + const Block* def = contentIds->getBlockDef(voxel->id); + if (def->obstacle) { + if (!def->rt.solid) { + const AABB& box = def->rotatable + ? def->rt.hitboxes[voxel->rotation()] + : def->hitbox; + scalar_t distance; + ivec3 norm; + // norm is dummy now, can be inefficient + if (Rays::rayIntersectAABB(start, dir, ivec3(ix, iy, iz), box, maxDist, norm, distance) > RayRelation::None) { + return start + (dir * vec3(distance)); + } + } + else { + return vec3(px + t * dx, py + t * dy, pz + t * dz); + } + } + if (txMax < tyMax) { + if (txMax < tzMax) { + ix += stepx; + t = txMax; + txMax += txDelta; + steppedIndex = 0; + } + else { + iz += stepz; + t = tzMax; + tzMax += tzDelta; + steppedIndex = 2; + } + } + else { + if (tyMax < tzMax) { + iy += stepy; + t = tyMax; + tyMax += tyDelta; + steppedIndex = 1; + } + else { + iz += stepz; + t = tzMax; + tzMax += tzDelta; + steppedIndex = 2; + } + } + } + return vec3(px + maxDist * dx, py + maxDist * dy, pz + maxDist * dz); +} + + void Chunks::setCenter(int x, int z) { int cx = floordiv(x, CHUNK_W); int cz = floordiv(z, CHUNK_D); diff --git a/src/voxels/Chunks.h b/src/voxels/Chunks.h index 78ed84bb..7b4fb9ac 100644 --- a/src/voxels/Chunks.h +++ b/src/voxels/Chunks.h @@ -51,6 +51,8 @@ public: glm::ivec3& norm, glm::ivec3& iend); + glm::vec3 rayCastToObstacle(glm::vec3 start, glm::vec3 dir, float maxDist); + const AABB* isObstacle(float x, float y, float z); // does not move chunks inside