Merge pull request #56 from A-lex-Ra/main
placing non-obstacle blocks feature
This commit is contained in:
commit
cbdc3b2b10
@ -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";
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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();
|
||||
};
|
||||
|
||||
|
||||
@ -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));
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user