Multiple Hitboxes

This commit is contained in:
InfiniteCoder 2024-02-24 00:21:17 +03:00
parent d1fbaaa28b
commit 5f551d6888
4 changed files with 42 additions and 17 deletions

View File

@ -151,6 +151,15 @@ void ContentLoader::loadBlock(Block& def, std::string name, fs::path file) {
aabb.a = glm::vec3(boxarr->num(0), boxarr->num(1), boxarr->num(2));
aabb.b = glm::vec3(boxarr->num(3), boxarr->num(4), boxarr->num(5));
aabb.b += aabb.a;
def.hitboxExplicit = true;
} else if (def.modelBoxes.empty()) {
def.hitboxExplicit = true;
} else {
def.hitbox = def.modelBoxes[0];
for (const auto& box : def.modelBoxes) {
def.hitbox.a = glm::min(def.hitbox.a, box.a);
def.hitbox.b = glm::max(def.hitbox.b, box.b);
}
}
// block light emission [r, g, b] where r,g,b in range [0..15]

View File

@ -190,20 +190,30 @@ void WorldRenderer::draw(const GfxContext& pctx, Camera* camera, bool hudVisible
const vec3 pos = PlayerController::selectedBlockPosition;
const vec3 point = PlayerController::selectedPointPosition;
const vec3 norm = PlayerController::selectedBlockNormal;
AABB hitbox = block->hitbox;
std::vector<AABB> hitboxes;
if (!block->hitboxExplicit) {
hitboxes = block->modelBoxes;
} else {
hitboxes = { block->hitbox };
}
if (block->rotatable) {
auto states = PlayerController::selectedBlockStates;
block->rotations.variants[states].transform(hitbox);
auto states = PlayerController::selectedBlockStates;
for (auto& hitbox: hitboxes) {
block->rotations.variants[states].transform(hitbox);
}
}
const vec3 center = pos + hitbox.center();
const vec3 size = hitbox.size();
linesShader->use();
linesShader->uniformMatrix("u_projview", camera->getProjView());
lineBatch->lineWidth(2.0f);
lineBatch->box(center, size + vec3(0.02), vec4(0.f, 0.f, 0.f, 0.5f));
if (level->player->debug)
lineBatch->line(point, point+norm*0.5f, vec4(1.0f, 0.0f, 1.0f, 1.0f));
linesShader->use();
linesShader->uniformMatrix("u_projview", camera->getProjView());
lineBatch->lineWidth(2.0f);
for (auto& hitbox: hitboxes) {
const vec3 center = pos + hitbox.center();
const vec3 size = hitbox.size();
lineBatch->box(center, size + vec3(0.02), vec4(0.f, 0.f, 0.f, 0.5f));
if (level->player->debug)
lineBatch->line(point, point+norm*0.5f, vec4(1.0f, 0.0f, 1.0f, 1.0f));
}
lineBatch->render();
}
skybox->unbind();
@ -289,4 +299,4 @@ void WorldRenderer::drawBorders(int sx, int sy, int sz, int ex, int ey, int ez)
lineBatch->render();
}
float WorldRenderer::fog = 0.0f;
float WorldRenderer::fog = 0.0f;

View File

@ -94,6 +94,7 @@ public:
bool grounded = false;
bool hidden = false;
AABB hitbox;
bool hitboxExplicit = false;
BlockRotProfile rotations;
std::string pickingItem = name+BLOCK_ITEM_SUFFIX;
std::string scriptName = name.substr(name.find(':')+1);

View File

@ -15,6 +15,7 @@
#include <math.h>
#include <limits.h>
#include <vector>
Chunks::Chunks(int w, int d,
int ox, int oz,
@ -52,7 +53,7 @@ const AABB* Chunks::isObstacleAt(float x, float y, float z){
int ix = floor(x);
int iy = floor(y);
int iz = floor(z);
voxel* v = get(ix,iy,iz);
voxel* v = get(ix, iy, iz);
if (v == nullptr)
return &contentIds->getBlockDef(0)->hitbox;
const Block* def = contentIds->getBlockDef(v->id);
@ -62,10 +63,14 @@ const AABB* Chunks::isObstacleAt(float x, float y, float z){
: def->hitbox;
if (def->rt.solid) {
return &hitbox;
} else {
if (hitbox.contains({x - ix, y - iy, z - iz}))
return &hitbox;
return nullptr;
} else if (def->hitboxExplicit) {
if (hitbox.contains({x - ix, y - iy, z - iz}))
return &hitbox;
} else {
for (const auto& hitbox : def->modelBoxes) {
if (hitbox.contains({x - ix, y - iy, z - iz}))
return &hitbox;
}
}
}
return nullptr;