Skip to main content

viewport_lib/
lib.rs

1#![warn(missing_docs)]
2//! `viewport-lib` : a 3D viewport library for `wgpu` applications.
3//!
4//! Built on `wgpu` and `glam`, with no required UI toolkit. The crate provides
5//! the renderer, camera, picking, and interaction code; host applications keep
6//! their own windowing and event loop.
7//!
8//! # Quick start (single viewport, pass-based)
9//!
10//! 1. Create a [`ViewportRenderer`] from a `wgpu::Device` and target format.
11//! 2. Upload meshes or volumes through [`ViewportGpuResources`].
12//! 3. Build a [`FrameData`] each frame (camera via [`CameraFrame`] and
13//!    [`RenderCamera`], scene content via [`SceneFrame`], viewport chrome via
14//!    [`ViewportFrame`], etc.).
15//! 4. Call [`PassPath::prepare`] then [`PassPath::paint`] via `renderer.pass()`.
16//!
17//! # Quick start (single viewport, owned-encoder)
18//!
19//! Use `renderer.owned().render(device, queue, &output_view, &frame)` when you
20//! own the wgpu encoder (winit, raw wgpu). The call handles prepare and draw
21//! internally and returns a [`wgpu::CommandBuffer`] to submit.
22//!
23//! # Rendering paths
24//!
25//! [`ViewportRenderer::pass`] returns a [`PassPath`] for framework callbacks
26//! that hand you a render pass (eframe, iced). [`ViewportRenderer::owned`]
27//! returns an [`OwnedPath`] for setups where you own the encoder (winit, raw wgpu).
28//!
29//! # Multi-viewport rendering
30//!
31//! To render the same scene from multiple independent cameras (e.g. a CAD
32//! quad-view layout):
33//!
34//! ```rust,ignore
35//! // --- Setup (once at startup) ---
36//! let vp_persp = renderer.create_viewport(&device);   // ViewportId(0)
37//! let vp_top   = renderer.create_viewport(&device);   // ViewportId(1)
38//! let vp_front = renderer.create_viewport(&device);   // ViewportId(2)
39//!
40//! // --- Each frame ---
41//! // 1. Build per-viewport FrameData (shared scene, independent cameras).
42//! let frame_persp = FrameData {
43//!     camera: CameraFrame::from_camera(&cam_persp, vp_size).with_viewport_index(vp_persp.0),
44//!     scene: shared_scene.clone(),
45//!     ..FrameData::default()
46//! };
47//! // ... similarly for vp_top, vp_front ...
48//!
49//! // 2. Prepare scene data once (lighting, shadows, batching).
50//! let (scene_fx, _) = frame_persp.effects.split();
51//! renderer.pass().prepare_scene(&device, &queue, &frame_persp, &scene_fx);
52//!
53//! // 3. Prepare per-viewport state (camera uniforms, clip planes, overlays).
54//! renderer.pass().prepare_viewport(&device, &queue, vp_persp, &frame_persp);
55//! renderer.pass().prepare_viewport(&device, &queue, vp_top,   &frame_top);
56//! renderer.pass().prepare_viewport(&device, &queue, vp_front, &frame_front);
57//!
58//! // 4a. LDR path : single render pass with viewport/scissor rects.
59//! let mut rp = encoder.begin_render_pass(...);
60//! rp.set_viewport(0.0, 0.0, half_w, half_h, 0.0, 1.0);
61//! renderer.pass().paint_viewport(&mut rp, vp_persp, &frame_persp);
62//! rp.set_viewport(half_w, 0.0, half_w, half_h, 0.0, 1.0);
63//! renderer.pass().paint_viewport(&mut rp, vp_top, &frame_top);
64//! // ...
65//!
66//! // 4b. HDR path : one command buffer per viewport, each into its own texture.
67//! let cmd0 = renderer.owned().render_viewport(&device, &queue, &view0, vp_persp, &frame_persp);
68//! let cmd1 = renderer.owned().render_viewport(&device, &queue, &view1, vp_top,   &frame_top);
69//! queue.submit([cmd0, cmd1]);
70//! ```
71
72/// Error types for the viewport library.
73pub mod error;
74
75/// Arcball camera, frustum, view presets, and animator.
76pub mod camera;
77/// BVH picking, marching cubes, isolines, and cap geometry.
78pub mod geometry;
79/// Gizmo, snap, selection, picking, and input.
80pub mod interaction;
81/// Plugin substrate: target descriptors, shared bind layouts, WGSL helpers,
82/// pipeline builders. See [`plugin_api`] for the published extension surface.
83pub mod plugin_api;
84/// On-surface vector quantities (intrinsic vectors, Whitney one-forms).
85pub mod quantities;
86/// Main viewport renderer wrapping all GPU resources.
87pub mod renderer;
88/// GPU resource container (pipelines, buffers, bind groups).
89pub mod resources;
90/// Scene runtime: per-frame orchestration, plugin system, and physics hooks.
91pub mod runtime;
92/// Scene graph, material, traits, and AABB.
93pub mod scene;
94/// Axes orientation indicator.
95pub mod widgets;
96
97// ---------------------------------------------------------------------------
98// Module re-exports : preserve old `viewport_lib::foo::Bar` paths.
99// ---------------------------------------------------------------------------
100
101pub use geometry::bvh;
102pub use geometry::primitives;
103pub use interaction::clip_plane;
104pub use interaction::gizmo;
105pub use interaction::input;
106pub use interaction::manipulation;
107pub use interaction::picking;
108pub use interaction::selection;
109pub use interaction::snap;
110pub use scene::aabb;
111pub use scene::material;
112pub use scene::scatter_volume;
113pub use scene::scatter_volume::{
114    ColourSource, DensityRemap, Emission, EmissionCurve, NoiseDriver, RefractionParams,
115    ScatterShape, ScatterVolume,
116};
117pub use scene::traits;
118pub use widgets::axes_indicator;
119
120// ---------------------------------------------------------------------------
121// Flat re-exports : these form the public crate API.
122// ---------------------------------------------------------------------------
123
124pub use error::{ViewportError, ViewportResult};
125
126pub use camera::animator::{CameraAnimator, CameraDamping, Easing};
127pub use camera::camera::{Camera, CameraTarget, Projection};
128pub use camera::frustum::{CullStats, Frustum};
129pub use camera::track::{CameraTrack, interpolate_camera};
130pub use camera::turntable::TurntableController;
131pub use camera::view_preset::ViewPreset;
132
133pub use scene::aabb::Aabb;
134pub use scene::material::{
135    BackfacePattern, BackfacePolicy, ItemSettings, Material, ParamVis, ParamVisMode, PatternConfig,
136    ShadingModel,
137};
138pub use scene::scene::{
139    DecalHandle, Group, GroupId, Layer, LayerId, LiveDecal, Scene, SceneNode, SceneStats,
140};
141pub use scene::traits::{RenderMode, ViewportObject};
142
143pub use geometry::bvh::PickAccelerator;
144pub use geometry::implicit::{
145    ImplicitRenderOptions, march_implicit_surface, march_implicit_surface_colour,
146};
147pub use geometry::isoline::{IsolineItem, extract_isolines};
148pub use geometry::marching_cubes::{VolumeData, extract_isosurface};
149
150pub use interaction::gizmo::{
151    Gizmo, GizmoAxis, GizmoMode, GizmoSpace, PivotMode, gizmo_center_for_pivot,
152};
153pub use interaction::input::{
154    Action, ActionState, Binding, FrameInput, InputMode, InputSystem, KeyCode, Modifiers,
155    MouseButton, NavigationMode,
156};
157// New input pipeline : re-exported at crate root for convenience.
158pub use interaction::input::{
159    ActionFrame, BindingPreset, ButtonState, ModifiersMatch, NavigationActions,
160    OrbitCameraController, ResolvedActionState, ScrollUnits, ViewportBinding, ViewportContext,
161    ViewportEvent, ViewportGesture, ViewportInput, viewport_all_bindings,
162};
163pub use interaction::manipulation::solvers::{
164    angular_rotation_from_cursor, constrained_scale, constrained_translation,
165};
166pub use interaction::manipulation::{
167    GizmoInfo, ManipResult, ManipulationContext, ManipulationController, ManipulationKind,
168    ManipulationState, TransformDelta,
169};
170
171pub use interaction::widgets::{
172    BoxWidget, CylinderWidget, DiskWidget, LineProbeWidget, PlaneWidget, PolylineWidget,
173    SphereWidget, SplineWidget, WidgetContext, WidgetResult,
174};
175
176pub use interaction::clip_plane::{
177    ClipAxis, ClipPlaneContext, ClipPlaneController, ClipPlaneDelta, ClipPlaneHit, ClipPlaneResult,
178    ClipPlaneSessionKind, hit_test_normal_handle, hit_test_plane_quad, plane_from_axis_preset,
179    project_drag_onto_normal, ray_plane_intersection, snap_plane_distance,
180};
181pub use interaction::pick_mask::PickMask;
182pub use interaction::picking::{
183    GpuPickHit, PickHit, ProbeBinding, RectPickResult, nearest_vertex_on_hit,
184    pick_gaussian_splat_cpu, pick_gaussian_splat_rect, pick_point_cloud_cpu, pick_rect,
185    pick_scene_accelerated_with_probe_cpu, pick_scene_nodes_with_probe_cpu,
186    pick_scene_with_probe_cpu, pick_transparent_volume_mesh_cpu, pick_transparent_volume_mesh_rect,
187    pick_volume_cpu, pick_volume_rect, voxel_world_aabb,
188};
189pub use interaction::selection::{NodeId, Selection};
190pub use interaction::snap::{ConstraintOverlay, SnapConfig};
191pub use interaction::sub_object;
192pub use interaction::sub_object::{
193    CellSelectionInfo, PolylineSelectionInfo, SubObjectRef, SubSelection, SubSelectionRef,
194    VolumeSelectionInfo,
195};
196
197pub use widgets::axes_indicator::AxisView;
198
199pub use renderer::ShadowDebugStats;
200pub use renderer::shader_hashes::ShaderValidation;
201pub use renderer::stats::{FrameStats, PerformancePolicy, QualityPreset, RuntimeMode};
202pub use renderer::{
203    AtlasViewerCorner, BorderMode, CameraFrame, ClipObject, ClipShape, ComputeFilterItem,
204    ComputeFilterKind, CylindricalFacing, DebugOutputMode, DebugQuantity, DebugVis, DecalAnimation,
205    DecalBlendMode, DecalItem, DecalProjection, EffectsFrame, EnvironmentMap, FilterMode,
206    FrameData, GaussianSplatData, GaussianSplatId, GaussianSplatItem, GlyphItem, GlyphSetRefItem,
207    GlyphType,
208    GroundPlane, GroundPlaneMode, ImageAnchor, ImageSliceItem, InteractionFrame, LabelAnchor,
209    LabelItem, LicOverlay, LightKind, LightSource, LightingSettings, LineCap, LoadingBarAnchor,
210    LoadingBarItem, MeshInstanceItem, OverlayAnimation, OverlayFill, OverlayFrame, OverlayImageItem, OverlayRectItem,
211    OverlayShape, OverlayShapeItem, OverlayTextureId, OwnedPath, PassPath, PassView, PickId,
212    PickRectResult, PointCloudItem, PointCloudRefItem, PointRenderMode, PolylineItem,
213    PolylineRefItem, PostProcessSettings,
214    RenderCamera, RibbonItem, RibbonRefItem, RulerItem, ScalarBarAnchor, ScalarBarItem,
215    ScalarBarOrientation,
216    ScatterQuality, ScatterSettings, ScatterVolumeItem, SceneEffects, SceneFrame, SceneRenderItem,
217    ScreenImageItem, ShDegree, ShadowFilter, SliceAxis, SpriteBlend, SpriteInstanceSetRefItem,
218    SpriteItem, SpriteSetRefItem, SpriteSizeMode,
219    StreamtubeItem, StreamtubeRefItem, SurfaceLICConfig, SurfaceSubmission, TensorGlyphItem,
220    TensorGlyphSetRefItem, ToneMapping, TransparentVolumeMeshItem, TriangleDirection, TubeItem,
221    TubeRefItem,
222    ViewportEffects, ViewportFrame,
223    ViewportId, ViewportRenderer, VolumeItem, VolumeMeshItem, VolumeSurfaceSliceItem,
224    aabb_wireframe_polyline, sphere_wireframe_polyline,
225};
226
227pub use quantities::{
228    edge_one_form_to_glyphs, face_intrinsic_to_glyphs, polyline_edge_vectors_to_glyphs,
229    polyline_node_vectors_to_glyphs, vertex_intrinsic_to_glyphs,
230    volume_mesh_cell_vectors_to_glyphs, volume_mesh_vertex_vectors_to_glyphs,
231};
232
233pub use resources::colourmap_data::{
234    export_paraview_xml_colourmap, lerp_colourmap_lut, parse_paraview_xml_colourmap,
235};
236pub use resources::mesh_store::MeshId;
237pub use resources::{
238    GlyphSetId, PointCloudId, PolylineId, RibbonId, SpriteInstanceSetId, SpriteSetId, StreamtubeId,
239    TensorGlyphSetId, TubeId,
240};
241pub use resources::sparse_volume::SparseVolumeGridData;
242pub use resources::volume_mesh::{CELL_SENTINEL, VolumeMeshData, extract_clipped_volume_faces};
243pub use resources::{
244    AttributeData, AttributeKind, AttributeRef, BuiltinColourmap, BuiltinMatcap, CLIP_VOLUME_MAX,
245    CameraUniform, ClipVolumeEntry, ClipVolumesUniform, ColourmapId, ComputeFilterResult,
246    FontError, FontHandle, GpuImplicitItem, GpuImplicitOptions, GpuMarchingCubesJob,
247    ImplicitBlendMode, ImplicitPrimitive, JobId, LightUniform, LightsUniform, MatcapId, MeshData,
248    ProgressHandle, ProjectedTetId, SingleLightUniform, SkinWeights, TextureMemoryStats,
249    UploadStatus, ViewportGpuResources, VolumeGpuId, VolumeId, lerp_attributes,
250};
251
252pub use runtime::{
253    AnimationClip, AnimationPlugin, AnimationTrack, CameraFollow, Channel, ClipPlayerPlugin,
254    Constraint, ConstraintPlugin, ContactEvent, DebugDraw, DebugLayer, DebugPrim, FixedStepIter,
255    FixedTimestep, Interpolation, Joint, JointMatrices, Keyframe, ManipulationSystem,
256    NodeTransformOp, PhysicsBody, PhysicsLitePlugin, Pose, RuntimeFrameContext, RuntimeOutput,
257    RuntimePhase, RuntimePlugin, RuntimeStepContext, Sampler, SceneRuntimeMode, SelectionOp,
258    SelectionSystem, SimulationStepContext, Skeleton, SkeletonPlugin, SkinnedActor,
259    SkinnedActorPart, SkinnedActorPlugin, SkinnedMeshUpdate, SkinnedPoseUpdate, SkinningPath,
260    Track, TrackValue, TrackValues, TransformSnapshot, TransformSnapshotTable, TransformWriteback,
261    ViewportRuntime, apply_skin,
262};