diff --git a/crates/modules/cosmobiologia/cosmobiologia-canvas/src/lib.rs b/crates/modules/cosmobiologia/cosmobiologia-canvas/src/lib.rs index 3855b35..43952af 100644 --- a/crates/modules/cosmobiologia/cosmobiologia-canvas/src/lib.rs +++ b/crates/modules/cosmobiologia/cosmobiologia-canvas/src/lib.rs @@ -171,6 +171,8 @@ pub struct CanvasState { pub sphere_3d: bool, /// Orientación de la esfera 3D — la muta el drag. pub sphere_view: SphereView, + /// Si se dibujan las figuras de constelaciones en la esfera 3D. + pub show_constellations: bool, drag_jog: Option, drag_pan: Option, drag_sphere: Option, @@ -258,6 +260,7 @@ impl Default for CanvasState { rectificacion: None, sphere_3d: false, sphere_view: SphereView::default(), + show_constellations: true, drag_jog: None, drag_pan: None, drag_sphere: None, @@ -383,6 +386,12 @@ impl AstrologyCanvas { cx.notify(); } + /// Enciende o apaga las figuras de constelaciones en la esfera 3D. + pub fn toggle_constellations(&mut self, cx: &mut Context<'_, Self>) { + self.state.show_constellations = !self.state.show_constellations; + cx.notify(); + } + /// Resetea zoom y pan a sus defaults (1.0 y 0,0). No toca rotation /// ni time offset — esos son ortogonales y tienen su propio reset. pub fn reset_view(&mut self, cx: &mut Context<'_, Self>) { @@ -821,6 +830,10 @@ impl AstrologyCanvas { self.toggle_sphere(cx); return; } + "b" | "B" => { + self.toggle_constellations(cx); + return; + } _ => return, }; self.toggle_layer(kind, cx); @@ -914,6 +927,7 @@ impl Render for AstrologyCanvas { &theme, render, self.state.sphere_view, + self.state.show_constellations, self.state.view_scale, self.state.view_pan_x, self.state.view_pan_y, @@ -965,6 +979,36 @@ impl Render for AstrologyCanvas { ) }); + // Switch de constelaciones — solo en modo esfera 3D. + let constellations_toggle = (matches!(self.state.mode, CanvasMode::Wheel { .. }) + && self.state.sphere_3d) + .then(|| { + let on = self.state.show_constellations; + let label = if on { + "● Constelaciones" + } else { + "○ Constelaciones" + }; + div() + .absolute() + .top(px(44.0)) + .right(px(12.0)) + .px(px(11.0)) + .py(px(5.0)) + .rounded(px(6.0)) + .bg(theme.bg_panel_alt.clone()) + .border_1() + .border_color(theme.border) + .text_size(px(11.0)) + .text_color(if on { theme.fg_text } else { theme.fg_muted }) + .cursor_pointer() + .child(label) + .on_mouse_down( + MouseButton::Left, + cx.listener(|this, _, _w, cx| this.toggle_constellations(cx)), + ) + }); + // Depth field: capa absoluta detrás del body, ocupa todo el // canvas. Vignette radial — el centro queda claro y los // bordes se oscurecen, dando profundidad sin "ruido" de @@ -1005,6 +1049,7 @@ impl Render for AstrologyCanvas { .child(body), ) .children(sphere_toggle) + .children(constellations_toggle) } } @@ -1080,6 +1125,7 @@ fn render_sphere( theme: &Theme, render: &RenderModel, view: SphereView, + show_constellations: bool, view_scale: f32, view_pan_x: f32, view_pan_y: f32, @@ -1093,6 +1139,7 @@ fn render_sphere( } else { Palette::light() }, + show_constellations, ..Default::default() }; let commands = compose_sphere(render, &view, &opts); diff --git a/crates/modules/cosmobiologia/cosmobiologia-render/src/sphere3d.rs b/crates/modules/cosmobiologia/cosmobiologia-render/src/sphere3d.rs index 2508d98..a18f8a4 100644 --- a/crates/modules/cosmobiologia/cosmobiologia-render/src/sphere3d.rs +++ b/crates/modules/cosmobiologia/cosmobiologia-render/src/sphere3d.rs @@ -313,15 +313,16 @@ fn add_sphere_shading( cy: center, r: rad * (0.95 - 0.95 * t), stroke: None, - fill: Some(glow.with_alpha(0.04)), + fill: Some(glow.with_alpha(0.028)), stroke_w: 0.0, }, )); } - // Brillo especular desplazado hacia la luz. + // Brillo especular desplazado hacia la luz — tenue: la luminosidad + // viva la reparte la Vía Láctea, que sí gira con la esfera. let hx = center - rad * 0.34; let hy = center - rad * 0.34; - const HALO: usize = 7; + const HALO: usize = 6; for i in 0..HALO { let t = i as f32 / (HALO - 1) as f32; items.push(( @@ -331,7 +332,7 @@ fn add_sphere_shading( cy: hy, r: rad * 0.5 * (1.0 - t), stroke: None, - fill: Some(highlight.with_alpha(0.05)), + fill: Some(highlight.with_alpha(0.018)), stroke_w: 0.0, }, )); @@ -562,6 +563,10 @@ fn add_point_marker( /// estándar IAU que fija el plano de la Vía Láctea. const GAL_POLE_RA: f32 = 192.859; const GAL_POLE_DEC: f32 = 27.128; +/// Centro galáctico (Sgr A*, J2000): AR 266.405°, Dec −28.936°. Hacia +/// ahí la Vía Láctea es más brillante. +const GAL_CENTER_RA: f32 = 266.405; +const GAL_CENTER_DEC: f32 = -28.936; /// Hash entero → f32 en [0,1). Determinista (variante de splitmix32): /// la misma entrada da siempre el mismo valor, así el campo de @@ -659,6 +664,46 @@ fn add_starfield(items: &mut Vec<(f32, DrawCommand)>, proj: &Projector, size: f3 } } +/// El resplandor difuso de la Vía Láctea — una luminosidad repartida a +/// lo largo del plano galáctico, no un brillo fijo a la pantalla. Gira +/// con la esfera. Es más intensa hacia el centro galáctico (en +/// Sagitario, como en el cielo real) y, si hay horizonte, se atenúa en +/// la parte que queda bajo tierra esa noche — la franja como se ve +/// desde la Tierra ese día. +fn add_milky_way_glow( + items: &mut Vec<(f32, DrawCommand)>, + proj: &Projector, + eps: f32, + size: f32, + zenith: Option, +) { + let gpole = rot_x(equatorial_dir(GAL_POLE_RA, GAL_POLE_DEC), eps); + let gcenter = rot_x(equatorial_dir(GAL_CENTER_RA, GAL_CENTER_DEC), eps); + let band = Rgba::opaque(0.78, 0.82, 0.96); + for p3 in great_circle_perp(gpole, 54) { + // Más brillo hacia el centro galáctico. + let toward = (p3.dot(gcenter) * 0.5 + 0.5).clamp(0.0, 1.0); + let bright = 0.28 + 0.72 * toward * toward; + // Atenuada bajo el horizonte local (no se ve esa noche). + let vis = match zenith { + Some(z) if p3.dot(z) < 0.0 => 0.40, + _ => 1.0, + }; + let p = proj.project(p3); + items.push(( + p.depth - 4.0, + DrawCommand::Circle { + cx: p.x, + cy: p.y, + r: size * 0.045, + stroke: None, + fill: Some(band.with_alpha(0.030 * bright * vis * depth_alpha(p.depth))), + stroke_w: 0.0, + }, + )); + } +} + // --- Estrellas fijas notables ---------------------------------------- /// Latitud eclíptica (grados, J2000) de las estrellas fijas notables @@ -982,8 +1027,9 @@ pub fn compose_sphere( // --- Cuerpo de la esfera: sombreado con volumen --- add_sphere_shading(&mut items, pal, center, rad); - // --- Cielo de fondo: estrellas + Vía Láctea (solo tema oscuro) --- + // --- Cielo de fondo: Vía Láctea + estrellas (solo tema oscuro) --- if opts.show_sky && pal.is_dark { + add_milky_way_glow(&mut items, &proj, eps, size, zenith); add_starfield(&mut items, &proj, size, eps); }