Skip to main content
Version: v0.1.0

StreamedPointCloud

The primary component for rendering live point-cloud streams. Handles ingest, buffering, and rendering in one place.

import { StreamedPointCloud, type StreamedPointCloudRef } from "pointflow";

Quick example

const api = useRef<StreamedPointCloudRef>(null);

<StreamedPointCloud
maxPoints={200_000}
colorBy="velocity"
workerMode={true}
onReady={(ref) => { api.current = ref; }}
/>

// Push data:
api.current?.pushChunk({ points: [...] });
api.current?.pushBinary(xyzFloat32, attributes, count);

Props

Capacity

PropTypeDefaultDescription
maxPointsnumberHard ceiling on the number of retained points. Required unless you pass a config with a streamed or global default.
dynamicAlloc{ initialCapacity?: number; growthFactor?: number }undefinedStart small and grow toward maxPoints. See Dynamic allocation.

Rendering

PropTypeDefaultDescription
colorBystringundefinedAttribute key to map to a colour gradient.
rendererBackend"auto" | "webgpu" | "webgl""auto"Force a renderer or let PointFlow pick.
powerPreference"high-performance" | "low-power" | "default""high-performance"GPU power preference hint passed to the WebGPU adapter. "high-performance" asks the browser to prefer the discrete GPU on multi-GPU systems. "low-power" prefers the integrated GPU. "default" lets the browser decide. No-op on the WebGL path. The browser may ignore the hint — for a hard guarantee, use OS-level GPU assignment (Windows Graphics Settings or NVIDIA/AMD control panel).
frustumCullingbooleantrueDiscard points outside the camera frustum before upload.
autoLodbooleanfalseAutomatically pick LOD level by camera distance.
lodLevelnumber0Fixed LOD level when autoLod is false. 0 = full detail.
lodLevelsnumber3Total number of LOD levels.
visualRefreshRateHznumber60Target upload rate. Frames are skipped when the renderer is faster.
adaptiveRefreshbooleanfalseReduce upload rate when frame times are long.
backgroundstringundefinedCanvas background colour as a CSS hex string (e.g. "#0d1117").

Ingest

PropTypeDefaultDescription
workerModebooleanfalseRun chunk processing in a Web Worker.
adaptiveIngestbooleanfalseThin incoming chunks under high buffer pressure.

Importance and sampling

PropTypeDefaultDescription
importanceFieldstring | "auto"undefinedAttribute key for importance scoring. "auto" picks from the first chunk.
maxStalenessMsnumber0Recency half-life in milliseconds.
importanceSamplingEnabledbooleanfalseGPU stochastic sampling weighted by importance. WebGPU only.
fovStrengthnumber0Foveated boost for points near screen center. 0 = off, 3 = strong. WebGPU + importanceSampling only.
accumulationModebooleanfalseFull-detail rendering when camera is static. WebGPU only.
accumulationThresholdMsnumber200Ms camera must be static before accumulation activates.

Temporal window

PropTypeDefaultDescription
timeWindowMsnumber0Show only points from the last N milliseconds. 0 = all points.

Culling

PropTypeDefaultDescription
spatialCullingbooleantrueUniform-grid index for batch frustum tests. Active when frustum culling is on and LOD stride is 1.
workerCullingbooleanfalseFilter off-frustum points at ingest time. Permanent discard.

Policy

PropTypeDefaultDescription
runtimeMode"eco" | "balanced" | "max_throughput" | "custom""balanced"Operating mode. Drives point budget and update cadence.
tierTierLevelauto-detectedHardware capability tier.
constraintsUserConstraintsundefinedHard ceilings for policy decisions. Only applies in custom mode.
legacyModebooleanfalseDisable tier/mode/policy and use maxPoints directly.

Point picking

PropTypeDefaultDescription
onPointPick(pt: PickedPoint) => voidundefinedCalled on pointer down when a point is found within the radius.
pickRadiusnumber8Pick radius in CSS pixels.
pickStrategy"highestImportance" | "nearest" | "recentFirst""highestImportance"Which point wins when multiple qualify.

Camera

PropTypeDefaultDescription
cameraFit{ halfsize: number }undefinedAuto-fit the camera to the point cloud. halfsize is the scene half-extent in world units.

Lifecycle and telemetry

PropTypeDefaultDescription
onReady(api: StreamedPointCloudRef) => voidundefinedCalled once after the GPU pipeline is ready and the first frame has submitted.
onRendererResolved(backend: "webgpu" | "webgl") => voidundefinedCalled once with the resolved backend.
onStats(stats) => voidundefinedCalled each frame with buffer fill and backpressure stats.
onRenderMetrics(metrics) => voidundefinedCalled each frame with render timing metrics.
renderMetricsRefReact.MutableRefObject<...>undefinedRef written each frame without triggering React updates. Use with a polling timer.
onTemporalStats(stats) => voidundefinedCalled each frame when timeWindowMs > 0.
onAccumulationChange(active: boolean) => voidundefinedCalled when accumulation state changes.
onIngestTelemetry(event) => voidundefinedPer-chunk ingest lifecycle.
onRawIngest(xyz, attributes, count) => voidundefinedCalled immediately after each chunk ingests, on the main thread.
sourceNamestringundefinedHuman-readable label for this source, used in metrics output.
configPointFlowConfigundefinedShared config object from pointflow/config.

Ref methods (StreamedPointCloudRef)

MethodSignatureDescription
pushChunk(chunk: PointChunk) => voidIngest a JSON point chunk.
pushBinary(xyz: Float32Array, attributes: DenseAttributeChannel[], count: number) => voidIngest pre-packed SoA data. Zero allocation.
reset() => voidClear all points.
getOldestRetainedAgeMs() => numberAge of the oldest buffered point in milliseconds.

PointChunk shape

type PointChunk = {
points: Array<{
x: number;
y: number;
z: number;
attributes?: Record<string, number>;
}>;
};

PickedPoint shape

type PickedPoint = {
x: number;
y: number;
z: number;
attributes: Record<string, number>;
screenDist: number; // distance from click center in CSS px
slotIndex: number; // ring buffer slot
confidence: number; // 0-1
};