import type { Material } from "@babylonjs/core/Materials/material"; import type { MultiMaterial } from "@babylonjs/core/Materials/multiMaterial"; import type { MorphTargetManager } from "@babylonjs/core/Morph/morphTargetManager"; import type { DeepImmutable, Nullable } from "@babylonjs/core/types"; import type { MmdModelMetadata } from "../Loader/mmdModelMetadata"; import type { Vec3, Vec4 } from "../Loader/Parser/mmdTypes"; import { PmxObject } from "../Loader/Parser/pmxObject"; import type { ILogger } from "./ILogger"; import type { IMmdMaterialProxyConstructor } from "./IMmdMaterialProxy"; import type { MmdRuntimeBone } from "./mmdRuntimeBone"; /** * Represents a material morph element in MMD runtime * * This information is used to induce material recompilation */ export interface RuntimeMaterialMorphElement { index: number; type: PmxObject.Morph.MaterialMorph.Type; diffuse: Nullable; specular: Nullable; shininess: Nullable; ambient: Nullable; edgeColor: Nullable; edgeSize: Nullable; textureColor: Nullable; sphereTextureColor: Nullable; toonTextureColor: Nullable; } /** * Morph information exposed to the user * * Only material morphs data are exposed */ export interface ReadonlyRuntimeMorph { readonly name: string; readonly type: PmxObject.Morph.Type; readonly materialElements: Nullable[]>; } /** * The MmdMorphController uses `MorphTargetManager` to handle position uv morphs, while the material, bone, and group morphs are handled by CPU bound * * As a result, it reproduces the behavior of the MMD morph system */ export declare class MmdMorphController { private readonly _logger; private readonly _morphTargetManager; private readonly _runtimeBones; private readonly _materials; private readonly _morphs; private readonly _morphIndexMap; private readonly _morphWeights; private readonly _activeMorphs; /** * Creates a new MmdMorphController * @param morphTargetManager MorphTargetManager * @param runtimeBones MMD runtime bones which are original order * @param material MMD multi material * @param materialProxyConstructor The constructor of `IMmdMaterialProxy` * @param morphsMetadata Morphs metadata * @param logger Logger */ constructor(morphTargetManager: Nullable, runtimeBones: readonly MmdRuntimeBone[], material: Nullable, materialProxyConstructor: Nullable>, morphsMetadata: readonly MmdModelMetadata.Morph[], logger: ILogger); /** * Sets the weight of the morph * * If there are multiple morphs with the same name, all of them will be set to the same weight, this is the behavior of MMD * @param morphName Name of the morph * @param weight Weight of the morph */ setMorphWeight(morphName: string, weight: number): void; /** * Gets the weight of the morph * * If there are multiple morphs with the same name, the weight of the first one will be returned * @param morphName Name of the morph * @returns Weight of the morph */ getMorphWeight(morphName: string): number; /** * Gets the indices of the morph with the given name * * The index array is returned because multiple morphs can have the same name * @param morphName Name of the morph * @returns */ getMorphIndices(morphName: string): readonly number[] | undefined; /** * Sets the weight of the morph from the index * * This method is faster than `setMorphWeight` because it does not need to search the morphs with the given name */ setMorphWeightFromIndex(morphIndex: number, weight: number): void; /** * Gets the weight of the morph from the index * @param morphIndex Index of the morph * @returns Weight of the morph */ getMorphWeightFromIndex(morphIndex: number): number; /** * Set the weights of all morphs to 0 */ resetMorphWeights(): void; private readonly _updatedMaterials; /** * Apply the morphs to mesh */ update(): void; /** * Gets the morph data */ get morphs(): readonly ReadonlyRuntimeMorph[]; private _createRuntimeMorphData; private _groupMorphFlatForeach; private _resetMorph; private readonly _tempQuaternion; private _applyMorph; private _applyMaterialMorph; }