diff --git a/app-proto/main.css b/app-proto/main.css index d56784f..f787535 100644 --- a/app-proto/main.css +++ b/app-proto/main.css @@ -90,10 +90,6 @@ summary > div, .regulator { padding-right: 8px; } -.element > input { - margin-left: 8px; -} - .element-switch { width: 18px; padding-left: 2px; diff --git a/app-proto/src/assembly.rs b/app-proto/src/assembly.rs index 6c91fc0..436ac35 100644 --- a/app-proto/src/assembly.rs +++ b/app-proto/src/assembly.rs @@ -102,7 +102,6 @@ pub trait Element: Serial + ProblemPoser + DisplayItem { fn id(&self) -> &String; fn label(&self) -> &String; fn representation(&self) -> Signal>; - fn ghost(&self) -> Signal; // the regulators the element is subject to. the assembly that owns the // element is responsible for keeping this set up to date @@ -160,7 +159,6 @@ pub struct Sphere { pub label: String, pub color: ElementColor, pub representation: Signal>, - pub ghost: Signal, pub regulators: Signal>>, serial: u64, column_index: Cell> @@ -180,7 +178,6 @@ impl Sphere { label: label, color: color, representation: create_signal(representation), - ghost: create_signal(false), regulators: create_signal(BTreeSet::new()), serial: Self::next_serial(), column_index: None.into() @@ -218,10 +215,6 @@ impl Element for Sphere { self.representation } - fn ghost(&self) -> Signal { - self.ghost - } - fn regulators(&self) -> Signal>> { self.regulators } @@ -260,7 +253,6 @@ pub struct Point { pub label: String, pub color: ElementColor, pub representation: Signal>, - pub ghost: Signal, pub regulators: Signal>>, serial: u64, column_index: Cell> @@ -280,7 +272,6 @@ impl Point { label, color, representation: create_signal(representation), - ghost: create_signal(false), regulators: create_signal(BTreeSet::new()), serial: Self::next_serial(), column_index: None.into() @@ -314,10 +305,6 @@ impl Element for Point { self.representation } - fn ghost(&self) -> Signal { - self.ghost - } - fn regulators(&self) -> Signal>> { self.regulators } diff --git a/app-proto/src/display.rs b/app-proto/src/display.rs index 69a3659..a2fe4b6 100644 --- a/app-proto/src/display.rs +++ b/app-proto/src/display.rs @@ -20,23 +20,11 @@ use crate::{ assembly::{Element, ElementColor, ElementMotion, Point, Sphere} }; -// --- color --- - -const COLOR_SIZE: usize = 3; -type ColorWithOpacity = [f32; COLOR_SIZE + 1]; - -fn combine_channels(color: ElementColor, opacity: f32) -> ColorWithOpacity { - let mut color_with_opacity = [0.0; COLOR_SIZE + 1]; - color_with_opacity[..COLOR_SIZE].copy_from_slice(&color); - color_with_opacity[COLOR_SIZE] = opacity; - color_with_opacity -} - // --- scene data --- struct SceneSpheres { representations: Vec>, - colors_with_opacity: Vec, + colors: Vec, highlights: Vec } @@ -44,7 +32,7 @@ impl SceneSpheres { fn new() -> SceneSpheres{ SceneSpheres { representations: Vec::new(), - colors_with_opacity: Vec::new(), + colors: Vec::new(), highlights: Vec::new() } } @@ -53,16 +41,16 @@ impl SceneSpheres { self.representations.len().try_into().expect("Number of spheres must fit in a 32-bit integer") } - fn push(&mut self, representation: DVector, color: ElementColor, opacity: f32, highlight: f32) { + fn push(&mut self, representation: DVector, color: ElementColor, highlight: f32) { self.representations.push(representation); - self.colors_with_opacity.push(combine_channels(color, opacity)); + self.colors.push(color); self.highlights.push(highlight); } } struct ScenePoints { representations: Vec>, - colors_with_opacity: Vec, + colors: Vec, highlights: Vec, selections: Vec } @@ -71,15 +59,15 @@ impl ScenePoints { fn new() -> ScenePoints { ScenePoints { representations: Vec::new(), - colors_with_opacity: Vec::new(), + colors: Vec::new(), highlights: Vec::new(), selections: Vec::new() } } - fn push(&mut self, representation: DVector, color: ElementColor, opacity: f32, highlight: f32, selected: bool) { + fn push(&mut self, representation: DVector, color: ElementColor, highlight: f32, selected: bool) { self.representations.push(representation); - self.colors_with_opacity.push(combine_channels(color, opacity)); + self.colors.push(color); self.highlights.push(highlight); self.selections.push(if selected { 1.0 } else { 0.0 }); } @@ -110,16 +98,11 @@ pub trait DisplayItem { impl DisplayItem for Sphere { fn show(&self, scene: &mut Scene, selected: bool) { - /* SCAFFOLDING */ - const DEFAULT_OPACITY: f32 = 0.5; - const GHOST_OPACITY: f32 = 0.2; - const HIGHLIGHT: f32 = 0.2; - + const HIGHLIGHT: f32 = 0.2; /* SCAFFOLDING */ let representation = self.representation.get_clone_untracked(); let color = if selected { self.color.map(|channel| 0.2 + 0.8*channel) } else { self.color }; - let opacity = if self.ghost.get() { GHOST_OPACITY } else { DEFAULT_OPACITY }; let highlight = if selected { 1.0 } else { HIGHLIGHT }; - scene.spheres.push(representation, color, opacity, highlight); + scene.spheres.push(representation, color, highlight); } // this method should be kept synchronized with `sphere_cast` in @@ -165,15 +148,11 @@ impl DisplayItem for Sphere { impl DisplayItem for Point { fn show(&self, scene: &mut Scene, selected: bool) { - /* SCAFFOLDING */ - const GHOST_OPACITY: f32 = 0.4; - const HIGHLIGHT: f32 = 0.5; - + const HIGHLIGHT: f32 = 0.5; /* SCAFFOLDING */ let representation = self.representation.get_clone_untracked(); let color = if selected { self.color.map(|channel| 0.2 + 0.8*channel) } else { self.color }; - let opacity = if self.ghost.get() { GHOST_OPACITY } else { 1.0 }; let highlight = if selected { 1.0 } else { HIGHLIGHT }; - scene.points.push(representation, color, opacity, highlight, selected); + scene.points.push(representation, color, highlight, selected); } /* SCAFFOLDING */ @@ -386,7 +365,6 @@ pub fn Display() -> View { state.assembly.elements.with(|elts| { for elt in elts { elt.representation().track(); - elt.ghost().track(); } }); state.selection.track(); @@ -417,6 +395,7 @@ pub fn Display() -> View { const SHRINKING_SPEED: f64 = 0.15; // in length units per second // display parameters + const OPACITY: f32 = 0.5; /* SCAFFOLDING */ const LAYER_THRESHOLD: i32 = 0; /* DEBUG */ const DEBUG_MODE: i32 = 0; /* DEBUG */ @@ -490,6 +469,7 @@ pub fn Display() -> View { ); let resolution_loc = ctx.get_uniform_location(&sphere_program, "resolution"); let shortdim_loc = ctx.get_uniform_location(&sphere_program, "shortdim"); + let opacity_loc = ctx.get_uniform_location(&sphere_program, "opacity"); let layer_threshold_loc = ctx.get_uniform_location(&sphere_program, "layer_threshold"); let debug_mode_loc = ctx.get_uniform_location(&sphere_program, "debug_mode"); @@ -674,9 +654,9 @@ pub fn Display() -> View { sphere_lt_locs[n].as_ref(), v.rows(3, 2).as_slice() ); - ctx.uniform4fv_with_f32_array( + ctx.uniform3fv_with_f32_array( sphere_color_locs[n].as_ref(), - &scene.spheres.colors_with_opacity[n] + &scene.spheres.colors[n] ); ctx.uniform1f( sphere_highlight_locs[n].as_ref(), @@ -685,6 +665,7 @@ pub fn Display() -> View { } // pass the display parameters + ctx.uniform1f(opacity_loc.as_ref(), OPACITY); ctx.uniform1i(layer_threshold_loc.as_ref(), LAYER_THRESHOLD); ctx.uniform1i(debug_mode_loc.as_ref(), DEBUG_MODE); @@ -722,7 +703,7 @@ pub fn Display() -> View { // bind them to the corresponding attributes in the vertex // 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_color_attr, (COLOR_SIZE + 1) as i32, scene.points.colors_with_opacity.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()); @@ -870,11 +851,7 @@ pub fn Display() -> View { let (dir, pixel_size) = event_dir(&event); console::log_1(&JsValue::from(dir.to_string())); let mut clicked: Option<(Rc, f64)> = None; - let tangible_elts = state.assembly.elements - .get_clone_untracked() - .into_iter() - .filter(|elt| !elt.ghost().get()); - for elt in tangible_elts { + for elt in state.assembly.elements.get_clone_untracked() { match assembly_to_world.with(|asm_to_world| elt.cast(dir, asm_to_world, pixel_size)) { Some(depth) => match clicked { Some((_, best_depth)) => { diff --git a/app-proto/src/outline.rs b/app-proto/src/outline.rs index 59bbdcc..caf11e8 100644 --- a/app-proto/src/outline.rs +++ b/app-proto/src/outline.rs @@ -202,11 +202,7 @@ fn ElementOutlineItem(element: Rc) -> View { ) { div(class="element-label") { (label) } div(class="element-representation") { (rep_components) } - input( - r#type="checkbox", - bind:checked=element.ghost(), - on:click=|event: MouseEvent| event.stop_propagation() - ) + div(class="status") } } ul(class="regulators") { diff --git a/app-proto/src/point.frag b/app-proto/src/point.frag index 194a072..3a361a8 100644 --- a/app-proto/src/point.frag +++ b/app-proto/src/point.frag @@ -2,7 +2,7 @@ precision highp float; -in vec4 point_color; +in vec3 point_color; in float point_highlight; in float total_radius; @@ -13,7 +13,6 @@ void main() { const float POINT_RADIUS = 4.; float border = smoothstep(POINT_RADIUS - 1., POINT_RADIUS, r); - float disk = 1. - smoothstep(total_radius - 1., total_radius, r); - vec4 color = mix(point_color, vec4(1.), border * point_highlight); - outColor = vec4(vec3(1.), disk) * color; + vec3 color = mix(point_color, vec3(1.), border * point_highlight); + outColor = vec4(color, 1. - smoothstep(total_radius - 1., total_radius, r)); } \ No newline at end of file diff --git a/app-proto/src/point.vert b/app-proto/src/point.vert index 0b76bc1..6945010 100644 --- a/app-proto/src/point.vert +++ b/app-proto/src/point.vert @@ -1,11 +1,11 @@ #version 300 es in vec4 position; -in vec4 color; +in vec3 color; in float highlight; in float selected; -out vec4 point_color; +out vec3 point_color; out float point_highlight; out float total_radius; diff --git a/app-proto/src/spheres.frag b/app-proto/src/spheres.frag index fa317a8..d50cb1e 100644 --- a/app-proto/src/spheres.frag +++ b/app-proto/src/spheres.frag @@ -17,7 +17,7 @@ struct vecInv { const int SPHERE_MAX = 200; uniform int sphere_cnt; uniform vecInv sphere_list[SPHERE_MAX]; -uniform vec4 color_list[SPHERE_MAX]; +uniform vec3 color_list[SPHERE_MAX]; uniform float highlight_list[SPHERE_MAX]; // view @@ -25,6 +25,7 @@ uniform vec2 resolution; uniform float shortdim; // controls +uniform float opacity; uniform int layer_threshold; uniform bool debug_mode; @@ -68,7 +69,7 @@ struct Fragment { vec4 color; }; -Fragment sphere_shading(vecInv v, vec3 pt, vec4 base_color) { +Fragment sphere_shading(vecInv v, vec3 pt, vec3 base_color) { // 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 @@ -78,7 +79,7 @@ Fragment sphere_shading(vecInv v, vec3 pt, vec4 base_color) { float incidence = dot(normal, light_dir); float illum = mix(0.4, 1.0, max(incidence, 0.0)); - return Fragment(pt, normal, vec4(illum * base_color.rgb, base_color.a)); + return Fragment(pt, normal, vec4(illum * base_color, opacity)); } float intersection_dist(Fragment a, Fragment b) { @@ -191,11 +192,10 @@ void main() { vec3 color = vec3(0.); int layer = layer_cnt - 1; TaggedDepth hit = top_hits[layer]; - vec4 sphere_color = color_list[hit.id]; Fragment frag_next = sphere_shading( sphere_list[hit.id], hit.depth * dir, - vec4(hit.dimming * sphere_color.rgb, sphere_color.a) + hit.dimming * color_list[hit.id] ); float highlight_next = highlight_list[hit.id]; --layer; @@ -206,11 +206,10 @@ void main() { // shade the next fragment hit = top_hits[layer]; - sphere_color = color_list[hit.id]; frag_next = sphere_shading( sphere_list[hit.id], hit.depth * dir, - vec4(hit.dimming * sphere_color.rgb, sphere_color.a) + hit.dimming * color_list[hit.id] ); highlight_next = highlight_list[hit.id];