Merge pull request #766 from clasher113/main

blocks raycast enhancement
This commit is contained in:
MihailRis 2026-01-06 13:45:43 +03:00 • committed by GitHub
commit 4c7043d4c2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 57 additions and 24 deletions

View file

@ -476,8 +476,10 @@ static int l_raycast(lua::State* L) {
auto start = lua::tovec<3>(L, 1);
auto dir = lua::tovec<3>(L, 2);
auto maxDistance = lua::tonumber(L, 3);
bool includeNonSelectable = false;
std::set<blockid_t> filteredBlocks {};
if (lua::gettop(L) >= 5) {
const int luaStackSize = lua::gettop(L);
if (luaStackSize >= 5) {
if (lua::istable(L, 5)) {
int addLen = lua::objlen(L, 5);
for (int i = 0; i < addLen; i++) {
@ -493,6 +495,9 @@ static int l_raycast(lua::State* L) {
throw std::runtime_error("table expected for filter");
}
}
if (luaStackSize >= 6) {
includeNonSelectable = lua::toboolean(L, 6);
}
glm::vec3 end;
glm::ivec3 normal;
glm::ivec3 iend;
@ -504,9 +509,10 @@ static int l_raycast(lua::State* L) {
end,
normal,
iend,
filteredBlocks
filteredBlocks,
includeNonSelectable
)) {
if (lua::gettop(L) >= 4 && !lua::isnil(L, 4)) {
if (luaStackSize >= 4 && !lua::isnil(L, 4)) {
lua::pushvalue(L, 4);
} else {
lua::createtable(L, 0, 5);

View file

@ -141,8 +141,10 @@ static int l_raycast(lua::State* L) {
auto dir = lua::tovec<3>(L, 2);
auto maxDistance = lua::tonumber(L, 3);
auto ignoreEntityId = lua::tointeger(L, 4);
bool includeNonSelectable = false;
std::set<blockid_t> filteredBlocks {};
if (lua::gettop(L) >= 6) {
const int luaStackSize = lua::gettop(L);
if (luaStackSize >= 6) {
if (lua::istable(L, 6)) {
int addLen = lua::objlen(L, 6);
for (int i = 0; i < addLen; i++) {
@ -158,6 +160,9 @@ static int l_raycast(lua::State* L) {
throw std::runtime_error("table expected for filter");
}
}
if (luaStackSize >= 7) {
includeNonSelectable = lua::toboolean(L, 6);
}
glm::vec3 end;
glm::ivec3 normal;
@ -173,14 +178,15 @@ static int l_raycast(lua::State* L) {
end,
normal,
iend,
filteredBlocks
filteredBlocks,
includeNonSelectable
)) {
maxDistance = glm::distance(start, end);
block = voxel->id;
}
if (auto ray =
level->entities->rayCast(start, dir, maxDistance, ignoreEntityId)) {
if (lua::gettop(L) >= 5 && !lua::isnil(L, 5)) {
if (luaStackSize >= 5 && !lua::isnil(L, 5)) {
lua::pushvalue(L, 5);
} else {
lua::createtable(L, 0, 6);

View file

@ -215,10 +215,11 @@ voxel* Chunks::rayCast(
glm::vec3& end,
glm::ivec3& norm,
glm::ivec3& iend,
std::set<blockid_t> filter
std::set<blockid_t> filter,
bool includeNonSelectable
) const {
return blocks_agent::raycast(
*this, start, dir, maxDist, end, norm, iend, std::move(filter)
*this, start, dir, maxDist, end, norm, iend, std::move(filter), includeNonSelectable
);
}

View file

@ -111,7 +111,8 @@ public:
glm::vec3& end,
glm::ivec3& norm,
glm::ivec3& iend,
std::set<blockid_t> filter = {}
std::set<blockid_t> filter = {},
bool includeNonSelectable = false
) const;
glm::vec3 rayCastToObstacle(

View file

@ -221,7 +221,8 @@ static inline voxel* raycast_blocks(
glm::vec3& end,
glm::ivec3& norm,
glm::ivec3& iend,
std::set<blockid_t> filter
std::set<blockid_t> filter,
bool includeNonSelectable
) {
const auto& blocks = chunks.getContentIndices().blocks;
float px = start.x;
@ -264,8 +265,8 @@ static inline voxel* raycast_blocks(
}
const auto& def = blocks.require(voxel->id);
if ((filter.empty() && def.selectable) ||
(!filter.empty() && filter.find(def.rt.id) == filter.end())) {
if (voxel->id != BLOCK_AIR && (def.selectable || includeNonSelectable) &&
(filter.empty() || filter.find(def.rt.id) == filter.end())) {
end.x = px + t * dx;
end.y = py + t * dy;
end.z = pz + t * dz;
@ -362,9 +363,10 @@ voxel* blocks_agent::raycast(
glm::vec3& end,
glm::ivec3& norm,
glm::ivec3& iend,
std::set<blockid_t> filter
std::set<blockid_t> filter,
bool includeNonSelectable
) {
return raycast_blocks(chunks, start, dir, maxDist, end, norm, iend, filter);
return raycast_blocks(chunks, start, dir, maxDist, end, norm, iend, filter, includeNonSelectable);
}
voxel* blocks_agent::raycast(
@ -375,9 +377,10 @@ voxel* blocks_agent::raycast(
glm::vec3& end,
glm::ivec3& norm,
glm::ivec3& iend,
std::set<blockid_t> filter
std::set<blockid_t> filter,
bool includeNonSelectable
) {
return raycast_blocks(chunks, start, dir, maxDist, end, norm, iend, filter);
return raycast_blocks(chunks, start, dir, maxDist, end, norm, iend, filter, includeNonSelectable);
}
// reduce nesting on next modification

View file

@ -419,6 +419,7 @@ inline void set_rotation(
/// @param norm [out] surface normal vector
/// @param iend [out] ray end integer position (voxel position + normal)
/// @param filter filtered ids
/// @param includeNonSelectable will non-selectable blocks be included
/// @return voxel pointer or nullptr
voxel* raycast(
const Chunks& chunks,
@ -428,7 +429,8 @@ voxel* raycast(
glm::vec3& end,
glm::ivec3& norm,
glm::ivec3& iend,
std::set<blockid_t> filter
std::set<blockid_t> filter,
bool includeNonSelectable
);
/// @brief Cast ray to a selectable block with filter based on id.
@ -440,6 +442,7 @@ voxel* raycast(
/// @param norm [out] surface normal vector
/// @param iend [out] ray end integer position (voxel position + normal)
/// @param filter filtered ids
/// @param includeNonSelectable will non-selectable blocks be included
/// @return voxel pointer or nullptr
voxel* raycast(
const GlobalChunks& chunks,
@ -449,7 +452,8 @@ voxel* raycast(
glm::vec3& end,
glm::ivec3& norm,
glm::ivec3& iend,
std::set<blockid_t> filter
std::set<blockid_t> filter,
bool includeNonSelectable
);
void get_voxels(const Chunks& chunks, VoxelsVolume* volume, bool backlight=false);