add radial triggers
This commit is contained in:
parent
e6c3775286
commit
736e5b95b6
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"hitbox": [0.2, 0.125, 0.2],
|
"hitbox": [0.2, 0.125, 0.2],
|
||||||
"triggers": [
|
"triggers": [
|
||||||
["aabb", -0.2, -0.2, -0.2, 0.2, 0.2, 0.2]
|
["aabb", -0.2, -0.2, -0.2, 0.2, 0.2, 0.2],
|
||||||
|
["radius", 1.6]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,7 @@ local rig = entity.modeltree
|
|||||||
|
|
||||||
inair = true
|
inair = true
|
||||||
ready = false
|
ready = false
|
||||||
|
target = -1
|
||||||
|
|
||||||
local dropitem = ARGS.item
|
local dropitem = ARGS.item
|
||||||
local scale = {1, 1, 1}
|
local scale = {1, 1, 1}
|
||||||
@ -60,11 +61,20 @@ function on_fall()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function on_trigger_enter(index, oid)
|
function on_trigger_enter(index, oid)
|
||||||
if ready and oid == 0 then
|
if ready and oid == 0 and index == 0 then
|
||||||
entity:despawn()
|
entity:despawn()
|
||||||
inventory.add(player.get_inventory(oid), dropitem.id, dropitem.count)
|
inventory.add(player.get_inventory(oid), dropitem.id, dropitem.count)
|
||||||
audio.play_sound_2d("events/pickup", 0.5, 0.8+math.random()*0.4, "regular")
|
audio.play_sound_2d("events/pickup", 0.5, 0.8+math.random()*0.4, "regular")
|
||||||
end
|
end
|
||||||
|
if index == 1 and ready and oid == 0 then
|
||||||
|
target = oid
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function on_trigger_exit(index, oid)
|
||||||
|
if oid == target and index == 1 then
|
||||||
|
target = -1
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function on_update()
|
function on_update()
|
||||||
@ -79,4 +89,10 @@ function on_update()
|
|||||||
mat4.scale(matrix, scale, matrix)
|
mat4.scale(matrix, scale, matrix)
|
||||||
rig:set_matrix(0, matrix)
|
rig:set_matrix(0, matrix)
|
||||||
end
|
end
|
||||||
|
if target ~= -1 then
|
||||||
|
local dir = vec3.sub({player.get_pos(target)}, tsf:get_pos())
|
||||||
|
vec3.normalize(dir, dir)
|
||||||
|
vec3.mul(dir, 10.0, dir)
|
||||||
|
body:set_vel(dir)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -14,7 +14,6 @@ function on_hud_open()
|
|||||||
local pvel = {player.get_vel(pid)}
|
local pvel = {player.get_vel(pid)}
|
||||||
local ppos = vec3.add({player.get_pos(pid)}, {0, 0.7, 0})
|
local ppos = vec3.add({player.get_pos(pid)}, {0, 0.7, 0})
|
||||||
local throw_force = vec3.mul(player.get_dir(pid), DROP_FORCE)
|
local throw_force = vec3.mul(player.get_dir(pid), DROP_FORCE)
|
||||||
|
|
||||||
local drop = entities.spawn("base:drop", ppos, {item={
|
local drop = entities.spawn("base:drop", ppos, {item={
|
||||||
id=itemid,
|
id=itemid,
|
||||||
count=1
|
count=1
|
||||||
|
|||||||
@ -320,10 +320,12 @@ void ContentLoader::loadEntity(EntityDef& def, const std::string& name, const fs
|
|||||||
if (auto triggerarr = triggersarr->list(i)) {
|
if (auto triggerarr = triggersarr->list(i)) {
|
||||||
auto triggerType = triggerarr->str(0);
|
auto triggerType = triggerarr->str(0);
|
||||||
if (triggerType == "aabb") {
|
if (triggerType == "aabb") {
|
||||||
def.boxTriggers.push_back({
|
def.boxTriggers.push_back({i, {
|
||||||
{triggerarr->num(1), triggerarr->num(2), triggerarr->num(3)},
|
{triggerarr->num(1), triggerarr->num(2), triggerarr->num(3)},
|
||||||
{triggerarr->num(4), triggerarr->num(5), triggerarr->num(6)}
|
{triggerarr->num(4), triggerarr->num(5), triggerarr->num(6)}
|
||||||
});
|
}});
|
||||||
|
} else if (triggerType == "radius") {
|
||||||
|
def.radialTriggers.push_back({i, triggerarr->num(1)});
|
||||||
} else {
|
} else {
|
||||||
logger.error() << name << ": trigger #" << i << " - unknown type "
|
logger.error() << name << ": trigger #" << i << " - unknown type "
|
||||||
<< util::quote(triggerType);
|
<< util::quote(triggerType);
|
||||||
|
|||||||
@ -8,7 +8,7 @@ struct AABB {
|
|||||||
glm::vec3 a {0.0f};
|
glm::vec3 a {0.0f};
|
||||||
glm::vec3 b {1.0f, 1.0f, 1.0f};
|
glm::vec3 b {1.0f, 1.0f, 1.0f};
|
||||||
|
|
||||||
AABB() {}
|
AABB() = default;
|
||||||
|
|
||||||
AABB(glm::vec3 size) : a(0.0f), b(size) {
|
AABB(glm::vec3 size) : a(0.0f), b(size) {
|
||||||
}
|
}
|
||||||
|
|||||||
@ -42,6 +42,17 @@ void Entity::setRig(rigging::RigConfig* rigConfig) {
|
|||||||
Entities::Entities(Level* level) : level(level) {
|
Entities::Entities(Level* level) : level(level) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<void(*callback)(const Entity&, size_t, entityid_t)>
|
||||||
|
static triggercallback create_trigger_callback(Entities* entities) {
|
||||||
|
return [=](auto entityid, auto index, auto otherid) {
|
||||||
|
if (auto entity = entities->get(entityid)) {
|
||||||
|
if (entity->isValid()) {
|
||||||
|
callback(*entity, index, otherid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
entityid_t Entities::spawn(
|
entityid_t Entities::spawn(
|
||||||
Assets* assets,
|
Assets* assets,
|
||||||
EntityDef& def,
|
EntityDef& def,
|
||||||
@ -59,28 +70,25 @@ entityid_t Entities::spawn(
|
|||||||
registry.emplace<Transform>(entity, pos, size, glm::mat3(1.0f));
|
registry.emplace<Transform>(entity, pos, size, glm::mat3(1.0f));
|
||||||
auto& body = registry.emplace<Rigidbody>(
|
auto& body = registry.emplace<Rigidbody>(
|
||||||
entity, true, Hitbox {pos, def.hitbox}, std::vector<Trigger>{});
|
entity, true, Hitbox {pos, def.hitbox}, std::vector<Trigger>{});
|
||||||
for (auto& box : def.boxTriggers) {
|
|
||||||
body.triggers.emplace_back(Trigger{
|
body.triggers.resize(def.radialTriggers.size() + def.boxTriggers.size());
|
||||||
true,
|
for (auto& [i, box] : def.boxTriggers) {
|
||||||
id,
|
TriggerParams params {};
|
||||||
box,
|
params.aabb = box;
|
||||||
AABB{},
|
body.triggers[i] = Trigger {
|
||||||
{},
|
true, TriggerType::AABB, i, id, params, params, {}, {},
|
||||||
{},
|
create_trigger_callback<scripting::on_trigger_enter>(this),
|
||||||
[=](auto entityid, auto index, auto otherid) {
|
create_trigger_callback<scripting::on_trigger_exit>(this)
|
||||||
if (auto entity = get(entityid)) {
|
};
|
||||||
if (entity->isValid()) {
|
}
|
||||||
scripting::on_trigger_enter(*entity, index, otherid);
|
for (auto& [i, radius] : def.radialTriggers) {
|
||||||
}
|
TriggerParams params {};
|
||||||
}
|
params.radial = glm::vec4(radius);
|
||||||
},
|
body.triggers[i] = Trigger {
|
||||||
[=](auto entityid, auto index, auto otherid) {
|
true, TriggerType::RADIUS, i, id, params, params, {}, {},
|
||||||
if (auto entity = get(entityid)) {
|
create_trigger_callback<scripting::on_trigger_enter>(this),
|
||||||
if (entity->isValid()) {
|
create_trigger_callback<scripting::on_trigger_exit>(this)
|
||||||
scripting::on_trigger_exit(*entity, index, otherid);
|
};
|
||||||
}
|
|
||||||
}
|
|
||||||
}});
|
|
||||||
}
|
}
|
||||||
auto& scripting = registry.emplace<Scripting>(
|
auto& scripting = registry.emplace<Scripting>(
|
||||||
entity, entity_funcs_set {}, nullptr);
|
entity, entity_funcs_set {}, nullptr);
|
||||||
@ -135,8 +143,21 @@ void Entities::preparePhysics() {
|
|||||||
}
|
}
|
||||||
trigger.prevEntered = trigger.nextEntered;
|
trigger.prevEntered = trigger.nextEntered;
|
||||||
trigger.nextEntered.clear();
|
trigger.nextEntered.clear();
|
||||||
trigger.calculated = trigger.aabb;
|
|
||||||
trigger.calculated.transform(transform.combined);
|
switch (trigger.type) {
|
||||||
|
case TriggerType::AABB:
|
||||||
|
trigger.calculated.aabb = trigger.params.aabb;
|
||||||
|
trigger.calculated.aabb.transform(transform.combined);
|
||||||
|
break;
|
||||||
|
case TriggerType::RADIUS:
|
||||||
|
trigger.calculated.radial = glm::vec4(
|
||||||
|
rigidbody.hitbox.position.x,
|
||||||
|
rigidbody.hitbox.position.y,
|
||||||
|
rigidbody.hitbox.position.z,
|
||||||
|
trigger.params.radial.w*
|
||||||
|
trigger.params.radial.w);
|
||||||
|
break;
|
||||||
|
}
|
||||||
triggers.push_back(&trigger);
|
triggers.push_back(&trigger);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -204,9 +225,11 @@ void Entities::renderDebug(LineBatch& batch, const Frustum& frustum) {
|
|||||||
batch.box(hitbox.position, hitbox.halfsize * 2.0f, glm::vec4(1.0f));
|
batch.box(hitbox.position, hitbox.halfsize * 2.0f, glm::vec4(1.0f));
|
||||||
|
|
||||||
for (auto& trigger : rigidbody.triggers) {
|
for (auto& trigger : rigidbody.triggers) {
|
||||||
|
if (trigger.type != TriggerType::AABB)
|
||||||
|
continue;
|
||||||
batch.box(
|
batch.box(
|
||||||
trigger.calculated.center(),
|
trigger.calculated.aabb.center(),
|
||||||
trigger.calculated.size(),
|
trigger.calculated.aabb.size(),
|
||||||
glm::vec4(1.0f, 1.0f, 0.0f, 1.0f));
|
glm::vec4(1.0f, 1.0f, 0.0f, 1.0f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,7 +18,8 @@ struct EntityDef {
|
|||||||
|
|
||||||
std::string scriptName = name.substr(name.find(':')+1);
|
std::string scriptName = name.substr(name.find(':')+1);
|
||||||
glm::vec3 hitbox {0.5f};
|
glm::vec3 hitbox {0.5f};
|
||||||
std::vector<AABB> boxTriggers {};
|
std::vector<std::pair<size_t, AABB>> boxTriggers {};
|
||||||
|
std::vector<std::pair<size_t, float>> radialTriggers {};
|
||||||
std::string rigName = name.substr(name.find(":")+1);
|
std::string rigName = name.substr(name.find(":")+1);
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
|||||||
@ -8,15 +8,32 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
enum class TriggerType {
|
||||||
|
AABB,
|
||||||
|
RADIUS,
|
||||||
|
};
|
||||||
|
|
||||||
|
union TriggerParams {
|
||||||
|
AABB aabb;
|
||||||
|
glm::vec4 radial; // x,y,z calculated entity coords + w - radius
|
||||||
|
|
||||||
|
constexpr TriggerParams() : aabb() {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
using triggercallback = std::function<void(entityid_t, size_t, entityid_t)>;
|
||||||
|
|
||||||
struct Trigger {
|
struct Trigger {
|
||||||
bool enabled = true;
|
bool enabled = true;
|
||||||
|
TriggerType type;
|
||||||
|
size_t index;
|
||||||
entityid_t entity;
|
entityid_t entity;
|
||||||
AABB aabb;
|
TriggerParams params;
|
||||||
AABB calculated;
|
TriggerParams calculated;
|
||||||
std::set<entityid_t> prevEntered;
|
std::set<entityid_t> prevEntered;
|
||||||
std::set<entityid_t> nextEntered;
|
std::set<entityid_t> nextEntered;
|
||||||
std::function<void(entityid_t, size_t, entityid_t)> enterCallback;
|
triggercallback enterCallback;
|
||||||
std::function<void(entityid_t, size_t, entityid_t)> exitCallback;
|
triggercallback exitCallback;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Hitbox {
|
struct Hitbox {
|
||||||
|
|||||||
@ -7,13 +7,15 @@
|
|||||||
#include "../voxels/voxel.hpp"
|
#include "../voxels/voxel.hpp"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#define GLM_ENABLE_EXPERIMENTAL
|
||||||
|
#include <glm/gtx/norm.hpp>
|
||||||
|
|
||||||
const float E = 0.03f;
|
const float E = 0.03f;
|
||||||
const float MAX_FIX = 0.1f;
|
const float MAX_FIX = 0.1f;
|
||||||
|
|
||||||
PhysicsSolver::PhysicsSolver(glm::vec3 gravity) : gravity(gravity) {
|
PhysicsSolver::PhysicsSolver(glm::vec3 gravity) : gravity(gravity) {
|
||||||
}
|
}
|
||||||
#include "../util/timeutil.hpp"
|
|
||||||
void PhysicsSolver::step(
|
void PhysicsSolver::step(
|
||||||
Chunks* chunks,
|
Chunks* chunks,
|
||||||
Hitbox* hitbox,
|
Hitbox* hitbox,
|
||||||
@ -85,15 +87,27 @@ void PhysicsSolver::step(
|
|||||||
aabb.a = hitbox->position - hitbox->halfsize;
|
aabb.a = hitbox->position - hitbox->halfsize;
|
||||||
aabb.b = hitbox->position + hitbox->halfsize;
|
aabb.b = hitbox->position + hitbox->halfsize;
|
||||||
for (size_t i = 0; i < triggers.size(); i++) {
|
for (size_t i = 0; i < triggers.size(); i++) {
|
||||||
auto& trigger = triggers[i];
|
auto& trigger = *triggers[i];
|
||||||
if (trigger->entity == entity) {
|
if (trigger.entity == entity) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (aabb.intersect(trigger->calculated)) {
|
|
||||||
if (trigger->prevEntered.find(entity) == trigger->prevEntered.end()) {
|
bool triggered = false;
|
||||||
trigger->enterCallback(trigger->entity, i, entity);
|
switch (trigger.type) {
|
||||||
|
case TriggerType::AABB:
|
||||||
|
triggered = aabb.intersect(trigger.calculated.aabb);
|
||||||
|
break;
|
||||||
|
case TriggerType::RADIUS:
|
||||||
|
triggered = glm::distance2(
|
||||||
|
hitbox->position, glm::vec3(trigger.calculated.radial))
|
||||||
|
< trigger.calculated.radial.w;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (triggered) {
|
||||||
|
if (trigger.prevEntered.find(entity) == trigger.prevEntered.end()) {
|
||||||
|
trigger.enterCallback(trigger.entity, trigger.index, entity);
|
||||||
}
|
}
|
||||||
trigger->nextEntered.insert(entity);
|
trigger.nextEntered.insert(entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user