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 { MmdRuntimeModelAnimationContainer } from "./Animation/mmdRuntimeModelAnimationContainer"; 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, TrimmedMmdSkinnedMesh } from "./mmdMesh"; import { MmdMorphController } from "./mmdMorphController"; import type { IMmdModelPhysicsCreationOptions } from "./mmdRuntime"; import type { MmdRuntimeAnimationHandle } from "./mmdRuntimeAnimationHandle"; import type { IMmdPhysics } from "./Physics/IMmdPhysics"; type RuntimeModelAnimation = MmdRuntimeModelAnimation | MmdRuntimeModelAnimationContainer | MmdCompositeRuntimeModelAnimation | IMmdRuntimeModelAnimation; /** * Physics options for construct MmdModel */ export interface IMmdModelCtorPhysicsOptions { physicsImpl: IMmdPhysics; physicsOptions: Nullable; } /** * 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: MmdSkinnedMesh | TrimmedMmdSkinnedMesh; /** * 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 if it is 1, IK solver is enabled */ readonly ikSolverStates: Uint8Array; /** * Uint8Array that stores the state of RigidBody * * - If bone position is driven by physics, the value is 1 * - If bone position is driven by only animation, the value is 0 * * You can get the state of the rigid body by `rigidBodyStates[MmdModel.runtimeBones[i].rigidBodyIndex]` */ readonly rigidBodyStates: 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 animation duration is changed * * Value is 30fps frame time duration of the animation */ readonly onAnimationDurationChangedObservable: Observable; private readonly _animationHandleMap; 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 physicsParams Physics options * @param trimMetadata Whether to trim the metadata of the model * @param logger Logger */ constructor(mmdSkinnedMesh: MmdSkinnedMesh, skeleton: IMmdLinkedBoneContainer, materialProxyConstructor: Nullable>, physicsParams: Nullable, trimMetadata: boolean, logger: ILogger); /** * Dispose this model * * Use MmdWasmRuntime.destroyMmdModel instead of this method * * Restore the original bone matrix update behavior * * Dispose the physics resources if the physics is enabled * * @internal */ _dispose(): void; /** * Get the sorted bones of this model * * The bones are sorted by `transformOrder` */ get sortedRuntimeBones(): readonly IMmdRuntimeBone[]; /** * Bind the animation to this model and return a handle to the runtime animation * @param animation MMD animation or MMD model animation group to add * @param retargetingMap Animation bone name to model bone name map * @returns A handle to the runtime animation */ createRuntimeAnimation(animation: IMmdBindableModelAnimation, retargetingMap?: { [key: string]: string; }): MmdRuntimeAnimationHandle; /** * Destroy a runtime animation by its handle * @param handle The handle of the runtime animation to destroy * @returns True if the animation was destroyed, false if it was not found */ destroyRuntimeAnimation(handle: MmdRuntimeAnimationHandle): boolean; /** * Set the current animation of this model * * If handle is null, the current animation will be cleared * @param handle The handle of the animation to set as current * @param updateMorphTarget Whether to update morph target manager numMaxInfluencers (default: true) * @throws {Error} if the animation with the handle is not found */ setRuntimeAnimation(handle: Nullable, updateMorphTarget?: boolean): void; /** * Get the runtime animation map of this model */ get runtimeAnimations(): ReadonlyMap; /** * Get the current animation of this model */ get currentAnimation(): Nullable; /** * 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): 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 {};