Merge pull request #161 from InfiniteCoder01/main

Fix #160
This commit is contained in:
MihailRis 2024-02-24 18:19:49 +03:00 committed by GitHub
commit 00bd8c64d7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 74 additions and 85 deletions

View File

@ -82,16 +82,11 @@ Content* ContentBuilder::build() {
def->rt.solid = def->model == BlockModel::block;
if (def->rotatable) {
const AABB& hitbox = def->hitbox;
for (uint i = 0; i < BlockRotProfile::MAX_COUNT; i++) {
AABB aabb = hitbox;
def->rotations.variants[i].transform(aabb);
def->rt.hitboxes[i] = aabb;
def->rt.modelBoxes[i].reserve(def->modelBoxes.size());
for (AABB aabb : def->modelBoxes) {
def->rt.hitboxes[i].reserve(def->hitboxes.size());
for (AABB aabb : def->hitboxes) {
def->rotations.variants[i].transform(aabb);
def->rt.modelBoxes[i].push_back(aabb);
def->rt.hitboxes[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]
auto boxarr = root->list("hitbox");
auto boxarr = root->list("hitboxes");
if (boxarr) {
AABB& aabb = def.hitbox;
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;
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 {
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);
boxarr = root->list("hitbox");
if (boxarr) {
AABB aabb;
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.hitboxes = { aabb };
} else if (!def.modelBoxes.empty()) {
def.hitboxes = def.modelBoxes;
} else {
def.hitboxes = { AABB() };
}
}

View File

@ -39,8 +39,13 @@ ImageData* BlocksPreview::draw(
glm::vec4(1.0f), !def->rt.emissive);
break;
case BlockModel::aabb:
batch->blockCube(def->hitbox.size() * glm::vec3(size * 0.63f),
texfaces, glm::vec4(1.0f), !def->rt.emissive);
{
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);
}
break;
case BlockModel::custom:
case BlockModel::xsprite: {
@ -99,7 +104,10 @@ std::unique_ptr<Atlas> BlocksPreview::build(
glm::vec3 offset(0.1f, 0.5f, 0.1f);
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();
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 norm = PlayerController::selectedBlockNormal;
std::vector<AABB> hitboxes;
if (!block->hitboxExplicit) {
hitboxes = block->modelBoxes;
} else {
hitboxes = { block->hitbox };
}
if (block->rotatable) {
auto states = PlayerController::selectedBlockStates;
for (auto& hitbox: hitboxes) {
block->rotations.variants[states].transform(hitbox);
}
}
std::vector<AABB>& hitboxes = block->rotatable
? block->rt.hitboxes[PlayerController::selectedBlockStates]
: block->hitboxes;
linesShader->use();
linesShader->uniformMatrix("u_projview", camera->getProjView());

View File

@ -220,9 +220,17 @@ void BlocksRenderer::blockAABB(const ivec3& icoord,
const UVRegion(&texfaces)[6],
const Block* block, ubyte rotation,
bool lights) {
AABB hitbox = block->hitbox;
vec3 size = hitbox.size();
if (block->hitboxes.empty()) {
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 Y(0, 1, 0);
vec3 Z(0, 0, 1);

View File

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

View File

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