Skip to content

Commit

Permalink
Merge pull request #13 from Froggy618157725/beacon
Browse files Browse the repository at this point in the history
Add Beacon to Utilities
  • Loading branch information
cohaereo authored Jan 14, 2024
2 parents 3a06df4 + 850043f commit 15a8227
Show file tree
Hide file tree
Showing 8 changed files with 251 additions and 26 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)
- Add Global Utility Objects by @Froggy618167725 in [#12](https://github.com/cohaereo/alkahest/pull/12)
- Lazy entity updating by @cohaereo
- Global entity tag by @cohaereo
- Add Beacon Utility tool by @Froggy618157725 in [#13](https://github.com/cohaereo/alkahest/pull/13)

### Changed

Expand Down
37 changes: 33 additions & 4 deletions src/camera.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::{

#[derive(Clone)]
pub struct FpsCamera {
orientation: Vec2,
pub orientation: Vec2,
pub rotation: Quat,

pub front: Vec3,
Expand Down Expand Up @@ -70,6 +70,14 @@ impl FpsCamera {

pub fn update_mouse(&mut self, mouse_delta: Vec2) {
self.orientation += Vec2::new(mouse_delta.y * 0.8, mouse_delta.x) * 0.15;
// Cancel angle tween if the user rotates the camera
if self
.tween
.as_ref()
.map_or(false, |t| t.angle_movement.is_some())
{
self.tween = None;
}
self.update_vectors();
}

Expand Down Expand Up @@ -145,7 +153,8 @@ impl FpsCamera {
}

if let Some(tween) = &mut self.tween {
self.position = tween.update();
self.position = tween.update_pos().unwrap_or(self.position);
self.orientation = tween.update_angle().unwrap_or(self.orientation);
} else {
self.position += direction * speed;
}
Expand Down Expand Up @@ -297,8 +306,8 @@ impl FpsCamera {
pub fn focus(&mut self, pos: Vec3, distance: f32) {
self.tween = Some(Tween::new(
tween::ease_out_exponential,
self.position,
pos - self.front * distance,
Some((self.position, pos - self.front * distance)),
None,
0.70,
));
}
Expand All @@ -309,4 +318,24 @@ impl FpsCamera {

self.focus(center, radius);
}

// Calculate angle to point camera at pos.
// The angle has a minimal diff to current camera angle.
pub fn get_look_angle(&self, pos: Vec3) -> Vec2 {
let dir = pos - self.position;
let inv_r = dir.length_recip();
if inv_r.is_infinite() {
self.orientation
} else {
let theta = dir.x.atan2(dir.y).to_degrees();
let mut diff = (theta - self.orientation.y).rem_euclid(360.0);
if diff > 180.0 {
diff -= 360.0;
}
Vec2::new(
(dir.z * inv_r).acos().to_degrees() - 90.0,
self.orientation.y + diff,
)
}
}
}
115 changes: 109 additions & 6 deletions src/ecs/component_panels.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ use crate::{
ecs::transform::TransformFlags,
hotkeys::{SHORTCUT_DELETE, SHORTCUT_HIDE},
icons::{
ICON_ALERT, ICON_ALPHA_A_BOX, ICON_ALPHA_B_BOX, ICON_AXIS_ARROW, ICON_CAMERA_CONTROL,
ICON_CUBE_OUTLINE, ICON_DELETE, ICON_EYE, ICON_EYE_OFF, ICON_HELP, ICON_IDENTIFIER,
ICON_MAP_MARKER, ICON_RADIUS_OUTLINE, ICON_RESIZE, ICON_ROTATE_ORBIT, ICON_RULER_SQUARE,
ICON_SPHERE, ICON_TAG,
ICON_ALERT, ICON_ALPHA_A_BOX, ICON_ALPHA_B_BOX, ICON_AXIS_ARROW, ICON_CAMERA,
ICON_CAMERA_CONTROL, ICON_CUBE_OUTLINE, ICON_DELETE, ICON_EYE, ICON_EYE_OFF, ICON_HELP,
ICON_IDENTIFIER, ICON_MAP_MARKER, ICON_RADIUS_OUTLINE, ICON_RESIZE, ICON_ROTATE_ORBIT,
ICON_RULER_SQUARE, ICON_SIGN_POLE, ICON_SPHERE, ICON_TAG,
},
render::tween::Tween,
resources::Resources,
util::{
text::{prettify_distance, split_pascal_case},
Expand All @@ -21,7 +22,7 @@ use crate::{

use super::{
components::{
EntityModel, EntityWorldId, Global, Label, Mutable, ResourcePoint, Ruler, Sphere,
Beacon, EntityModel, EntityWorldId, Global, Label, Mutable, ResourcePoint, Ruler, Sphere,
StaticInstances, Visible,
},
resolve_entity_icon, resolve_entity_name,
Expand Down Expand Up @@ -170,7 +171,8 @@ fn show_inspector_components(ui: &mut egui::Ui, e: EntityRef<'_>, resources: &Re
// HavokShape,
EntityWorldId,
Ruler,
Sphere
Sphere,
Beacon
);
}

Expand Down Expand Up @@ -589,3 +591,104 @@ impl ComponentPanel for Sphere {
});
}
}

impl ComponentPanel for Beacon {
fn inspector_name() -> &'static str {
"Beacon"
}

fn inspector_icon() -> char {
ICON_SIGN_POLE
}

fn has_inspector_ui() -> bool {
true
}

fn show_inspector_ui(&mut self, e: EntityRef<'_>, ui: &mut egui::Ui, resources: &Resources) {
if !e.has::<Transform>() {
ui.label(format!(
"{} This entity has no transform component",
ICON_ALERT
));
}

ui.horizontal(|ui| {
ui.strong("Distance after travel: ");
ui.add(
egui::DragValue::new(&mut self.distance)
.speed(0.1)
.clamp_range(0f32..=f32::INFINITY)
.min_decimals(2)
.max_decimals(2)
.suffix(" m"),
)
});

ui.horizontal(|ui| {
ui.strong("Duration of travel: ");
ui.add(
egui::DragValue::new(&mut self.travel_time)
.speed(0.1)
.clamp_range(0f32..=60.0)
.min_decimals(2)
.max_decimals(2)
.suffix(" s"),
)
});

ui.horizontal(|ui| {
ui.strong("Blink Frequency");
ui.add(
egui::DragValue::new(&mut self.freq)
.speed(0.1)
.clamp_range(0.0..=20.0),
)
});

ui.horizontal(|ui| {
ui.color_edit_button_srgb(&mut self.color);

ui.label("Color");
});

ui.separator();

let mut camera = resources.get_mut::<FpsCamera>().unwrap();
if let Some(transform) = e.get::<&Transform>() {
ui.label(format!(
"Distance to Beacon: {:.2} m",
(transform.translation - camera.position).length()
));

ui.horizontal(|ui| {
if ui.button(ICON_MAP_MARKER.to_string()).clicked() {
camera.tween = Some(Tween::new(
|x| x,
Some((
camera.position,
transform.translation - camera.front * self.distance,
)),
None,
self.travel_time,
));
}
ui.label("Go to Beacon Location");
});
ui.horizontal(|ui| {
if ui.button(ICON_CAMERA.to_string()).clicked() {
camera.tween = Some(Tween::new(
|x| x,
None,
Some((
camera.orientation,
camera.get_look_angle(transform.translation),
)),
self.travel_time,
));
}
ui.label("Look at Beacon Location");
});
}
}
}
18 changes: 18 additions & 0 deletions src/ecs/components.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,24 @@ impl Default for Sphere {
}
}
}

pub struct Beacon {
pub color: [u8; 3],
pub freq: f32,
pub distance: f32,
pub travel_time: f32,
}

impl Default for Beacon {
fn default() -> Self {
Self {
color: [255, 255, 255],
freq: 1.0,
distance: 0.5,
travel_time: 0.7,
}
}
}
/// Marker component to indicate that the entity is allowed to be modified in potentially destructive ways
/// (e.g. deleting it, changing it's name, etc.)
pub struct Mutable;
3 changes: 2 additions & 1 deletion src/ecs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ pub fn resolve_entity_icon(e: EntityRef<'_>) -> Option<char> {
icon_from_component_panels!(
// TODO(cohae): Custom havok icon
// HavokShape,
Beacon,
Ruler,
Sphere,
EntityModel,
Expand Down Expand Up @@ -66,7 +67,7 @@ pub fn resolve_entity_name(e: EntityRef<'_>, append_ent: bool) -> String {
};
}

name_from_component_panels!(Ruler, Sphere, EntityModel, StaticInstances);
name_from_component_panels!(Beacon, Ruler, Sphere, EntityModel, StaticInstances);

format!("ent {}", e.entity().id())
}
Expand Down
34 changes: 32 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ use std::time::{Duration, Instant};

use crate::activity::SActivity;
use crate::ecs::components::{
ActivityGroup, EntityModel, ResourcePoint, Ruler, Sphere, StaticInstances, Terrain, Visible,
Water,
ActivityGroup, Beacon, EntityModel, ResourcePoint, Ruler, Sphere, StaticInstances, Terrain,
Visible, Water,
};
use crate::ecs::resolve_aabb;
use crate::ecs::resources::SelectedEntity;
Expand Down Expand Up @@ -853,6 +853,16 @@ pub async fn main() -> anyhow::Result<()> {
}
draw_sphere(&mut debugshapes, transform, sphere, start_time);
}
for (_, (transform, beacon, visible)) in map
.scene
.query::<(&Transform, &Beacon, Option<&Visible>)>()
.iter()
{
if !visible.map_or(true, |v| v.0) {
continue;
}
draw_beacon(&mut debugshapes, transform, beacon, start_time);
}
}

