feat(lines): line impl mostly done
Signed-off-by: Schmarni <marnistromer@gmail.com>
This commit is contained in:
9
Cargo.lock
generated
9
Cargo.lock
generated
@@ -6402,7 +6402,8 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "tracing-tracy"
|
||||
version = "0.11.4"
|
||||
source = "git+https://github.com/nagisa/rust_tracy_client?tag=tracy-client-v0.18.1#7d084307f54959999ca3729c42bd4f4f3f0df54d"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0eaa1852afa96e0fe9e44caa53dc0bd2d9d05e0f2611ce09f97f8677af56e4ba"
|
||||
dependencies = [
|
||||
"tracing-core",
|
||||
"tracing-subscriber",
|
||||
@@ -6423,7 +6424,8 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "tracy-client"
|
||||
version = "0.18.1"
|
||||
source = "git+https://github.com/nagisa/rust_tracy_client?tag=tracy-client-v0.18.1#7d084307f54959999ca3729c42bd4f4f3f0df54d"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3927832d93178f979a970d26deed7b03510586e328f31b0f9ad7a73985b8332a"
|
||||
dependencies = [
|
||||
"loom",
|
||||
"once_cell",
|
||||
@@ -6433,7 +6435,8 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "tracy-client-sys"
|
||||
version = "0.25.0"
|
||||
source = "git+https://github.com/nagisa/rust_tracy_client?tag=tracy-client-v0.18.1#7d084307f54959999ca3729c42bd4f4f3f0df54d"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c032d68a49d25d9012a864fef1c64ac17aee43c87e0477bf7301d8ae8bfea7b7"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"windows-targets 0.48.5",
|
||||
|
||||
19
src/main.rs
19
src/main.rs
@@ -44,6 +44,7 @@ use clap::Parser;
|
||||
use core::client::{Client, tick_internal_client};
|
||||
use core::task;
|
||||
use directories::ProjectDirs;
|
||||
use nodes::drawable::lines::LinesNodePlugin;
|
||||
use nodes::drawable::model::ModelNodePlugin;
|
||||
use nodes::drawable::text::TextNodePlugin;
|
||||
use nodes::spatial::SpatialNodePlugin;
|
||||
@@ -117,6 +118,13 @@ static STARDUST_INSTANCE: OnceLock<String> = OnceLock::new();
|
||||
// #[tokio::main(flavor = "current_thread")]
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
// let mut out = Vec::new();
|
||||
// for i in 0..8 {
|
||||
// for base in [0, 8, 1, 8, 9, 1] {
|
||||
// out.push(base + i as u16);
|
||||
// }
|
||||
// }
|
||||
// panic!("{out:?}");
|
||||
color_eyre::install().unwrap();
|
||||
|
||||
let registry = tracing_subscriber::registry();
|
||||
@@ -387,6 +395,7 @@ fn bevy_loop(
|
||||
SpatialNodePlugin,
|
||||
ModelNodePlugin,
|
||||
TextNodePlugin,
|
||||
LinesNodePlugin,
|
||||
PlaySpacePlugin,
|
||||
HandPlugin,
|
||||
ControllerPlugin,
|
||||
@@ -400,16 +409,6 @@ fn bevy_loop(
|
||||
.in_set(OxrWaitFrameSystem)
|
||||
.in_set(XrHandleEvents::FrameLoop),
|
||||
);
|
||||
use std::process::Command;
|
||||
|
||||
let output = Command::new("fc-match")
|
||||
.arg("-f")
|
||||
.arg("%{file}")
|
||||
.output()
|
||||
.expect("Failed to run fc-match");
|
||||
|
||||
let font_path = String::from_utf8_lossy(&output.stdout);
|
||||
info!("Default font path: {}", font_path);
|
||||
|
||||
app.run();
|
||||
}
|
||||
|
||||
@@ -1,20 +1,170 @@
|
||||
use super::{Line, LinesAspect};
|
||||
use crate::{
|
||||
core::{client::Client, error::Result, registry::Registry},
|
||||
nodes::{Node, spatial::Spatial},
|
||||
core::{client::Client, color::ColorConvert, error::Result, registry::Registry},
|
||||
nodes::{
|
||||
Node,
|
||||
spatial::{Spatial, SpatialNode},
|
||||
},
|
||||
};
|
||||
use bevy::{
|
||||
asset::RenderAssetUsages,
|
||||
prelude::*,
|
||||
render::mesh::{Indices, PrimitiveTopology},
|
||||
};
|
||||
use bevy_sk::vr_materials::PbrMaterial;
|
||||
use glam::{FloatExt, Vec3};
|
||||
use parking_lot::Mutex;
|
||||
use std::{collections::VecDeque, sync::Arc};
|
||||
use std::{
|
||||
collections::VecDeque,
|
||||
sync::{
|
||||
Arc, OnceLock,
|
||||
atomic::{AtomicBool, Ordering},
|
||||
},
|
||||
};
|
||||
use stereokit_rust::{
|
||||
maths::Bounds, sk::MainThreadToken, system::LinePoint as SkLinePoint, util::Color128,
|
||||
};
|
||||
|
||||
pub struct LinesNodePlugin;
|
||||
|
||||
impl Plugin for LinesNodePlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_systems(Update, build_line_mesh);
|
||||
}
|
||||
}
|
||||
const POINTS: [Vec3; 8] = [
|
||||
Vec3::X,
|
||||
Vec3::new(1., 0., 1.),
|
||||
Vec3::Z,
|
||||
Vec3::new(-1., 0., 1.),
|
||||
Vec3::NEG_X,
|
||||
Vec3::new(-1., 0., -1.),
|
||||
Vec3::NEG_Z,
|
||||
Vec3::new(1., 0., -1.),
|
||||
];
|
||||
|
||||
fn build_line_mesh(
|
||||
mut meshes: ResMut<Assets<Mesh>>,
|
||||
mut cmds: Commands,
|
||||
mut materials: ResMut<Assets<PbrMaterial>>,
|
||||
) {
|
||||
for lines in LINES_REGISTRY
|
||||
.get_valid_contents()
|
||||
.into_iter()
|
||||
.filter(|l| l.gen_mesh.load(Ordering::Relaxed))
|
||||
{
|
||||
lines.gen_mesh.store(false, Ordering::Relaxed);
|
||||
let mut vertex_positions = Vec::<Vec3>::new();
|
||||
let mut vertex_normals = Vec::<Vec3>::new();
|
||||
let mut vertex_colors = Vec::<[f32; 4]>::new();
|
||||
let mut vertex_indecies = Vec::<u32>::new();
|
||||
let lines_data = lines.data.lock();
|
||||
if lines_data.is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let mut idk = 0;
|
||||
for line in lines_data.iter() {
|
||||
let optional_points = {
|
||||
let mut out = Vec::new();
|
||||
let mut last = line.cyclic.then(|| line.points.last()).flatten();
|
||||
let mut peekable = line.points.iter().peekable();
|
||||
while let Some(curr) = peekable.next() {
|
||||
let next = match peekable.peek() {
|
||||
Some(v) => Some(*v),
|
||||
None => line.cyclic.then(|| line.points.first()).flatten(),
|
||||
};
|
||||
|
||||
out.push((last, curr, next));
|
||||
last = Some(curr);
|
||||
}
|
||||
out
|
||||
};
|
||||
for (last, curr, next) in optional_points {
|
||||
let last_quat = last.map(|v| {
|
||||
Quat::from_rotation_arc(
|
||||
Vec3::Y,
|
||||
(Vec3::from(curr.point) - Vec3::from(v.point)).normalize(),
|
||||
)
|
||||
});
|
||||
let next_quat = next.map(|v| {
|
||||
Quat::from_rotation_arc(
|
||||
Vec3::Y,
|
||||
(Vec3::from(v.point) - Vec3::from(curr.point)).normalize(),
|
||||
)
|
||||
});
|
||||
let quat = match (last_quat, next_quat) {
|
||||
(None, None) => unreachable!(),
|
||||
(None, Some(next)) => next,
|
||||
(Some(last), None) => last,
|
||||
(Some(last), Some(next)) => last.lerp(next, 0.5),
|
||||
};
|
||||
let normals = [
|
||||
Vec3::X,
|
||||
Vec3::new(1., 0., 1.).normalize(),
|
||||
Vec3::Z,
|
||||
Vec3::new(-1., 0., 1.).normalize(),
|
||||
Vec3::NEG_X,
|
||||
Vec3::new(-1., 0., -1.).normalize(),
|
||||
Vec3::NEG_Z,
|
||||
Vec3::new(1., 0., -1.).normalize(),
|
||||
]
|
||||
.map(Vec3::normalize)
|
||||
.map(|v| (quat * v));
|
||||
let points = normals.map(|v| (v * curr.thickness) + Vec3::from(curr.point));
|
||||
vertex_normals.extend(normals);
|
||||
vertex_positions.extend(points);
|
||||
vertex_colors.extend([curr.color.to_bevy().to_srgba().to_f32_array(); 8]);
|
||||
idk += 1;
|
||||
}
|
||||
}
|
||||
let vertex_indecies = (0..idk - 1).flat_map(indecies).collect::<Vec<_>>();
|
||||
let mut mesh = Mesh::new(
|
||||
PrimitiveTopology::TriangleList,
|
||||
RenderAssetUsages::RENDER_WORLD,
|
||||
);
|
||||
mesh.insert_indices(Indices::U32(vertex_indecies));
|
||||
mesh.insert_attribute(Mesh::ATTRIBUTE_COLOR, vertex_colors);
|
||||
mesh.insert_attribute(Mesh::ATTRIBUTE_NORMAL, vertex_normals);
|
||||
mesh.insert_attribute(Mesh::ATTRIBUTE_POSITION, vertex_positions);
|
||||
|
||||
match lines.entity.get() {
|
||||
Some(e) => cmds.entity(*e),
|
||||
None => cmds.spawn(SpatialNode(Arc::downgrade(&lines.spatial))),
|
||||
}
|
||||
.insert((
|
||||
Mesh3d(meshes.add(mesh)),
|
||||
MeshMaterial3d(materials.add(PbrMaterial {
|
||||
color: Color::WHITE,
|
||||
roughness: 1.0,
|
||||
alpha_mode: AlphaMode::Blend,
|
||||
..default()
|
||||
})),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
// const BASE: [u16; 6] = [0, 8, 1, 8, 9, 1];
|
||||
const INDECIES: [u32; 48] = [
|
||||
0, 8, 1, 8, 9, 1, 1, 9, 2, 9, 10, 2, 2, 10, 3, 10, 11, 3, 3, 11, 4, 11, 12, 4, 4, 12, 5, 12,
|
||||
13, 5, 5, 13, 6, 13, 14, 6, 6, 14, 7, 14, 15, 7, 7, 15, 0, 15, 8, 0,
|
||||
];
|
||||
fn indecies(base: u32) -> [u32; INDECIES.len()] {
|
||||
INDECIES.map(|v| v + (base * 8))
|
||||
}
|
||||
fn cyclic_indecies(base: u32) -> [u32; INDECIES.len()] {
|
||||
let mut out = INDECIES.map(|v| if v >= 8 { v + (base * 8) } else { v });
|
||||
out.reverse();
|
||||
out
|
||||
}
|
||||
|
||||
static LINES_REGISTRY: Registry<Lines> = Registry::new();
|
||||
|
||||
pub struct Lines {
|
||||
space: Arc<Spatial>,
|
||||
spatial: Arc<Spatial>,
|
||||
data: Mutex<Vec<Line>>,
|
||||
gen_mesh: AtomicBool,
|
||||
entity: OnceLock<Entity>,
|
||||
}
|
||||
impl Lines {
|
||||
pub fn add_to(node: &Arc<Node>, lines: Vec<Line>) -> Result<Arc<Lines>> {
|
||||
@@ -34,9 +184,12 @@ impl Lines {
|
||||
bounds
|
||||
});
|
||||
|
||||
info!("line::add_to");
|
||||
let lines = LINES_REGISTRY.add(Lines {
|
||||
space: node.get_aspect::<Spatial>()?.clone(),
|
||||
spatial: node.get_aspect::<Spatial>()?.clone(),
|
||||
data: Mutex::new(lines),
|
||||
gen_mesh: AtomicBool::new(true),
|
||||
entity: OnceLock::new(),
|
||||
});
|
||||
node.add_aspect_raw(lines.clone());
|
||||
|
||||
@@ -44,7 +197,7 @@ impl Lines {
|
||||
}
|
||||
|
||||
fn draw(&self, token: &MainThreadToken) {
|
||||
let transform_mat = self.space.global_transform();
|
||||
let transform_mat = self.spatial.global_transform();
|
||||
let data = self.data.lock().clone();
|
||||
for line in &data {
|
||||
let mut points: VecDeque<SkLinePoint> = line
|
||||
@@ -82,8 +235,10 @@ impl Lines {
|
||||
}
|
||||
impl LinesAspect for Lines {
|
||||
fn set_lines(node: Arc<Node>, _calling_client: Arc<Client>, lines: Vec<Line>) -> Result<()> {
|
||||
info!("set_lines");
|
||||
let lines_aspect = node.get_aspect::<Lines>()?;
|
||||
*lines_aspect.data.lock() = lines;
|
||||
lines_aspect.gen_mesh.store(true, Ordering::Relaxed);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -95,7 +250,7 @@ impl Drop for Lines {
|
||||
|
||||
pub fn draw_all(token: &MainThreadToken) {
|
||||
for lines in LINES_REGISTRY.get_valid_contents() {
|
||||
if let Some(node) = lines.space.node() {
|
||||
if let Some(node) = lines.spatial.node() {
|
||||
if node.enabled() {
|
||||
lines.draw(token);
|
||||
}
|
||||
|
||||
@@ -242,7 +242,6 @@ impl HashedPbrMaterial {
|
||||
hash_color(mat.emission_factor, state);
|
||||
state.write_u32(mat.metallic.to_bits());
|
||||
state.write_u32(mat.roughness.to_bits());
|
||||
mat.use_stereokit_uvs.hash(state);
|
||||
match mat.alpha_mode {
|
||||
AlphaMode::Opaque => state.write_u8(0),
|
||||
AlphaMode::Mask(v) => {
|
||||
@@ -392,7 +391,6 @@ impl MaterialParameter {
|
||||
}
|
||||
}
|
||||
mat.alpha_mode = AlphaMode::AlphaToCoverage;
|
||||
mat.use_stereokit_uvs = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -438,7 +436,6 @@ impl Material {
|
||||
.as_ref()
|
||||
.map(|p| asset_server.load(p.as_path())),
|
||||
spherical_harmonics: bevy_sk::skytext::SPHERICAL_HARMONICS_HANDLE,
|
||||
use_stereokit_uvs: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,7 +226,6 @@ impl SkHand {
|
||||
let material = materials.add(PbrMaterial {
|
||||
color: Srgba::new(1.0, 1.0, 1.0, 1.0).into(),
|
||||
alpha_mode: AlphaMode::Blend,
|
||||
use_stereokit_uvs: false,
|
||||
diffuse_texture: Some(GRADIENT_TEXTURE_HANDLE),
|
||||
roughness: 1.0,
|
||||
..default()
|
||||
|
||||
Reference in New Issue
Block a user