viewport-lib 0.19.0

3D viewport rendering library
Documentation
#![warn(missing_docs)]
//! `viewport-lib` : a 3D viewport library for `wgpu` applications.
//!
//! Built on `wgpu` and `glam`, with no required UI toolkit. The crate provides
//! the renderer, camera, picking, and interaction code; host applications keep
//! their own windowing and event loop.
//!
//! # Quick start (single viewport, pass-based)
//!
//! 1. Create a [`ViewportRenderer`] from a `wgpu::Device` and target format.
//! 2. Upload meshes or volumes through [`DeviceResources`].
//! 3. Build a [`FrameData`] each frame (camera via [`CameraFrame`] and
//!    [`RenderCamera`], scene content via [`SceneFrame`], viewport chrome via
//!    [`ViewportFrame`], etc.).
//! 4. Call [`PassPath::prepare`] then [`PassPath::paint`] via `renderer.pass()`.
//!
//! # Quick start (single viewport, owned-encoder)
//!
//! Use `renderer.owned().render(device, queue, &output_view, &frame)` when you
//! own the wgpu encoder (winit, raw wgpu). The call handles prepare and draw
//! internally and returns a [`wgpu::CommandBuffer`] to submit.
//!
//! # Rendering paths
//!
//! [`ViewportRenderer::pass`] returns a [`PassPath`] for framework callbacks
//! that hand you a render pass (eframe, iced). [`ViewportRenderer::owned`]
//! returns an [`OwnedPath`] for setups where you own the encoder (winit, raw wgpu).
//!
//! # Multi-viewport rendering
//!
//! To render the same scene from multiple independent cameras (e.g. a CAD
//! quad-view layout):
//!
//! ```rust,ignore
//! // --- Setup (once at startup) ---
//! let vp_persp = renderer.create_viewport(&device);   // ViewportId(0)
//! let vp_top   = renderer.create_viewport(&device);   // ViewportId(1)
//! let vp_front = renderer.create_viewport(&device);   // ViewportId(2)
//!
//! // --- Each frame ---
//! // 1. Build per-viewport FrameData (shared scene, independent cameras).
//! let frame_persp = FrameData {
//!     camera: CameraFrame::from_camera(&cam_persp, vp_size).with_viewport_index(vp_persp.0),
//!     scene: shared_scene.clone(),
//!     ..FrameData::default()
//! };
//! // ... similarly for vp_top, vp_front ...
//!
//! // 2. Prepare scene data once (lighting, shadows, batching).
//! let (scene_fx, _) = frame_persp.effects.split();
//! renderer.pass().prepare_scene(&device, &queue, &frame_persp, &scene_fx);
//!
//! // 3. Prepare per-viewport state (camera uniforms, clip planes, overlays).
//! renderer.pass().prepare_viewport(&device, &queue, vp_persp, &frame_persp);
//! renderer.pass().prepare_viewport(&device, &queue, vp_top,   &frame_top);
//! renderer.pass().prepare_viewport(&device, &queue, vp_front, &frame_front);
//!
//! // 4a. LDR path : single render pass with viewport/scissor rects.
//! let mut rp = encoder.begin_render_pass(...);
//! rp.set_viewport(0.0, 0.0, half_w, half_h, 0.0, 1.0);
//! renderer.pass().paint_viewport(&mut rp, vp_persp, &frame_persp);
//! rp.set_viewport(half_w, 0.0, half_w, half_h, 0.0, 1.0);
//! renderer.pass().paint_viewport(&mut rp, vp_top, &frame_top);
//! // ...
//!
//! // 4b. HDR path : one command buffer per viewport, each into its own texture.
//! let cmd0 = renderer.owned().render_viewport(&device, &queue, &view0, vp_persp, &frame_persp);
//! let cmd1 = renderer.owned().render_viewport(&device, &queue, &view1, vp_top,   &frame_top);
//! queue.submit([cmd0, cmd1]);
//! ```

/// Error types for the viewport library.
pub mod error;

