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 { 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 type { IMmdPhysics } from "../Physics/IMmdPhysics";
import type { MmdWasmAnimation } from "./Animation/mmdWasmAnimation";
import type { MmdWasmRuntimeModelAnimation } from "./Animation/mmdWasmRuntimeModelAnimation";
import { MmdWasmMorphController } from "./mmdWasmMorphController";
import type { MmdWasmRuntime } from "./mmdWasmRuntime";
import { MmdWasmRuntimeAnimationEvaluationType } from "./mmdWasmRuntime";
type RuntimeModelAnimation = MmdWasmRuntimeModelAnimation | MmdRuntimeModelAnimation | MmdRuntimeModelAnimationGroup | MmdCompositeRuntimeModelAnimation | IMmdRuntimeModelAnimation;
/**
 * MmdWasmModel is a class that controls the `MmdSkinnedMesh` to animate the Mesh with MMD Wasm Runtime
 *
 * The mesh that instantiates `MmdWasmModel` 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 `MmdWasmModel.afterPhysics()` stage
 *
 * IMPORTANT: The typed array members of this class are pointers to wasm memory.
 * Note that when wasm memory is resized, the typed array is no longer valid.
 * It is designed to always return a valid typed array at the time of a get,
 * so as long as you don't copy the typed array reference in an instance of this class elsewhere, you are safe.
 */
export declare class MmdWasmModel implements IMmdModel {
    /**
     * Pointer to wasm side MmdModel
     */
    readonly ptr: number;
    /**
     * 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 MmdWasmModel.metadata.skeleton is not always equal to MmdWasmModel.skeleton
     */
    readonly skeleton: IMmdLinkedBoneContainer;
    private readonly _worldTransformMatrices;
    /**
     * The array of final transform matrices of bones (ie. the matrix sent to shaders)
     *
     * This array reference should not be copied elsewhere and must be read and written with minimal scope
     */
    get worldTransformMatrices(): Float32Array;
    private readonly _boneAnimationStates;
    /**
     * Wasm side bone animation states. this value is automatically synchronized with `MmdWasmModel.skeleton` on `MmdWasmModel.beforePhysics()` stage
     *
     * repr: [..., positionX, positionY, positionZ, padding, rotationX, rotationY, rotationZ, rotationW, scaleX, scaleY, scaleZ, padding, ...]
     *
     * This array reference should not be copied elsewhere and must be read and written with minimal scope
     */
    get boneAnimationStates(): Float32Array;
    private readonly _ikSolverStates;
    /**
     * 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
     *
     * This array reference should not be copied elsewhere and must be read and written with minimal scope
     */
    get 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 `MmdWasmMorphController` not only wrapper of `MorphTargetManager` but also controls the CPU bound morphs (bone, material, group)
     */
    readonly morph: MmdWasmMorphController;
    private readonly _physicsModel;
    private readonly _runtime;
    private readonly _sortedRuntimeBones;
    readonly onCurrentAnimationChangedObservable: Observable<Nullable<RuntimeModelAnimation>>;
    private readonly _animations;
    private readonly _animationIndexMap;
    private _currentAnimation;
    private _needStateReset;
    /**
     * Create a MmdWasmModel
     *
     * IMPORTANT: when wasm runtime using buffered evaluation, this constructor must be called before waiting for the WasmMmdRuntime.lock
     * otherwise, it will cause a datarace
     * @param wasmRuntime MMD WASM runtime
     * @param ptr Pointer to wasm side MmdModel
     * @param mmdSkinnedMesh Mesh that able to instantiate `MmdWasmModel`
     * @param skeleton The virtualized bone container of the mesh
     * @param materialProxyConstructor The constructor of `IMmdMaterialProxy`
     * @param wasmMorphIndexMap Mmd morph to WASM morph index map
     * @param externalPhysics The external physics engine
     */
    constructor(wasmRuntime: MmdWasmRuntime, ptr: number, mmdSkinnedMesh: MmdSkinnedMesh, skeleton: IMmdLinkedBoneContainer, materialProxyConstructor: Nullable<IMmdMaterialProxyConstructor<Material>>, wasmMorphIndexMap: Int32Array, externalPhysics: Nullable<IMmdPhysics>);
    /**
     * 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 | MmdWasmAnimation, retargetingMap?: {
        [key: string]: string;
    }): void;
    private _removeAnimationByReference;
    /**
     * 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;
    private _removeAnimation;
    /**
     * 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" and before the "wasm before solver" stage
     *
     * 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
     */
    beforePhysicsAndWasm(frameTime: Nullable<number>): void;
    /**
     * Before the "physics stage" and after the "wasm before solver" stage
     */
    beforePhysics(): void;
    /**
     * After the "physics stage" and before the "wasm after solver" stage
     */
    afterPhysicsAndWasm(): void;
    /**
     * After the "physics stage" and after the "wasm after solver" stage
     *
     * mmd solvers are run by wasm runtime
     *
     * This method must be called after the physics stage
     */
    afterPhysics(): void;
    private _buildRuntimeSkeleton;
    private _originalComputeTransformMatrices;
    private _disableSkeletonWorldMatrixUpdate;
    private _enableSkeletonWorldMatrixUpdate;
    private _resetPose;
    /**
     * @internal
     * @param evaluationType New evaluation type
     */
    onEvaluationTypeChanged(evaluationType: MmdWasmRuntimeAnimationEvaluationType): void;
    /**
     * @internal
     * swap the front and back buffer of the world transform matrices
     */
    swapWorldTransformMatricesBuffer(): void;
}
export {};
