feat(solid3d): ISOLINES and silhouettes on sphere and torus faces
Extends the curved-face wireframe treatment from cones to spheres and tori, so a solid built from those faces reads the way a cylinder already did. ISOLINES: sphere faces get meridian lines across the face's colatitude span at evenly spaced longitudes; torus faces get minor cross-section circles at evenly spaced revolution angles. Both clip to the face's own parametric window (from the boundary polygon via a shared `angular_span` gap-finder), so a partial sphere or torus arc doesn't draw lines out over the missing part. Silhouettes (DISPSILH): `CurvedGen` becomes an enum. A sphere silhouettes as the great circle perpendicular to the view, clipped to the face window; a torus as the two curves where the tube turns edge-on, traced around the revolution. The silhouette now uses the camera's view *direction* alone, not the eye position — a single parallel direction for the whole scene — so the outline follows the view angle, holds still under pan, and doesn't foreshorten, which is the orthographic silhouette a CAD wireframe expects. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
ae5231427b
commit
8c72a06790
4 changed files with 458 additions and 128 deletions
|
|
@ -39,31 +39,59 @@ pub struct MeshModel {
|
|||
/// A curved face's generator, kept so a view-dependent silhouette (DISPSILH)
|
||||
/// can be computed per frame — the silhouette is where the surface turns away
|
||||
/// from the eye, which no baked edge can capture. World-space, post body
|
||||
/// transform; the base point carries a double-single low half so it stays
|
||||
/// precise at UTM scale like the mesh verts.
|
||||
/// transform; base/centre points carry a double-single low half so they stay
|
||||
/// precise at UTM scale like the mesh verts. Each variant also carries the
|
||||
/// face's parametric extent so the silhouette is clipped to the actual face
|
||||
/// rather than drawn across the whole (possibly partial) surface.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct CurvedGen {
|
||||
/// Base-circle centre (world), high half of the double-single.
|
||||
pub base: [f32; 3],
|
||||
/// Low residual paired with `base`.
|
||||
pub base_low: [f32; 3],
|
||||
/// Unit axis direction (world).
|
||||
pub axis: [f32; 3],
|
||||
/// Radial frame: `u` is the θ=0 direction, `v = axis × u`.
|
||||
pub u_dir: [f32; 3],
|
||||
pub v_dir: [f32; 3],
|
||||
/// Radius at the base (`h = 0`).
|
||||
pub radius: f32,
|
||||
/// `tan(half-angle)`: radius at height `h` is `radius + h * tan_a`
|
||||
/// (0 for a cylinder, non-zero for a cone).
|
||||
pub tan_a: f32,
|
||||
/// Height span along the axis the face covers.
|
||||
pub h_min: f32,
|
||||
pub h_max: f32,
|
||||
/// Angular span the face covers; `full` = a closed revolution.
|
||||
pub theta_min: f32,
|
||||
pub theta_span: f32,
|
||||
pub full: bool,
|
||||
pub enum CurvedGen {
|
||||
/// Cone / cylinder: two edge-on lines up the surface.
|
||||
Cone {
|
||||
base: [f32; 3],
|
||||
base_low: [f32; 3],
|
||||
axis: [f32; 3],
|
||||
/// Radial frame: `u` is the θ=0 direction, `v = axis × u`.
|
||||
u_dir: [f32; 3],
|
||||
v_dir: [f32; 3],
|
||||
/// Radius at the base (`h = 0`).
|
||||
radius: f32,
|
||||
/// `tan(half-angle)`: radius at height `h` is `radius + h * tan_a`.
|
||||
tan_a: f32,
|
||||
/// Height span along the axis the face covers (base is `h = 0`).
|
||||
h_max: f32,
|
||||
theta_min: f32,
|
||||
theta_span: f32,
|
||||
full: bool,
|
||||
},
|
||||
/// Sphere: the great circle perpendicular to the view, clipped to the
|
||||
/// face's longitude/colatitude window.
|
||||
Sphere {
|
||||
center: [f32; 3],
|
||||
center_low: [f32; 3],
|
||||
pole: [f32; 3],
|
||||
u_dir: [f32; 3],
|
||||
v_dir: [f32; 3],
|
||||
radius: f32,
|
||||
theta_min: f32,
|
||||
theta_span: f32,
|
||||
full: bool,
|
||||
phi_min: f32,
|
||||
phi_max: f32,
|
||||
},
|
||||
/// Torus: the two extreme circles of the tube (outer/inner), clipped to the
|
||||
/// revolution window the face covers.
|
||||
Torus {
|
||||
center: [f32; 3],
|
||||
center_low: [f32; 3],
|
||||
axis: [f32; 3],
|
||||
u_dir: [f32; 3],
|
||||
v_dir: [f32; 3],
|
||||
major: f32,
|
||||
minor: f32,
|
||||
phi_min: f32,
|
||||
phi_span: f32,
|
||||
full: bool,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
|
|
|||
Loading…
Reference in a new issue