Merge pull request #56 from A-lex-Ra/main

placing non-obstacle blocks feature
This commit is contained in:
MihailRis 2023-12-11 19:38:04 +03:00 committed by GitHub
commit cbdc3b2b10
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 125 additions and 8 deletions

View File

@ -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";

View File

@ -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);

View File

@ -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);

View File

@ -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() {
@ -257,7 +277,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);
}

View File

@ -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();
};

View File

@ -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));
}

View File

@ -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;

View File

@ -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<float>::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);

View File

@ -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