I3sGeometryDecoder

Transcodes an I3S node's default (uncompressed) geometry buffer to a GltfModel so the existing 3D-Tiles mesh pipeline consumes it unchanged (the JIT "I3S→glTF" strategy CesiumJS uses).

The buffer is structure-of-arrays: integer header (vertexCount, featureCount), then each vertex attribute as one contiguous block in schema order, then per-feature blocks. Topology is PerAttributeArray (non-indexed → drawn via drawArrays); positions are node-local, placed by the tile's tileToWorld, so GltfPrimitiveInstance.worldMatrix is identity.

Draco compressedAttributes buffers (sniffed by magic) route through the registered GltfDecoderRegistry.dracoDecoder instead; global scenes' pre-scaled lon/lat offsets are restored via the i3s-scale_x/y metadata (I3sDracoMeta) before the same per-vertex placement.

Scope: Esri default schema (I3sGeometrySchema.DEFAULT) + Draco. TODO: KTX2/DDS/Basis textures (JPEG/PNG pass through as GltfImage); verify attribute order/types on more datasets.

Types

Link copied to clipboard
class I3sTexture(val bytes: ByteArray, val mimeType: String)

A texture resource fetched from the node's textures/… entry, paired with its MIME type.

Functions

Link copied to clipboard
fun decode(geometryBytes: ByteArray, texture: I3sGeometryDecoder.I3sTexture? = null, schema: I3sGeometrySchema = I3sGeometrySchema.DEFAULT, doubleSided: Boolean = false, positionScaleX: Double = 1.0, positionScaleY: Double = 1.0, emitNormals: Boolean = true, vertexMapper: I3sVertexMapper? = null): GltfModel

Decode a node's geometries/{n}.bin into a one-primitive model. texture is the node's base-color texture (a separate archive entry); doubleSided flips back-face culling.