Merge pull request #945 from MihailRis/get-set-raycast-opacity

add rigidbody:is_selectable, :set_selectable
This commit is contained in:
MihailRis 2026-08-23 12:39:00 +03:00 • committed by GitHub
commit 136cf48605
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 40 additions and 4 deletions

View file

@ -67,9 +67,10 @@ If true - the entity blocks the placement of a block that intersects with the en
Default value: *true*.
### *selectable*
### *selectable* (raycast opacity)
If set to `false` the cursor will ignore the entity, passing the ray.
Applies to all uses of raycast without the include_non_selectable flag.
### *sensors*

View file

@ -36,6 +36,11 @@ entity:set_enabled(name: str, enable: bool)
-- At components initialization -1 is also returned,
-- since the binding occurs after initialization.
entity:get_player() -> int or nil
-- Checks the 'selectable' property of an entity (raycast opacity)
body:is_selectable() -> bool
-- Sets the value of the 'selectable' property of an entity
body:set_selectable(flag: bool)
```
## Custom Components

View file

@ -67,9 +67,10 @@
Значение по-умолчанию: *true*.
### Выделяемость - *selectable*
### Непрозрачность для лучей - *selectable*
При значении в `false` курсор будет игнорировать cущность, пропуская луч далее.
Распространяется на все использования raycast без флага include_non_selectable.
### Список сенсоров - *sensors*

View file

@ -134,6 +134,11 @@ body:set_elasticity(elasticity: number)
-- Возвращает скорость поверхности, на которой находится тело, либо {0,0,0}
body:get_ground_vel() -> vec3
-- Проверяет свойство 'selectable' у сущности (непрозрачность для лучей)
body:is_selectable() -> bool
-- Устанавливает значение свойство 'selectable' у сущности
body:set_selectable(flag: bool)
```
### Skeleton

View file

@ -39,6 +39,8 @@ local Rigidbody = {__index={
set_mass=function(self, v) return __rigidbody.set_mass(self.eid, v) end,
set_elasticity=function(self, v) return __rigidbody.set_elasticity(self.eid, v) end,
get_ground_vel=function(self) return __rigidbody.get_ground_vel(self.eid) end,
is_selectable=function (self) return __rigidbody.is_selectable(self.eid) end,
set_selectable=function (self, b) return __rigidbody.set_selectable(self.eid, b) end,
}}
local function new_Rigidbody(eid)

View file

@ -199,6 +199,20 @@ static int l_get_ground_vel(lua::State* L) {
return 0;
}
static int l_is_selectable(lua::State* L) {
if (auto entity = get_entity(L, 1)) {
return lua::pushboolean(L, entity->getRigidbody().hitbox.selectable);
}
return 0;
}
static int l_set_selectable(lua::State* L) {
if (auto entity = get_entity(L, 1)) {
entity->getRigidbody().selectable = lua::toboolean(L, 2);
}
return 0;
}
const luaL_Reg rigidbodylib[] = {
{"is_enabled", lua::wrap<l_is_enabled>},
@ -226,5 +240,7 @@ const luaL_Reg rigidbodylib[] = {
{"get_elasticity", lua::wrap<l_get_elasticity>},
{"set_elasticity", lua::wrap<l_set_elasticity>},
{"get_ground_vel", lua::wrap<l_get_ground_vel>},
{"is_selectable", lua::wrap<l_is_selectable>},
{"set_selectable", lua::wrap<l_set_selectable>},
{nullptr, nullptr}
};

View file

@ -175,9 +175,10 @@ std::optional<Entities::RaycastResult> Entities::rayCast(
glm::ivec3 foundNormal;
for (auto [entity, eid, transform, body] : view.each()) {
const auto& hitbox = body.hitbox;
if (eid.uid == settings.ignoredUid || !body.enabled ||
(settings.solidEntitiesOnly && !eid.def.solid) ||
(!eid.def.selectable && !settings.includeNonSelectable)) {
(!hitbox.selectable && !settings.includeNonSelectable)) {
continue;
}
if (settings.entitiesFilter) {
@ -187,7 +188,6 @@ std::optional<Entities::RaycastResult> Entities::rayCast(
continue;
}
}
const auto& hitbox = body.hitbox;
glm::ivec3 normal;
double distance;
if (ray.intersectAABB(
@ -330,6 +330,7 @@ void Entities::preparePhysics(float delta) {
? rigidbody.mass
: std::numeric_limits<float>::infinity();
rigidbody.hitbox.elasticity = rigidbody.elasticity;
rigidbody.hitbox.selectable = rigidbody.selectable;
hitboxes.emplace_back(&rigidbody.hitbox);
if (!eid.def.solid) {
continue;

View file

@ -24,6 +24,7 @@ dv::value Rigidbody::serialize(bool saveVelocity, bool saveBodySettings) const {
}
bodymap["mass"] = mass;
bodymap["elasticity"] = elasticity;
bodymap["selectable"] = selectable;
}
return bodymap;
}
@ -37,6 +38,7 @@ void Rigidbody::deserialize(const dv::value& root) {
root["damping"].asNumber(hitbox.linearDamping);
root["mass"].asNumber(mass);
root["elasticity"].asNumber(elasticity);
root["selectable"].asBoolean(selectable);
}
template <void (*callback)(const Entity&, size_t, entityid_t)>
@ -55,6 +57,7 @@ void Rigidbody::initialize(
) {
mass = def.mass;
elasticity = def.elasticity;
selectable = def.selectable;
sensors.resize(def.radialSensors.size() + def.boxSensors.size());
for (auto& [i, box] : def.boxSensors) {
SensorParams params {};

View file

@ -15,6 +15,7 @@ struct Rigidbody {
std::vector<Sensor> sensors;
float mass;
float elasticity;
bool selectable;
dv::value serialize(bool saveVelocity, bool saveBodySettings) const;
void deserialize(const dv::value& root);

View file

@ -65,6 +65,7 @@ struct Hitbox {
float stepHeight = 0.5f;
float mass = 1.0f;
float elasticity = 0.0f;
bool selectable = true;
std::string material;
std::string groundMaterial;
glm::vec3 groundVelocity {};