/** * SplatCharacterHost — entity-generic native character driver for a Gaussian-SPLAT body * (render "Part 2", the photoreal counterpart to {@link CharacterHost}'s rasterized skinned mesh). * * A character entity whose body is a trained Gaussian splat cloud — loaded from the existing * splat infrastructure (`GaussianPlyLoader` for `.ply`, the `GaussianSplatData` codec interchange * for glTF/SPZ) rather than procedurally generated. Like CharacterHost it is: * - entity-generic (D.094): keyed by `entityId`, default-anything, nothing hardcoded; * - mind-bearing (D.102): `bindMind` adopts a wallet identity + `private:` memory so the * SAME agent inhabits this body across substrates — identical seam to CharacterHost. * * `render()` frames the cloud automatically (centroid + bounding radius → a +Z-forward camera that * fits it), so a real capture centred anywhere in world space renders without the caller knowing * its coordinate frame. NO Three.js, NO R3F — this drives the same native WebGPU splat pipeline as * `renderSplats`, which reuses the Paper-grade `GaussianSplatSorter` unchanged. * * @module character-render */ import { type RawSplatInput } from '../native-render/splat-render'; import type { Gaussian3D } from '../gpu/GaussianTrainer3D'; import type { GaussianSplatData } from '../gpu/codecs/types'; import type { CameraState } from '../gpu/GaussianSplatSorter'; import type { PixelGrid } from '../native-render/gpu-verify'; import type { CharacterMind, MindIdentity, MindMemoryEntry } from './CharacterMind'; /** * Build a camera that frames an arbitrary splat cloud. Computes the cloud's centroid and bounding * radius, then places a +Z-forward perspective camera (the splat pipeline treats `depth=(view·pos).z` * and culls `depth<0.01`, so the whole cloud must sit at positive camera-space Z) at a distance that * fits the radius within the vertical FoV with margin. Column-major; `view` is identity-rotation + * a translation that maps the centroid to `(0,0,dist)`. */ export declare function framingSplatCamera(splats: readonly RawSplatInput[], size: number, fovYDeg?: number): CameraState; export interface SplatCharacterHostOptions { /** Entity id — the agent this splat body belongs to (D.094 entity-generic). */ entityId: string; /** The body's splats (use a `from*` factory to load from the splat infrastructure). */ splats: readonly RawSplatInput[]; } export interface SplatCharacterRenderOptions { /** Square framebuffer edge (default 128). */ size?: number; /** Vertical FoV for the auto-framing camera (ignored when `camera` is supplied). */ fovYDeg?: number; /** Clear RGBA 0..1 (default opaque black). */ clear?: [number, number, number, number]; /** Camera override; defaults to {@link framingSplatCamera} over this body's splats. */ camera?: CameraState; } export declare class SplatCharacterHost { readonly entityId: string; private readonly splats; private mind; private boundIdentity; private memory; constructor(opts: SplatCharacterHostOptions); /** Load a body from the trainer / `.ply`-loader `Gaussian3D` SoA. */ static fromGaussian3D(entityId: string, g: Gaussian3D): SplatCharacterHost; /** Load a body from the codec interchange format (`GltfGaussianSplatCodec` / SPZ decode). */ static fromGaussianSplatData(entityId: string, d: GaussianSplatData): SplatCharacterHost; /** Load a body directly from 3DGS `.ply` bytes (consumes the proven `loadGaussianPly` decode). */ static fromPly(entityId: string, ply: Uint8Array | ArrayBuffer): SplatCharacterHost; /** Number of Gaussians in this body. */ get splatCount(): number; /** * Render this splat body to verified pixels. Auto-frames the cloud unless a `camera` is given. */ render(device: GPUDevice, opts?: SplatCharacterRenderOptions): Promise; /** * Bind a portable mind to this body: adopt its wallet identity and load its wallet-scoped memory * so the SAME agent inhabits the splat body across substrates. Degrades to body-only on any * failure — NEVER throws, and never changes how the body renders. */ bindMind(mind: CharacterMind, query?: string, limit?: number): Promise; /** The bound mind's identity (wallet + agent id), or null if no mind is bound. */ getIdentity(): MindIdentity | null; /** A copy of the loaded wallet-scoped memory (empty if no mind / load failed). */ getMemory(): MindMemoryEntry[]; /** True once a mind has been bound (regardless of whether memory loaded). */ hasMind(): boolean; } //# sourceMappingURL=SplatCharacterHost.d.ts.map