mark a source

This commit is contained in:
numzero 2025-11-14 03:34:28 +03:00
parent 44700b217f
commit 41805ca05b
2 changed files with 99 additions and 0 deletions

View File

@ -1,3 +1,5 @@
#![feature(gen_blocks)]
use std::{error::Error, f32::consts::PI, sync::Arc}; use std::{error::Error, f32::consts::PI, sync::Arc};
use glam::{Mat4, vec3}; use glam::{Mat4, vec3};
@ -11,10 +13,12 @@ use winit::{
use crate::{ use crate::{
camera::OrbitalCamera, camera::OrbitalCamera,
render::lines::{LookParams, Mesh, Pipeline, Vertex}, render::lines::{LookParams, Mesh, Pipeline, Vertex},
trace::Source,
}; };
mod camera; mod camera;
mod render; mod render;
mod trace;
const TITLE: &str = "WGPU example"; const TITLE: &str = "WGPU example";
const OUTPUT_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Bgra8UnormSrgb; const OUTPUT_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Bgra8UnormSrgb;
@ -44,6 +48,23 @@ pub fn new_tripod(device: &wgpu::Device) -> Mesh {
) )
} }
fn loop_list<T: Clone, U>(
iter: impl IntoIterator<Item = T>,
mut fa: impl FnMut(T) -> U,
mut fb: impl FnMut(T) -> U,
) -> impl Iterator<Item = U> {
gen move {
let mut iter = iter.into_iter();
let Some(first) = iter.next() else { return };
yield fa(first.clone());
for item in iter {
yield fb(item.clone());
yield fa(item);
}
yield fb(first);
}
}
impl MainWindow { impl MainWindow {
fn new(event_loop: &ActiveEventLoop) -> Self { fn new(event_loop: &ActiveEventLoop) -> Self {
let handle = event_loop let handle = event_loop
@ -111,6 +132,29 @@ impl MainWindow {
..Default::default() ..Default::default()
}); });
self.pipeline.render(&mut pass, [&self.tripod]); self.pipeline.render(&mut pass, [&self.tripod]);
let source = Source {
position_yaw: 0.0,
position_pitch: PI / 3.,
distance: 1.0,
diameter: 0.25,
};
let contour = source.contour(17);
let contour: Vec<Vertex> = loop_list(
contour,
|pos| Vertex {
pos,
color: vec3(1., 1., 0.),
},
|pos| Vertex {
pos,
color: vec3(1., 1., 1.),
},
)
.collect();
self.pipeline
.render(&mut pass, [&Mesh::new(&self.device, &contour)]);
drop(pass); drop(pass);
self.queue.submit(std::iter::once(encoder.finish())); self.queue.submit(std::iter::once(encoder.finish()));
} }

55
src/trace.rs Normal file
View File

@ -0,0 +1,55 @@
use std::f32::consts::PI;
use glam::{Mat4, Vec3, vec3};
use crate::camera::OrbitalCamera;
#[derive(Debug, Clone)]
pub struct Source {
/// Horizontal position (angle), in radians from +X towards +Y.
pub position_yaw: f32,
/// Vertical position (angle), in radians from XY plane towards +Z.
pub position_pitch: f32,
/// Distance from the origin.
pub distance: f32,
/// Disc diameter.
pub diameter: f32,
}
impl Source {
fn orbital(&self) -> OrbitalCamera {
let &Self {
position_yaw,
position_pitch,
distance,
..
} = self;
OrbitalCamera {
position_yaw,
position_pitch,
distance,
}
}
pub fn position(&self) -> Vec3 {
self.orbital().position()
}
pub fn transform(&self) -> Mat4 {
self.orbital().transform().inverse()
}
pub fn contour(&self, n: usize) -> impl Iterator<Item = Vec3> {
let step = 2. * PI / n as f32;
let r = 0.5 * self.diameter;
let m = self.transform();
(0..n).map(move |k| {
let angle = (k as f32) * step;
let (x, y) = angle.sin_cos();
m.transform_point3(r * vec3(x, y, 0.))
})
}
}