From 96afad0c97ccfc5f5fca6825d50dd5e8079fd8ac Mon Sep 17 00:00:00 2001 From: Aaron Fenyes Date: Mon, 16 Sep 2024 15:46:45 -0700 Subject: [PATCH] Display: highlight selected elements --- app-proto/sketch-outline/src/display.rs | 16 ++++++++++++---- app-proto/sketch-outline/src/inversive.frag | 12 ++++++++---- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/app-proto/sketch-outline/src/display.rs b/app-proto/sketch-outline/src/display.rs index 70beacf..373c857 100644 --- a/app-proto/sketch-outline/src/display.rs +++ b/app-proto/sketch-outline/src/display.rs @@ -199,10 +199,12 @@ pub fn Display() -> View { let color_locs = get_uniform_array_locations::( &ctx, &program, "color_list", None ); + let highlight_locs = get_uniform_array_locations::( + &ctx, &program, "highlight_list", None + ); let resolution_loc = ctx.get_uniform_location(&program, "resolution"); let shortdim_loc = ctx.get_uniform_location(&program, "shortdim"); let opacity_loc = ctx.get_uniform_location(&program, "opacity"); - let highlight_loc = ctx.get_uniform_location(&program, "highlight"); let layer_threshold_loc = ctx.get_uniform_location(&program, "layer_threshold"); let debug_mode_loc = ctx.get_uniform_location(&program, "debug_mode"); @@ -289,13 +291,16 @@ pub fn Display() -> View { let elements = state.assembly.elements.get_clone(); let element_iter = (&elements).into_iter(); let reps_world: Vec<_> = element_iter.clone().map(|elt| &assembly_to_world * &elt.rep).collect(); - let colors: Vec<_> = element_iter.map(|elt| + let colors: Vec<_> = element_iter.clone().map(|elt| if elt.selected.get() { - elt.color.map(|ch| 0.5 + 0.5*ch) + elt.color.map(|ch| 0.2 + 0.8*ch) } else { elt.color } ).collect(); + let highlights: Vec<_> = element_iter.map(|elt| + if elt.selected.get() { 1.0_f32 } else { HIGHLIGHT } + ).collect(); // set the resolution let width = canvas.width() as f32; @@ -319,11 +324,14 @@ pub fn Display() -> View { color_locs[n].as_ref(), &colors[n] ); + ctx.uniform1f( + highlight_locs[n].as_ref(), + highlights[n] + ); } // pass the display parameters ctx.uniform1f(opacity_loc.as_ref(), OPACITY); - ctx.uniform1f(highlight_loc.as_ref(), HIGHLIGHT); ctx.uniform1i(layer_threshold_loc.as_ref(), LAYER_THRESHOLD); ctx.uniform1i(debug_mode_loc.as_ref(), DEBUG_MODE); diff --git a/app-proto/sketch-outline/src/inversive.frag b/app-proto/sketch-outline/src/inversive.frag index d75377e..47743eb 100644 --- a/app-proto/sketch-outline/src/inversive.frag +++ b/app-proto/sketch-outline/src/inversive.frag @@ -18,6 +18,7 @@ const int SPHERE_MAX = 200; uniform int sphere_cnt; uniform vecInv sphere_list[SPHERE_MAX]; uniform vec3 color_list[SPHERE_MAX]; +uniform float highlight_list[SPHERE_MAX]; // view uniform vec2 resolution; @@ -25,7 +26,6 @@ uniform float shortdim; // controls uniform float opacity; -uniform float highlight; uniform int layer_threshold; uniform bool debug_mode; @@ -66,6 +66,7 @@ vec3 sRGB(vec3 color) { struct taggedFrag { int id; vec4 color; + float highlight; vec3 pt; vec3 normal; }; @@ -82,7 +83,7 @@ taggedFrag[2] sort(taggedFrag a, taggedFrag b) { return result; } -taggedFrag sphere_shading(vecInv v, vec3 pt, vec3 base_color, int id) { +taggedFrag sphere_shading(vecInv v, vec3 pt, vec3 base_color, float highlight, int id) { // the expression for normal needs to be checked. it's supposed to give the // negative gradient of the lorentz product between the impact point vector // and the sphere vector with respect to the coordinates of the impact @@ -92,7 +93,7 @@ taggedFrag sphere_shading(vecInv v, vec3 pt, vec3 base_color, int id) { float incidence = dot(normal, light_dir); float illum = mix(0.4, 1.0, max(incidence, 0.0)); - return taggedFrag(id, vec4(illum * base_color, opacity), pt, normal); + return taggedFrag(id, vec4(illum * base_color, opacity), highlight, pt, normal); } // --- ray-casting --- @@ -158,6 +159,7 @@ void main() { sphere_list[id], hit_depths[side] * dir, dimming * color_list[id], + highlight_list[id], id ); } @@ -203,13 +205,15 @@ void main() { abs(dot(frag1.normal, disp)), abs(dot(frag0.normal, disp)) ) / ixn_sin; - float ixn_highlight = 0.5 * highlight * (1. - smoothstep(2./3.*ixn_threshold, 1.5*ixn_threshold, ixn_dist)); + float max_highlight = max(frags[i].highlight, frags[i-1].highlight); + float ixn_highlight = 0.5 * max_highlight * (1. - smoothstep(2./3.*ixn_threshold, 1.5*ixn_threshold, ixn_dist)); frags[i].color = mix(frags[i].color, vec4(1.), ixn_highlight); frags[i-1].color = mix(frags[i-1].color, vec4(1.), ixn_highlight); // cusps float cusp_cos = abs(dot(dir, frag0.normal)); float cusp_threshold = 2.*sqrt(ixn_threshold * sphere_list[frag0.id].lt.s); + float highlight = frags[i].highlight; float cusp_highlight = highlight * (1. - smoothstep(2./3.*cusp_threshold, 1.5*cusp_threshold, cusp_cos)); frags[i].color = mix(frags[i].color, vec4(1.), cusp_highlight); }