fix integer raycast filters & add simple raycast test

This commit is contained in:
MihailRis 2026-07-17 00:23:16 +03:00
parent f6e1f23c84
commit 39a4236553
4 changed files with 85 additions and 9 deletions

47
dev/tests/raycast.lua Normal file
View file

@ -0,0 +1,47 @@
local util = require "core:tests_util"
-- Create world and prepare settings
util.create_demo_world("core:default")
app.set_setting("chunks.load-distance", 3)
app.set_setting("chunks.load-speed", 1)
-- Create player
local pid = player.create("Xerxes")
player.set_spawnpoint(pid, 0, 100, 0)
player.set_pos(pid, 0, 100, 0)
app.sleep_until(function () return block.get(0, 0, 0) ~= -1 end)
app.sleep_until(function () return block.get(-5, 8, 2) ~= -1 end)
local sand_idx = block.index("base:sand")
block.set(0, 1, 0, sand_idx)
local start = {-5, 8, 2}
local target = {0.5, 1.5, 0.5}
local ray = world.raycast({
start = start,
dir = vec3.normalize(vec3.sub(target, start)),
distance = 10,
})
debug.print(ray)
assert(ray, "ray didn't hit")
util.check_int(sand_idx, ray.block, "ray.block")
util.check_vec3({0, 1, 0}, ray.normal, "ray.normal")
util.check_vec3({0.0769, 2, 0.6153}, ray.endpoint, "ray.endpoint")
util.check_vec3({0, 1, 0}, ray.iendpoint, "ray.iendpoint")
util.check_float(7.9807, ray.length, "ray.length")
ray = world.raycast({
start = start,
dir = vec3.normalize(vec3.sub(target, start)),
distance = 10,
filter_blocks = {sand_idx},
})
debug.print(ray)
assert(ray, "ray didn't hit")
util.check_int(block.index("core:obstacle"), ray.block, "ray.block")
util.check_vec3({0, 1, 0}, ray.normal, "ray.normal")
util.check_vec3({0.923, 1, 0.3846}, ray.endpoint, "ray.endpoint")
util.check_vec3({0, 0, 0}, ray.iendpoint, "ray.iendpoint")
util.check_float(9.3108, ray.length, "ray.length")

View file

@ -5,4 +5,25 @@ function util.create_demo_world(generator)
app.new_world("demo", "2019", generator or "core:default")
end
function util.check_vec3(expected, fact, name, delta)
delta = delta or 1e-4
for i=1,3 do
assert(math.abs(fact[i] - expected[i]) < delta,
name.."["..i.."] expected: "..expected[i]..", fact: "..fact[i])
end
end
function util.check_float(expected, fact, name, delta)
delta = delta or 1e-4
local actual_delta = math.abs(fact - expected)
assert(actual_delta < delta,
name.." expected: "..expected..", fact: "..fact..
" (delta: "..actual_delta.." > "..delta..")")
end
function util.check_int(expected, fact, name)
assert(fact == expected,
name.." expected: "..expected..", fact: "..fact)
end
return util

View file

@ -230,10 +230,14 @@ static void load_blocks_filter(lua::State* L, int idx, std::set<blockid_t>& dst)
int count = lua::objlen(L, idx);
for (int i = 0; i < count; i++) {
lua::rawgeti(L, i + 1, idx);
auto blockName = std::string(lua::tostring(L, -1));
const Block* block = content->blocks.find(blockName);
if (block != nullptr) {
dst.insert(block->rt.id);
if (lua::isnumber(L, -1)) {
dst.insert(lua::touinteger(L, -1));
} else {
auto blockName = std::string(lua::tostring(L, -1));
const Block* block = content->blocks.find(blockName);
if (block != nullptr) {
dst.insert(block->rt.id);
}
}
lua::pop(L);
}
@ -243,10 +247,14 @@ static void load_entities_filter(lua::State* L, int idx, std::set<entitydefid_t>
int count = lua::objlen(L, idx);
for (int i = 0; i < count; i++) {
lua::rawgeti(L, i + 1, idx);
auto entityName = std::string(lua::tostring(L, -1));
const EntityDef* entity = content->entities.find(entityName);
if (entity != nullptr) {
dst.insert(entity->rt.id);
if (lua::isnumber(L, -1)) {
dst.insert(lua::touinteger(L, -1));
} else {
auto entityName = std::string(lua::tostring(L, -1));
const EntityDef* entity = content->entities.find(entityName);
if (entity != nullptr) {
dst.insert(entity->rt.id);
}
}
lua::pop(L);
}

View file

@ -269,7 +269,7 @@ static inline voxel* raycast_blocks(
const auto& def = blocks.require(voxel->id);
if (voxel->id != BLOCK_AIR &&
(def.selectable || includeNonSelectable) &&
(filter == nullptr || (filter->find(def.rt.id) == filter->end()) ==
((filter == nullptr || filter->find(def.rt.id) == filter->end()) ==
settings.blocksFilterExcludeMode)) {
end = start + t * dir;
iend = {ix, iy, iz};