trigger system
This commit is contained in:
@@ -10,6 +10,7 @@ pub mod noclip;
|
|||||||
pub mod physics;
|
pub mod physics;
|
||||||
pub mod rotate;
|
pub mod rotate;
|
||||||
pub mod tree_instances;
|
pub mod tree_instances;
|
||||||
|
pub mod trigger;
|
||||||
|
|
||||||
pub use camera::CameraComponent;
|
pub use camera::CameraComponent;
|
||||||
pub use dissolve::DissolveComponent;
|
pub use dissolve::DissolveComponent;
|
||||||
@@ -21,3 +22,4 @@ pub use movement::MovementComponent;
|
|||||||
pub use physics::PhysicsComponent;
|
pub use physics::PhysicsComponent;
|
||||||
pub use rotate::RotateComponent;
|
pub use rotate::RotateComponent;
|
||||||
pub use tree_instances::TreeInstancesComponent;
|
pub use tree_instances::TreeInstancesComponent;
|
||||||
|
pub use trigger::{TriggerComponent, TriggerEvent, TriggerEventKind, TriggerFilter, TriggerShape, TriggerState};
|
||||||
|
|||||||
37
src/components/trigger.rs
Normal file
37
src/components/trigger.rs
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
use crate::entity::EntityHandle;
|
||||||
|
|
||||||
|
pub enum TriggerShape
|
||||||
|
{
|
||||||
|
Sphere { radius: f32 },
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum TriggerFilter
|
||||||
|
{
|
||||||
|
Player,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum TriggerState
|
||||||
|
{
|
||||||
|
Idle,
|
||||||
|
Inside,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct TriggerComponent
|
||||||
|
{
|
||||||
|
pub shape: TriggerShape,
|
||||||
|
pub filter: TriggerFilter,
|
||||||
|
pub state: TriggerState,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum TriggerEventKind
|
||||||
|
{
|
||||||
|
Entered,
|
||||||
|
Exited,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct TriggerEvent
|
||||||
|
{
|
||||||
|
pub trigger_entity: EntityHandle,
|
||||||
|
pub activator_entity: EntityHandle,
|
||||||
|
pub kind: TriggerEventKind,
|
||||||
|
}
|
||||||
@@ -41,6 +41,7 @@ use crate::systems::{
|
|||||||
camera_follow_system, camera_input_system, camera_view_matrix, physics_sync_system,
|
camera_follow_system, camera_input_system, camera_view_matrix, physics_sync_system,
|
||||||
player_input_system, render_system, rotate_system, snow_system, spotlight_sync_system,
|
player_input_system, render_system, rotate_system, snow_system, spotlight_sync_system,
|
||||||
start_camera_following, state_machine_physics_system, state_machine_system,
|
start_camera_following, state_machine_physics_system, state_machine_system,
|
||||||
|
trigger_system,
|
||||||
};
|
};
|
||||||
use crate::systems::camera::stop_camera_following;
|
use crate::systems::camera::stop_camera_following;
|
||||||
use crate::utility::time::Time;
|
use crate::utility::time::Time;
|
||||||
@@ -283,6 +284,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>>
|
|||||||
PhysicsManager::physics_step();
|
PhysicsManager::physics_step();
|
||||||
|
|
||||||
physics_sync_system(&mut world);
|
physics_sync_system(&mut world);
|
||||||
|
trigger_system(&mut world);
|
||||||
|
|
||||||
physics_accumulator -= FIXED_TIMESTEP;
|
physics_accumulator -= FIXED_TIMESTEP;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ pub mod snow;
|
|||||||
pub mod spotlight_sync;
|
pub mod spotlight_sync;
|
||||||
pub mod state_machine;
|
pub mod state_machine;
|
||||||
pub mod tree_dissolve;
|
pub mod tree_dissolve;
|
||||||
|
pub mod trigger;
|
||||||
|
|
||||||
pub use camera::{
|
pub use camera::{
|
||||||
camera_follow_system, camera_input_system, camera_noclip_system, camera_view_matrix,
|
camera_follow_system, camera_input_system, camera_noclip_system, camera_view_matrix,
|
||||||
@@ -21,3 +22,7 @@ pub use rotate::rotate_system;
|
|||||||
pub use snow::snow_system;
|
pub use snow::snow_system;
|
||||||
pub use spotlight_sync::spotlight_sync_system;
|
pub use spotlight_sync::spotlight_sync_system;
|
||||||
pub use state_machine::{state_machine_physics_system, state_machine_system};
|
pub use state_machine::{state_machine_physics_system, state_machine_system};
|
||||||
|
pub use tree_dissolve::{
|
||||||
|
tree_dissolve_update_system, tree_instance_buffer_update_system, tree_occlusion_system,
|
||||||
|
};
|
||||||
|
pub use trigger::trigger_system;
|
||||||
|
|||||||
82
src/systems/trigger.rs
Normal file
82
src/systems/trigger.rs
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
use glam::Vec3;
|
||||||
|
|
||||||
|
use crate::components::trigger::{TriggerEvent, TriggerEventKind, TriggerFilter, TriggerShape, TriggerState};
|
||||||
|
use crate::entity::EntityHandle;
|
||||||
|
use crate::world::World;
|
||||||
|
|
||||||
|
pub fn trigger_system(world: &mut World)
|
||||||
|
{
|
||||||
|
world.trigger_events.clear();
|
||||||
|
|
||||||
|
let trigger_entities: Vec<EntityHandle> = world.triggers.all();
|
||||||
|
let mut pending_events: Vec<TriggerEvent> = Vec::new();
|
||||||
|
|
||||||
|
for trigger_entity in trigger_entities
|
||||||
|
{
|
||||||
|
let trigger_pos = match world.transforms.get(trigger_entity)
|
||||||
|
{
|
||||||
|
Some(t) => t.position,
|
||||||
|
None => continue,
|
||||||
|
};
|
||||||
|
|
||||||
|
let candidate_entities: Vec<EntityHandle> = match world.triggers.get(trigger_entity)
|
||||||
|
{
|
||||||
|
Some(trigger) => match &trigger.filter
|
||||||
|
{
|
||||||
|
TriggerFilter::Player => world.player_tags.all(),
|
||||||
|
},
|
||||||
|
None => continue,
|
||||||
|
};
|
||||||
|
|
||||||
|
let activator_positions: Vec<(EntityHandle, Vec3)> = candidate_entities
|
||||||
|
.into_iter()
|
||||||
|
.filter_map(|e| world.transforms.get(e).map(|t| (e, t.position)))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let overlapping = match world.triggers.get(trigger_entity)
|
||||||
|
{
|
||||||
|
Some(trigger) => activator_positions.iter().any(|(_, pos)| match &trigger.shape
|
||||||
|
{
|
||||||
|
TriggerShape::Sphere { radius } => (trigger_pos - *pos).length() < *radius,
|
||||||
|
}),
|
||||||
|
None => continue,
|
||||||
|
};
|
||||||
|
|
||||||
|
let first_activator = activator_positions.first().map(|(e, _)| *e);
|
||||||
|
|
||||||
|
if let Some(trigger) = world.triggers.get_mut(trigger_entity)
|
||||||
|
{
|
||||||
|
match (&trigger.state, overlapping)
|
||||||
|
{
|
||||||
|
(TriggerState::Idle, true) =>
|
||||||
|
{
|
||||||
|
trigger.state = TriggerState::Inside;
|
||||||
|
if let Some(activator_entity) = first_activator
|
||||||
|
{
|
||||||
|
pending_events.push(TriggerEvent {
|
||||||
|
trigger_entity,
|
||||||
|
activator_entity,
|
||||||
|
kind: TriggerEventKind::Entered,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(TriggerState::Inside, false) =>
|
||||||
|
{
|
||||||
|
trigger.state = TriggerState::Idle;
|
||||||
|
if let Some(activator_entity) = first_activator
|
||||||
|
{
|
||||||
|
pending_events.push(TriggerEvent {
|
||||||
|
trigger_entity,
|
||||||
|
activator_entity,
|
||||||
|
kind: TriggerEventKind::Exited,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ =>
|
||||||
|
{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
world.trigger_events.extend(pending_events);
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ use crate::components::dissolve::DissolveComponent;
|
|||||||
use crate::components::follow::FollowComponent;
|
use crate::components::follow::FollowComponent;
|
||||||
use crate::components::lights::spot::SpotlightComponent;
|
use crate::components::lights::spot::SpotlightComponent;
|
||||||
use crate::components::tree_instances::TreeInstancesComponent;
|
use crate::components::tree_instances::TreeInstancesComponent;
|
||||||
|
use crate::components::trigger::{TriggerComponent, TriggerEvent};
|
||||||
use crate::components::{
|
use crate::components::{
|
||||||
CameraComponent, InputComponent, JumpComponent, MeshComponent, MovementComponent,
|
CameraComponent, InputComponent, JumpComponent, MeshComponent, MovementComponent,
|
||||||
PhysicsComponent, RotateComponent,
|
PhysicsComponent, RotateComponent,
|
||||||
@@ -86,6 +87,8 @@ pub struct World
|
|||||||
pub rotates: Storage<RotateComponent>,
|
pub rotates: Storage<RotateComponent>,
|
||||||
pub tree_instances: Storage<TreeInstancesComponent>,
|
pub tree_instances: Storage<TreeInstancesComponent>,
|
||||||
pub names: Storage<String>,
|
pub names: Storage<String>,
|
||||||
|
pub triggers: Storage<TriggerComponent>,
|
||||||
|
pub trigger_events: Vec<TriggerEvent>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl World
|
impl World
|
||||||
@@ -110,6 +113,8 @@ impl World
|
|||||||
rotates: Storage::new(),
|
rotates: Storage::new(),
|
||||||
tree_instances: Storage::new(),
|
tree_instances: Storage::new(),
|
||||||
names: Storage::new(),
|
names: Storage::new(),
|
||||||
|
triggers: Storage::new(),
|
||||||
|
trigger_events: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,6 +141,7 @@ impl World
|
|||||||
self.rotates.remove(entity);
|
self.rotates.remove(entity);
|
||||||
self.tree_instances.remove(entity);
|
self.tree_instances.remove(entity);
|
||||||
self.names.remove(entity);
|
self.names.remove(entity);
|
||||||
|
self.triggers.remove(entity);
|
||||||
self.entities.despawn(entity);
|
self.entities.despawn(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user