Fix #160 with suggestions from @A-lex-Ra

This commit is contained in:
InfiniteCoder 2024-02-24 17:09:11 +03:00
parent 7ee0c672f0
commit 3edf065550
7 changed files with 63 additions and 82 deletions

View File

@ -82,16 +82,11 @@ Content* ContentBuilder::build() {
def->rt.solid = def->model == BlockModel::block; def->rt.solid = def->model == BlockModel::block;
if (def->rotatable) { if (def->rotatable) {
const AABB& hitbox = def->hitbox;
for (uint i = 0; i < BlockRotProfile::MAX_COUNT; i++) { for (uint i = 0; i < BlockRotProfile::MAX_COUNT; i++) {
AABB aabb = hitbox; def->rt.hitboxes[i].reserve(def->hitboxes.size());
for (AABB aabb : def->hitboxes) {
def->rotations.variants[i].transform(aabb); def->rotations.variants[i].transform(aabb);
def->rt.hitboxes[i] = aabb; def->rt.hitboxes[i].push_back(aabb);
def->rt.modelBoxes[i].reserve(def->modelBoxes.size());
for (AABB aabb : def->modelBoxes) {
def->rotations.variants[i].transform(aabb);
def->rt.modelBoxes[i].push_back(aabb);
} }
} }
} }

View File

@ -145,20 +145,27 @@ void ContentLoader::loadBlock(Block& def, std::string name, fs::path file) {
} }
// block hitbox AABB [x, y, z, width, height, depth] // block hitbox AABB [x, y, z, width, height, depth]
auto boxarr = root->list("hitbox"); auto boxarr = root->list("hitboxes");
if (boxarr) { if (boxarr) {
AABB& aabb = def.hitbox; def.hitboxes.resize(boxarr->size());
for (uint i = 0; i < boxarr->size(); i++) {
auto box = boxarr->list(i);
def.hitboxes[i].a = glm::vec3(box->num(0), box->num(1), box->num(2));
def.hitboxes[i].b = glm::vec3(box->num(3), box->num(4), box->num(5));
def.hitboxes[i].b += def.hitboxes[i].a;
}
} else {
boxarr = root->list("hitbox");
if (boxarr) {
AABB aabb;
aabb.a = glm::vec3(boxarr->num(0), boxarr->num(1), boxarr->num(2)); 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 = glm::vec3(boxarr->num(3), boxarr->num(4), boxarr->num(5));
aabb.b += aabb.a; aabb.b += aabb.a;
def.hitboxExplicit = true; def.hitboxes = { aabb };
} else if (def.modelBoxes.empty()) { } else if (!def.modelBoxes.empty()) {
def.hitboxExplicit = true; def.hitboxes = def.modelBoxes;
} else { } else {
def.hitbox = def.modelBoxes[0]; def.hitboxes = { AABB() };
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);
} }
} }

View File

@ -39,8 +39,13 @@ ImageData* BlocksPreview::draw(
glm::vec4(1.0f), !def->rt.emissive); glm::vec4(1.0f), !def->rt.emissive);
break; break;
case BlockModel::aabb: case BlockModel::aabb:
batch->blockCube(def->hitbox.size() * glm::vec3(size * 0.63f), {
glm::vec3 hitbox = glm::vec3();
for (const auto& box : def->hitboxes)
hitbox = glm::max(hitbox, box.size());
batch->blockCube(hitbox * glm::vec3(size * 0.63f),
texfaces, glm::vec4(1.0f), !def->rt.emissive); texfaces, glm::vec4(1.0f), !def->rt.emissive);
}
break; break;
case BlockModel::custom: case BlockModel::custom:
case BlockModel::xsprite: { case BlockModel::xsprite: {
@ -99,7 +104,10 @@ std::unique_ptr<Atlas> BlocksPreview::build(
glm::vec3 offset(0.1f, 0.5f, 0.1f); glm::vec3 offset(0.1f, 0.5f, 0.1f);
if (def->model == BlockModel::aabb) { if (def->model == BlockModel::aabb) {
offset.y += (1.0f - def->hitbox.size()).y * 0.5f; glm::vec3 size = glm::vec3(0, 0, 0);
for (const auto& box : def->hitboxes)
size = glm::max(size, box.size());
offset.y += (1.0f - size).y * 0.5f;
} }
atlas->getTexture()->bind(); atlas->getTexture()->bind();
shader->uniformMatrix("u_apply", glm::translate(glm::mat4(1.0f), offset)); shader->uniformMatrix("u_apply", glm::translate(glm::mat4(1.0f), offset));

View File

@ -191,18 +191,9 @@ void WorldRenderer::draw(const GfxContext& pctx, Camera* camera, bool hudVisible
const vec3 point = PlayerController::selectedPointPosition; const vec3 point = PlayerController::selectedPointPosition;
const vec3 norm = PlayerController::selectedBlockNormal; const vec3 norm = PlayerController::selectedBlockNormal;
std::vector<AABB> hitboxes; std::vector<AABB>& hitboxes = block->rotatable
if (!block->hitboxExplicit) { ? block->rt.hitboxes[PlayerController::selectedBlockStates]
hitboxes = block->modelBoxes; : block->hitboxes;
} else {
hitboxes = { block->hitbox };
}
if (block->rotatable) {
auto states = PlayerController::selectedBlockStates;
for (auto& hitbox: hitboxes) {
block->rotations.variants[states].transform(hitbox);
}
}
linesShader->use(); linesShader->use();
linesShader->uniformMatrix("u_projview", camera->getProjView()); linesShader->uniformMatrix("u_projview", camera->getProjView());

View File

@ -220,9 +220,17 @@ void BlocksRenderer::blockAABB(const ivec3& icoord,
const UVRegion(&texfaces)[6], const UVRegion(&texfaces)[6],
const Block* block, ubyte rotation, const Block* block, ubyte rotation,
bool lights) { bool lights) {
AABB hitbox = block->hitbox; if (block->hitboxes.empty()) {
vec3 size = hitbox.size(); return;
}
AABB hitbox = block->hitboxes[0];
for (const auto& box : block->hitboxes) {
hitbox.a = glm::min(hitbox.a, box.a);
hitbox.b = glm::max(hitbox.b, box.b);
}
vec3 size = hitbox.size();
vec3 X(1, 0, 0); vec3 X(1, 0, 0);
vec3 Y(0, 1, 0); vec3 Y(0, 1, 0);
vec3 Z(0, 0, 1); vec3 Z(0, 0, 1);

View File

@ -93,8 +93,7 @@ public:
bool rotatable = false; bool rotatable = false;
bool grounded = false; bool grounded = false;
bool hidden = false; bool hidden = false;
AABB hitbox; std::vector<AABB> hitboxes;
bool hitboxExplicit = false;
BlockRotProfile rotations; BlockRotProfile rotations;
std::string pickingItem = name+BLOCK_ITEM_SUFFIX; std::string pickingItem = name+BLOCK_ITEM_SUFFIX;
std::string scriptName = name.substr(name.find(':')+1); std::string scriptName = name.substr(name.find(':')+1);
@ -105,8 +104,7 @@ public:
blockid_t id; blockid_t id;
bool solid = true; bool solid = true;
bool emissive = false; bool emissive = false;
AABB hitboxes[BlockRotProfile::MAX_COUNT]; std::vector<AABB> hitboxes[BlockRotProfile::MAX_COUNT];
std::vector<AABB> modelBoxes[BlockRotProfile::MAX_COUNT];
block_funcs_set funcsset {}; block_funcs_set funcsset {};
itemid_t pickingItem = 0; itemid_t pickingItem = 0;
} rt; } rt;

View File

@ -54,28 +54,20 @@ const AABB* Chunks::isObstacleAt(float x, float y, float z){
int iy = floor(y); int iy = floor(y);
int iz = floor(z); int iz = floor(z);
voxel* v = get(ix, iy, iz); voxel* v = get(ix, iy, iz);
if (v == nullptr) if (v == nullptr) {
return &contentIds->getBlockDef(0)->hitbox; static const AABB empty;
return &empty;
}
const Block* def = contentIds->getBlockDef(v->id); const Block* def = contentIds->getBlockDef(v->id);
if (def->obstacle) { if (def->obstacle) {
const AABB& hitbox = def->rotatable
? def->rt.hitboxes[v->rotation()]
: def->hitbox;
if (def->rt.solid) {
return &hitbox;
} else if (def->hitboxExplicit) {
if (hitbox.contains({x - ix, y - iy, z - iz}))
return &hitbox;
} else {
const auto& boxes = def->rotatable const auto& boxes = def->rotatable
? def->rt.modelBoxes[v->rotation()] ? def->rt.hitboxes[v->rotation()]
: def->modelBoxes; : def->hitboxes;
for (const auto& hitbox : boxes) { for (const auto& hitbox : boxes) {
if (hitbox.contains({x - ix, y - iy, z - iz})) if (hitbox.contains({x - ix, y - iy, z - iz}))
return &hitbox; return &hitbox;
} }
} }
}
return nullptr; return nullptr;
} }
@ -247,18 +239,9 @@ voxel* Chunks::rayCast(glm::vec3 start,
iend.z = iz; iend.z = iz;
if (!def->rt.solid) { if (!def->rt.solid) {
std::vector<AABB> hitboxes; const std::vector<AABB>& hitboxes = def->rotatable
if (def->hitboxExplicit) {
hitboxes = {
def->rotatable
? def->rt.hitboxes[voxel->rotation()] ? def->rt.hitboxes[voxel->rotation()]
: def->hitbox : def->hitboxes;
};
} else {
hitboxes = def->rotatable
? def->rt.modelBoxes[voxel->rotation()]
: def->modelBoxes;
}
scalar_t distance = maxDist; scalar_t distance = maxDist;
Ray ray(start, dir); Ray ray(start, dir);
@ -365,18 +348,9 @@ glm::vec3 Chunks::rayCastToObstacle(glm::vec3 start, glm::vec3 dir, float maxDis
const Block* def = contentIds->getBlockDef(voxel->id); const Block* def = contentIds->getBlockDef(voxel->id);
if (def->obstacle) { if (def->obstacle) {
if (!def->rt.solid) { if (!def->rt.solid) {
std::vector<AABB> hitboxes; const std::vector<AABB>& hitboxes = def->rotatable
if (def->hitboxExplicit) {
hitboxes = {
def->rotatable
? def->rt.hitboxes[voxel->rotation()] ? def->rt.hitboxes[voxel->rotation()]
: def->hitbox
};
} else {
hitboxes = def->rotatable
? def->rt.modelBoxes[voxel->rotation()]
: def->modelBoxes; : def->modelBoxes;
}
scalar_t distance; scalar_t distance;
glm::ivec3 norm; glm::ivec3 norm;