Fix #160 with suggestions from @A-lex-Ra
This commit is contained in:
parent
7ee0c672f0
commit
3edf065550
@ -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());
|
||||||
def->rotations.variants[i].transform(aabb);
|
for (AABB aabb : def->hitboxes) {
|
||||||
def->rt.hitboxes[i] = aabb;
|
|
||||||
|
|
||||||
def->rt.modelBoxes[i].reserve(def->modelBoxes.size());
|
|
||||||
for (AABB aabb : def->modelBoxes) {
|
|
||||||
def->rotations.variants[i].transform(aabb);
|
def->rotations.variants[i].transform(aabb);
|
||||||
def->rt.modelBoxes[i].push_back(aabb);
|
def->rt.hitboxes[i].push_back(aabb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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());
|
||||||
aabb.a = glm::vec3(boxarr->num(0), boxarr->num(1), boxarr->num(2));
|
for (uint i = 0; i < boxarr->size(); i++) {
|
||||||
aabb.b = glm::vec3(boxarr->num(3), boxarr->num(4), boxarr->num(5));
|
auto box = boxarr->list(i);
|
||||||
aabb.b += aabb.a;
|
def.hitboxes[i].a = glm::vec3(box->num(0), box->num(1), box->num(2));
|
||||||
def.hitboxExplicit = true;
|
def.hitboxes[i].b = glm::vec3(box->num(3), box->num(4), box->num(5));
|
||||||
} else if (def.modelBoxes.empty()) {
|
def.hitboxes[i].b += def.hitboxes[i].a;
|
||||||
def.hitboxExplicit = true;
|
}
|
||||||
} else {
|
} else {
|
||||||
def.hitbox = def.modelBoxes[0];
|
boxarr = root->list("hitbox");
|
||||||
for (const auto& box : def.modelBoxes) {
|
if (boxarr) {
|
||||||
def.hitbox.a = glm::min(def.hitbox.a, box.a);
|
AABB aabb;
|
||||||
def.hitbox.b = glm::max(def.hitbox.b, box.b);
|
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() };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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),
|
{
|
||||||
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;
|
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));
|
||||||
|
|||||||
@ -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());
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -54,27 +54,19 @@ 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 ∅
|
||||||
|
}
|
||||||
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
|
const auto& boxes = def->rotatable
|
||||||
? def->rt.hitboxes[v->rotation()]
|
? def->rt.hitboxes[v->rotation()]
|
||||||
: def->hitbox;
|
: def->hitboxes;
|
||||||
if (def->rt.solid) {
|
for (const auto& hitbox : boxes) {
|
||||||
return &hitbox;
|
|
||||||
} else if (def->hitboxExplicit) {
|
|
||||||
if (hitbox.contains({x - ix, y - iy, z - iz}))
|
if (hitbox.contains({x - ix, y - iy, z - iz}))
|
||||||
return &hitbox;
|
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;
|
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) {
|
? def->rt.hitboxes[voxel->rotation()]
|
||||||
hitboxes = {
|
: def->hitboxes;
|
||||||
def->rotatable
|
|
||||||
? def->rt.hitboxes[voxel->rotation()]
|
|
||||||
: def->hitbox
|
|
||||||
};
|
|
||||||
} 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) {
|
? def->rt.hitboxes[voxel->rotation()]
|
||||||
hitboxes = {
|
: def->modelBoxes;
|
||||||
def->rotatable
|
|
||||||
? def->rt.hitboxes[voxel->rotation()]
|
|
||||||
: def->hitbox
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
hitboxes = def->rotatable
|
|
||||||
? def->rt.modelBoxes[voxel->rotation()]
|
|
||||||
: def->modelBoxes;
|
|
||||||
}
|
|
||||||
|
|
||||||
scalar_t distance;
|
scalar_t distance;
|
||||||
glm::ivec3 norm;
|
glm::ivec3 norm;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user