import * as THREE from 'three';
import type { GLTF } from 'three/addons/loaders/GLTFLoader.js';
import type { Appearance } from '../core/contract.js';
import type { AnimationId } from '../wire/room.js';
import type { CharacterAsset } from '../character/contract.js';
export type AvatarBudget = {
    profile?: string;
    triangles: number;
    drawCalls: number | null;
    materials: number;
    texturePixels: number;
    textureBytes: number;
    skinningTextureBytes: number;
    joints: number;
    influences: number;
    coveredTriangles: number;
    pass: string;
};
export type Avatar = {
    root: THREE.Group;
    update: (delta: number, locomotion: boolean | AnimationId) => void;
    wave: () => void;
    emote: (id: 'wave' | 'dance', age?: number) => void;
    dispose: () => void;
    playClip?: (asset: CharacterAsset, id: string, loop?: boolean) => Promise<void>;
    budget: AvatarBudget;
    diagnostics: () => {
        activeActions: number;
        locomotion: string;
        emote: string | null;
    };
};
export declare function composeAvatar(appearance: Appearance, base: GLTF, items: GLTF[]): Avatar;
export declare function loadAvatar(appearance: Appearance): Promise<Avatar>;
/** Measure actual submitted geometry in one opaque colour pass, with no scene props or shadows. */
export declare function measureAvatar(renderer: THREE.WebGLRenderer, avatar: Avatar): AvatarBudget;