/// Arcball camera, frustum, view presets, and animator.
pub mod camera;
/// BVH picking, marching cubes, isolines, and cap geometry.
pub mod geometry;
/// Gizmo, snap, selection, picking, and input.
pub mod interaction;
/// Plugin substrate: target descriptors, shared bind layouts, WGSL helpers,
/// pipeline builders. See [`plugin_api`] for the published extension surface.
pub mod plugin_api;
/// Built-in plugins: skinning, animation, constraints, physics, skeleton.
pub mod plugins;
/// On-surface vector quantities (intrinsic vectors, Whitney one-forms).
pub mod quantities;
/// Main viewport renderer wrapping all GPU resources.
pub mod renderer;
/// GPU resource container (pipelines, buffers, bind groups).
pub mod resources;
/// Scene runtime: per-frame orchestration, plugin system, and physics hooks.
pub mod runtime;
/// Scene graph, material, traits, and AABB.
pub mod scene;

// ---------------------------------------------------------------------------
// Module re-exports : preserve old `viewport_lib::foo::Bar` paths.
// ---------------------------------------------------------------------------

pub use geometry::bvh;
pub use geometry::primitives;
pub use interaction::input;
pub use interaction::manipulation;
pub use interaction::manipulation::clip_plane;
pub use interaction::manipulation::gizmo;
pub use interaction::query::picking;
pub use interaction::query::snap;
pub use interaction::select::selection;
pub use interaction::widgets::axes_indicator;
pub use scene::aabb;
pub use scene::material;
pub use scene::scatter_volume;
pub use scene::scatter_volume::{
    ColourSource, DensityRemap, Emission, EmissionCurve, NoiseDriver, RefractionParams,
    ScatterShape, ScatterVolume,
};
pub use scene::traits;

// ---------------------------------------------------------------------------
// Flat re-exports : these form the public crate API.
// ---------------------------------------------------------------------------

pub use error::{ViewportError, ViewportResult};

pub use camera::camera::{Camera, CameraTarget, Projection};
pub use camera::controllers::TurntableController;
pub use camera::controllers::{CameraAnimator, CameraDamping, Easing};
pub use camera::frustum::{CullStats, Frustum};
pub use camera::track::{CameraTrack, interpolate_camera};
pub use camera::view_preset::ViewPreset;

pub use scene::aabb::Aabb;
pub use scene::material::{
    BackfacePattern, BackfacePolicy, ItemSettings, Material, ParamVis, ParamVisMode, PatternConfig,
    ShadingModel,
};
pub use scene::scene::{
    DecalHandle, Group, GroupId, Layer, LayerId, LiveDecal, Scene, SceneNode, SceneStats,
};
pub use scene::traits::{RenderMode, ViewportObject};

pub use geometry::bvh::PickAccelerator;
pub use geometry::implicit::{
    ImplicitRenderOptions, march_implicit_surface, march_implicit_surface_colour,
};
pub use geometry::isoline::{IsolineItem, extract_isolines};
pub use geometry::marching_cubes::{VolumeData, extract_isosurface};

pub use interaction::input::{
    Action, ActionState, Binding, FrameInput, InputMode, InputSystem, KeyCode, Modifiers,
    MouseButton, NavigationMode,
};
pub use interaction::manipulation::gizmo::{
    Gizmo, GizmoAxis, GizmoMode, GizmoSpace, PivotMode, gizmo_center_for_pivot,
};
// New input pipeline : re-exported at crate root for convenience.
pub use camera::controllers::{
    FirstPersonCameraController, OrbitCameraController, ThirdPersonCameraController,
    wish_xy_from_actions,
};
pub use interaction::input::{
    ActionFrame, BindingPreset, ButtonState, ModifiersMatch, NavigationActions,
    ResolvedActionState, ScrollUnits, ViewportBinding, ViewportContext, ViewportEvent,
    ViewportGesture, ViewportInput, viewport_all_bindings,
};
pub use interaction::manipulation::solvers::{
    angular_rotation_from_cursor, constrained_scale, constrained_translation,
};
pub use interaction::manipulation::{
    GizmoInfo, ManipResult, ManipulationContext, ManipulationController, ManipulationKind,
    ManipulationState, TransformDelta,
};

