import type { AnimationGroup } from "@babylonjs/core/Animations/animationGroup"; import type { Skeleton } from "@babylonjs/core/Bones/skeleton"; import { Vector3 } from "@babylonjs/core/Maths/math.vector"; import { Matrix } from "@babylonjs/core/Maths/math.vector"; import type { TransformNode } from "@babylonjs/core/Meshes/transformNode"; import type { DeepImmutable, Nullable } from "@babylonjs/core/types"; /** * Options for AnimationRetargeter.retargetAnimation */ export interface IRetargetOptions { /** * Clone animation group before retargeting (default: true) */ cloneAnimation?: boolean; /** * Remove bone rotation offset (default: false) */ removeBoneRotationOffset?: boolean; /** * Bone name to euler angle rotation offset map * * Typically used when converting from A to T pose */ rotationOffsets?: { [key: string]: DeepImmutable; }; } /** * Make animation compatible with mmd model */ export declare class AnimationRetargeter { private _boneNameMap; private _sourceSkeleton; private _targetSkeleton; private _sourceSkeletonTransformOffset; private _sourceSkeletonAbsoluteMatrices; private _targetBoneNameMap; private _loggingEnabled; /** @internal */ log: (message: string) => void; /** @internal */ warn: (message: string) => void; /** @internal */ error: (message: string) => void; /** * Instantiate AnimationRetargeter */ constructor(); /** * Set source bone to target bone name map * @param boneMap source bone to target bone name map * @returns this */ setBoneMap(boneMap: { [key: string]: string; }): this; /** * Set source skeleton that has animation to retarget * * In general use case, the source skeleton and the target skeleton should be looking in the same direction in the world space * * And the `transformOffset` must be set to the mesh that binded to the source skeleton * @param skeleton source skeleton * @param transformOffset transform offset * @returns this */ setSourceSkeleton(skeleton: Skeleton, transformOffset?: TransformNode | Matrix): this; /** * Set target skeleton * @param skeleton target skeleton * @returns this */ setTargetSkeleton(skeleton: Skeleton): this; /** * Remap the bone's name and modify the animation data to convert it to a rotation that matches the source skeleton * * In the current implementation, retargeting is performed assuming that all bones in the target skeleton have no rotation offset * * because that's the bone structure of the mmd model * * These limitations may be removed in the future * * @param animationGroup animation group to retarget * @param options rtetarget options * @returns retargeted animation group */ retargetAnimation(animationGroup: AnimationGroup, options?: IRetargetOptions): Nullable; private _isSkeletonAnimation; private static readonly _Stack; private _computeSkeletonAbsoluteMatrices; private _removeScaleAnimation; private _getFinalTarget; private _flattenAnimationTarget; private _removeBoneRotationOffset; private _retargetAnimationInternal; /** * Enable or disable debug logging (default: false) */ get loggingEnabled(): boolean; set loggingEnabled(value: boolean); private _logEnabled; private _logDisabled; private _warnEnabled; private _warnDisabled; private _errorEnabled; private _errorDisabled; }