import * as THREE from 'three'; export declare class AnimationController { private anim; private boneData; private bones; private kfOffsets; private seqIndex; private localTime; private globalSeqTimers; private playing; private _trans; private _scale; private _quat; private _matT; private _matR; private _matNP; constructor(anim: AnimData, boneData: BoneInfo_2[], bones: THREE.Bone[]); setSequence(seqIndex: number): void; getAnimationList(): Array<{ seqIndex: number; label: string; animId: number; subAnimId: number; duration: number; }>; update(deltaMs: number): void; private sampleVec3; private sampleQuat; } /** Info about an available animation sequence. */ export declare interface AnimationInfo { seqIndex: number; animId: number; subAnimId: number; label: string; duration: number; } declare interface AnimData { sequences: SequenceInfo[]; globalSeqDurations: number[]; boneTracks: BoneTrackInfo[]; boneCount: number; seqCount: number; view: DataView; indexOfs: number; } /** Resolves relative asset paths to full URLs and optionally provides fetch options. */ export declare interface AssetResolver { /** Resolve a relative asset path (e.g. '/models/human-male/model.json') to a full URL. */ resolve(path: string): string; /** Optional fetch options (auth headers, credentials). */ fetchOpts?(): RequestInit; } /** Equipment texture base paths for body armor compositing. No gender suffix, no .tex extension. * Resolver tries _{gender}.tex → _U.tex → .tex, using the first that loads. * Example: '/item-textures/ArmUpperTexture/Plate_A_01Silver_Sleeve_AU' */ export declare interface BodyArmor { armUpperBase?: string; armLowerBase?: string; handBase?: string; torsoUpperBase?: string; torsoLowerBase?: string; legUpperBase?: string; legLowerBase?: string; footBase?: string; /** GeosetGroup[0] value for gloves slot (group 4). 1=401, 2=402, 3=403. 0/undefined = default bare hands. */ handGeoset?: number; /** GeosetGroup[0] value for boots slot (group 5). 1=501, 2=502, 3=503. 0/undefined = default bare feet. */ footGeoset?: number; /** Sleeve geoset (group 8). 2→802 fitted, 3→803 armored. 0/undefined = no sleeve geometry. */ sleeveGeoset?: number; /** Wrist geoset (group 9). 2→902 leather, 3→903 armored. 0/undefined = no wrist geometry. */ wristGeoset?: number; /** Robe leg extension (group 13). 2→1302 robe skirt. 0/undefined = default thigh (1301). */ robeGeoset?: number; /** Helmet model slug, e.g. 'helm-plate-d-02'. Race-gender variant resolved at load time. */ helmet?: string; /** HelmetGeosetVisData IDs [male, female] — controls which geosets to hide. */ helmetGeosetVisID?: [number, number]; /** Helmet texture slug — used to pick textures/{slug}.tex instead of main.tex. */ helmetTexture?: string; /** Shoulder model slug, e.g. 'leather-blood-b-01'. */ shoulderSlug?: string; /** Whether the right shoulder model exists. */ shoulderHasRight?: boolean; /** Shoulder texture slug — used to pick textures/{slug}.tex instead of main.tex. */ shoulderTexture?: string; } export declare interface BoneInfo { parent: number; pivot: [number, number, number]; rotation: [number, number, number, number]; translation: [number, number, number]; } declare interface BoneInfo_2 { parent: number; pivot: [number, number, number]; rotation: [number, number, number, number]; translation: [number, number, number]; } declare interface BoneTrackInfo { transInterp: number; rotInterp: number; scaleInterp: number; transGlobalSeq: number; rotGlobalSeq: number; scaleGlobalSeq: number; } /** Configuration for creating a CDN resolver. */ export declare interface CdnResolverOptions { /** Auth cookie value (for Chronicle-style session auth). */ auth?: string; } /** Compositing region identifiers */ export declare enum CharRegion { ARM_UPPER = 0, ARM_LOWER = 1, HAND = 2, FACE_UPPER = 3, FACE_LOWER = 4, TORSO_UPPER = 5, TORSO_LOWER = 6, LEG_UPPER = 7, LEG_LOWER = 8, FOOT = 9 } /** * Composite character textures into a single 256x256 atlas. * * @param baseImageData - Full 256x256 body skin texture (CharSections type=0) * @param layers - Additional overlay layers (face, underwear, equipment) * @returns HTMLCanvasElement with the composited texture */ export declare function composeCharTexture(baseImageData: ImageData, layers: TextureLayer[]): HTMLCanvasElement; /** * Create a simple CDN resolver that prepends a base URL. * Pass an empty string for same-origin (local dev server). * * @example * // Remote CDN * createCdnResolver('https://models.chronicleclassic.com') * * // Local dev (Vite serves public/) * createCdnResolver('') */ export declare function createCdnResolver(baseUrl: string, opts?: CdnResolverOptions): AssetResolver; /** Equipment options passed to ModelViewer.equip() or loadModel(). */ export declare interface EquipmentOptions { weapon?: { path: string; texture?: string; }; offhand?: { path: string; texture?: string; }; armor?: BodyArmor; } export declare function loadAnimations(modelDir: string, resolver: AssetResolver): Promise; export declare interface LoadedModel { group: THREE.Group; bones: THREE.Bone[]; boneData: BoneInfo[]; } /** * Load a character model from a directory. * @param modelDir - e.g. '/models/human-male' — loads model.json, model.bin, textures/skin.tex */ export declare function loadModel(modelDir: string, resolver: AssetResolver, options?: { enabledGeosets?: Set; weapon?: string; weaponTexture?: string; offhand?: string; offhandTexture?: string; armor?: BodyArmor; }): Promise; /** * Load a .tex file and return ImageData for compositing. * .tex format: uint16 width + uint16 height + RGBA pixels. */ export declare function loadTexImageData(url: string, resolver: AssetResolver): Promise; export declare class ModelViewer { private renderer; private scene; private camera; private controls; private resolver; private canvas; private currentModel; private animController; private currentRace; private currentGender; private currentEquipment; private animFrameId; private lastFrameTime; private disposed; private resizeObserver; constructor(config: ModelViewerConfig); /** Load a character model. */ loadCharacter(race: string, gender: 'male' | 'female'): Promise; /** Equip items. Triggers a full model reload. */ equip(equipment: EquipmentOptions): Promise; /** Clear all equipment. */ unequip(): Promise; /** Get available animations for the current model. */ getAnimations(): AnimationInfo[]; /** Play an animation by sequence index. */ playAnimation(seqIndex: number): void; /** Play an animation by name (e.g. 'Stand', 'Walk', 'EmoteDance'). */ playAnimationByName(name: string): void; /** Get the list of supported races. */ static getRaces(): Array<{ slug: string; label: string; }>; /** Clean up all Three.js resources and remove the canvas. */ dispose(): void; private reload; private disposeModel; private frameCameraOnModel; private handleResize; private animate; } /** Configuration for the ModelViewer constructor. */ export declare interface ModelViewerConfig { /** DOM element to mount the canvas into. */ container: HTMLElement; /** Asset resolver (use createCdnResolver for simple CDN setup). */ assets: AssetResolver; /** Background color (default: 0x333333). */ backgroundColor?: number; } declare interface SequenceInfo { animId: number; subAnimId: number; duration: number; flags: number; blendTime: number; frequency: number; variationNext: number; aliasNext: number; } /** A texture layer to composite onto the atlas */ declare interface TextureLayer { imageData: ImageData; region: CharRegion; layer: number; } export { }