pub use interaction::widgets::{
    BoxWidget, CylinderWidget, DiskWidget, LineProbeWidget, PlaneWidget, PolylineWidget,
    SphereWidget, SplineWidget, WidgetContext, WidgetResult,
};

pub use interaction::manipulation::clip_plane::{
    ClipAxis, ClipPlaneContext, ClipPlaneController, ClipPlaneDelta, ClipPlaneHit, ClipPlaneResult,
    ClipPlaneSessionKind, hit_test_normal_handle, hit_test_plane_quad, plane_from_axis_preset,
    project_drag_onto_normal, ray_plane_intersection, snap_plane_distance,
};
pub use interaction::query::picking::{
    GpuPickHit, PickHit, ProbeBinding, RectPickResult, nearest_vertex_on_hit,
    pick_gaussian_splat_cpu, pick_gaussian_splat_rect, pick_point_cloud_cpu,
    pick_scene_accelerated_with_probe_cpu, pick_scene_nodes_with_probe_cpu,
    pick_scene_with_probe_cpu, pick_transparent_volume_mesh_cpu, pick_transparent_volume_mesh_rect,
    pick_volume_cpu, pick_volume_rect, voxel_world_aabb,
};
pub use interaction::query::snap::{ConstraintOverlay, SnapConfig};
pub use interaction::select::pick_mask::PickMask;
pub use interaction::select::selection::{NodeId, Selection};
pub use interaction::select::sub_object;
pub use interaction::select::sub_object::{
    CellSelectionInfo, PolylineSelectionInfo, SubObjectRef, SubSelection, SubSelectionRef,
    VolumeSelectionInfo,
};

pub use interaction::widgets::axes_indicator::AxisView;

pub use renderer::ShadowDebugStats;
pub use renderer::shader_hashes::ShaderValidation;
pub use renderer::stats::{
    FrameStats, GpuBreakdown, PerformancePolicy, PrepareBreakdown, QualityPreset, RuntimeMode,
};
pub use renderer::{
    AnimTrack, AtlasViewerCorner, BorderMode, CameraFrame, ClipObject, ClipShape,
    ComputeFilterItem, ComputeFilterKind, CylindricalFacing, DebugOutputMode, DebugQuantity,
    DebugVis, DecalAnimation, DecalBlendMode, DecalItem, DecalProjection, EffectsFrame,
    EmitterConfig, EnvironmentMap, FilterMode, ForceField, FrameData, GaussianSplatData,
    GaussianSplatId, GaussianSplatItem, GlyphItem, GlyphSetRefItem, GlyphType,
    GpuParticleSystemItem, GradientStop, GroundPlane, GroundPlaneMode, ImageAnchor, ImageSliceItem,
    InteractionFrame, LabelAnchor, LabelItem, LerpAnim, LicOverlay, LightKind, LightSource,
    LightingSettings, LineCap, LineJoin, LoadingBarAnchor, LoadingBarItem, MeshInstanceItem,
    NineSlice, OVERLAY_MAX_GRADIENT_STOPS, OverlayAnimation, OverlayAnimations, OverlayEasing,
    OverlayFill, OverlayFrame, OverlayImageItem, OverlayPolylineItem, OverlayRectItem,
    OverlayShape, OverlayShapeItem, OverlayTextureId, OwnedPath, ParticleMeshAlign, PassPath,
    PassView, PathTrack, PickId, PickRectResult, PointCloudItem, PointCloudRefItem,
    PointRenderMode, PolylineItem, PolylineRefItem, PostProcessSettings, RenderCamera, RepeatMode,
    RibbonItem, RibbonRefItem, RulerItem, ScalarBarAnchor, ScalarBarItem, ScalarBarOrientation,
    ScatterQuality, ScatterSettings, ScatterVolumeItem, SceneEffects, SceneFrame, SceneRenderItem,
    ScreenImageItem, ShDegree, ShadowFilter, SliceAxis, SpawnShape, SpriteBlend,
    SpriteInstanceSetRefItem, SpriteItem, SpriteOrientation, SpriteSetRefItem, SpriteSizeMode,
    StreamtubeItem, StreamtubeRefItem, SurfaceLICConfig, SurfaceSubmission, TensorGlyphItem,
    TensorGlyphSetRefItem, TextureTransform, TileMode, ToneMapping, TriangleDirection, TubeItem,
    TubeRefItem, VelocityDist, ViewportEffects, ViewportFrame, ViewportId, ViewportRenderer,
    VolumeItem, VolumeMeshItem, VolumeSurfaceSliceItem, VolumeTransparency,
    aabb_wireframe_polyline, sphere_wireframe_polyline,
};

