mirror of
https://github.com/MihailRis/voxelcore.git
synced 2026-10-04 18:41:51 +00:00
add world.raycast
This commit is contained in:
parent
baa952a172
commit
ad6b72f87c
2 changed files with 78 additions and 59 deletions
|
|
@ -312,6 +312,8 @@ entities.get_all = function(uids)
|
||||||
return stdcomp.get_all(uids)
|
return stdcomp.get_all(uids)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
world.raycast = entities.__world_raycast
|
||||||
|
entities.__world_raycast = nil
|
||||||
|
|
||||||
__vc_scripts_registry = require "core:internal/scripts_registry"
|
__vc_scripts_registry = require "core:internal/scripts_registry"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -197,7 +197,8 @@ static int l_raycast(
|
||||||
const glm::vec3& dir,
|
const glm::vec3& dir,
|
||||||
float maxDistance,
|
float maxDistance,
|
||||||
const blocks_agent::RaycastSettings& voxelRaycast,
|
const blocks_agent::RaycastSettings& voxelRaycast,
|
||||||
const Entities::RaycastSettings& entityRaycast
|
const Entities::RaycastSettings& entityRaycast,
|
||||||
|
bool entities
|
||||||
) {
|
) {
|
||||||
glm::vec3 end;
|
glm::vec3 end;
|
||||||
glm::ivec3 normal;
|
glm::ivec3 normal;
|
||||||
|
|
@ -218,7 +219,10 @@ static int l_raycast(
|
||||||
maxDistance = glm::distance(start, end);
|
maxDistance = glm::distance(start, end);
|
||||||
block = voxel->id;
|
block = voxel->id;
|
||||||
}
|
}
|
||||||
auto ray = level->entities->rayCast(start, dir, maxDistance, entityRaycast);
|
auto ray =
|
||||||
|
entities
|
||||||
|
? level->entities->rayCast(start, dir, maxDistance, entityRaycast)
|
||||||
|
: std::nullopt;
|
||||||
return l_push_ray(L, ray, block, start, dir, end, iend, normal);
|
return l_push_ray(L, ray, block, start, dir, end, iend, normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -248,7 +252,7 @@ static void load_entities_filter(lua::State* L, int idx, std::set<entitydefid_t>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int l_raycast(lua::State* L) {
|
static int l_world_raycast(lua::State* L) {
|
||||||
blocks_agent::RaycastSettings blocksRaycast {};
|
blocks_agent::RaycastSettings blocksRaycast {};
|
||||||
Entities::RaycastSettings entityRaycast {};
|
Entities::RaycastSettings entityRaycast {};
|
||||||
|
|
||||||
|
|
@ -257,68 +261,80 @@ static int l_raycast(lua::State* L) {
|
||||||
|
|
||||||
glm::vec3 start, dir;
|
glm::vec3 start, dir;
|
||||||
float maxDistance;
|
float maxDistance;
|
||||||
|
bool entities = true;
|
||||||
|
|
||||||
|
if (!lua::istable(L, 1)) {
|
||||||
|
throw std::runtime_error("invalid function overload");
|
||||||
|
}
|
||||||
|
|
||||||
|
lua::requirefield(L, "start", 1);
|
||||||
|
start = lua::tovec3(L, -1);
|
||||||
|
|
||||||
|
lua::requirefield(L, "dir", 1);
|
||||||
|
dir = lua::tovec3(L, -1);
|
||||||
|
|
||||||
|
lua::requirefield(L, "distance", 1);
|
||||||
|
maxDistance = lua::tonumber(L, -1);
|
||||||
|
|
||||||
|
lua::pop(L, 3);
|
||||||
|
|
||||||
|
if (lua::getfield(L, "entities", 1)) {
|
||||||
|
entities = lua::toboolean(L, -1);
|
||||||
|
lua::pop(L);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lua::getfield(L, "ignore_uid", 1)) {
|
||||||
|
entityRaycast.ignoredUid = lua::tointeger(L, -1);
|
||||||
|
lua::pop(L);
|
||||||
|
}
|
||||||
|
if (lua::getfield(L, "ignore_entities")) {
|
||||||
|
load_entities_filter(L, -1, filteredEntities);
|
||||||
|
blocksRaycast.filter = &filteredEntities;
|
||||||
|
lua::pop(L);
|
||||||
|
}
|
||||||
|
if (lua::getfield(L, "entities_exclusion")) {
|
||||||
|
entityRaycast.entityFilterExcludeMode = lua::toboolean(L, -1);
|
||||||
|
lua::pop(L);
|
||||||
|
}
|
||||||
|
if (lua::getfield(L, "filter_blocks", 1)) {
|
||||||
|
load_blocks_filter(L, -1, filteredBlocks);
|
||||||
|
blocksRaycast.filter = &filteredBlocks;
|
||||||
|
lua::pop(L);
|
||||||
|
}
|
||||||
|
if (lua::getfield(L, "nonselect_blocks", 1)) {
|
||||||
|
blocksRaycast.includeNonSelectable = lua::toboolean(L, -1);
|
||||||
|
lua::pop(L);
|
||||||
|
}
|
||||||
|
return l_raycast(
|
||||||
|
L, start, dir, maxDistance, blocksRaycast, entityRaycast, entities
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int l_raycast(lua::State* L) {
|
||||||
|
blocks_agent::RaycastSettings blocksRaycast {};
|
||||||
|
Entities::RaycastSettings entityRaycast {};
|
||||||
|
std::set<blockid_t> filteredBlocks {};
|
||||||
|
|
||||||
const int luaStackSize = lua::gettop(L);
|
const int luaStackSize = lua::gettop(L);
|
||||||
if (luaStackSize == 1) {
|
glm::vec3 start = lua::tovec<3>(L, 1);
|
||||||
if (!lua::istable(L, 1)) {
|
glm::vec3 dir = lua::tovec<3>(L, 2);
|
||||||
throw std::runtime_error("invalid function overload");
|
float maxDistance = lua::tonumber(L, 3);
|
||||||
}
|
|
||||||
|
|
||||||
lua::requirefield(L, "start", 1);
|
entityRaycast.ignoredUid = lua::tointeger(L, 4);
|
||||||
start = lua::tovec3(L, -1);
|
if (luaStackSize >= 6) {
|
||||||
|
if (lua::istable(L, 6)) {
|
||||||
lua::requirefield(L, "dir", 1);
|
load_blocks_filter(L, 6, filteredBlocks);
|
||||||
dir = lua::tovec3(L, -1);
|
blocksRaycast.filter = &filteredBlocks;
|
||||||
|
} else {
|
||||||
lua::requirefield(L, "distance", 1);
|
throw std::runtime_error("table expected for filter");
|
||||||
maxDistance = lua::tonumber(L, -1);
|
|
||||||
|
|
||||||
lua::pop(L, 3);
|
|
||||||
|
|
||||||
if (lua::getfield(L, "ignore_uid", 1)) {
|
|
||||||
entityRaycast.ignoredUid = lua::tointeger(L, -1);
|
|
||||||
lua::pop(L);
|
|
||||||
}
|
|
||||||
if (lua::getfield(L, "ignore_entities")) {
|
|
||||||
load_entities_filter(L, -1, filteredEntities);
|
|
||||||
lua::pop(L);
|
|
||||||
}
|
|
||||||
if (lua::getfield(L, "entities_exclusion")) {
|
|
||||||
entityRaycast.entityFilterExcludeMode = lua::toboolean(L, -1);
|
|
||||||
lua::pop(L);
|
|
||||||
}
|
|
||||||
if (lua::getfield(L, "filter_blocks", 1)) {
|
|
||||||
load_blocks_filter(L, -1, filteredBlocks);
|
|
||||||
lua::pop(L);
|
|
||||||
}
|
|
||||||
if (lua::getfield(L, "nonselect_blocks", 1)) {
|
|
||||||
blocksRaycast.includeNonSelectable = lua::toboolean(L, -1);
|
|
||||||
lua::pop(L);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
start = lua::tovec<3>(L, 1);
|
|
||||||
dir = lua::tovec<3>(L, 2);
|
|
||||||
maxDistance = lua::tonumber(L, 3);
|
|
||||||
|
|
||||||
entityRaycast.ignoredUid = lua::tointeger(L, 4);
|
|
||||||
if (luaStackSize >= 6) {
|
|
||||||
if (lua::istable(L, 6)) {
|
|
||||||
load_blocks_filter(L, 6, filteredBlocks);
|
|
||||||
} else {
|
|
||||||
throw std::runtime_error("table expected for filter");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (luaStackSize >= 7) {
|
|
||||||
blocksRaycast.includeNonSelectable = lua::toboolean(L, 6);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!filteredBlocks.empty()) {
|
if (luaStackSize >= 7) {
|
||||||
blocksRaycast.filter = &filteredBlocks;
|
blocksRaycast.includeNonSelectable = lua::toboolean(L, 6);
|
||||||
}
|
}
|
||||||
if (!filteredEntities.empty()) {
|
return l_raycast(
|
||||||
blocksRaycast.filter = &filteredEntities;
|
L, start, dir, maxDistance, blocksRaycast, entityRaycast, true
|
||||||
}
|
);
|
||||||
return l_raycast(L, start, dir, maxDistance, blocksRaycast, entityRaycast);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int l_reload_component(lua::State* L) {
|
static int l_reload_component(lua::State* L) {
|
||||||
|
|
@ -355,6 +371,7 @@ const luaL_Reg entitylib[] = {
|
||||||
{"get_all_in_box", lua::wrap<l_get_all_in_box>},
|
{"get_all_in_box", lua::wrap<l_get_all_in_box>},
|
||||||
{"get_all_in_radius", lua::wrap<l_get_all_in_radius>},
|
{"get_all_in_radius", lua::wrap<l_get_all_in_radius>},
|
||||||
{"raycast", lua::wrap<l_raycast>},
|
{"raycast", lua::wrap<l_raycast>},
|
||||||
|
{"__world_raycast", lua::wrap<l_world_raycast>},
|
||||||
{"reload_component", lua::wrap<l_reload_component>},
|
{"reload_component", lua::wrap<l_reload_component>},
|
||||||
{nullptr, nullptr}
|
{nullptr, nullptr}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue