From 0a14d6220abbdfffb6171d8f13dab7a3daf61606 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 9 Jul 2024 06:39:05 +0300 Subject: [PATCH] add BodyType, fix crouching --- res/modules/internal/stdcomp.lua | 4 +++ src/content/ContentLoader.cpp | 33 +++++++++--------- src/logic/scripting/lua/lib__rigidbody.cpp | 39 ++++++++++++++++++++++ src/logic/scripting/lua/libblock.cpp | 8 +---- src/objects/Entities.cpp | 4 +-- src/objects/EntityDef.hpp | 2 ++ src/objects/Player.cpp | 1 + src/physics/Hitbox.cpp | 24 +++++++++++-- src/physics/Hitbox.hpp | 13 +++++++- src/physics/PhysicsSolver.cpp | 6 ++-- src/physics/PhysicsSolver.hpp | 2 -- src/voxels/Block.cpp | 25 ++++++++++++++ src/voxels/Block.hpp | 4 +++ 13 files changed, 131 insertions(+), 34 deletions(-) diff --git a/res/modules/internal/stdcomp.lua b/res/modules/internal/stdcomp.lua index 0754c5a4..ce85dc4a 100644 --- a/res/modules/internal/stdcomp.lua +++ b/res/modules/internal/stdcomp.lua @@ -25,6 +25,10 @@ local Rigidbody = {__index={ is_vdamping=function(self) return __rigidbody.is_vdamping(self.eid) end, set_vdamping=function(self, b) return __rigidbody.set_vdamping(self.eid, b) end, is_grounded=function(self) return __rigidbody.is_grounded(self.eid) end, + is_crouching=function(self) return __rigidbody.is_crouching(self.eid) end, + set_crouching=function(self, b) return __rigidbody.set_crouching(self.eid, b) end, + get_body_type=function(self) return __rigidbody.get_body_type(self.eid) end, + set_body_type=function(self, s) return __rigidbody.set_body_type(self.eid, s) end, }} local function new_Rigidbody(eid) diff --git a/src/content/ContentLoader.cpp b/src/content/ContentLoader.cpp index d1b64bf1..2e0cb4de 100644 --- a/src/content/ContentLoader.cpp +++ b/src/content/ContentLoader.cpp @@ -138,22 +138,19 @@ void ContentLoader::loadBlock(Block& def, const std::string& name, const fs::pat } // block model - std::string model = "block"; - root->str("model", model); - if (model == "block") def.model = BlockModel::block; - else if (model == "aabb") def.model = BlockModel::aabb; - else if (model == "custom") { - def.model = BlockModel::custom; - if (root->has("model-primitives")) { - loadCustomBlockModel(def, root->map("model-primitives").get()); - } else { - logger.error() << name << ": no 'model-primitives' found"; + std::string modelName; + root->str("model", modelName); + if (auto model = BlockModel_from(modelName)) { + if (*model == BlockModel::custom) { + if (root->has("model-primitives")) { + loadCustomBlockModel(def, root->map("model-primitives").get()); + } else { + logger.error() << name << ": no 'model-primitives' found"; + } } - } - else if (model == "X") def.model = BlockModel::xsprite; - else if (model == "none") def.model = BlockModel::none; - else { - logger.error() << "unknown model " << model; + def.model = *model; + } else if (!modelName.empty()) { + logger.error() << "unknown model " << modelName; def.model = BlockModel::none; } @@ -341,6 +338,12 @@ void ContentLoader::loadEntity(EntityDef& def, const std::string& name, const fs root->flag("save", def.save.enabled); root->flag("save-rig-pose", def.save.rig.pose); root->flag("save-rig-textures", def.save.rig.textures); + + std::string bodyTypeName; + root->str("body-type", bodyTypeName); + if (auto bodyType = BodyType_from(bodyTypeName)) { + def.bodyType = *bodyType; + } } void ContentLoader::loadEntity(EntityDef& def, const std::string& full, const std::string& name) { diff --git a/src/logic/scripting/lua/lib__rigidbody.cpp b/src/logic/scripting/lua/lib__rigidbody.cpp index 12768f15..0b390543 100644 --- a/src/logic/scripting/lua/lib__rigidbody.cpp +++ b/src/logic/scripting/lua/lib__rigidbody.cpp @@ -1,5 +1,7 @@ #include "libentity.hpp" +#include "../../../util/stringutil.hpp" + static int l_rigidbody_get_vel(lua::State* L) { if (auto entity = get_entity(L, 1)) { return lua::pushvec3_arr(L, entity->getRigidbody().hitbox.velocity); @@ -77,6 +79,39 @@ static int l_rigidbody_is_grounded(lua::State* L) { return 0; } +static int l_rigidbody_is_crouching(lua::State* L) { + if (auto entity = get_entity(L, 1)) { + return lua::pushboolean(L, entity->getRigidbody().hitbox.crouching); + } + return 0; +} + +static int l_rigidbody_set_crouching(lua::State* L) { + if (auto entity = get_entity(L, 1)) { + entity->getRigidbody().hitbox.crouching = lua::toboolean(L, 2); + } + return 0; +} + +static int l_rigidbody_get_body_type(lua::State* L) { + if (auto entity = get_entity(L, 1)) { + return lua::pushstring(L, to_string(entity->getRigidbody().hitbox.type)); + } + return 0; +} + +static int l_rigidbody_set_body_type(lua::State* L) { + if (auto entity = get_entity(L, 1)) { + if (auto type = BodyType_from(lua::tostring(L, 2))) { + entity->getRigidbody().hitbox.type = *type; + } else { + throw std::runtime_error( + "unknown body type "+util::quote(lua::tostring(L, 2))); + } + } + return 0; +} + const luaL_Reg rigidbodylib [] = { {"is_enabled", lua::wrap}, {"set_enabled", lua::wrap}, @@ -89,5 +124,9 @@ const luaL_Reg rigidbodylib [] = { {"is_vdamping", lua::wrap}, {"set_vdamping", lua::wrap}, {"is_grounded", lua::wrap}, + {"is_crouching", lua::wrap}, + {"set_crouching", lua::wrap}, + {"get_body_type", lua::wrap}, + {"set_body_type", lua::wrap}, {NULL, NULL} }; diff --git a/src/logic/scripting/lua/libblock.cpp b/src/logic/scripting/lua/libblock.cpp index ce54b258..09eddbb7 100644 --- a/src/logic/scripting/lua/libblock.cpp +++ b/src/logic/scripting/lua/libblock.cpp @@ -273,13 +273,7 @@ static int l_get_textures(lua::State* L) { static int l_get_model(lua::State* L) { if (auto def = require_block(L)) { - switch (def->model) { - case BlockModel::block: return lua::pushstring(L, "block"); - case BlockModel::aabb: return lua::pushstring(L, "aabb"); - case BlockModel::xsprite: return lua::pushstring(L, "X"); - case BlockModel::custom: return lua::pushstring(L, "custom"); - case BlockModel::none: return lua::pushstring(L, "none"); - } + return lua::pushstring(L, to_string(def->model)); } return 0; } diff --git a/src/objects/Entities.cpp b/src/objects/Entities.cpp index b11106d0..675df87f 100644 --- a/src/objects/Entities.cpp +++ b/src/objects/Entities.cpp @@ -85,7 +85,7 @@ entityid_t Entities::spawn( const auto& tsf = registry.emplace( entity, position, glm::vec3(1.0f), glm::mat3(1.0f), glm::mat4(1.0f), true); auto& body = registry.emplace( - entity, true, Hitbox {position, def.hitbox}, std::vector{}); + entity, true, Hitbox {def.bodyType, position, def.hitbox}, std::vector{}); body.triggers.resize(def.radialTriggers.size() + def.boxTriggers.size()); for (auto& [i, box] : def.boxTriggers) { @@ -307,8 +307,6 @@ void Entities::updatePhysics(float delta) { &hitbox, delta, substeps, - false, - true, eid.uid ); hitbox.linearDamping = hitbox.grounded * 24; diff --git a/src/objects/EntityDef.hpp b/src/objects/EntityDef.hpp index 5273113c..5ac16de1 100644 --- a/src/objects/EntityDef.hpp +++ b/src/objects/EntityDef.hpp @@ -7,6 +7,7 @@ #include "../typedefs.hpp" #include "../maths/aabb.hpp" +#include "../physics/Hitbox.hpp" namespace rigging { class RigConfig; @@ -18,6 +19,7 @@ struct EntityDef { std::vector components; + BodyType bodyType = BodyType::DYNAMIC; glm::vec3 hitbox {0.5f}; std::vector> boxTriggers {}; std::vector> radialTriggers {}; diff --git a/src/objects/Player.cpp b/src/objects/Player.cpp index 2d319830..679ef5dd 100644 --- a/src/objects/Player.cpp +++ b/src/objects/Player.cpp @@ -71,6 +71,7 @@ void Player::updateInput(PlayerInput& input, float delta) { speed *= CHEAT_SPEED_MUL; } + hitbox->crouching = crouch; if (crouch) { speed *= CROUCH_SPEED_MUL; } else if (input.sprint) { diff --git a/src/physics/Hitbox.cpp b/src/physics/Hitbox.cpp index 8cd127e4..e77be865 100644 --- a/src/physics/Hitbox.cpp +++ b/src/physics/Hitbox.cpp @@ -1,7 +1,27 @@ #include "Hitbox.hpp" -Hitbox::Hitbox(glm::vec3 position, glm::vec3 halfsize) - : position(position), +#include + +std::optional BodyType_from(std::string_view str) { + if (str == "kinematic") { + return BodyType::KINEMATIC; + } else if (str == "dynamic") { + return BodyType::DYNAMIC; + } + return std::nullopt; +} + +std::string to_string(BodyType type) { + switch (type) { + case BodyType::KINEMATIC: return "kinematic"; + case BodyType::DYNAMIC: return "dynamic"; + default: return "unknown"; + } +} + +Hitbox::Hitbox(BodyType type, glm::vec3 position, glm::vec3 halfsize) + : type(type), + position(position), halfsize(halfsize), velocity(0.0f,0.0f,0.0f), linearDamping(0.1f) diff --git a/src/physics/Hitbox.hpp b/src/physics/Hitbox.hpp index 56955fa5..3cc355c8 100644 --- a/src/physics/Hitbox.hpp +++ b/src/physics/Hitbox.hpp @@ -5,6 +5,8 @@ #include "../typedefs.hpp" #include +#include +#include #include #include @@ -36,7 +38,15 @@ struct Trigger { triggercallback exitCallback; }; +enum class BodyType { + KINEMATIC, DYNAMIC +}; + +std::optional BodyType_from(std::string_view str); +std::string to_string(BodyType type); + struct Hitbox { + BodyType type; glm::vec3 position; glm::vec3 halfsize; glm::vec3 velocity; @@ -44,8 +54,9 @@ struct Hitbox { bool verticalDamping = false; bool grounded = false; float gravityScale = 1.0f; + bool crouching = false; - Hitbox(glm::vec3 position, glm::vec3 halfsize); + Hitbox(BodyType type, glm::vec3 position, glm::vec3 halfsize); }; #endif // PHYSICS_HITBOX_HPP_ diff --git a/src/physics/PhysicsSolver.cpp b/src/physics/PhysicsSolver.cpp index 17620a9e..d513e0e7 100644 --- a/src/physics/PhysicsSolver.cpp +++ b/src/physics/PhysicsSolver.cpp @@ -21,8 +21,6 @@ void PhysicsSolver::step( Hitbox* hitbox, float delta, uint substeps, - bool shifting, - bool collisions, entityid_t entity ) { float dt = delta / static_cast(substeps); @@ -42,7 +40,7 @@ void PhysicsSolver::step( float pz = pos.z; vel += gravity * dt * gravityScale; - if (collisions) { + if (hitbox->type == BodyType::DYNAMIC) { colisionCalc(chunks, hitbox, vel, pos, half, (prevGrounded && gravityScale > 0.0f) ? 0.5f : 0.0f); } @@ -57,7 +55,7 @@ void PhysicsSolver::step( pos.y = py; } - if (shifting && hitbox->grounded){ + if (hitbox->crouching && hitbox->grounded){ float y = (pos.y-half.y-E); hitbox->grounded = false; for (float x = (px-half.x+E); x <= (px+half.x-E); x+=s){ diff --git a/src/physics/PhysicsSolver.hpp b/src/physics/PhysicsSolver.hpp index 75569b22..bb8e31a9 100644 --- a/src/physics/PhysicsSolver.hpp +++ b/src/physics/PhysicsSolver.hpp @@ -23,8 +23,6 @@ public: Hitbox* hitbox, float delta, uint substeps, - bool shifting, - bool collisions, entityid_t entity ); void colisionCalc( diff --git a/src/voxels/Block.cpp b/src/voxels/Block.cpp index 28118c4a..c05d9af5 100644 --- a/src/voxels/Block.cpp +++ b/src/voxels/Block.cpp @@ -5,6 +5,31 @@ #include "../core_defs.hpp" #include "../util/stringutil.hpp" +std::string to_string(BlockModel model) { + switch (model) { + case BlockModel::none: return "none"; + case BlockModel::block: return "block"; + case BlockModel::xsprite: return "X"; + case BlockModel::aabb: return "aabb"; + case BlockModel::custom: return "custom"; + } +} + +std::optional BlockModel_from(std::string_view str) { + if (str == "none") { + return BlockModel::none; + } else if (str == "block") { + return BlockModel::block; + } else if (str == "X") { + return BlockModel::xsprite; + } else if (str == "aabb") { + return BlockModel::aabb; + } else if (str == "custom") { + return BlockModel::custom; + } + return std::nullopt; +} + CoordSystem::CoordSystem(glm::ivec3 axisX, glm::ivec3 axisY, glm::ivec3 axisZ) : axisX(axisX), axisY(axisY), axisZ(axisZ) { diff --git a/src/voxels/Block.hpp b/src/voxels/Block.hpp index 23ecdc26..ec917321 100644 --- a/src/voxels/Block.hpp +++ b/src/voxels/Block.hpp @@ -3,6 +3,7 @@ #include #include +#include #include #include "../maths/aabb.hpp" @@ -80,6 +81,9 @@ enum class BlockModel { custom }; +std::string to_string(BlockModel model); +std::optional BlockModel_from(std::string_view str); + using BoxModel = AABB;