pub use quantities::{
    edge_one_form_to_glyphs, face_intrinsic_to_glyphs, polyline_edge_vectors_to_glyphs,
    polyline_node_vectors_to_glyphs, vertex_intrinsic_to_glyphs,
    volume_mesh_cell_vectors_to_glyphs, volume_mesh_vertex_vectors_to_glyphs,
};

#[allow(deprecated)]
pub use resources::ViewportGpuResources;
pub use resources::material::colourmap_data::{
    export_paraview_xml_colourmap, lerp_colourmap_lut, parse_paraview_xml_colourmap,
};
pub use resources::mesh::lod::{
    LodGroup, LodGroupId, LodLevel, LodTransition, projected_screen_size,
};
pub use resources::mesh::mesh_store::MeshId;
pub use resources::volume::sparse_volume::SparseVolumeGridData;
pub use resources::volume::tetmesh::{TetMesh, TetMeshAttributes};
pub use resources::volume::volume_mesh::{
    CELL_SENTINEL, ConversionReport, ToTetMeshError, VolumeMeshData, extract_clipped_volume_faces,
};
pub use resources::{
    AttributeData, AttributeKind, AttributeRef, BuiltinColourmap, BuiltinMatcap, CLIP_VOLUME_MAX,
    CameraUniform, ClipVolumeEntry, ClipVolumesUniform, ColourmapId, CompressedTextureDesc,
    ComputeFilterResult, DeviceResources, FontError, FontHandle, GpuImplicitItem,
    GpuImplicitOptions, GpuMarchingCubesJob, ImplicitBlendMode, ImplicitPrimitive, JobId,
    LightUniform, LightsUniform, MatcapId, McVolumeId, MeshData, ProgressHandle, ResidentBytes,
    SingleLightUniform, TextureId, TextureMemoryStats, UploadStatus, VolumeId, VramBudget,
    lerp_attributes, supports_texture_format, vram_budget,
};
pub use resources::{
    DEFORM_PARAMS_PER_SLOT_PUB as DEFORM_PARAMS_PER_SLOT,
    DEFORM_SLOT_COUNT_PUB as DEFORM_SLOT_COUNT, DEFORM_SLOT_PARAMS_BYTES, DeformSlotHandle,
    DeformStage, DeformerDesc, DeformerId, deform_slot_params_byte_offset,
};
pub use resources::{
    GlyphSetId, GpuParticleSystemConfig, GpuParticleSystemId, ParticleRender, PointCloudId,
    PolylineId, RibbonId, SpriteInstanceSetId, SpriteSetId, StreamtubeId, TensorGlyphSetId, TubeId,
};

pub use runtime::{
    CameraFollow, DebugDraw, DebugLayer, DebugPrim, FixedStepIter, FixedTimestep,
    ManipulationSystem, NodeTransformOp, RuntimeFrameContext, RuntimeOutput, RuntimePhase,
    RuntimePlugin, RuntimeStats, RuntimeStepContext, SceneRuntimeMode, SelectionOp,
    SelectionSystem, SimulationStepContext, TransformSnapshot, TransformSnapshotTable,
    TransformWriteback, ViewportRuntime,
};