Skip to main content

ViewportRuntime

Struct ViewportRuntime 

Source
pub struct ViewportRuntime { /* private fields */ }
Expand description

Per-frame scene orchestration layer.

Owns plugins, an optional fixed timestep accumulator, and a transform snapshot table. Does not own the scene, selection, GPU resources, or window.

§Priority execution order

Each call to step executes plugins in ascending priority order:

  1. [i32::MIN, SELECT) – Prepare (100), Pick (200): once, at wall dt
  2. [SELECT, MANIPULATE) – Select (300): once (built-in SelectionSystem runs first)
  3. [MANIPULATE, SIMULATE) – Manipulate (400), Animate (500): once
  4. [SIMULATE, POST_SIM) – Simulate (600): once per fixed step or once at wall dt
  5. [POST_SIM, i32::MAX] – PostSim (700), Writeback (800): once at wall dt

Implementations§

Source§

impl ViewportRuntime

Source

pub fn new() -> Self

Create a runtime with default settings and no plugins.

Source

pub fn last_stats(&self) -> &RuntimeStats

Per-plugin timing from the most recent step / pre_prepare / post_paint. Lets a host or benchmark attribute frame time to a named plugin without linking it: any registered plugin is keyed by its RuntimePlugin::type_name / GpuPlugin::type_name.

Source

pub fn with_selection_system(self) -> Self

Enable the built-in click-to-select system.

The SelectionSystem runs before the Select phase each frame. It reads RuntimeFrameContext::clicked, pick_hit, and shift_held to produce SelectionOp entries in RuntimeOutput.

Source

pub fn with_manipulation_system(self) -> Self

Enable the built-in manipulation system.

The ManipulationSystem runs before the Manipulate phase each frame. It drives G/R/S sessions and gizmo drag from RuntimeFrameContext inputs, writing transform changes via TransformWriteback.

Source

pub fn is_manipulating(&self) -> bool

True while the built-in manipulation system has an active G/R/S session or gizmo drag.

Use this to suppress orbit camera movement while manipulating objects.

Source

pub fn manipulation_system(&self) -> Option<&ManipulationSystem>

Access the built-in manipulation system, if enabled.

Source

pub fn with_mode(self, mode: SceneRuntimeMode) -> Self

Set the runtime mode.

Source

pub fn with_plugin(self, plugin: impl RuntimePlugin) -> Self

Register a plugin. Plugins run in ascending priority order each frame. Plugins with equal priority run in registration order (stable sort).

Source

pub fn add_plugin(&mut self, plugin: impl RuntimePlugin)

Register a plugin on an existing runtime.

Same semantics as with_plugin but takes &mut self, for hosts that need to add plugins after the runtime has been constructed and possibly already run frames.

Source

pub fn with_gpu_plugin(self, plugin: impl GpuPlugin) -> Self

Register a GPU plugin. GPU plugins encode wgpu command buffers from ViewportRuntime::pre_prepare, which the host calls each frame after step and before renderer.prepare(). Plugins run in ascending priority order; equal priorities preserve registration order.

Registering a plugin after the runtime has already run a frame re-runs every GPU plugin’s init_gpu on the next pre_prepare. Implementations should be idempotent or guard their own one-time setup.

Source

pub fn add_gpu_plugin(&mut self, plugin: impl GpuPlugin)

Register a GPU plugin on an existing runtime.

Same semantics as with_gpu_plugin but takes &mut self.

Source

pub fn with_gpu_plugin_for_viewport( self, viewport: ViewportId, plugin: impl GpuPlugin, ) -> Self

Register a GPU plugin scoped to a single viewport.

The plugin’s pre_prepare and post_paint only execute when the host’s GpuFrameContext::viewport_id equals viewport. init_gpu and on_device_recreated still run unconditionally.

Use this in multi-viewport hosts (CAD quad-view, split-screen) that call pre_prepare / post_paint once per viewport with a populated viewport_id. Single-viewport hosts that never set viewport_id effectively disable scoped plugins; use with_gpu_plugin instead.

Source

pub fn notify_device_recreated(&mut self, device: &Device, queue: &Queue)

Notify every registered GPU plugin that the wgpu device has been recreated (device loss, surface re-init, host-driven reset).

Calls GpuPlugin::on_device_recreated on each plugin, then clears the init flag so init_gpu runs again with the new device on the next pre_prepare. The runtime does not detect device loss on its own; the host is responsible for invoking this when it recreates the device.

Source

