Renderer · class

StreamingScene

Explained in Hello world.

class StreamingScene
import { StreamingScene } from '@driftengine/core';

Constructor

new

constructor(capacity: StreamCapacity)
ParameterTypeDescription
capacityStreamCapacity

Properties

NameTypeDescription
capacityreadonlyStreamCapacity
cullreadonlyFloat32ArrayEight floats a cluster: world centre, radius, cone axis, cutoff.
lodreadonlyFloat32ArraySix floats a cluster: world centre, radius, own error, parent error.
metareadonlyUint32ArrayFour words a cluster: index offset, index count, cluster id, mesh index.
materialOfreadonlyUint32Array
transformsreadonlyFloat32Array
instanceSpheresreadonlyFloat32Array

Accessors

NameTypeDescription
liveClustersgetnumberHow many clusters currently draw. A removed cluster's slot is still allocated until released.
freeVerticesgetnumberRoom left on each axis, which scripts/stream-fragmentation.mjs and its tests read.
highWatergetStreamCapacityThe worst each axis ever reached, which is the occupancy a fragmentation run reports.
heldBytesgetnumberThe geometry this scene holds on the CPU, in bytes: what is staged for a pass that has not attached, and the two scratch arrays an attached scene interleaves through. Nothing past that — which is the whole of what GeometrySink is for, as a number a test and a readout can read.

Methods

attach

attach(sink: GeometrySink): void

Give the scene the one place its geometry goes, and send it everything staged so far.

ParameterTypeDescription
sinkGeometrySink
More

Once, and a second time is refused by name. The scene keeps no copy of what it has sent, so a second pass would bind two empty buffers and draw nothing — silently, which is the one answer this cannot give. The dirty journal already made a scene one pass's: two passes would each take its spans and each miss the other's.

detach

detach(): void

The pass has gone. Adds and removes still keep the records, and the geometry goes nowhere.

More

Called by GpuDrivenPass.dispose before it destroys its buffers, because a write to a destroyed buffer is a device error; and nothing waits after it, because nothing reads.

add

add(mesh: GpuDrivenMesh, transform: ArrayLike<number>, material: number): StreamHandle | null

Place a mesh, or refuse.

ParameterTypeDescription
meshGpuDrivenMesh
transformArrayLike<number>
materialnumber
More

Every claim before any write, and a rollback if the last one fails. A partial add is a mesh whose clusters point at vertices another mesh owns, which draws somebody else's geometry rather than failing — the shape of mistake packClusters documents one level up.

null rather than an exception, because a streaming consumer calls this from a frame loop when the player walks: an exception there is a crashed demo where a refusal is a chunk that arrives a frame later.

remove

remove(handle: StreamHandle): void

Take a mesh out. Its ranges go back and its clusters stop drawing.

ParameterTypeDescription
handleStreamHandle

takeDirty

takeDirty(): StreamUpload

What changed since the last call, then cleared. An unchanged frame uploads nothing.

sceneBounds

sceneBounds(out: Float32Array): void

A bounding sphere over every live cluster: centre in floats 0 to 2, radius in float 3.

ParameterTypeDescription
outFloat32Array
More

sceneShadowBounds itself rather than a second spelling of it, and that is not tidiness — the first version of this method wrote a box into the same four floats the pass reads a sphere out of, so the shadow camera was fitted to a sphere centred on the box's minimum corner with maxX as its radius. Two GPU-driven rigs lost their shadows and the maintainer saw it on the page before the capture diff was read.

The function's own header already says why there is one copy of this arithmetic: a light's box that disagrees with the cull's bounds clips casters out of a map the cull believes are in it. A second copy here was the same mistake one level up.