forked from StudioInfinity/dyna3
Compare commits
No commits in common. "b7375e7101c69c2a58428a8892abc3abb651f8c5" and "0fbb0715067232826e7391f1a3cb999e3fdf9147" have entirely different histories.
b7375e7101
...
0fbb071506
5 changed files with 21 additions and 81 deletions
|
@ -138,7 +138,7 @@ fn load_pointed_assemb(assembly: &Assembly) {
|
||||||
Point::new(
|
Point::new(
|
||||||
format!("point_front"),
|
format!("point_front"),
|
||||||
format!("Front point"),
|
format!("Front point"),
|
||||||
[0.75_f32, 0.75_f32, 0.75_f32],
|
[0.875_f32, 0.875_f32, 0.875_f32],
|
||||||
engine::point(0.0, 0.0, FRAC_1_SQRT_2)
|
engine::point(0.0, 0.0, FRAC_1_SQRT_2)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
@ -146,7 +146,7 @@ fn load_pointed_assemb(assembly: &Assembly) {
|
||||||
Point::new(
|
Point::new(
|
||||||
format!("point_back"),
|
format!("point_back"),
|
||||||
format!("Back point"),
|
format!("Back point"),
|
||||||
[0.75_f32, 0.75_f32, 0.75_f32],
|
[0.875_f32, 0.875_f32, 0.875_f32],
|
||||||
engine::point(0.0, 0.0, -FRAC_1_SQRT_2)
|
engine::point(0.0, 0.0, -FRAC_1_SQRT_2)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
@ -168,7 +168,7 @@ fn load_pointed_assemb(assembly: &Assembly) {
|
||||||
Point::new(
|
Point::new(
|
||||||
format!("point{index_x}{index_y}"),
|
format!("point{index_x}{index_y}"),
|
||||||
format!("Point {index_x}{index_y}"),
|
format!("Point {index_x}{index_y}"),
|
||||||
[0.5*(1.0 + x) as f32, 0.5*(1.0 + y) as f32, 0.5*(1.0 - x*y) as f32],
|
[0.4*(2.0 + x) as f32, 0.4*(2.0 + y) as f32, 0.4*(2.0 - x*y) as f32],
|
||||||
engine::point(x, y, 0.0)
|
engine::point(x, y, 0.0)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
|
@ -239,7 +239,7 @@ impl Element for Point {
|
||||||
Point::new(
|
Point::new(
|
||||||
id,
|
id,
|
||||||
format!("Point {id_num}"),
|
format!("Point {id_num}"),
|
||||||
[0.75_f32, 0.75_f32, 0.75_f32],
|
[0.875_f32, 0.875_f32, 0.875_f32],
|
||||||
point(0.0, 0.0, 0.0)
|
point(0.0, 0.0, 0.0)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,25 +50,19 @@ impl SceneSpheres {
|
||||||
struct ScenePoints {
|
struct ScenePoints {
|
||||||
representations: Vec<DVector<f64>>,
|
representations: Vec<DVector<f64>>,
|
||||||
colors: Vec<ElementColor>,
|
colors: Vec<ElementColor>,
|
||||||
highlights: Vec<f32>,
|
|
||||||
selections: Vec<f32>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ScenePoints {
|
impl ScenePoints {
|
||||||
fn new() -> ScenePoints {
|
fn new() -> ScenePoints {
|
||||||
ScenePoints {
|
ScenePoints {
|
||||||
representations: Vec::new(),
|
representations: Vec::new(),
|
||||||
colors: Vec::new(),
|
colors: Vec::new()
|
||||||
highlights: Vec::new(),
|
|
||||||
selections: Vec::new()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push(&mut self, representation: DVector<f64>, color: ElementColor, highlight: f32, selected: bool) {
|
fn push(&mut self, representation: DVector<f64>, color: ElementColor) {
|
||||||
self.representations.push(representation);
|
self.representations.push(representation);
|
||||||
self.colors.push(color);
|
self.colors.push(color);
|
||||||
self.highlights.push(highlight);
|
|
||||||
self.selections.push(if selected { 1.0 } else { 0.0 });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +86,7 @@ pub trait DisplayItem {
|
||||||
// the smallest positive depth, represented as a multiple of `dir`, where
|
// the smallest positive depth, represented as a multiple of `dir`, where
|
||||||
// the line generated by `dir` hits the element. returns `None` if the line
|
// the line generated by `dir` hits the element. returns `None` if the line
|
||||||
// misses the element
|
// misses the element
|
||||||
fn cast(&self, dir: Vector3<f64>, assembly_to_world: &DMatrix<f64>, pixel_size: f64) -> Option<f64>;
|
fn cast(&self, dir: Vector3<f64>, assembly_to_world: &DMatrix<f64>) -> Option<f64>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DisplayItem for Sphere {
|
impl DisplayItem for Sphere {
|
||||||
|
@ -106,7 +100,7 @@ impl DisplayItem for Sphere {
|
||||||
|
|
||||||
// this method should be kept synchronized with `sphere_cast` in
|
// this method should be kept synchronized with `sphere_cast` in
|
||||||
// `spheres.frag`, which does essentially the same thing on the GPU side
|
// `spheres.frag`, which does essentially the same thing on the GPU side
|
||||||
fn cast(&self, dir: Vector3<f64>, assembly_to_world: &DMatrix<f64>, _pixel_size: f64) -> Option<f64> {
|
fn cast(&self, dir: Vector3<f64>, assembly_to_world: &DMatrix<f64>) -> Option<f64> {
|
||||||
// if `a/b` is less than this threshold, we approximate
|
// if `a/b` is less than this threshold, we approximate
|
||||||
// `a*u^2 + b*u + c` by the linear function `b*u + c`
|
// `a*u^2 + b*u + c` by the linear function `b*u + c`
|
||||||
const DEG_THRESHOLD: f64 = 1e-9;
|
const DEG_THRESHOLD: f64 = 1e-9;
|
||||||
|
@ -146,40 +140,15 @@ impl DisplayItem for Sphere {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DisplayItem for Point {
|
impl DisplayItem for Point {
|
||||||
fn show(&self, scene: &mut Scene, selected: bool) {
|
fn show(&self, scene: &mut Scene, _selected: bool) {
|
||||||
const HIGHLIGHT: f32 = 0.5; /* SCAFFOLDING */
|
|
||||||
let representation = self.representation.get_clone_untracked();
|
let representation = self.representation.get_clone_untracked();
|
||||||
let color = if selected { self.color.map(|channel| 0.2 + 0.8*channel) } else { self.color };
|
scene.points.push(representation, self.color);
|
||||||
let highlight = if selected { 1.0 } else { HIGHLIGHT };
|
|
||||||
scene.points.push(representation, color, highlight, selected);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* SCAFFOLDING */
|
/* SCAFFOLDING */
|
||||||
fn cast(&self, dir: Vector3<f64>, assembly_to_world: &DMatrix<f64>, pixel_size: f64) -> Option<f64> {
|
fn cast(&self, _dir: Vector3<f64>, _assembly_to_world: &DMatrix<f64>) -> Option<f64> {
|
||||||
let rep = self.representation.with_untracked(|rep| assembly_to_world * rep);
|
|
||||||
if rep[2] < 0.0 {
|
|
||||||
// this constant should be kept synchronized with `point.frag`
|
|
||||||
const POINT_RADIUS_PX: f64 = 4.0;
|
|
||||||
|
|
||||||
// find the radius of the point in screen projection units
|
|
||||||
let point_radius_proj = POINT_RADIUS_PX * pixel_size;
|
|
||||||
|
|
||||||
// find the squared distance between the screen projections of the
|
|
||||||
// ray and the point
|
|
||||||
let dir_proj = -dir.fixed_rows::<2>(0) / dir[2];
|
|
||||||
let rep_proj = -rep.fixed_rows::<2>(0) / rep[2];
|
|
||||||
let dist_sq = (dir_proj - rep_proj).norm_squared();
|
|
||||||
|
|
||||||
// if the ray hits the point, return its depth
|
|
||||||
if dist_sq < point_radius_proj * point_radius_proj {
|
|
||||||
Some(rep[2] / dir[2])
|
|
||||||
} else {
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- WebGL utilities ---
|
// --- WebGL utilities ---
|
||||||
|
@ -304,7 +273,7 @@ fn bind_new_buffer_to_attribute(
|
||||||
}
|
}
|
||||||
|
|
||||||
// the direction in camera space that a mouse event is pointing along
|
// the direction in camera space that a mouse event is pointing along
|
||||||
fn event_dir(event: &MouseEvent) -> (Vector3<f64>, f64) {
|
fn event_dir(event: &MouseEvent) -> Vector3<f64> {
|
||||||
let target: web_sys::Element = event.target().unwrap().unchecked_into();
|
let target: web_sys::Element = event.target().unwrap().unchecked_into();
|
||||||
let rect = target.get_bounding_client_rect();
|
let rect = target.get_bounding_client_rect();
|
||||||
let width = rect.width();
|
let width = rect.width();
|
||||||
|
@ -315,13 +284,10 @@ fn event_dir(event: &MouseEvent) -> (Vector3<f64>, f64) {
|
||||||
// `point.vert`
|
// `point.vert`
|
||||||
const FOCAL_SLOPE: f64 = 0.3;
|
const FOCAL_SLOPE: f64 = 0.3;
|
||||||
|
|
||||||
(
|
|
||||||
Vector3::new(
|
Vector3::new(
|
||||||
FOCAL_SLOPE * (2.0*(f64::from(event.client_x()) - rect.left()) - width) / shortdim,
|
FOCAL_SLOPE * (2.0*(f64::from(event.client_x()) - rect.left()) - width) / shortdim,
|
||||||
FOCAL_SLOPE * (2.0*(rect.bottom() - f64::from(event.client_y())) - height) / shortdim,
|
FOCAL_SLOPE * (2.0*(rect.bottom() - f64::from(event.client_y())) - height) / shortdim,
|
||||||
-1.0
|
-1.0
|
||||||
),
|
|
||||||
FOCAL_SLOPE * 2.0 / shortdim
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -413,10 +379,6 @@ pub fn Display() -> View {
|
||||||
// disable depth testing
|
// disable depth testing
|
||||||
ctx.disable(WebGl2RenderingContext::DEPTH_TEST);
|
ctx.disable(WebGl2RenderingContext::DEPTH_TEST);
|
||||||
|
|
||||||
// set blend mode
|
|
||||||
ctx.enable(WebGl2RenderingContext::BLEND);
|
|
||||||
ctx.blend_func(WebGl2RenderingContext::SRC_ALPHA, WebGl2RenderingContext::ONE_MINUS_SRC_ALPHA);
|
|
||||||
|
|
||||||
// set up the sphere rendering program
|
// set up the sphere rendering program
|
||||||
let sphere_program = set_up_program(
|
let sphere_program = set_up_program(
|
||||||
&ctx,
|
&ctx,
|
||||||
|
@ -489,8 +451,6 @@ pub fn Display() -> View {
|
||||||
// find the point program's vertex attributes
|
// find the point program's vertex attributes
|
||||||
let point_position_attr = ctx.get_attrib_location(&point_program, "position") as u32;
|
let point_position_attr = ctx.get_attrib_location(&point_program, "position") as u32;
|
||||||
let point_color_attr = ctx.get_attrib_location(&point_program, "color") as u32;
|
let point_color_attr = ctx.get_attrib_location(&point_program, "color") as u32;
|
||||||
let point_highlight_attr = ctx.get_attrib_location(&point_program, "highlight") as u32;
|
|
||||||
let point_selection_attr = ctx.get_attrib_location(&point_program, "selected") as u32;
|
|
||||||
|
|
||||||
// set up a repainting routine
|
// set up a repainting routine
|
||||||
let (_, start_animation_loop, _) = create_raf(move || {
|
let (_, start_animation_loop, _) = create_raf(move || {
|
||||||
|
@ -687,8 +647,6 @@ pub fn Display() -> View {
|
||||||
// enable the point program's vertex attributes
|
// enable the point program's vertex attributes
|
||||||
ctx.enable_vertex_attrib_array(point_position_attr);
|
ctx.enable_vertex_attrib_array(point_position_attr);
|
||||||
ctx.enable_vertex_attrib_array(point_color_attr);
|
ctx.enable_vertex_attrib_array(point_color_attr);
|
||||||
ctx.enable_vertex_attrib_array(point_highlight_attr);
|
|
||||||
ctx.enable_vertex_attrib_array(point_selection_attr);
|
|
||||||
|
|
||||||
// write the points in world coordinates
|
// write the points in world coordinates
|
||||||
let asm_to_world_sp = asm_to_world.rows(0, SPACE_DIM);
|
let asm_to_world_sp = asm_to_world.rows(0, SPACE_DIM);
|
||||||
|
@ -703,8 +661,6 @@ pub fn Display() -> View {
|
||||||
// shader
|
// shader
|
||||||
bind_new_buffer_to_attribute(&ctx, point_position_attr, SPACE_DIM as i32, point_positions.as_slice());
|
bind_new_buffer_to_attribute(&ctx, point_position_attr, SPACE_DIM as i32, point_positions.as_slice());
|
||||||
bind_new_buffer_to_attribute(&ctx, point_color_attr, COLOR_SIZE as i32, scene.points.colors.concat().as_slice());
|
bind_new_buffer_to_attribute(&ctx, point_color_attr, COLOR_SIZE as i32, scene.points.colors.concat().as_slice());
|
||||||
bind_new_buffer_to_attribute(&ctx, point_highlight_attr, 1 as i32, scene.points.highlights.as_slice());
|
|
||||||
bind_new_buffer_to_attribute(&ctx, point_selection_attr, 1 as i32, scene.points.selections.as_slice());
|
|
||||||
|
|
||||||
// draw the scene
|
// draw the scene
|
||||||
ctx.draw_arrays(WebGl2RenderingContext::POINTS, 0, point_positions.ncols() as i32);
|
ctx.draw_arrays(WebGl2RenderingContext::POINTS, 0, point_positions.ncols() as i32);
|
||||||
|
@ -712,8 +668,6 @@ pub fn Display() -> View {
|
||||||
// disable the point program's vertex attributes
|
// disable the point program's vertex attributes
|
||||||
ctx.disable_vertex_attrib_array(point_position_attr);
|
ctx.disable_vertex_attrib_array(point_position_attr);
|
||||||
ctx.disable_vertex_attrib_array(point_color_attr);
|
ctx.disable_vertex_attrib_array(point_color_attr);
|
||||||
ctx.disable_vertex_attrib_array(point_highlight_attr);
|
|
||||||
ctx.disable_vertex_attrib_array(point_selection_attr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- update the display state ---
|
// --- update the display state ---
|
||||||
|
@ -847,11 +801,11 @@ pub fn Display() -> View {
|
||||||
},
|
},
|
||||||
on:click=move |event: MouseEvent| {
|
on:click=move |event: MouseEvent| {
|
||||||
// find the nearest element along the pointer direction
|
// find the nearest element along the pointer direction
|
||||||
let (dir, pixel_size) = event_dir(&event);
|
let dir = event_dir(&event);
|
||||||
console::log_1(&JsValue::from(dir.to_string()));
|
console::log_1(&JsValue::from(dir.to_string()));
|
||||||
let mut clicked: Option<(ElementKey, f64)> = None;
|
let mut clicked: Option<(ElementKey, f64)> = None;
|
||||||
for (key, elt) in state.assembly.elements.get_clone_untracked() {
|
for (key, elt) in state.assembly.elements.get_clone_untracked() {
|
||||||
match assembly_to_world.with(|asm_to_world| elt.cast(dir, asm_to_world, pixel_size)) {
|
match assembly_to_world.with(|asm_to_world| elt.cast(dir, asm_to_world)) {
|
||||||
Some(depth) => match clicked {
|
Some(depth) => match clicked {
|
||||||
Some((_, best_depth)) => {
|
Some((_, best_depth)) => {
|
||||||
if depth < best_depth {
|
if depth < best_depth {
|
||||||
|
|
|
@ -3,16 +3,9 @@
|
||||||
precision highp float;
|
precision highp float;
|
||||||
|
|
||||||
in vec3 point_color;
|
in vec3 point_color;
|
||||||
in float point_highlight;
|
|
||||||
in float total_radius;
|
|
||||||
|
|
||||||
out vec4 outColor;
|
out vec4 outColor;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
float r = total_radius * length(2.*gl_PointCoord - vec2(1.));
|
outColor = vec4(point_color, 1.);
|
||||||
|
|
||||||
const float POINT_RADIUS = 4.;
|
|
||||||
float border = smoothstep(POINT_RADIUS - 1., POINT_RADIUS, r);
|
|
||||||
vec3 color = mix(point_color, vec3(1.), border * point_highlight);
|
|
||||||
outColor = vec4(color, 1. - smoothstep(total_radius - 1., total_radius, r));
|
|
||||||
}
|
}
|
|
@ -2,23 +2,16 @@
|
||||||
|
|
||||||
in vec4 position;
|
in vec4 position;
|
||||||
in vec3 color;
|
in vec3 color;
|
||||||
in float highlight;
|
|
||||||
in float selected;
|
|
||||||
|
|
||||||
out vec3 point_color;
|
out vec3 point_color;
|
||||||
out float point_highlight;
|
|
||||||
out float total_radius;
|
|
||||||
|
|
||||||
// camera
|
// camera
|
||||||
const float focal_slope = 0.3;
|
const float focal_slope = 0.3;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
total_radius = 5. + 0.5*selected;
|
|
||||||
|
|
||||||
float depth = -focal_slope * position.z;
|
float depth = -focal_slope * position.z;
|
||||||
gl_Position = vec4(position.xy / depth, 0., 1.);
|
gl_Position = vec4(position.xy / depth, 0., 1.);
|
||||||
gl_PointSize = 2.*total_radius;
|
gl_PointSize = 5.;
|
||||||
|
|
||||||
point_color = color;
|
point_color = color;
|
||||||
point_highlight = highlight;
|
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue