mirror of
https://github.com/MihailRis/voxelcore.git
synced 2026-10-14 15:31:49 +00:00
add "include_non_selectable" parameter to blocks raycast
This commit is contained in:
parent
ce769143f8
commit
8f1739c85b
10 changed files with 57 additions and 23 deletions
|
|
@ -136,7 +136,9 @@ Set specified bits.
|
||||||
## Raycast
|
## Raycast
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
block.raycast(start: vec3, dir: vec3, max_distance: number, [optional] dest: table, [optional] filter: table) -> {
|
block.raycast(start: vec3, dir: vec3, max_distance: number, [optional] dest: table,
|
||||||
|
[optional] filter: table, [optional] include_non_selectable = false
|
||||||
|
) -> {
|
||||||
block: int, -- block id
|
block: int, -- block id
|
||||||
endpoint: vec3, -- point of the ray hit point
|
endpoint: vec3, -- point of the ray hit point
|
||||||
iendpoint: vec3, -- position of the block hit by the ray
|
iendpoint: vec3, -- position of the block hit by the ray
|
||||||
|
|
@ -150,6 +152,9 @@ Casts a ray from the start point in the direction of *dir*. Max_distance specifi
|
||||||
Argument `filter` can be used to tell ray what blocks can be skipped(passed through) during ray-casting.
|
Argument `filter` can be used to tell ray what blocks can be skipped(passed through) during ray-casting.
|
||||||
To use filter `dest` argument must be filled with some value(can be nil), it's done for backwards compatability
|
To use filter `dest` argument must be filled with some value(can be nil), it's done for backwards compatability
|
||||||
|
|
||||||
|
The `include_non_selectable` argument determines whether blocks that cannot be selected by the cursor will be included.
|
||||||
|
Example - `base:water`
|
||||||
|
|
||||||
The function returns a table with the results or nil if the ray does not hit any block.
|
The function returns a table with the results or nil if the ray does not hit any block.
|
||||||
|
|
||||||
The result will use the destination table instead of creating a new one if the optional argument specified.
|
The result will use the destination table instead of creating a new one if the optional argument specified.
|
||||||
|
|
|
||||||
|
|
@ -63,8 +63,9 @@ entities.get_all_in_radius(center: vec3, radius: number) -> array<int>
|
||||||
```
|
```
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
entities.raycast(start: vec3, dir: vec3, max_distance: number,
|
entities.raycast(start: vec3, dir: vec3, max_distance: number, ignore: int, [optional] destination: table,
|
||||||
ignore: int, [optional] destination: table, [optional] filter: table) -> table or nil
|
[optional] filter: table, [optional] include_non_selectable = false
|
||||||
|
) -> table or nil
|
||||||
```
|
```
|
||||||
|
|
||||||
The function is an extended version of [block.raycast](libblock.md#raycast). Returns a table with the results if the ray touches a block or entity.
|
The function is an extended version of [block.raycast](libblock.md#raycast). Returns a table with the results if the ray touches a block or entity.
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,9 @@ block.material(blockid: int) -> string
|
||||||
## Raycast
|
## Raycast
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
block.raycast(start: vec3, dir: vec3, max_distance: number, [опционально] dest: table, [опционально] filter: table) -> {
|
block.raycast(start: vec3, dir: vec3, max_distance: number, [опционально] dest: table,
|
||||||
|
[опционально] filter: table, [опционально] include_non_selectable = false
|
||||||
|
) -> {
|
||||||
block: int, -- id блока
|
block: int, -- id блока
|
||||||
endpoint: vec3, -- точка касания луча
|
endpoint: vec3, -- точка касания луча
|
||||||
iendpoint: vec3, -- позиция блока, которого касается луч
|
iendpoint: vec3, -- позиция блока, которого касается луч
|
||||||
|
|
@ -106,6 +108,9 @@ block.raycast(start: vec3, dir: vec3, max_distance: number, [опциональ
|
||||||
Аргумент `filter` позволяет указать какие блоки являются "прозрачными" для луча, прим.: {"base:glass","base:water"}.
|
Аргумент `filter` позволяет указать какие блоки являются "прозрачными" для луча, прим.: {"base:glass","base:water"}.
|
||||||
Для использования агрумент `dest` нужно чем-то заполнить(можно nil), это сделано для обратной совместимости
|
Для использования агрумент `dest` нужно чем-то заполнить(можно nil), это сделано для обратной совместимости
|
||||||
|
|
||||||
|
Аргумент `include_non_selectable` определяет, будут ли учтены блоки, которые нельзя выбрать курсором.
|
||||||
|
Пример - `base:water`
|
||||||
|
|
||||||
Функция возвращает таблицу с результатами или nil, если луч не касается блока.
|
Функция возвращает таблицу с результатами или nil, если луч не касается блока.
|
||||||
|
|
||||||
Для результата будет использоваться целевая (dest) таблица вместо создания новой, если указан опциональный аргумент.
|
Для результата будет использоваться целевая (dest) таблица вместо создания новой, если указан опциональный аргумент.
|
||||||
|
|
|
||||||
|
|
@ -62,8 +62,9 @@ entities.get_all_in_radius(center: vec3, radius: number) -> table<int>
|
||||||
```
|
```
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
entities.raycast(start: vec3, dir: vec3, max_distance: number,
|
entities.raycast(start: vec3, dir: vec3, max_distance: number, ignore: int, [optional] destination: table,
|
||||||
ignore: int, [optional] destination: table, [optional] filter: table) -> table или nil
|
[optional] filter: table, [optional] include_non_selectable = false
|
||||||
|
) -> table или nil
|
||||||
```
|
```
|
||||||
|
|
||||||
Функция является расширенным вариантом [block.raycast](libblock.md#raycast). Возвращает таблицу с результатами если луч касается блока, либо сущности.
|
Функция является расширенным вариантом [block.raycast](libblock.md#raycast). Возвращает таблицу с результатами если луч касается блока, либо сущности.
|
||||||
|
|
|
||||||
|
|
@ -476,8 +476,10 @@ static int l_raycast(lua::State* L) {
|
||||||
auto start = lua::tovec<3>(L, 1);
|
auto start = lua::tovec<3>(L, 1);
|
||||||
auto dir = lua::tovec<3>(L, 2);
|
auto dir = lua::tovec<3>(L, 2);
|
||||||
auto maxDistance = lua::tonumber(L, 3);
|
auto maxDistance = lua::tonumber(L, 3);
|
||||||
|
bool includeNonSelectable = false;
|
||||||
std::set<blockid_t> filteredBlocks {};
|
std::set<blockid_t> filteredBlocks {};
|
||||||
if (lua::gettop(L) >= 5) {
|
const int luaStackSize = lua::gettop(L);
|
||||||
|
if (luaStackSize >= 5) {
|
||||||
if (lua::istable(L, 5)) {
|
if (lua::istable(L, 5)) {
|
||||||
int addLen = lua::objlen(L, 5);
|
int addLen = lua::objlen(L, 5);
|
||||||
for (int i = 0; i < addLen; i++) {
|
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");
|
throw std::runtime_error("table expected for filter");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (luaStackSize >= 6) {
|
||||||
|
includeNonSelectable = lua::toboolean(L, 6);
|
||||||
|
}
|
||||||
glm::vec3 end;
|
glm::vec3 end;
|
||||||
glm::ivec3 normal;
|
glm::ivec3 normal;
|
||||||
glm::ivec3 iend;
|
glm::ivec3 iend;
|
||||||
|
|
@ -504,9 +509,10 @@ static int l_raycast(lua::State* L) {
|
||||||
end,
|
end,
|
||||||
normal,
|
normal,
|
||||||
iend,
|
iend,
|
||||||
filteredBlocks
|
filteredBlocks,
|
||||||
|
includeNonSelectable
|
||||||
)) {
|
)) {
|
||||||
if (lua::gettop(L) >= 4 && !lua::isnil(L, 4)) {
|
if (luaStackSize >= 4 && !lua::isnil(L, 4)) {
|
||||||
lua::pushvalue(L, 4);
|
lua::pushvalue(L, 4);
|
||||||
} else {
|
} else {
|
||||||
lua::createtable(L, 0, 5);
|
lua::createtable(L, 0, 5);
|
||||||
|
|
|
||||||
|
|
@ -141,8 +141,10 @@ static int l_raycast(lua::State* L) {
|
||||||
auto dir = lua::tovec<3>(L, 2);
|
auto dir = lua::tovec<3>(L, 2);
|
||||||
auto maxDistance = lua::tonumber(L, 3);
|
auto maxDistance = lua::tonumber(L, 3);
|
||||||
auto ignoreEntityId = lua::tointeger(L, 4);
|
auto ignoreEntityId = lua::tointeger(L, 4);
|
||||||
|
bool includeNonSelectable = false;
|
||||||
std::set<blockid_t> filteredBlocks {};
|
std::set<blockid_t> filteredBlocks {};
|
||||||
if (lua::gettop(L) >= 6) {
|
const int luaStackSize = lua::gettop(L);
|
||||||
|
if (luaStackSize >= 6) {
|
||||||
if (lua::istable(L, 6)) {
|
if (lua::istable(L, 6)) {
|
||||||
int addLen = lua::objlen(L, 6);
|
int addLen = lua::objlen(L, 6);
|
||||||
for (int i = 0; i < addLen; i++) {
|
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");
|
throw std::runtime_error("table expected for filter");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (luaStackSize >= 7) {
|
||||||
|
includeNonSelectable = lua::toboolean(L, 6);
|
||||||
|
}
|
||||||
|
|
||||||
glm::vec3 end;
|
glm::vec3 end;
|
||||||
glm::ivec3 normal;
|
glm::ivec3 normal;
|
||||||
|
|
@ -173,14 +178,15 @@ static int l_raycast(lua::State* L) {
|
||||||
end,
|
end,
|
||||||
normal,
|
normal,
|
||||||
iend,
|
iend,
|
||||||
filteredBlocks
|
filteredBlocks,
|
||||||
|
includeNonSelectable
|
||||||
)) {
|
)) {
|
||||||
maxDistance = glm::distance(start, end);
|
maxDistance = glm::distance(start, end);
|
||||||
block = voxel->id;
|
block = voxel->id;
|
||||||
}
|
}
|
||||||
if (auto ray =
|
if (auto ray =
|
||||||
level->entities->rayCast(start, dir, maxDistance, ignoreEntityId)) {
|
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);
|
lua::pushvalue(L, 5);
|
||||||
} else {
|
} else {
|
||||||
lua::createtable(L, 0, 6);
|
lua::createtable(L, 0, 6);
|
||||||
|
|
|
||||||
|
|
@ -215,10 +215,11 @@ voxel* Chunks::rayCast(
|
||||||
glm::vec3& end,
|
glm::vec3& end,
|
||||||
glm::ivec3& norm,
|
glm::ivec3& norm,
|
||||||
glm::ivec3& iend,
|
glm::ivec3& iend,
|
||||||
std::set<blockid_t> filter
|
std::set<blockid_t> filter,
|
||||||
|
bool includeNonSelectable
|
||||||
) const {
|
) const {
|
||||||
return blocks_agent::raycast(
|
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
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,8 @@ public:
|
||||||
glm::vec3& end,
|
glm::vec3& end,
|
||||||
glm::ivec3& norm,
|
glm::ivec3& norm,
|
||||||
glm::ivec3& iend,
|
glm::ivec3& iend,
|
||||||
std::set<blockid_t> filter = {}
|
std::set<blockid_t> filter = {},
|
||||||
|
bool includeNonSelectable = false
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
glm::vec3 rayCastToObstacle(
|
glm::vec3 rayCastToObstacle(
|
||||||
|
|
|
||||||
|
|
@ -221,7 +221,8 @@ static inline voxel* raycast_blocks(
|
||||||
glm::vec3& end,
|
glm::vec3& end,
|
||||||
glm::ivec3& norm,
|
glm::ivec3& norm,
|
||||||
glm::ivec3& iend,
|
glm::ivec3& iend,
|
||||||
std::set<blockid_t> filter
|
std::set<blockid_t> filter,
|
||||||
|
bool includeNonSelectable
|
||||||
) {
|
) {
|
||||||
const auto& blocks = chunks.getContentIndices().blocks;
|
const auto& blocks = chunks.getContentIndices().blocks;
|
||||||
float px = start.x;
|
float px = start.x;
|
||||||
|
|
@ -264,7 +265,8 @@ static inline voxel* raycast_blocks(
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& def = blocks.require(voxel->id);
|
const auto& def = blocks.require(voxel->id);
|
||||||
if (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.x = px + t * dx;
|
||||||
end.y = py + t * dy;
|
end.y = py + t * dy;
|
||||||
end.z = pz + t * dz;
|
end.z = pz + t * dz;
|
||||||
|
|
@ -361,9 +363,10 @@ voxel* blocks_agent::raycast(
|
||||||
glm::vec3& end,
|
glm::vec3& end,
|
||||||
glm::ivec3& norm,
|
glm::ivec3& norm,
|
||||||
glm::ivec3& iend,
|
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(
|
voxel* blocks_agent::raycast(
|
||||||
|
|
@ -374,9 +377,10 @@ voxel* blocks_agent::raycast(
|
||||||
glm::vec3& end,
|
glm::vec3& end,
|
||||||
glm::ivec3& norm,
|
glm::ivec3& norm,
|
||||||
glm::ivec3& iend,
|
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
|
// reduce nesting on next modification
|
||||||
|
|
|
||||||
|
|
@ -419,6 +419,7 @@ inline void set_rotation(
|
||||||
/// @param norm [out] surface normal vector
|
/// @param norm [out] surface normal vector
|
||||||
/// @param iend [out] ray end integer position (voxel position + normal)
|
/// @param iend [out] ray end integer position (voxel position + normal)
|
||||||
/// @param filter filtered ids
|
/// @param filter filtered ids
|
||||||
|
/// @param includeNonSelectable will non-selectable blocks be included
|
||||||
/// @return voxel pointer or nullptr
|
/// @return voxel pointer or nullptr
|
||||||
voxel* raycast(
|
voxel* raycast(
|
||||||
const Chunks& chunks,
|
const Chunks& chunks,
|
||||||
|
|
@ -428,7 +429,8 @@ voxel* raycast(
|
||||||
glm::vec3& end,
|
glm::vec3& end,
|
||||||
glm::ivec3& norm,
|
glm::ivec3& norm,
|
||||||
glm::ivec3& iend,
|
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.
|
/// @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 norm [out] surface normal vector
|
||||||
/// @param iend [out] ray end integer position (voxel position + normal)
|
/// @param iend [out] ray end integer position (voxel position + normal)
|
||||||
/// @param filter filtered ids
|
/// @param filter filtered ids
|
||||||
|
/// @param includeNonSelectable will non-selectable blocks be included
|
||||||
/// @return voxel pointer or nullptr
|
/// @return voxel pointer or nullptr
|
||||||
voxel* raycast(
|
voxel* raycast(
|
||||||
const GlobalChunks& chunks,
|
const GlobalChunks& chunks,
|
||||||
|
|
@ -449,7 +452,8 @@ voxel* raycast(
|
||||||
glm::vec3& end,
|
glm::vec3& end,
|
||||||
glm::ivec3& norm,
|
glm::ivec3& norm,
|
||||||
glm::ivec3& iend,
|
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);
|
void get_voxels(const Chunks& chunks, VoxelsVolume* volume, bool backlight=false);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue