forked from 1b-agent/opencadstudio-upstream
156 lines
7.0 KiB
Rust
156 lines
7.0 KiB
Rust
use crate::scene::view::camera::Camera;
|
|
use iced::Rectangle;
|
|
|
|
#[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)]
|
|
#[repr(C)]
|
|
pub struct Uniforms {
|
|
pub viewport_size: [f32; 2],
|
|
/// World units per screen pixel at the current zoom. Used by the
|
|
/// hatch shader to substitute solid fill when pattern line spacing
|
|
/// falls below ~2 px (Phase 3.3 LOD).
|
|
pub world_per_pixel: f32,
|
|
/// LWDISPLAY toggle (1.0 = show lineweights, 0.0 = force 1 px).
|
|
/// Read by the wire shader so the toggle does not require a retessellate.
|
|
pub lwdisplay_enable: f32,
|
|
/// 1.0 → mesh fragment shader replaces the interpolated vertex
|
|
/// normal with `normalize(cross(dpdx(pos), dpdy(pos)))` so each
|
|
/// triangle gets a uniform shade (FlatShaded mode); 0.0 → keeps the
|
|
/// per-vertex normal interpolation (GouraudShaded-style).
|
|
pub flat_shade: f32,
|
|
/// Transparency-display toggle (1.0 = honour entity transparency,
|
|
/// 0.0 = force opaque). Read by the wire shader so the toggle does not
|
|
/// require a retessellate.
|
|
pub transparency_enable: f32,
|
|
/// Per-viewport PSLTSCALE factor. Kept in the shared frame uniform so
|
|
/// zooming inside MSPACE changes one scalar instead of re-tessellating and
|
|
/// re-uploading every dashed wire.
|
|
pub linetype_scale: f32,
|
|
/// Multiplier for screen-space lineweights. Model space uses the user's
|
|
/// preview scale; paper layouts derive it from the current paper zoom.
|
|
pub lineweight_scale: f32,
|
|
|
|
// ── Relative-to-eye (double-single) additions ───────────────────────────
|
|
// Appended at the end so existing field offsets are unchanged; shaders that
|
|
// still read only the legacy fields keep working. Pipelines migrate to RTE
|
|
// one at a time. `view_rot` is the rotation-only view-projection; vertices
|
|
// pre-subtract the eye (via `eye_high`/`eye_low`, two f32 emulating f64) so
|
|
// the large eye translation never enters the f32 matrix → no large-coord
|
|
// jitter.
|
|
pub view_rot: glam::Mat4,
|
|
pub eye_high: [f32; 3],
|
|
pub _pad_eh: f32,
|
|
pub eye_low: [f32; 3],
|
|
pub _pad_el: f32,
|
|
|
|
// Up to four native AcDbLight/Sun sources. Positions are uploaded relative
|
|
// to the current eye, preserving large-coordinate precision without
|
|
// changing mesh buffers.
|
|
/// xyz = eye-relative source position, w = light type (1 distant, 2 point,
|
|
/// 3 spot).
|
|
pub light_position_type: [[f32; 4]; 4],
|
|
/// xyz = source-to-target direction, w = intensity.
|
|
pub light_direction_intensity: [[f32; 4]; 4],
|
|
/// rgb = source colour, w = cosine of hotspot angle.
|
|
pub light_color_hotspot: [[f32; 4]; 4],
|
|
/// x = attenuation mode, y/z = start/end limits, w = cosine of falloff.
|
|
pub light_attenuation: [[f32; 4]; 4],
|
|
/// x = active light count, yzw = per-viewport ambient-light RGB.
|
|
pub lighting: [f32; 4],
|
|
/// x = viewport face-colour mode, y = viewport face opacity,
|
|
/// z = highlight intensity for faces without an attached material,
|
|
/// w = visual-style brightness.
|
|
pub visual_style: [f32; 4],
|
|
/// Viewport visual-style mono/tint colour.
|
|
pub visual_style_color: [f32; 4],
|
|
/// RGB background selected by the viewport; alpha is one when a drawing
|
|
/// background object, rather than the application canvas, supplies it.
|
|
pub viewport_background: [f32; 4],
|
|
/// x/y = normalized linear brightness/contrast in the documented
|
|
/// -10..10 viewport range; z/w are reserved for exposure controls.
|
|
pub view_tone: [f32; 4],
|
|
pub background_top: [f32; 4],
|
|
pub background_middle: [f32; 4],
|
|
pub background_bottom: [f32; 4],
|
|
pub background_aux0: [f32; 4],
|
|
pub background_aux1: [f32; 4],
|
|
/// x = mode, y = horizon, z = height, w = rotation in radians.
|
|
pub background_params: [f32; 4],
|
|
/// x = fit, y = keep aspect, z = tile, w = decoded image aspect.
|
|
pub background_image_params: [f32; 4],
|
|
/// xy = image offset, zw = image scale.
|
|
pub background_image_transform: [f32; 4],
|
|
/// x = environment enabled, y = rotation, z = diffuse strength,
|
|
/// w = reflection strength.
|
|
pub environment_params: [f32; 4],
|
|
/// View-to-world rotation used to derive environment lookup directions.
|
|
pub environment_view: glam::Mat4,
|
|
/// Eye-relative light projection for the first shadow-casting source.
|
|
pub shadow_view_proj: glam::Mat4,
|
|
/// x = enabled, y = depth bias, z = softness, w = light index.
|
|
pub shadow_params: [f32; 4],
|
|
/// RGB = document render-environment fog colour.
|
|
pub fog_color: [f32; 4],
|
|
/// x = enabled, y = affect background, z/w = near/far density.
|
|
pub fog_params: [f32; 4],
|
|
/// x/y = near/far eye distance used to interpolate the density.
|
|
pub fog_distances: [f32; 4],
|
|
/// Eight normalized vertical-candela samples for each photometric light.
|
|
pub light_web_profile_a: [[f32; 4]; 4],
|
|
pub light_web_profile_b: [[f32; 4]; 4],
|
|
/// xyz = web rotation, w = profile enabled.
|
|
pub light_web_rotation: [[f32; 4]; 4],
|
|
}
|
|
|
|
impl Uniforms {
|
|
pub fn new(camera: &Camera, bounds: Rectangle, lwdisplay_enable: bool) -> Self {
|
|
let half_h = camera.ortho_size();
|
|
let world_per_pixel = if bounds.height > 0.0 {
|
|
(2.0 * half_h) / bounds.height
|
|
} else {
|
|
0.0
|
|
};
|
|
let (eye_high, eye_low) = camera.eye_high_low();
|
|
Self {
|
|
viewport_size: [bounds.width, bounds.height],
|
|
world_per_pixel,
|
|
lwdisplay_enable: if lwdisplay_enable { 1.0 } else { 0.0 },
|
|
flat_shade: 0.0,
|
|
transparency_enable: 1.0,
|
|
linetype_scale: 1.0,
|
|
lineweight_scale: 1.0,
|
|
view_rot: camera.view_proj_rte(bounds),
|
|
eye_high,
|
|
_pad_eh: 0.0,
|
|
eye_low,
|
|
_pad_el: 0.0,
|
|
light_position_type: [[0.0; 4]; 4],
|
|
light_direction_intensity: [[0.0; 4]; 4],
|
|
light_color_hotspot: [[0.0; 4]; 4],
|
|
light_attenuation: [[0.0; 4]; 4],
|
|
lighting: [0.0, 0.18, 0.18, 0.18],
|
|
visual_style: [1.0, 1.0, -1.0, 0.0],
|
|
visual_style_color: [1.0, 1.0, 1.0, 1.0],
|
|
viewport_background: [0.0, 0.0, 0.0, 0.0],
|
|
view_tone: [0.0; 4],
|
|
background_top: [0.0; 4],
|
|
background_middle: [0.0; 4],
|
|
background_bottom: [0.0; 4],
|
|
background_aux0: [0.0; 4],
|
|
background_aux1: [0.0; 4],
|
|
background_params: [0.0; 4],
|
|
background_image_params: [0.0; 4],
|
|
background_image_transform: [0.0, 0.0, 1.0, 1.0],
|
|
environment_params: [0.0, 0.0, 0.25, 0.35],
|
|
environment_view: glam::Mat4::IDENTITY,
|
|
shadow_view_proj: glam::Mat4::IDENTITY,
|
|
shadow_params: [0.0, 0.0015, 1.0, 0.0],
|
|
fog_color: [0.0, 0.0, 0.0, 1.0],
|
|
fog_params: [0.0; 4],
|
|
fog_distances: [0.0, 1.0, 0.0, 0.0],
|
|
light_web_profile_a: [[1.0; 4]; 4],
|
|
light_web_profile_b: [[1.0; 4]; 4],
|
|
light_web_rotation: [[0.0; 4]; 4],
|
|
}
|
|
}
|
|
}
|