pub fn pre_prepare( &mut self, device: &Device, queue: &Queue, ctx: &GpuFrameContext<'_>, ) -> Vec<CommandBuffer>

Run every registered GPU plugin’s pre_prepare in ascending priority order and return the concatenated command buffers.

Call after step and before renderer.prepare(). The returned buffers should be submitted ahead of the renderer’s own:

let plugin_bufs  = runtime.pre_prepare(device, queue, &gpu_ctx);
let prepare_bufs = renderer.pass().prepare(device, queue, &frame);
queue.submit(plugin_bufs.into_iter().chain(prepare_bufs));

wgpu submit ordering guarantees plugin work completes before prepare()’s, so any storage buffer written by a plugin is observable by the standard render passes in the same frame.

On the first call (or after a new plugin is registered), every plugin’s init_gpu is invoked once before any pre_prepare.

Source

pub fn post_paint( &mut self, device: &Device, queue: &Queue, targets: &PostPaintTargets<'_>, ctx: &GpuFrameContext<'_>, ) -> Vec<CommandBuffer>

Run every registered GPU plugin’s post_paint in ascending priority order and return the concatenated command buffers.

Call after renderer.paint_to() has run for the frame. The host supplies views of the just-rendered color and depth targets (and optionally a pick-id view), and is responsible for compositing any plugin overlay output into the final image: the lib does not loop plugin output back into the rendered color.

Plugins registered after the first frame still go through init_gpu on the next pre_prepare; this method does not trigger init on its own to keep the post-paint path deterministic.

Source

pub fn with_fixed_timestep(self, ts: FixedTimestep) -> Self

Enable fixed-timestep accumulation for physics plugins.

When set, plugins in the [SIMULATE, POST_SIM) range run once per accumulated fixed step rather than once per frame at wall dt. All other priority ranges always run once per frame.

Source

pub fn set_fixed_timestep(&mut self, ts: FixedTimestep)

Replace the fixed timestep at runtime. Resets the accumulator.

Use this to change the simulation rate after construction without rebuilding the runtime or its plugins.

Source

pub fn clear_fixed_timestep(&mut self)

Remove the fixed timestep, reverting to one simulate call per frame at wall dt.

Source

pub fn mode(&self) -> SceneRuntimeMode

The current runtime mode.

Source

pub fn snapshots(&self) -> &TransformSnapshotTable

The transform snapshot table for interpolated rendering.

Updated each frame during writeback. Pass alpha as the blend factor to TransformSnapshotTable::interpolated.

Source

pub fn resources(&self) -> &RuntimeResources

Read access to the shared resource registry.

Use this after step to inspect resources without running the frame loop. During the frame loop, access resources through RuntimeStepContext::resources.

Source

pub fn resources_mut(&mut self) -> &mut RuntimeResources

Write access to the shared resource registry.

Use this to pre-populate resources before the first step, or to inject resources from outside the plugin system (e.g. from the application).

Source

pub fn alpha(&self) -> f32

Blend factor for rendering interpolation between fixed steps.

Returns 1.0 if no fixed timestep is configured (render directly from current scene transforms without interpolation).

Source

pub fn step_index(&self) -> u64

Monotonically increasing simulation step counter.

Incremented once per simulate execution. With a fixed timestep this means it may increment multiple times per rendered frame. Wraps on overflow.

Source

pub fn with_camera_follow(self, follow: CameraFollow) -> Self

Set a camera follow binding (builder style).

Each call to step will compute a suggested camera center from the followed node and emit it as a CameraFollowTarget event on RuntimeOutput::events.

Source

pub fn set_camera_follow(&mut self, follow: CameraFollow)

Update the camera follow binding at runtime.

Source

pub fn clear_camera_follow(&mut self)

Remove the camera follow binding. No CameraFollowTarget event will be emitted after this call.

Source

pub fn camera_follow(&self) -> Option<&CameraFollow>

The current camera follow binding.

Source

pub fn step( &mut self, scene: &mut Scene, selection: &mut Selection, frame: &RuntimeFrameContext, ) -> RuntimeOutput

Run one frame of the runtime.

Plugins run in ascending priority order. The simulate range [SIMULATE, POST_SIM) runs once per accumulated fixed step (or once at frame.dt when no fixed timestep is configured). All other ranges run once per frame. Transform ops are flushed to scene and the snapshot table is updated after the writeback range.

Selection ops produced by plugins are applied to selection before returning. Contact events and the applied transform ops are returned in RuntimeOutput.

Trait Implementations§

Source§

impl Default for ViewportRuntime

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Converts Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Converts Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Converts &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Converts &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> Downcast<T> for T

Source§

fn downcast(&self) -> &T

Source§

impl<T> DowncastSend for T
where T: Any + Send,

Source§

fn into_any_send(self: Box<T>) -> Box<dyn Any + Send>

Converts Box<Trait> (where Trait: DowncastSend) to Box<dyn Any + Send>, which can then be downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<SS, SP> SupersetOf<SS> for SP
where SS: SubsetOf<SP>,

Source§

fn to_subset(&self) -> Option<SS>

The inverse inclusion map: attempts to construct self from the equivalent element of its superset. Read more
Source§

fn is_in_subset(&self) -> bool

Checks if self is actually part of its subset T (and can be converted to it).
Source§

fn to_subset_unchecked(&self) -> SS

Use with care! Same as self.to_subset but without any property checks. Always succeeds.
Source§

fn from_subset(element: &SS) -> SP

The inclusion map: converts self to the equivalent element of its superset.
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> Upcast<T> for T

Source§

fn upcast(&self) -> Option<&T>

Source§

impl<T> WasmNotSend for T
where T: Send,

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more