if let Some(map) = maps.current_map_mut() {
Expand Down Expand Up @@ -1106,6 +1116,26 @@ fn draw_sphere(
debugshapes.sphere(transform.translation, transform.radius(), color);
}

fn draw_beacon(
debugshapes: &mut DebugShapes,
transform: &Transform,
beacon: &Beacon,
start_time: Instant,
) {
let color = [
beacon.color[0],
beacon.color[1],
beacon.color[2],
(150.0 + (start_time.elapsed().as_secs_f32() * 2.0 * PI * beacon.freq).sin() * 50.0) as u8,
];
debugshapes.sphere(transform.translation, 0.1, color);
debugshapes.line(
transform.translation + Vec3::Z * 0.1,
transform.translation + Vec3::Z * 5000.0,
color,
);
}

fn load_render_globals(renderer: &Renderer) {
let tag =
get_named_tag::<0x8080978C>("render_globals").expect("Could not find render globals!");
Expand Down
32 changes: 29 additions & 3 deletions src/overlays/menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@ use glam::Vec3;
use crate::{
camera::FpsCamera,
ecs::{
components::{Mutable, Ruler, Sphere},
components::{Beacon, Mutable, Ruler, Sphere},
resources::SelectedEntity,
tags::{EntityTag, Tags},
transform::{Transform, TransformFlags},
},
icons::ICON_RULER_SQUARE,
icons::ICON_SPHERE,
icons::{ICON_RULER_SQUARE, ICON_SIGN_POLE, ICON_SPHERE},
map::MapDataList,
};

Expand Down Expand Up @@ -74,6 +73,33 @@ impl Overlay for MenuBar {
se.0 = Some(e);
}

ui.close_menu();
}
}
if ui.button(format!("{} Beacon", ICON_SIGN_POLE)).clicked() {
let mut maps: std::cell::RefMut<'_, MapDataList> =
resources.get_mut::<MapDataList>().unwrap();

if let Some(map) = maps.current_map_mut() {
let camera = resources.get::<FpsCamera>().unwrap();
let e = map.scene.spawn((
Transform {
translation: camera.position,
flags: TransformFlags::IGNORE_ROTATION
| TransformFlags::IGNORE_SCALE,
..Default::default()
},
Beacon {
..Default::default()
},
Tags::from_iter([EntityTag::Utility]),
Mutable,
));

if let Some(mut se) = resources.get_mut::<SelectedEntity>() {
se.0 = Some(e);
}

ui.close_menu();
}
}
Expand Down
Loading

0 comments on commit 15a8227

Please sign in to comment.