import type { Material } from "@babylonjs/core/Materials/material";
import { Observable } from "@babylonjs/core/Misc/observable";
import type { Nullable } from "@babylonjs/core/types";
import type { IMmdBindableModelAnimation } from "./Animation/IMmdBindableAnimation";
import type { IMmdRuntimeModelAnimation } from "./Animation/IMmdRuntimeAnimation";
import type { MmdCompositeRuntimeModelAnimation } from "./Animation/mmdCompositeRuntimeModelAnimation";
import type { MmdRuntimeModelAnimation } from "./Animation/mmdRuntimeModelAnimation";
import type { MmdRuntimeModelAnimationGroup } from "./Animation/mmdRuntimeModelAnimationGroup";
import type { ILogger } from "./ILogger";
import type { IMmdMaterialProxyConstructor } from "./IMmdMaterialProxy";
import type { IMmdModel } from "./IMmdModel";
import type { IMmdRuntimeBone } from "./IMmdRuntimeBone";
import type { IMmdLinkedBoneContainer } from "./IMmdRuntimeLinkedBone";
import type { MmdSkinnedMesh, RuntimeMmdMesh } from "./mmdMesh";
import { MmdMorphController } from "./mmdMorphController";
import type { IMmdPhysics } from "./Physics/IMmdPhysics";
type RuntimeModelAnimation = MmdRuntimeModelAnimation | MmdRuntimeModelAnimationGroup | MmdCompositeRuntimeModelAnimation | IMmdRuntimeModelAnimation;
/**
 * MmdModel is a class that controls the `MmdSkinnedMesh` to animate the Mesh with MMD Runtime
 *
 * The mesh that instantiates `MmdModel` ignores some original implementations of Babylon.js and follows the MMD specifications
 *
 * The biggest difference is that the methods that get the absolute transform of `mesh.skeleton.bones` no longer work properly and can only get absolute transform through `mmdModel.worldTransformMatrices`
 *
 * Final matrix is guaranteed to be updated after `MmdModel.afterPhysics()` stage
 */
export declare class MmdModel implements IMmdModel {
    /**
     * The root mesh of this model
     */
    readonly mesh: RuntimeMmdMesh;
    /**
     * The skeleton of this model
     *
     * This can be a instance of `Skeleton`, or if you are using a humanoid model, it will be referencing a virtualized bone tree
     *
     * So MmdModel.metadata.skeleton is not always equal to MmdModel.skeleton
     */
    readonly skeleton: IMmdLinkedBoneContainer;
    /**
     * The array of final transform matrices of bones (ie. the matrix sent to shaders)
     */
    readonly worldTransformMatrices: Float32Array;
    /**
     * Uint8Array that stores the state of IK solvers
     *
     * If `ikSolverState[MmdModel.runtimeBones[i].ikSolverIndex]` is 0, IK solver of `MmdModel.runtimeBones[i]` is disabled and vice versa
     */
    readonly ikSolverStates: Uint8Array;
    /**
     * Runtime bones of this model
     *
     * You can get the final transform matrix of a bone by `MmdModel.runtimeBones[i].getFinalMatrixToRef()`
     */
    readonly runtimeBones: readonly IMmdRuntimeBone[];
    /**
     * The morph controller of this model
     *
     * The `MmdMorphController` not only wrapper of `MorphTargetManager` but also controls the CPU bound morphs (bone, material, group)
     */
    readonly morph: MmdMorphController;
    private readonly _physicsModel;
    private readonly _logger;
    private readonly _sortedRuntimeBones;
    /**
     * Observable triggered when the current animation is changed
     */
    readonly onCurrentAnimationChangedObservable: Observable<Nullable<RuntimeModelAnimation>>;
    private readonly _animations;
    private readonly _animationIndexMap;
    private _currentAnimation;
    private _needStateReset;
    /**
     * Create a MmdModel
     * @param mmdSkinnedMesh Mesh that able to instantiate `MmdModel`
     * @param skeleton The virtualized bone container of the mesh
     * @param materialProxyConstructor The constructor of `IMmdMaterialProxy`
     * @param mmdPhysics Physics builder
     * @param logger Logger
     */
    constructor(mmdSkinnedMesh: MmdSkinnedMesh, skeleton: IMmdLinkedBoneContainer, materialProxyConstructor: Nullable<IMmdMaterialProxyConstructor<Material>>, mmdPhysics: Nullable<IMmdPhysics>, logger: ILogger);
    /**
     * Dispose this model
     *
     * Restore the original bone matrix update behavior
     *
     * Dispose the physics resources if the physics is enabled
     */
    dispose(): void;
    /**
     * Get the sorted bones of this model
     *
     * The bones are sorted by `transformOrder`
     */
    get sortedRuntimeBones(): readonly IMmdRuntimeBone[];
    /**
     * Add an animation to this model
     *
     * If the animation is already added, it will be replaced
     * @param animation MMD animation or MMD model animation group to add
     * @param retargetingMap Model bone name to animation bone name map
     */
    addAnimation(animation: IMmdBindableModelAnimation, retargetingMap?: {
        [key: string]: string;
    }): void;
    /**
     * Remove an animation from this model
     *
     * If index is out of range, do nothing
     * @param index The index of the animation to remove
     */
    removeAnimation(index: number): void;
    /**
     * Set the current animation of this model
     * @param name The name of the animation to set
     * @param updateMorphTarget Whether to update morph target manager numMaxInfluencers (default: true)
     * @throws {Error} if the animation is not found
     */
    setAnimation(name: Nullable<string>, updateMorphTarget?: boolean): void;
    /**
     * Get the animations of this model
     */
    get runtimeAnimations(): readonly RuntimeModelAnimation[];
    /**
     * Get the current animation of this model
     */
    get currentAnimation(): Nullable<RuntimeModelAnimation>;
    /**
     * Reset the rigid body positions and velocities of this model
     */
    initializePhysics(): void;
    /**
     * Before the physics stage, update animations and run MMD runtime solvers
     *
     * This method must be called before the physics stage
     *
     * If frameTime is null, animations are not updated
     * @param frameTime The time elapsed since the last frame in 30fps
     */
    beforePhysics(frameTime: Nullable<number>): void;
    /**
     * After the physics stage, run MMD runtime solvers
     *
     * This method must be called after the physics stage
     */
    afterPhysics(): void;
    private _update;
    private _buildRuntimeSkeleton;
    private _originalComputeTransformMatrices;
    private _disableSkeletonWorldMatrixUpdate;
    private _enableSkeletonWorldMatrixUpdate;
    private _resetPose;
}
export {};
