pub struct LodSwitch {
pub boundaries: Vec<LodBoundary>,
pub scale: f32,
pub band: LodBand,
}Expand description
When a placement draws each level of its prototype’s levels of detail (core.lod_switch), on the placement (an
entity with core.instance). Distances are in the world’s units, from the camera to the placement’s world box,
scaled by LodSwitchView::factor. boundaries[k] is the boundary between levels k and k + 1, in order (a
border that is never reached, such as a source’s 9999 m, is stated as it is).
Elden Ring (eldenring.exe 1.17.3, read from the executable’s code, not checked against frames of the running game):
the game evaluates the hysteresis rule from the level remembered between frames, and it remembers only that level’s
low two bits, so a placement at level 4 or 5 is next evaluated from level 0 or 1; and from level 4 it compares the
first border unscaled. Both are the game’s quirks, observed by decompilation, and LodSwitch::next does not
reproduce them: it states the rule the game’s code applies at levels 0 to 3.
Fields§
§boundaries: Vec<LodBoundary>§scale: f32A factor on every border, positive (a source’s per-kind scale of its draw distances).
band: LodBandImplementations§
Source§impl LodSwitch
impl LodSwitch
Sourcepub fn level_at(&self, distance: f32) -> u8
pub fn level_at(&self, distance: f32) -> u8
The level at scaled distance distance with no level drawn before: the largest k whose boundary below it is
passed, at border * scale + play with LodBand::CrossFade and at border * scale with
LodBand::Hysteresis (the plain boundaries: a view with no history takes no side of a band).
Sourcepub fn next(&self, current: u8, distance: f32) -> u8
pub fn next(&self, current: u8, distance: f32) -> u8
The level after one evaluation at distance from level current drawn before: with LodBand::Hysteresis the
boundary just above current is passed at border * scale + play, the one just below at border * scale - play, every other at border * scale; with LodBand::CrossFade, LodSwitch::level_at.
Sourcepub fn in_band(&self, distance: f32) -> bool
pub fn in_band(&self, distance: f32) -> bool
With LodBand::Hysteresis, whether the level at distance depends on the level drawn before: distance lies
within play of a scaled border, where LodSwitch::next can give either side. Never with
LodBand::CrossFade.
Sourcepub fn fade(&self, distance: f32) -> f32
pub fn fade(&self, distance: f32) -> f32
With LodBand::CrossFade, how far the level drawn at distance has faded into the next: (distance - border * scale) / play within the band past its boundary above, 0 elsewhere.
Trait Implementations§
Source§impl Component for LodSwitch
impl Component for LodSwitch
Source§fn apply_linear(&self, _l: &Linear) -> Linearity<Self>
fn apply_linear(&self, _l: &Linear) -> Linearity<Self>
World distances of the placement, not local-space geometry.
Source§fn verify(&self, e: Entity, w: &World) -> Result<(), String>
fn verify(&self, e: Entity, w: &World) -> Result<(), String>
On a placement; at least one boundary, at most 254; scale finite and positive; every border finite and not
negative, not below the one before it; every play finite and not negative.
const NAME: &'static str = "core.lod_switch"
Source§const GEOMETRY: Geometry = crate::Geometry::None
const GEOMETRY: Geometry = crate::Geometry::None
Geometry). Stated by every component,
with no default, so data that describes a mesh can’t be left behind by an edit of it unawares: the World’s edit
paths take it from there.Source§fn to_json(&self) -> Result<Option<Value>, JsonError>
fn to_json(&self) -> Result<Option<Value>, JsonError>
Ok(None) for components
that are not shown (bulk data, handles). The view must never lose a value: components that can be shown
derive serde::Serialize and return crate::json::to_value(self).map(Some), which refuses non-finite
floats instead of writing them as null.Source§const VERSION: u32 = 1
const VERSION: u32 = 1
Source§fn references(&self, _out: &mut Vec<Entity>)
fn references(&self, _out: &mut Vec<Entity>)
out: the edges
World::closure follows. A component holding entity references must declare every one of them.Source§fn payload_bytes(&self) -> u64
fn payload_bytes(&self) -> u64
Source§fn remap_primitives(&self, _from: &[usize]) -> Option<Result<Self, String>>
fn remap_primitives(&self, _from: &[usize]) -> Option<Result<Self, String>>
Geometry::PerPrimitive, Geometry::PerVertex): new primitive i comes from old primitive
from[i] (a source may repeat, when a primitive is split, or be absent, when one is dropped). Such a component
always answers (a value holding nothing per primitive answers with itself); None, the default, is for
components of Geometry::None, and World::remap_primitives refuses a dependent component that gives it.
An index the component does not have is an error. remap_list does the work for a list with one entry per
primitive.Source§fn remap_vertices(
&self,
_primitive: usize,
_from: &[u32],
) -> Option<Result<Self, String>>
fn remap_vertices( &self, _primitive: usize, _from: &[u32], ) -> Option<Result<Self, String>>
primitive were compacted or reordered, for a
component that holds something per vertex (Geometry::PerVertex): new vertex i of that primitive is old
vertex from[i] (a source may repeat or be absent). Such a component always answers (with itself when it holds
nothing for that primitive); None, the default, is for the others, and World::remap_vertices refuses a
per-vertex component that gives it. An index the component does not have is an error. Every pass that compacts
or reorders a primitive’s vertices calls World::remap_vertices. After a rebuild of the primitive list
(World::rebuild_primitives, Component::remap_primitives) a primitive’s per-vertex data is its source
primitive’s, and the vertex map is relative to that source.Source§fn blend_vertices(
&self,
_primitive: usize,
_from: &[VertexBlend],
) -> Option<Result<Self, String>>
fn blend_vertices( &self, _primitive: usize, _from: &[VertexBlend], ) -> Option<Result<Self, String>>
primitive were rebuilt as blends of old ones
(VertexBlend), for a component that holds something per vertex (Geometry::PerVertex): new vertex i
is the combination from[i] of old vertices, in whatever way the component’s data combines (a morph target’s
delta is interpolated, the way the surface it moves is). It answers as Component::remap_vertices does: with
itself when it holds nothing for that primitive; None, the default, is for a component that does not know how
to combine its data, and World::blend_vertices refuses a per-vertex component that gives it. An index the
component does not have is an error. A vertex that is a copy of one old vertex (VertexBlend::copy) is the
case Component::remap_vertices states, and a component answering one answers the other alike.Source§fn restate(&self, _resolved: &Resolved<'_>) -> Restated<Self>
fn restate(&self, _resolved: &Resolved<'_>) -> Restated<Self>
resolve-state (crate::state::ResolveState) gave the axes in resolved their values: a
component that holds crate::state::Clauses of its own (a record of parts each present in some states) reduces
them as core.condition is reduced (crate::state::Resolved::reduce: a clause that fails is dropped, a clause
left with no literal holds whatever the other axes are). Restated::Absent says the entity is not present in
this state (every clause failed): it is despawned as one whose core.condition fails is. The default holds no
clause: Restated::Unchanged.