Merge pull request #792 from MihailRis/physics-upgrade

solid entities
This commit is contained in:
MihailRis 2026-03-14 22:56:33 +03:00 • committed by GitHub
commit a78a924093
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
33 changed files with 786 additions and 416 deletions

View file

@ -44,7 +44,9 @@ namespace {
const float CROUCH_SHIFT_Y = -0.2f;
}
CameraControl::CameraControl(Player& player, const CameraSettings& settings)
CameraControl::CameraControl(
Player& player, const CameraSettings& settings
)
: player(player),
camera(player.fpCamera),
settings(settings),
@ -195,18 +197,30 @@ void CameraControl::update(
refreshPosition();
auto castRay = [](Player& player, Camera& camera, const glm::vec3& front)
-> glm::vec3 {
auto blockEnd = player.chunks->rayCastToObstacle(camera.position, front, 3.0f);
auto entityRay = player.getLevel().entities->rayCast(
camera.position, front, 3.0f, player.getEntity(), true
);
if (entityRay.has_value() &&
entityRay->distance < glm::distance(camera.position, blockEnd)) {
return (camera.position + front * entityRay->distance);
} else {
return blockEnd;
}
};
camera->updateVectors();
if (player.currentCamera == spCamera) {
spCamera->position =
chunks.rayCastToObstacle(camera->position, camera->front, 3.0f) -
0.4f * camera->front;
castRay(player, *camera, camera->front) - 0.4f * camera->front;
spCamera->dir = -camera->dir;
spCamera->front = -camera->front;
spCamera->right = -camera->right;
} else if (player.currentCamera == tpCamera) {
tpCamera->position =
chunks.rayCastToObstacle(camera->position, -camera->front, 3.0f) +
0.4f * camera->front;
tpCamera->position = castRay(player, *camera, camera->front * -1.0f) +
0.4f * camera->front;
tpCamera->dir = camera->dir;
tpCamera->front = camera->front;
tpCamera->right = camera->right;
@ -229,26 +243,8 @@ PlayerController::PlayerController(
}
void PlayerController::onFootstep(const Hitbox& hitbox) {
auto pos = hitbox.position;
auto half = hitbox.halfsize;
for (int offsetZ = -1; offsetZ <= 1; offsetZ++) {
for (int offsetX = -1; offsetX <= 1; offsetX++) {
int x = std::floor(pos.x + half.x * offsetX);
int y = std::floor(pos.y - half.y * 1.1f);
int z = std::floor(pos.z + half.z * offsetZ);
auto vox = player.chunks->get(x, y, z);
if (vox) {
auto& def = level.content.getIndices()->blocks.require(vox->id);
if (!def.obstacle) {
continue;
}
blocksController.onBlockInteraction(
&player, glm::ivec3(x, y, z), def, BlockInteraction::step
);
return;
}
}
if (footstepCallback) {
footstepCallback(hitbox);
}
}
@ -557,3 +553,7 @@ void PlayerController::updateInteraction(const Input& inputEvents, float delta)
Player& PlayerController::getPlayer() {
return player;
}
void PlayerController::setFootstepCallback(FootstepCallback&& callback) {
footstepCallback = std::move(callback);
}

View file

@ -18,6 +18,8 @@ struct Hitbox;
struct CameraSettings;
struct EngineSettings;
using FootstepCallback = std::function<void(const Hitbox&)>;
class CameraControl {
Player& player;
std::shared_ptr<Camera> camera;
@ -57,6 +59,7 @@ class PlayerController {
CameraControl camControl;
BlocksController& blocksController;
float interactionTimer = 0.0f;
FootstepCallback footstepCallback;
void updateKeyboard(const Input& inputEvents);
void resetKeyboard();
@ -89,5 +92,8 @@ public:
void postUpdate(
float delta, int windowHeight, const Input* inputEvents, bool pause
);
Player& getPlayer();
void setFootstepCallback(FootstepCallback&& callback);
};

View file

@ -150,6 +150,48 @@ static int l_set_linear_damping(lua::State* L) {
return 0;
}
static int l_set_material(lua::State* L) {
if (auto entity = get_entity(L, 1)) {
entity->getRigidbody().hitbox.material = lua::require_string(L, 2);
}
return 0;
}
static int l_get_material(lua::State* L) {
if (auto entity = get_entity(L, 1)) {
return lua::pushstring(L, entity->getRigidbody().hitbox.material);
}
return 0;
}
static int l_get_mass(lua::State* L) {
if (auto entity = get_entity(L, 1)) {
return lua::pushnumber(L, entity->getRigidbody().mass);
}
return 0;
}
static int l_set_mass(lua::State* L) {
if (auto entity = get_entity(L, 1)) {
entity->getRigidbody().mass = lua::tonumber(L, 2);
}
return 0;
}
static int l_get_elasticity(lua::State* L) {
if (auto entity = get_entity(L, 1)) {
return lua::pushnumber(L, entity->getRigidbody().elasticity);
}
return 0;
}
static int l_set_elasticity(lua::State* L) {
if (auto entity = get_entity(L, 1)) {
entity->getRigidbody().elasticity = lua::tonumber(L, 2);
}
return 0;
}
const luaL_Reg rigidbodylib[] = {
{"is_enabled", lua::wrap<l_is_enabled>},
{"set_enabled", lua::wrap<l_set_enabled>},
@ -169,5 +211,11 @@ const luaL_Reg rigidbodylib[] = {
{"set_crouching", lua::wrap<l_set_crouching>},
{"get_body_type", lua::wrap<l_get_body_type>},
{"set_body_type", lua::wrap<l_set_body_type>},
{"set_material", lua::wrap<l_set_material>},
{"get_material", lua::wrap<l_get_material>},
{"get_mass", lua::wrap<l_get_mass>},
{"set_mass", lua::wrap<l_set_mass>},
{"get_elasticity", lua::wrap<l_get_elasticity>},
{"set_elasticity", lua::wrap<l_set_elasticity>},
{nullptr, nullptr}
};

View file

@ -31,7 +31,7 @@ static int l_set_pos(lua::State* L) {
auto vec = lua::tovec3(L, 2);
check_valid(vec);
entity->getTransform().setPos(vec);
entity->getRigidbody().hitbox.position = vec;
entity->getRigidbody().hitbox.setPos(vec);
}
return 0;
}