add BodyType, fix crouching

This commit is contained in:
MihailRis 2024-07-09 06:39:05 +03:00
parent 7e80642ec3
commit 0a14d6220a
13 changed files with 131 additions and 34 deletions

View File

@ -25,6 +25,10 @@ local Rigidbody = {__index={
is_vdamping=function(self) return __rigidbody.is_vdamping(self.eid) end, is_vdamping=function(self) return __rigidbody.is_vdamping(self.eid) end,
set_vdamping=function(self, b) return __rigidbody.set_vdamping(self.eid, b) 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_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) local function new_Rigidbody(eid)

View File

@ -138,22 +138,19 @@ void ContentLoader::loadBlock(Block& def, const std::string& name, const fs::pat
} }
// block model // block model
std::string model = "block"; std::string modelName;
root->str("model", model); root->str("model", modelName);
if (model == "block") def.model = BlockModel::block; if (auto model = BlockModel_from(modelName)) {
else if (model == "aabb") def.model = BlockModel::aabb; if (*model == BlockModel::custom) {
else if (model == "custom") { if (root->has("model-primitives")) {
def.model = BlockModel::custom; loadCustomBlockModel(def, root->map("model-primitives").get());
if (root->has("model-primitives")) { } else {
loadCustomBlockModel(def, root->map("model-primitives").get()); logger.error() << name << ": no 'model-primitives' found";
} else { }
logger.error() << name << ": no 'model-primitives' found";
} }
} def.model = *model;
else if (model == "X") def.model = BlockModel::xsprite; } else if (!modelName.empty()) {
else if (model == "none") def.model = BlockModel::none; logger.error() << "unknown model " << modelName;
else {
logger.error() << "unknown model " << model;
def.model = BlockModel::none; 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", def.save.enabled);
root->flag("save-rig-pose", def.save.rig.pose); root->flag("save-rig-pose", def.save.rig.pose);
root->flag("save-rig-textures", def.save.rig.textures); 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) { void ContentLoader::loadEntity(EntityDef& def, const std::string& full, const std::string& name) {

View File

@ -1,5 +1,7 @@
#include "libentity.hpp" #include "libentity.hpp"
#include "../../../util/stringutil.hpp"
static int l_rigidbody_get_vel(lua::State* L) { static int l_rigidbody_get_vel(lua::State* L) {
if (auto entity = get_entity(L, 1)) { if (auto entity = get_entity(L, 1)) {
return lua::pushvec3_arr(L, entity->getRigidbody().hitbox.velocity); return lua::pushvec3_arr(L, entity->getRigidbody().hitbox.velocity);
@ -77,6 +79,39 @@ static int l_rigidbody_is_grounded(lua::State* L) {
return 0; 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 [] = { const luaL_Reg rigidbodylib [] = {
{"is_enabled", lua::wrap<l_rigidbody_is_enabled>}, {"is_enabled", lua::wrap<l_rigidbody_is_enabled>},
{"set_enabled", lua::wrap<l_rigidbody_set_enabled>}, {"set_enabled", lua::wrap<l_rigidbody_set_enabled>},
@ -89,5 +124,9 @@ const luaL_Reg rigidbodylib [] = {
{"is_vdamping", lua::wrap<l_rigidbody_is_vdamping>}, {"is_vdamping", lua::wrap<l_rigidbody_is_vdamping>},
{"set_vdamping", lua::wrap<l_rigidbody_set_vdamping>}, {"set_vdamping", lua::wrap<l_rigidbody_set_vdamping>},
{"is_grounded", lua::wrap<l_rigidbody_is_grounded>}, {"is_grounded", lua::wrap<l_rigidbody_is_grounded>},
{"is_crouching", lua::wrap<l_rigidbody_is_crouching>},
{"set_crouching", lua::wrap<l_rigidbody_set_crouching>},
{"get_body_type", lua::wrap<l_rigidbody_get_body_type>},
{"set_body_type", lua::wrap<l_rigidbody_set_body_type>},
{NULL, NULL} {NULL, NULL}
}; };

View File

@ -273,13 +273,7 @@ static int l_get_textures(lua::State* L) {
static int l_get_model(lua::State* L) { static int l_get_model(lua::State* L) {
if (auto def = require_block(L)) { if (auto def = require_block(L)) {
switch (def->model) { return lua::pushstring(L, to_string(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 0; return 0;
} }

View File

@ -85,7 +85,7 @@ entityid_t Entities::spawn(
const auto& tsf = registry.emplace<Transform>( const auto& tsf = registry.emplace<Transform>(
entity, position, glm::vec3(1.0f), glm::mat3(1.0f), glm::mat4(1.0f), true); entity, position, glm::vec3(1.0f), glm::mat3(1.0f), glm::mat4(1.0f), true);
auto& body = registry.emplace<Rigidbody>( auto& body = registry.emplace<Rigidbody>(
entity, true, Hitbox {position, def.hitbox}, std::vector<Trigger>{}); entity, true, Hitbox {def.bodyType, position, def.hitbox}, std::vector<Trigger>{});
body.triggers.resize(def.radialTriggers.size() + def.boxTriggers.size()); body.triggers.resize(def.radialTriggers.size() + def.boxTriggers.size());
for (auto& [i, box] : def.boxTriggers) { for (auto& [i, box] : def.boxTriggers) {
@ -307,8 +307,6 @@ void Entities::updatePhysics(float delta) {
&hitbox, &hitbox,
delta, delta,
substeps, substeps,
false,
true,
eid.uid eid.uid
); );
hitbox.linearDamping = hitbox.grounded * 24; hitbox.linearDamping = hitbox.grounded * 24;

View File

@ -7,6 +7,7 @@
#include "../typedefs.hpp" #include "../typedefs.hpp"
#include "../maths/aabb.hpp" #include "../maths/aabb.hpp"
#include "../physics/Hitbox.hpp"
namespace rigging { namespace rigging {
class RigConfig; class RigConfig;
@ -18,6 +19,7 @@ struct EntityDef {
std::vector<std::string> components; std::vector<std::string> components;
BodyType bodyType = BodyType::DYNAMIC;
glm::vec3 hitbox {0.5f}; glm::vec3 hitbox {0.5f};
std::vector<std::pair<size_t, AABB>> boxTriggers {}; std::vector<std::pair<size_t, AABB>> boxTriggers {};
std::vector<std::pair<size_t, float>> radialTriggers {}; std::vector<std::pair<size_t, float>> radialTriggers {};

View File

@ -71,6 +71,7 @@ void Player::updateInput(PlayerInput& input, float delta) {
speed *= CHEAT_SPEED_MUL; speed *= CHEAT_SPEED_MUL;
} }
hitbox->crouching = crouch;
if (crouch) { if (crouch) {
speed *= CROUCH_SPEED_MUL; speed *= CROUCH_SPEED_MUL;
} else if (input.sprint) { } else if (input.sprint) {

View File

@ -1,7 +1,27 @@
#include "Hitbox.hpp" #include "Hitbox.hpp"
Hitbox::Hitbox(glm::vec3 position, glm::vec3 halfsize) #include <stdexcept>
: position(position),
std::optional<BodyType> 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), halfsize(halfsize),
velocity(0.0f,0.0f,0.0f), velocity(0.0f,0.0f,0.0f),
linearDamping(0.1f) linearDamping(0.1f)

View File

@ -5,6 +5,8 @@
#include "../typedefs.hpp" #include "../typedefs.hpp"
#include <set> #include <set>
#include <string>
#include <optional>
#include <functional> #include <functional>
#include <glm/glm.hpp> #include <glm/glm.hpp>
@ -36,7 +38,15 @@ struct Trigger {
triggercallback exitCallback; triggercallback exitCallback;
}; };
enum class BodyType {
KINEMATIC, DYNAMIC
};
std::optional<BodyType> BodyType_from(std::string_view str);
std::string to_string(BodyType type);
struct Hitbox { struct Hitbox {
BodyType type;
glm::vec3 position; glm::vec3 position;
glm::vec3 halfsize; glm::vec3 halfsize;
glm::vec3 velocity; glm::vec3 velocity;
@ -44,8 +54,9 @@ struct Hitbox {
bool verticalDamping = false; bool verticalDamping = false;
bool grounded = false; bool grounded = false;
float gravityScale = 1.0f; 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_ #endif // PHYSICS_HITBOX_HPP_

View File

@ -21,8 +21,6 @@ void PhysicsSolver::step(
Hitbox* hitbox, Hitbox* hitbox,
float delta, float delta,
uint substeps, uint substeps,
bool shifting,
bool collisions,
entityid_t entity entityid_t entity
) { ) {
float dt = delta / static_cast<float>(substeps); float dt = delta / static_cast<float>(substeps);
@ -42,7 +40,7 @@ void PhysicsSolver::step(
float pz = pos.z; float pz = pos.z;
vel += gravity * dt * gravityScale; vel += gravity * dt * gravityScale;
if (collisions) { if (hitbox->type == BodyType::DYNAMIC) {
colisionCalc(chunks, hitbox, vel, pos, half, colisionCalc(chunks, hitbox, vel, pos, half,
(prevGrounded && gravityScale > 0.0f) ? 0.5f : 0.0f); (prevGrounded && gravityScale > 0.0f) ? 0.5f : 0.0f);
} }
@ -57,7 +55,7 @@ void PhysicsSolver::step(
pos.y = py; pos.y = py;
} }
if (shifting && hitbox->grounded){ if (hitbox->crouching && hitbox->grounded){
float y = (pos.y-half.y-E); float y = (pos.y-half.y-E);
hitbox->grounded = false; hitbox->grounded = false;
for (float x = (px-half.x+E); x <= (px+half.x-E); x+=s){ for (float x = (px-half.x+E); x <= (px+half.x-E); x+=s){

View File

@ -23,8 +23,6 @@ public:
Hitbox* hitbox, Hitbox* hitbox,
float delta, float delta,
uint substeps, uint substeps,
bool shifting,
bool collisions,
entityid_t entity entityid_t entity
); );
void colisionCalc( void colisionCalc(

View File

@ -5,6 +5,31 @@
#include "../core_defs.hpp" #include "../core_defs.hpp"
#include "../util/stringutil.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> 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) CoordSystem::CoordSystem(glm::ivec3 axisX, glm::ivec3 axisY, glm::ivec3 axisZ)
: axisX(axisX), axisY(axisY), axisZ(axisZ) : axisX(axisX), axisY(axisY), axisZ(axisZ)
{ {

View File

@ -3,6 +3,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <optional>
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include "../maths/aabb.hpp" #include "../maths/aabb.hpp"
@ -80,6 +81,9 @@ enum class BlockModel {
custom custom
}; };
std::string to_string(BlockModel model);
std::optional<BlockModel> BlockModel_from(std::string_view str);
using BoxModel = AABB; using BoxModel = AABB;