# `ExCodecs.Spatial.Accel`
[🔗](https://github.com/AnimaLogica/codecs/blob/v0.2.4/lib/ex_codecs/spatial/accel.ex#L1)

Elixir facade over the spatial Rust NIFs (EXCP, GSPL, binary PLY).

Callers fall back to pure Elixir when `available?/0` is false or a call
returns `:nif_not_loaded`. This module defines the **cross-language ABI**:
row tuple shapes must match `native/ex_codecs_native/src/spatial.rs`.

## Chunk semantics

Unpack NIFs return `{:ok, {rows, next_offset}}`. Pass at most `chunk_size/0`
(4096) rows per call and advance `offset` from `next_offset`. Whole-payload
decode paths loop the same way. A partial final record is silently skipped
(the unpack `break`s); callers can detect truncation by comparing
`next_offset` to the expected body size.

## Data coercion

Out-of-range color bytes are **clamped** to `[0, 255]` (not wrapped). Missing
SH coefficients are zero-filled to the declared `sh_rest` length. Both
coercions are lossy: a round-trip through encode may not reproduce the
original if the input contained out-of-range values.

## Row formats

  * EXCP point row: `{x, y, z, color, normal}` where `color` / `normal` are
    `nil` or tuples matching header flags
  * GSPL gaussian row:
    `{{x, y, z}, {r, g, b}, opacity, {sx, sy, sz}, {rw, rx, ry, rz}, sh_list}`
  * PLY binary: flat numeric lists per vertex, typed by `ply_type_tag/1`

## mmap

Do not truncate or replace a file while an mmap resource from `mmap_open/1`
is live — concurrent truncation can SIGBUS and kill the BEAM. Prefer
`accel: false` / plain IO for untrusted paths.

This module is intentional infrastructure; HexDocs may still group it under
internals depending on ExDoc filters.

# `append_file`

# `available?`

```elixir
@spec available?() :: boolean()
```

Returns whether spatial NIFs are loaded (cached for the VM lifetime).

# `chunk_size`

```elixir
@spec chunk_size() :: pos_integer()
```

Preferred max row count per unpack NIF call.

# `excp_pack`

# `excp_unpack`

# `excp_unpack_mmap`

# `gaussian_to_row`

# `gspl_pack`

# `gspl_unpack`

# `gspl_unpack_mmap`

# `mmap_len`

# `mmap_open`

# `ply_binary_unpack`

# `ply_binary_unpack_mmap`

# `ply_type_tag`

# `point_to_row`

# `row_to_gaussian`

# `row_to_point`

---

*Consult [api-reference.md](api-reference.md) for complete listing*
