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,
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)

View File

@ -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) {

View File

@ -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<l_rigidbody_is_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>},
{"set_vdamping", lua::wrap<l_rigidbody_set_vdamping>},
{"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}
};

View File

@ -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;
}

View File

@ -85,7 +85,7 @@ entityid_t Entities::spawn(
const auto& tsf = registry.emplace<Transform>(
entity, position, glm::vec3(1.0f), glm::mat3(1.0f), glm::mat4(1.0f), true);
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());
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;

View File

@ -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<std::string> components;
BodyType bodyType = BodyType::DYNAMIC;
glm::vec3 hitbox {0.5f};
std::vector<std::pair<size_t, AABB>> boxTriggers {};
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;
}
hitbox->crouching = crouch;
if (crouch) {
speed *= CROUCH_SPEED_MUL;
} else if (input.sprint) {

View File

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

View File

@ -5,6 +5,8 @@
#include "../typedefs.hpp"
#include <set>
#include <string>
#include <optional>
#include <functional>
#include <glm/glm.hpp>
@ -36,7 +38,15 @@ struct Trigger {
triggercallback exitCallback;
};
enum class BodyType {
KINEMATIC, DYNAMIC
};
std::optional<BodyType> 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_

View File

@ -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<float>(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){

View File

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

View File

@ -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> 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)
{

View File

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