remove Player.hitbox (WIP)

This commit is contained in:
MihailRis 2024-07-08 03:51:46 +03:00
parent 2c7b5de50a
commit 7dfda981a8
11 changed files with 108 additions and 94 deletions

View File

@ -1,3 +1,3 @@
{ {
"hitbox": [0.5, 1.8, 0.5] "hitbox": [0.6, 1.8, 0.6]
} }

View File

@ -129,20 +129,18 @@ std::shared_ptr<UINode> create_debug_panel(
auto box = std::make_shared<TextBox>(L""); auto box = std::make_shared<TextBox>(L"");
auto boxRef = box.get(); auto boxRef = box.get();
box->setTextSupplier([=]() { box->setTextSupplier([=]() {
Hitbox* hitbox = player->hitbox.get(); return util::to_wstring(player->getPosition()[ax], 2);
return util::to_wstring(hitbox->position[ax], 2);
}); });
box->setTextConsumer([=](const std::wstring& text) { box->setTextConsumer([=](const std::wstring& text) {
try { try {
glm::vec3 position = player->hitbox->position; glm::vec3 position = player->getPosition();
position[ax] = std::stoi(text); position[ax] = std::stoi(text);
player->teleport(position); player->teleport(position);
} catch (std::exception& _){ } catch (std::exception& _){
} }
}); });
box->setOnEditStart([=](){ box->setOnEditStart([=](){
Hitbox* hitbox = player->hitbox.get(); boxRef->setText(std::to_wstring(static_cast<int>(player->getPosition()[ax])));
boxRef->setText(std::to_wstring(int(hitbox->position[ax])));
}); });
box->setSize(glm::vec2(230, 27)); box->setSize(glm::vec2(230, 27));

View File

@ -136,9 +136,13 @@ void LevelScreen::update(float delta) {
bool paused = hud->isPause(); bool paused = hud->isPause();
audio::get_channel("regular")->setPaused(paused); audio::get_channel("regular")->setPaused(paused);
audio::get_channel("ambient")->setPaused(paused); audio::get_channel("ambient")->setPaused(paused);
glm::vec3 velocity {};
if (auto hitbox = player->getHitbox()) {
velocity = hitbox->velocity;
}
audio::set_listener( audio::set_listener(
camera->position-camera->dir, camera->position-camera->dir,
player->hitbox->velocity, velocity,
camera->dir, camera->dir,
glm::vec3(0, 1, 0) glm::vec3(0, 1, 0)
); );

View File

@ -25,7 +25,7 @@ LevelController::LevelController(EngineSettings& settings, std::unique_ptr<Level
} }
void LevelController::update(float delta, bool input, bool pause) { void LevelController::update(float delta, bool input, bool pause) {
glm::vec3 position = player->getPlayer()->hitbox->position; glm::vec3 position = player->getPlayer()->getPosition();
level->loadMatrix(position.x, position.z, level->loadMatrix(position.x, position.z,
settings.chunks.loadDistance.get() + settings.chunks.loadDistance.get() +
settings.chunks.padding.get() * 2); settings.chunks.padding.get() * 2);

View File

@ -46,7 +46,7 @@ CameraControl::CameraControl(const std::shared_ptr<Player>& player, const Camera
} }
void CameraControl::refresh() { void CameraControl::refresh() {
camera->position = player->hitbox->position + offset; camera->position = player->getPosition() + offset;
} }
void CameraControl::updateMouse(PlayerInput& input) { void CameraControl::updateMouse(PlayerInput& input) {
@ -77,20 +77,19 @@ void CameraControl::updateMouse(PlayerInput& input) {
camera->rotate(glm::radians(cam.y), glm::radians(cam.x), glm::radians(cam.z)); camera->rotate(glm::radians(cam.y), glm::radians(cam.x), glm::radians(cam.z));
} }
glm::vec3 CameraControl::updateCameraShaking(float delta) { glm::vec3 CameraControl::updateCameraShaking(const Hitbox& hitbox, float delta) {
glm::vec3 offset {}; glm::vec3 offset {};
auto hitbox = player->hitbox.get();
const float k = CAM_SHAKE_DELTA_K; const float k = CAM_SHAKE_DELTA_K;
const float ov = CAM_SHAKE_OFFSET_Y; const float ov = CAM_SHAKE_OFFSET_Y;
const glm::vec3& vel = hitbox->velocity; const glm::vec3& vel = hitbox.velocity;
interpVel = interpVel * (1.0f - delta * 5) + vel * delta * 0.1f; interpVel = interpVel * (1.0f - delta * 5) + vel * delta * 0.1f;
if (hitbox->grounded && interpVel.y < 0.0f){ if (hitbox.grounded && interpVel.y < 0.0f){
interpVel.y *= -30.0f; interpVel.y *= -30.0f;
} }
shake = shake * (1.0f - delta * k); shake = shake * (1.0f - delta * k);
float oh = CAM_SHAKE_OFFSET; float oh = CAM_SHAKE_OFFSET;
if (hitbox->grounded) { if (hitbox.grounded) {
float f = glm::length(glm::vec2(vel.x, vel.z)); float f = glm::length(glm::vec2(vel.x, vel.z));
shakeTimer += delta * f * CAM_SHAKE_SPEED; shakeTimer += delta * f * CAM_SHAKE_SPEED;
shake += f * delta * k; shake += f * delta * k;
@ -103,9 +102,9 @@ glm::vec3 CameraControl::updateCameraShaking(float delta) {
return offset; return offset;
} }
void CameraControl::updateFovEffects(const PlayerInput& input, float delta) { void CameraControl::updateFovEffects(const Hitbox& hitbox,
auto hitbox = player->hitbox.get(); const PlayerInput& input, float delta) {
bool crouch = input.shift && hitbox->grounded && !input.sprint; bool crouch = input.shift && hitbox.grounded && !input.sprint;
float dt = fmin(1.0f, delta * ZOOM_SPEED); float dt = fmin(1.0f, delta * ZOOM_SPEED);
float zoomValue = 1.0f; float zoomValue = 1.0f;
@ -146,11 +145,13 @@ void CameraControl::switchCamera() {
void CameraControl::update(const PlayerInput& input, float delta, Chunks* chunks) { void CameraControl::update(const PlayerInput& input, float delta, Chunks* chunks) {
offset = glm::vec3(0.0f, 0.7f, 0.0f); offset = glm::vec3(0.0f, 0.7f, 0.0f);
if (settings.shaking.get() && !input.cheat) { if (auto hitbox = player->getHitbox()) {
offset += updateCameraShaking(delta); if (settings.shaking.get() && !input.cheat) {
} offset += updateCameraShaking(*hitbox, delta);
if (settings.fovEffects.get()){ }
updateFovEffects(input, delta); if (settings.fovEffects.get()){
updateFovEffects(*hitbox, input, delta);
}
} }
if (input.cameraMode) { if (input.cameraMode) {
switchCamera(); switchCamera();
@ -192,10 +193,9 @@ void PlayerController::onBlockInteraction(
} }
} }
void PlayerController::onFootstep() { void PlayerController::onFootstep(const Hitbox& hitbox) {
auto hitbox = player->hitbox.get(); auto pos = hitbox.position;
glm::vec3 pos = hitbox->position; auto half = hitbox.halfsize;
glm::vec3 half = hitbox->halfsize;
for (int offsetZ = -1; offsetZ <= 1; offsetZ++) { for (int offsetZ = -1; offsetZ <= 1; offsetZ++) {
for (int offsetX = -1; offsetX <= 1; offsetX++) { for (int offsetX = -1; offsetX <= 1; offsetX++) {
@ -218,15 +218,14 @@ void PlayerController::onFootstep() {
} }
void PlayerController::updateFootsteps(float delta) { void PlayerController::updateFootsteps(float delta) {
auto hitbox = player->hitbox.get(); auto hitbox = player->getHitbox();
if (hitbox && hitbox->grounded) {
if (hitbox->grounded) {
const glm::vec3& vel = hitbox->velocity; const glm::vec3& vel = hitbox->velocity;
float f = glm::length(glm::vec2(vel.x, vel.z)); float f = glm::length(glm::vec2(vel.x, vel.z));
stepsTimer += delta * f * STEPS_SPEED; stepsTimer += delta * f * STEPS_SPEED;
if (stepsTimer >= M_PI) { if (stepsTimer >= M_PI) {
stepsTimer = fmod(stepsTimer, M_PI); stepsTimer = fmod(stepsTimer, M_PI);
onFootstep(); onFootstep(*hitbox);
} }
} else { } else {
stepsTimer = M_PI; stepsTimer = M_PI;
@ -289,8 +288,8 @@ void PlayerController::resetKeyboard() {
} }
void PlayerController::updatePlayer(float delta) { void PlayerController::updatePlayer(float delta) {
player->updateEntity(level); player->updateEntity();
player->updateInput(level, input, delta); player->updateInput(input, delta);
} }
static int determine_rotation(Block* def, const glm::ivec3& norm, glm::vec3& camDir) { static int determine_rotation(Block* def, const glm::ivec3& norm, glm::vec3& camDir) {
@ -395,8 +394,9 @@ void PlayerController::processRightClick(Block* def, Block* target) {
} }
blockid_t chosenBlock = def->rt.id; blockid_t chosenBlock = def->rt.id;
if (def->obstacle && level->physics->isBlockInside( auto hitbox = player->getHitbox();
coord.x, coord.y, coord.z, def,state, player->hitbox.get())) { if (hitbox && def->obstacle && level->physics->isBlockInside(
coord.x, coord.y, coord.z, def,state, hitbox)) {
return; return;
} }
auto vox = chunks->get(coord); auto vox = chunks->get(coord);

View File

@ -13,6 +13,7 @@ class Level;
class Block; class Block;
class Chunks; class Chunks;
class BlocksController; class BlocksController;
struct Hitbox;
struct CameraSettings; struct CameraSettings;
class CameraControl { class CameraControl {
@ -27,17 +28,19 @@ class CameraControl {
/// @brief Update shaking timer and calculate camera offset /// @brief Update shaking timer and calculate camera offset
/// @param delta delta time /// @param delta delta time
/// @return camera offset /// @return camera offset
glm::vec3 updateCameraShaking(float delta); glm::vec3 updateCameraShaking(const Hitbox& hitbox, float delta);
/// @brief Update field-of-view effects /// @brief Update field-of-view effects
/// @param input player inputs /// @param input player inputs
/// @param delta delta time /// @param delta delta time
void updateFovEffects(const PlayerInput& input, float delta); void updateFovEffects(const Hitbox& hitbox, const PlayerInput& input,
float delta);
/// @brief Switch active player camera /// @brief Switch active player camera
void switchCamera(); void switchCamera();
public: public:
CameraControl(const std::shared_ptr<Player>& player, const CameraSettings& settings); CameraControl(const std::shared_ptr<Player>& player,
const CameraSettings& settings);
void updateMouse(PlayerInput& input); void updateMouse(PlayerInput& input);
void update(const PlayerInput& input, float delta, Chunks* chunks); void update(const PlayerInput& input, float delta, Chunks* chunks);
void refresh(); void refresh();
@ -74,7 +77,7 @@ class PlayerController {
); );
float stepsTimer = 0.0f; float stepsTimer = 0.0f;
void onFootstep(); void onFootstep(const Hitbox& hitbox);
void updateFootsteps(float delta); void updateFootsteps(float delta);
void processRightClick(Block* def, Block* target); void processRightClick(Block* def, Block* target);

View File

@ -2,6 +2,7 @@
#include "../../../world/Level.hpp" #include "../../../world/Level.hpp"
#include "../../../objects/Player.hpp" #include "../../../objects/Player.hpp"
#include "../../../objects/Entities.hpp"
#include "../../../physics/Hitbox.hpp" #include "../../../physics/Hitbox.hpp"
#include "../../../window/Camera.hpp" #include "../../../window/Camera.hpp"
#include "../../../items/Inventory.hpp" #include "../../../items/Inventory.hpp"
@ -16,7 +17,7 @@ inline std::shared_ptr<Player> get_player(lua::State* L, int idx) {
static int l_player_get_pos(lua::State* L) { static int l_player_get_pos(lua::State* L) {
if (auto player = get_player(L, 1)) { if (auto player = get_player(L, 1)) {
return lua::pushvec3(L, player->hitbox->position); return lua::pushvec3(L, player->getPosition());
} }
return 0; return 0;
} }
@ -29,13 +30,15 @@ static int l_player_set_pos(lua::State* L) {
auto x = lua::tonumber(L, 2); auto x = lua::tonumber(L, 2);
auto y = lua::tonumber(L, 3); auto y = lua::tonumber(L, 3);
auto z = lua::tonumber(L, 4); auto z = lua::tonumber(L, 4);
player->hitbox->position = glm::vec3(x, y, z); player->teleport(glm::vec3(x, y, z));
return 0; return 0;
} }
static int l_player_get_vel(lua::State* L) { static int l_player_get_vel(lua::State* L) {
if (auto player = get_player(L, 1)) { if (auto player = get_player(L, 1)) {
return lua::pushvec3(L, player->hitbox->velocity); if (auto hitbox = player->getHitbox()) {
return lua::pushvec3(L, hitbox->velocity);
}
} }
return 0; return 0;
} }
@ -48,7 +51,9 @@ static int l_player_set_vel(lua::State* L) {
auto x = lua::tonumber(L, 2); auto x = lua::tonumber(L, 2);
auto y = lua::tonumber(L, 3); auto y = lua::tonumber(L, 3);
auto z = lua::tonumber(L, 4); auto z = lua::tonumber(L, 4);
player->hitbox->velocity = glm::vec3(x, y, z); if (auto hitbox = player->getHitbox()) {
hitbox->velocity = glm::vec3(x, y, z);
}
return 0; return 0;
} }

View File

@ -21,33 +21,46 @@ const float FLIGHT_SPEED_MUL = 4.0f;
const float CHEAT_SPEED_MUL = 5.0f; const float CHEAT_SPEED_MUL = 5.0f;
const float JUMP_FORCE = 8.0f; const float JUMP_FORCE = 8.0f;
Player::Player(glm::vec3 position, float speed, std::shared_ptr<Inventory> inv, Player::Player(Level* level, glm::vec3 position, float speed,
entityid_t eid) : std::shared_ptr<Inventory> inv, entityid_t eid) :
level(level),
speed(speed), speed(speed),
chosenSlot(0), chosenSlot(0),
position(position), position(position),
inventory(std::move(inv)), inventory(std::move(inv)),
entity(eid), eid(eid),
camera(std::make_shared<Camera>(position, glm::radians(90.0f))), camera(std::make_shared<Camera>(position, glm::radians(90.0f))),
spCamera(std::make_shared<Camera>(position, glm::radians(90.0f))), spCamera(std::make_shared<Camera>(position, glm::radians(90.0f))),
tpCamera(std::make_shared<Camera>(position, glm::radians(90.0f))), tpCamera(std::make_shared<Camera>(position, glm::radians(90.0f))),
currentCamera(camera), currentCamera(camera)
hitbox(std::make_unique<Hitbox>(position, glm::vec3(0.3f,0.9f,0.3f)))
{ {
} }
Player::~Player() { Player::~Player() {
} }
void Player::updateEntity(Level* level) { void Player::updateEntity() {
if (entity == 0) { if (eid == 0) {
// spawn entity // spawn entity
} else if (auto entity = level->entities->get(eid)) {
position = entity->getTransform().pos;
} else { } else {
// check entity, respawn if despawned // check if chunk loaded
} }
} }
void Player::updateInput(Level* level, PlayerInput& input, float delta) { Hitbox* Player::getHitbox() {
if (auto entity = level->entities->get(eid)) {
return &entity->getRigidbody().hitbox;
}
return nullptr;
}
void Player::updateInput(PlayerInput& input, float delta) {
auto hitbox = getHitbox();
if (hitbox == nullptr) {
return;
}
bool crouch = input.shift && hitbox->grounded && !input.sprint; bool crouch = input.shift && hitbox->grounded && !input.sprint;
float speed = this->speed; float speed = this->speed;
if (flight){ if (flight){
@ -65,40 +78,23 @@ void Player::updateInput(Level* level, PlayerInput& input, float delta) {
glm::vec3 dir(0,0,0); glm::vec3 dir(0,0,0);
if (input.moveForward){ if (input.moveForward){
dir.x += camera->dir.x; dir += camera->dir;
dir.z += camera->dir.z;
} }
if (input.moveBack){ if (input.moveBack){
dir.x -= camera->dir.x; dir -= camera->dir;
dir.z -= camera->dir.z;
} }
if (input.moveRight){ if (input.moveRight){
dir.x += camera->right.x; dir += camera->right;
dir.z += camera->right.z;
} }
if (input.moveLeft){ if (input.moveLeft){
dir.x -= camera->right.x; dir -= camera->right;
dir.z -= camera->right.z;
} }
if (glm::length(dir) > 0.0f){ if (glm::length(dir) > 0.0f){
dir = glm::normalize(dir); dir = glm::normalize(dir);
hitbox->velocity.x += dir.x * speed * delta * 9; hitbox->velocity += dir * speed * delta * 9.0f;
hitbox->velocity.z += dir.z * speed * delta * 9;
} }
float vel = glm::length(hitbox->velocity); // physics calculation was here
int substeps = int(delta * vel * 20);
substeps = std::min(100, std::max(2, substeps));
level->physics->step(
level->chunks.get(),
hitbox.get(),
delta,
substeps,
crouch,
flight ? 0.0f : 1.0f,
!noclip,
0
);
if (flight && hitbox->grounded) { if (flight && hitbox->grounded) {
flight = false; flight = false;
@ -138,20 +134,22 @@ void Player::updateInput(Level* level, PlayerInput& input, float delta) {
input.flight = false; input.flight = false;
if (spawnpoint.y <= 0.1) { if (spawnpoint.y <= 0.1) {
attemptToFindSpawnpoint(level); attemptToFindSpawnpoint();
} }
} }
void Player::teleport(glm::vec3 position) { void Player::teleport(glm::vec3 position) {
hitbox->position = position; this->position = position;
if (auto hitbox = getHitbox()) {
hitbox->position = position;
}
} }
void Player::attemptToFindSpawnpoint(Level* level) { void Player::attemptToFindSpawnpoint() {
glm::vec3 ppos = hitbox->position;
glm::vec3 newpos ( glm::vec3 newpos (
ppos.x + (rand() % 200 - 100), position.x + (rand() % 200 - 100),
rand() % 80 + 100, rand() % 80 + 100,
ppos.z + (rand() % 200 - 100) position.z + (rand() % 200 - 100)
); );
while (newpos.y > 0 && !level->chunks->isObstacleBlock(newpos.x, newpos.y-2, newpos.z)) { while (newpos.y > 0 && !level->chunks->isObstacleBlock(newpos.x, newpos.y-2, newpos.z)) {
newpos.y--; newpos.y--;
@ -194,11 +192,11 @@ void Player::setNoclip(bool flag) {
} }
entityid_t Player::getEntity() const { entityid_t Player::getEntity() const {
return entity; return eid;
} }
void Player::setEntity(entityid_t eid) { void Player::setEntity(entityid_t eid) {
entity = eid; this->eid = eid;
} }
std::shared_ptr<Inventory> Player::getInventory() const { std::shared_ptr<Inventory> Player::getInventory() const {
@ -214,7 +212,6 @@ glm::vec3 Player::getSpawnPoint() const {
} }
std::unique_ptr<dynamic::Map> Player::serialize() const { std::unique_ptr<dynamic::Map> Player::serialize() const {
glm::vec3 position = hitbox->position;
auto root = std::make_unique<dynamic::Map>(); auto root = std::make_unique<dynamic::Map>();
auto& posarr = root->putList("position"); auto& posarr = root->putList("position");
posarr.put(position.x); posarr.put(position.x);
@ -234,14 +231,13 @@ std::unique_ptr<dynamic::Map> Player::serialize() const {
root->put("flight", flight); root->put("flight", flight);
root->put("noclip", noclip); root->put("noclip", noclip);
root->put("chosen-slot", chosenSlot); root->put("chosen-slot", chosenSlot);
root->put("entity", entity); root->put("entity", eid);
root->put("inventory", inventory->serialize()); root->put("inventory", inventory->serialize());
return root; return root;
} }
void Player::deserialize(dynamic::Map *src) { void Player::deserialize(dynamic::Map *src) {
auto posarr = src->list("position"); auto posarr = src->list("position");
glm::vec3& position = hitbox->position;
position.x = posarr->num(0); position.x = posarr->num(0);
position.y = posarr->num(1); position.y = posarr->num(1);
position.z = posarr->num(2); position.z = posarr->num(2);
@ -268,7 +264,7 @@ void Player::deserialize(dynamic::Map *src) {
src->flag("flight", flight); src->flag("flight", flight);
src->flag("noclip", noclip); src->flag("noclip", noclip);
setChosenSlot(src->get("chosen-slot", getChosenSlot())); setChosenSlot(src->get("chosen-slot", getChosenSlot()));
src->num("enitity", entity); src->num("enitity", eid);
if (auto invmap = src->map("inventory")) { if (auto invmap = src->map("inventory")) {
getInventory()->deserialize(invmap.get()); getInventory()->deserialize(invmap.get());

View File

@ -8,6 +8,7 @@
#include "../interfaces/Object.hpp" #include "../interfaces/Object.hpp"
#include <memory> #include <memory>
#include <optional>
#include <glm/glm.hpp> #include <glm/glm.hpp>
class Camera; class Camera;
@ -41,6 +42,7 @@ struct BlockSelection {
}; };
class Player : public Object, public Serializable { class Player : public Object, public Serializable {
Level* level;
float speed; float speed;
int chosenSlot; int chosenSlot;
glm::vec3 position; glm::vec3 position;
@ -48,24 +50,23 @@ class Player : public Object, public Serializable {
std::shared_ptr<Inventory> inventory; std::shared_ptr<Inventory> inventory;
bool flight = false; bool flight = false;
bool noclip = false; bool noclip = false;
entityid_t entity; entityid_t eid;
public: public:
std::shared_ptr<Camera> camera, spCamera, tpCamera; std::shared_ptr<Camera> camera, spCamera, tpCamera;
std::shared_ptr<Camera> currentCamera; std::shared_ptr<Camera> currentCamera;
std::unique_ptr<Hitbox> hitbox;
bool debug = false; bool debug = false;
glm::vec3 cam {}; glm::vec3 cam {};
BlockSelection selection {}; BlockSelection selection {};
Player(glm::vec3 position, float speed, std::shared_ptr<Inventory> inv, Player(Level* level, glm::vec3 position, float speed,
entityid_t eid); std::shared_ptr<Inventory> inv, entityid_t eid);
~Player(); ~Player();
void teleport(glm::vec3 position); void teleport(glm::vec3 position);
void updateEntity(Level* level); void updateEntity();
void updateInput(Level* level, PlayerInput& input, float delta); void updateInput(PlayerInput& input, float delta);
void attemptToFindSpawnpoint(Level* level); void attemptToFindSpawnpoint();
void setChosenSlot(int index); void setChosenSlot(int index);
@ -83,6 +84,12 @@ public:
std::shared_ptr<Inventory> getInventory() const; std::shared_ptr<Inventory> getInventory() const;
glm::vec3 getPosition() const {
return position;
}
Hitbox* getHitbox();
void setSpawnPoint(glm::vec3 point); void setSpawnPoint(glm::vec3 point);
glm::vec3 getSpawnPoint() const; glm::vec3 getSpawnPoint() const;

View File

@ -31,7 +31,7 @@ Level::Level(
this->world->getNextInventoryId(), DEF_PLAYER_INVENTORY_SIZE this->world->getNextInventoryId(), DEF_PLAYER_INVENTORY_SIZE
); );
auto player = spawnObject<Player>( auto player = spawnObject<Player>(
glm::vec3(0, DEF_PLAYER_Y, 0), DEF_PLAYER_SPEED, inv, 0 this, glm::vec3(0, DEF_PLAYER_Y, 0), DEF_PLAYER_SPEED, inv, 0
); );
uint matrixSize = ( uint matrixSize = (

View File

@ -109,6 +109,7 @@ std::unique_ptr<Level> World::load(
auto players = playerFile->list("players"); auto players = playerFile->list("players");
for (size_t i = 0; i < players->size(); i++) { for (size_t i = 0; i < players->size(); i++) {
auto player = level->spawnObject<Player>( auto player = level->spawnObject<Player>(
level.get(),
glm::vec3(0, DEF_PLAYER_Y, 0), glm::vec3(0, DEF_PLAYER_Y, 0),
DEF_PLAYER_SPEED, DEF_PLAYER_SPEED,
level->inventories->create(DEF_PLAYER_INVENTORY_SIZE), level->inventories->create(DEF_PLAYER_INVENTORY_SIZE),