libblock.raycast: Add argument to specify blocks to ignore during ray casting
libentity.raycast: Add argument to specify blocks to ignore during ray casting Chunk::rayCast: Add argument to specify blocks to ignore during ray casting. On lua side filter blocks are passed as list of strings in form of "MOD:BLOCK_NAME" On C++ size filter blocks are std::set of blockid_t
This commit is contained in:
parent
8ef288c189
commit
1be50c2e06
@ -353,13 +353,30 @@ 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);
|
||||||
|
std::set<blockid_t> filteredBlocks {};
|
||||||
|
if (lua::gettop(L) >= 5) {
|
||||||
|
if (lua::istable(L, 5)) {
|
||||||
|
int addLen = lua::objlen(L, 5);
|
||||||
|
for (int i = 0; i < addLen; i++) {
|
||||||
|
lua::rawgeti(L, i + 1, 5);
|
||||||
|
auto blockName = std::string(lua::tostring(L, -1));
|
||||||
|
Block* block = content->blocks.find(blockName);
|
||||||
|
if (block != nullptr) {
|
||||||
|
filteredBlocks.insert(block->rt.id);
|
||||||
|
}
|
||||||
|
lua::pop(L);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw std::runtime_error("table expected for filter");
|
||||||
|
}
|
||||||
|
}
|
||||||
glm::vec3 end;
|
glm::vec3 end;
|
||||||
glm::ivec3 normal;
|
glm::ivec3 normal;
|
||||||
glm::ivec3 iend;
|
glm::ivec3 iend;
|
||||||
if (auto voxel = level->chunks->rayCast(
|
if (auto voxel = level->chunks->rayCast(
|
||||||
start, dir, maxDistance, end, normal, iend
|
start, dir, maxDistance, end, normal, iend, filteredBlocks
|
||||||
)) {
|
)) {
|
||||||
if (lua::gettop(L) >= 4) {
|
if (lua::gettop(L) >= 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);
|
||||||
@ -452,4 +469,5 @@ const luaL_Reg blocklib[] = {
|
|||||||
{"raycast", lua::wrap<l_raycast>},
|
{"raycast", lua::wrap<l_raycast>},
|
||||||
{"compose_state", lua::wrap<l_compose_state>},
|
{"compose_state", lua::wrap<l_compose_state>},
|
||||||
{"decompose_state", lua::wrap<l_decompose_state>},
|
{"decompose_state", lua::wrap<l_decompose_state>},
|
||||||
{NULL, NULL}};
|
{NULL, NULL}
|
||||||
|
};
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
#include "objects/rigging.hpp"
|
#include "objects/rigging.hpp"
|
||||||
#include "physics/Hitbox.hpp"
|
#include "physics/Hitbox.hpp"
|
||||||
#include "voxels/Chunks.hpp"
|
#include "voxels/Chunks.hpp"
|
||||||
|
#include "voxels/Block.hpp"
|
||||||
#include "window/Camera.hpp"
|
#include "window/Camera.hpp"
|
||||||
|
|
||||||
using namespace scripting;
|
using namespace scripting;
|
||||||
@ -118,7 +119,25 @@ 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);
|
||||||
auto ignore = lua::tointeger(L, 4);
|
auto ignoreEntityId = lua::tointeger(L, 4);
|
||||||
|
std::set<blockid_t> filteredBlocks {};
|
||||||
|
if (lua::gettop(L) >= 6) {
|
||||||
|
if (lua::istable(L, 6)) {
|
||||||
|
int addLen = lua::objlen(L, 6);
|
||||||
|
for (int i = 0; i < addLen; i++) {
|
||||||
|
lua::rawgeti(L, i + 1, 6);
|
||||||
|
auto blockName = std::string(lua::tostring(L, -1));
|
||||||
|
Block* block = content->blocks.find(blockName);
|
||||||
|
if (block != nullptr) {
|
||||||
|
filteredBlocks.insert(block->rt.id);
|
||||||
|
}
|
||||||
|
lua::pop(L);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw std::runtime_error("table expected for filter");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
glm::vec3 end;
|
glm::vec3 end;
|
||||||
glm::ivec3 normal;
|
glm::ivec3 normal;
|
||||||
glm::ivec3 iend;
|
glm::ivec3 iend;
|
||||||
@ -126,13 +145,14 @@ static int l_raycast(lua::State* L) {
|
|||||||
blockid_t block = BLOCK_VOID;
|
blockid_t block = BLOCK_VOID;
|
||||||
|
|
||||||
if (auto voxel = level->chunks->rayCast(
|
if (auto voxel = level->chunks->rayCast(
|
||||||
start, dir, maxDistance, end, normal, iend
|
start, dir, maxDistance, end, normal, iend, filteredBlocks
|
||||||
)) {
|
)) {
|
||||||
maxDistance = glm::distance(start, end);
|
maxDistance = glm::distance(start, end);
|
||||||
block = voxel->id;
|
block = voxel->id;
|
||||||
}
|
}
|
||||||
if (auto ray = level->entities->rayCast(start, dir, maxDistance, ignore)) {
|
if (auto ray =
|
||||||
if (lua::gettop(L) >= 5) {
|
level->entities->rayCast(start, dir, maxDistance, ignoreEntityId)) {
|
||||||
|
if (lua::gettop(L) >= 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);
|
||||||
@ -157,7 +177,7 @@ static int l_raycast(lua::State* L) {
|
|||||||
lua::setfield(L, "entity");
|
lua::setfield(L, "entity");
|
||||||
return 1;
|
return 1;
|
||||||
} else if (block != BLOCK_VOID) {
|
} else if (block != BLOCK_VOID) {
|
||||||
if (lua::gettop(L) >= 5) {
|
if (lua::gettop(L) >= 5 && !lua::isnil(L, 5)) {
|
||||||
lua::pushvalue(L, 5);
|
lua::pushvalue(L, 5);
|
||||||
} else {
|
} else {
|
||||||
lua::createtable(L, 0, 5);
|
lua::createtable(L, 0, 5);
|
||||||
@ -194,4 +214,5 @@ 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>},
|
||||||
{NULL, NULL}};
|
{NULL, NULL}
|
||||||
|
};
|
||||||
|
|||||||
@ -414,7 +414,8 @@ voxel* Chunks::rayCast(
|
|||||||
float maxDist,
|
float maxDist,
|
||||||
glm::vec3& end,
|
glm::vec3& end,
|
||||||
glm::ivec3& norm,
|
glm::ivec3& norm,
|
||||||
glm::ivec3& iend
|
glm::ivec3& iend,
|
||||||
|
std::set<blockid_t> filter
|
||||||
) {
|
) {
|
||||||
float px = start.x;
|
float px = start.x;
|
||||||
float py = start.y;
|
float py = start.y;
|
||||||
@ -454,8 +455,10 @@ voxel* Chunks::rayCast(
|
|||||||
if (voxel == nullptr) {
|
if (voxel == nullptr) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& def = indices->blocks.require(voxel->id);
|
const auto& def = indices->blocks.require(voxel->id);
|
||||||
if (def.selectable) {
|
if ((filter.empty() && def.selectable) ||
|
||||||
|
(!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;
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "typedefs.hpp"
|
#include "typedefs.hpp"
|
||||||
@ -93,7 +94,8 @@ public:
|
|||||||
float maxLength,
|
float maxLength,
|
||||||
glm::vec3& end,
|
glm::vec3& end,
|
||||||
glm::ivec3& norm,
|
glm::ivec3& norm,
|
||||||
glm::ivec3& iend
|
glm::ivec3& iend,
|
||||||
|
std::set<blockid_t> filter = {}
|
||||||
);
|
);
|
||||||
|
|
||||||
glm::vec3 rayCastToObstacle(glm::vec3 start, glm::vec3 dir, float maxDist);
|
glm::vec3 rayCastToObstacle(glm::vec3 start, glm::vec3 dir, float maxDist);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user