import { VRM } from "@pixiv/three-vrm";
import * as THREE from "three";
import { MouthExpressionManager, MouthExpression } from "./MouthExpressionManager.ts";
import { FaceExpressionManager, FaceExpression } from "./FaceExpressionManager.ts";
import { MotionExpressionManager, MotionExpression } from "./MotionExpressionManager.ts";
import { MotionConversionWorkerClient } from "./MotionExpressionWorkerClient.ts";
import { Observable } from "rxjs";
export declare class LoopType {
    static FastForward: number;
    static Repeat: number;
    static Once: number;
}
export declare class InterpolationType {
    static discrete: number;
    static linear: number;
    static smooth: number;
}
export declare class AnimationBlendType {
    static normal: number;
    static additive: number;
}
export interface ExpressionOptions {
    interpolationMode: THREE.InterpolationModes;
    animationBlendMode: THREE.AnimationBlendMode;
    smoothing: number;
    bodySmoothing: number;
    headSmoothing: number;
    faceSmoothing: number;
    armsSmoothing: number;
    legsSmoothing: number;
    handsSmoothing: number;
}
export interface ExpressionInput {
    /**
     *  ```ts
     *  FaceExpression {
     *    duration: number;
     *    angry?: number; // between 0 and 1
     *    happy?: number; // between 0 and 1
     *    neutral?: number; // between 0 and 1
     *    relaxed?: number; // between 0 and 1
     *    sad?: number; // between 0 and 1
     *    surprised?: number; // between 0 and 1
     * }
     * ```
     */
    faceExpressions?: FaceExpression[];
    /**
     *  ```ts
     *  MouthExpression {
     *    duration: number;
     *    aa?: number; // between 0 and 1
     *    ee?: number; // between 0 and 1
     *    ih?: number; // between 0 and 1
     *    oh?: number; // between 0 and 1
     *    ou?: number; // between 0 and 1
     *  }
     * ```
     */
    mouthExpressions?: MouthExpression[];
    /**
     *  ```ts
     *  MotionExpression {
     *    clip: THREE.AnimationClip;
     *    duration?: number; // will default to clip duration if not provided
     *  }
     * ```
     */
    motionExpressions?: MotionExpression[];
    /**
     * 1001: FastForward
     *
     * 2201: THREE.LoopRepeat
     *
     * 2200: THREE.LoopOnce
     */
    loopMotion?: LoopType;
    opt?: ExpressionOptions;
}
export declare class ExpressionManager {
    mouth: MouthExpressionManager;
    face: FaceExpressionManager;
    motion: MotionExpressionManager;
    _vrm: VRM;
    /** Expressions that should be decoupled by default. For example,
     *  the "happy" expression should not control the same vertices as
     *  the "blink" expression, as the eyes would close, if the "happy"
     *  expression is detected, meaning that the person in the video
     *  feed might not have their eyes closed, but the model would.
     *
     *  This applies to "aa", "ee", "ih", "oh", "ou", "blinkLeft" and
     *  "blinkRight" as well
     */
    static defaultDecouplables: [string, string, number][];
    private _vrmUrl;
    private _expressionOverlaps;
    private _expressionStreams;
    private _expressionResetters;
    /**
     * Used to store the original geometires before other expressions are decoupled.
     */
    private _initialExpressoinGeometries;
    constructor(vrm: VRM, vrmUrl: string, motionConversionWorkerClient?: MotionConversionWorkerClient);
    _express(expressionInput: ExpressionInput, opt?: {
        skipMotionSubscription?: boolean;
        skipMouthSubscription?: boolean;
        skipFaceSubscription?: boolean;
    }): Observable<MotionExpression | FaceExpression | MouthExpression>;
    express(expressionInput: ExpressionInput, opt?: {
        skipMotionSubscription?: boolean;
        skipMouthSubscription?: boolean;
        skipFaceSubscription?: boolean;
    }): Observable<MotionExpression | FaceExpression | MouthExpression>;
    /**
     * 3D artists have the unfortunate habit of creating models that
     * have broken blendshapes when combined. The most common example
     * is opening the mouth for the 'happy' shapekey.
     *
     * While the mistake is understandable, it leads to various issues,
     * like the mouth not opening when an emotion targets the mouth
     * vertices and has them closed or the mouth being wide open
     * whenever a model displays an emotion that has been mapped
     * to an open mouth, breaking mouth movements.
     *
     * This decouples those vertices as best as possible, but really it
     * is the models that need to be fixed.
     *
     * Honestly if something like lip-sync doesn't work, it is more likely
     * to be an issue with the model than with the underlying implementation.
     *
     * I spent countless days trying to debug phantom-issues like these
     * only to discover that the models were broken.
     *
     * Don't be like me, check the models first, then check if the issue
     * exists after you called this function, and then you can come
     * and bash my head in if it still doesn't work.
     */
    decoupleCommonBrokenBlendshapes(): void;
    /**
     * If you previously called [decoupleCommonBrokenBlendshapes], you can run
     * this to undo the decoupling
     */
    recoupleCommonBrokenBlendshapes(): void;
    private findOverlappingExpressions;
    private findExpressionVertexDeltas;
    private markGeometryForUpdate;
    private cloneMorphGeometry;
    private ensureInitialGeometryStored;
    /**
     * Decouples overlapping expressions.
     *
     * If two expressions target the same vertices (e.g. "happy" and "blink" both close the eyes),
     * you can pass the expression you want to stop targeting the overlapping vertices as the target
     * expression and the expression that targets these vertices more precisely as the delta expression.
     *
     * For example, if you model closes it's eyes when set to {happy: 1} and you want the eyes to be
     * unaffected, you'd pass:
     * ```js
     * decoupleExpression("happy", "blink");
     * ```
     *
     * @param targetExpression The expression to decouple from
     * @param deltaExpression The expression that overlaps with the target expression
     * @param withDelta The delta to determine the degree of overlap. If you're
     *  not sure what this should be, the default is set reasonably.
     *  If you're model closes it's eyes when set to "happy" for example, but you want
     *  the eyes to be unaffected, you'd pass "blink" as the delta expression. If "happy"
     *  then still influences the eyes, you should increase this delta value and see which
     *  value works best for your model.
     * @returns void
     */
    decoupleExpression(targetExpression: string, deltaExpression: string, withDelta?: number): void;
    recoupleExpression(expressionKey: string): void;
    update(delta: number): void;
    destroy(): void;
}
//# sourceMappingURL=ExpressionManager.d.ts.map