Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Routes again #26

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/alkahest-data/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
pub mod activity;
pub mod buffers;
pub mod common;
pub mod decorator;
pub mod dxgi;
pub mod entity;
pub mod geometry;
Expand All @@ -15,6 +16,5 @@ pub mod text;
pub mod texture;
pub mod tfx;
pub mod unknown;
pub mod decorator;

pub use tag::{Tag, WideHash, WideTag};
22 changes: 18 additions & 4 deletions crates/alkahest-renderer/src/camera/fps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,13 +117,19 @@ impl CameraController for FpsCamera {
speed *= speed_mul;

// Cancel tween if the user moves the camera
if tween.is_some() && direction.length() > 0.0 {
*tween = None;
if direction.length() > 0.0 {
if let Some(t) = tween {
t.abort();
}
}

if let Some(tween) = tween {
self.target_position = tween.update_pos().unwrap_or(self.target_position);
self.orientation = tween.update_angle().unwrap_or(self.orientation);
if tween.is_aborted() {
self.target_position += direction * speed;
} else {
self.target_position = tween.update_pos().unwrap_or(self.target_position);
self.orientation = tween.update_angle().unwrap_or(self.orientation);
}
} else {
self.target_position += direction * speed;
}
Expand Down Expand Up @@ -190,6 +196,14 @@ impl CameraController for FpsCamera {
Mat4::look_at_rh(self.position, self.position + self.forward, Vec3::Z)
}

fn view_angle(&self) -> Vec2 {
self.orientation
}

fn get_look_angle(&self, pos: Vec3) -> Vec2 {
super::get_look_angle(self.orientation, self.position, pos)
}

fn set_position(&mut self, position: Vec3) {
self.position = position;
self.target_position = position;
Expand Down
27 changes: 27 additions & 0 deletions crates/alkahest-renderer/src/camera/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,32 @@ pub trait CameraController {
fn up(&self) -> Vec3;

fn view_matrix(&self) -> Mat4;
fn view_angle(&self) -> Vec2;
fn get_look_angle(&self, pos: Vec3) -> Vec2;

fn set_position(&mut self, position: Vec3);
fn set_orientation(&mut self, orientation: Vec2);
// fn set_rotation(&mut self, rotation: Quat);
// fn look_at(&mut self, target: Vec3);
}

pub fn get_look_angle(start_angle: Vec2, pos1: Vec3, pos2: Vec3) -> Vec2 {
let dir = pos2 - pos1;
let inv_r = dir.length_recip();
if inv_r.is_infinite() {
start_angle
} else {
let theta = dir.x.atan2(dir.y).to_degrees();
let mut diff = (theta - start_angle.y).rem_euclid(360.0);
if diff > 180.0 {
diff -= 360.0;
}
Vec2::new(
(dir.z * inv_r).acos().to_degrees() - 90.0,
start_angle.y + diff,
)
}
}
pub struct Camera {
controller: Box<dyn CameraController>,
viewport: Viewport,
Expand Down Expand Up @@ -192,6 +211,14 @@ impl Camera {
self.controller.set_orientation(orientation);
}

pub fn view_angle(&self) -> Vec2 {
self.controller.view_angle()
}

pub fn get_look_angle(&self, pos: Vec3) -> Vec2 {
self.controller.get_look_angle(pos)
}

// pub fn set_rotation(&mut self, rotation: Quat) {
// self.controller.set_rotation(rotation);
// }
Expand Down
13 changes: 13 additions & 0 deletions crates/alkahest-renderer/src/camera/tween.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,22 @@ impl Tween {
new_angle
}

pub fn reset(&mut self) {
self.start_time = Instant::now();
}

pub fn abort(&mut self) {
self.angle_movement = None;
self.pos_movement = None;
}

pub fn is_finished(&self) -> bool {
self.start_time.elapsed().as_secs_f32() >= self.duration
}

pub fn is_aborted(&self) -> bool {
self.angle_movement.is_none() && self.pos_movement.is_none()
}
}

// https://easings.net/#easeOutExpo
Expand Down
176 changes: 175 additions & 1 deletion crates/alkahest-renderer/src/ecs/utility.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::f32::consts::PI;

use destiny_pkg::TagHash;
use glam::Vec3;
use hecs::Entity;

Expand Down Expand Up @@ -78,7 +79,56 @@ impl Default for Beacon {
}
}

pub fn draw_utilities(renderer: &Renderer, scene: &Scene, resources: &Resources) {
pub struct RouteNode {
pub pos: Vec3,
pub map_hash: Option<TagHash>,
pub is_teleport: bool,
pub label: Option<String>,
}

impl Default for RouteNode {
fn default() -> Self {
Self {
pos: Vec3::ZERO,
map_hash: None,
is_teleport: false,
label: None,
}
}
}

pub struct Route {
pub path: Vec<RouteNode>,
pub color: Color,
pub rainbow: bool,
pub speed_multiplier: f32,
pub scale: f32,
pub marker_interval: f32,
pub show_all: bool,
pub activity_hash: Option<TagHash>,
}

impl Default for Route {
fn default() -> Self {
Self {
path: vec![],
color: Color::WHITE,
rainbow: false,
speed_multiplier: 1.0,
scale: 1.0,
marker_interval: 0.0,
show_all: false,
activity_hash: None,
}
}
}

pub fn draw_utilities(
renderer: &Renderer,
scene: &Scene,
resources: &Resources,
current_hash: TagHash,
) {
for (e, ruler) in scene.query::<&Ruler>().without::<&Hidden>().iter() {
draw_ruler(renderer, ruler, Some(e), resources);
}
Expand All @@ -98,6 +148,10 @@ pub fn draw_utilities(renderer: &Renderer, scene: &Scene, resources: &Resources)
{
draw_beacon(renderer, transform, beacon, Some(e), resources);
}

for (e, route) in scene.query::<&Route>().without::<&Hidden>().iter() {
draw_route(renderer, route, current_hash, Some(e), resources);
}
}

fn draw_ruler(
Expand Down Expand Up @@ -329,3 +383,123 @@ fn draw_beacon(
// // entity,
// );
}

fn draw_route(
renderer: &Renderer,
route: &Route,
current_hash: TagHash,
entity: Option<Entity>,
resources: &Resources,
) {
let selected = resources.get::<SelectedEntity>();
let color = if route.rainbow {
selected.select_fade_color(Color::from(*Hsv::rainbow()), entity)
} else {
selected.select_fade_color(route.color, entity)
};

const BASE_RADIUS: f32 = 0.1;
let mut prev_is_local = false;
for i in 0..route.path.len() {
if let Some(node) = route.path.get(i) {
let node_is_local = node.map_hash.map_or(true, |h| h == current_hash);
let next_node = route.path.get(i + 1);
let next_is_local = next_node.map_or(false, |node| {
node.map_hash.map_or(false, |h| h == current_hash)
});

if !node_is_local {
if prev_is_local || next_is_local || route.show_all {
draw_sphere_skeleton(renderer, node.pos, BASE_RADIUS * route.scale, 2, color);
}
} else {
renderer.immediate.sphere(
node.pos,
BASE_RADIUS * route.scale,
color,
//DebugDrawFlags::DRAW_NORMAL,
//None,
);
}

// TODO (cohae): Fix up once we have text rendering
// if node_is_local || prev_is_local || next_is_local {
// if let Some(label) = node.label.as_ref() {
// renderer.immediate.text(
// label.to_string(),
// node.pos + route.scale / 2.0 * Vec3::Z,
// egui::Align2::CENTER_BOTTOM,
// [255, 255, 255],
// );
// }
// }
prev_is_local = node_is_local;

if next_node.is_some() {
let next_node = next_node.unwrap();
let segment_length = (next_node.pos - node.pos).length();

if !(route.show_all || node_is_local || next_is_local) {
continue;
}

renderer.immediate.line_dotted(
next_node.pos,
node.pos,
color,
color,
1.0,
route.scale,
if next_node.is_teleport { 0.10 } else { 0.75 },
if next_node.is_teleport { 1.5 } else { 0.5 },
);
if route.marker_interval > 0.0 {
let sphere_color = color.invert().keep_bright();
let sphere_color = Color::from_rgba_premultiplied(
sphere_color[0],
sphere_color[1],
sphere_color[2],
0.75,
);

let mut current = 0.0;
while current < segment_length {
if current > 0.0 {
let pos = node.pos + (next_node.pos - node.pos).normalize() * current;

renderer.immediate.sphere(
pos,
route.scale * 0.20,
sphere_color,
//DebugDrawFlags::DRAW_NORMAL,
//None,
);
}

current += route.marker_interval;
}
}
//TODO (cohae): Fix this once pick buffer exists
// renderer.immediate.cube_extents(
// (node.pos + next_node.pos) / 2.0,
// Vec3::new(segment_length / 2.0, route.scale / 2.0, route.scale / 2.0),
// Quat::from_rotation_arc(Vec3::X, (next_node.pos - node.pos).normalize()),
// color,
// true,
// DebugDrawFlags::DRAW_PICK,
// entity,
// )
} else {
// renderer.immediate.cube_extents(
// node.pos,
// Vec3::new(route.scale / 2.0, route.scale / 2.0, route.scale / 2.0),
// Quat::IDENTITY,
// color,
// true,
// DebugDrawFlags::DRAW_PICK,
// entity,
// )
}
}
}
}
4 changes: 2 additions & 2 deletions crates/alkahest-renderer/src/renderer/immediate.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use std::f32::consts::PI;

use alkahest_data::occlusion::AABB;
use alkahest_data::{geometry::EPrimitiveType, tfx::TfxShaderStage};
use genmesh::{
generators::{IndexedPolygon, SharedVertex},
Triangulate,
};
use glam::{Mat4, Vec3, Vec4};
use alkahest_data::occlusion::AABB;

use crate::{
gpu::{buffer::ConstantBuffer, SharedGpuContext},
Expand Down Expand Up @@ -299,7 +299,7 @@ impl ImmediateRenderer {
.DrawIndexed(self.ib_cube.length as u32, 0, 0);
}
}

pub fn cube_outline_aabb<C: Into<Color>>(&self, aabb: &AABB, color: C) {
let center = aabb.center();
let extents = aabb.extents();
Expand Down
11 changes: 9 additions & 2 deletions crates/alkahest-renderer/src/renderer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ mod transparents_pass;
use std::{sync::Arc, time::Instant};

use alkahest_data::tfx::TfxShaderStage;
use destiny_pkg::TagHash;
use parking_lot::Mutex;
use serde::{Deserialize, Serialize};
use windows::Win32::Graphics::Direct3D11::D3D11_VIEWPORT;
Expand Down Expand Up @@ -94,7 +95,13 @@ impl Renderer {
data.asset_manager.techniques.get_shared(handle)
}

pub fn render_world(&self, view: &impl View, scene: &Scene, resources: &Resources) {
pub fn render_world(
&self,
view: &impl View,
scene: &Scene,
resources: &Resources,
current_hash: TagHash,
) {
self.begin_world_frame(scene);

update_dynamic_model_system(scene);
Expand All @@ -112,7 +119,7 @@ impl Renderer {
self.draw_shading_pass(scene);
self.draw_transparents_pass(scene);

draw_utilities(self, scene, resources)
draw_utilities(self, scene, resources, current_hash)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Map hash should not be passed into the renderer.
Is there a way we can identify local nodes without needing information about maps (besides the scene)?
If not, then we might need to pass a Map into the renderer instead of a Scene

}

self.gpu.blit_texture(
Expand Down
Loading
Loading