async _onViseme()

in src/core/LipsyncFeature.js [256:339]


  async _onViseme({mark}) {
    Object.entries(this._visemeLayers).forEach(([layerName, animName]) => {
      // Make sure the layer can be manipulated
      const {isActive, visemeMap} = this._managedLayers[layerName].animations[
        animName
      ];

      if (!isActive) {
        return;
      }

      // Take variables from the viseme if they exist and default to the layer
      const {
        name: viseme,
        isActive: isVisemeActive,
        decayRate,
        blendTime,
        easingFn,
        overrideWeight,
      } = {
        ...this._managedLayers[layerName],
        ...visemeMap[mark.value],
      };

      const visemeNames = this._host.AnimationFeature.getAnimationBlendNames(
        layerName,
        animName
      );

      // Make sure the new viseme has an active freeBlend weight
      if (!isVisemeActive || !visemeNames.includes(viseme)) {
        return;
      }

      // Find the peak weight for the viseme and the amount of time it should
      // take to reach it
      let weight = 1;
      const duration = mark.duration / 1000;
      if (duration < blendTime) {
        const lerpFactor = blendTime > 0 ? duration / blendTime : 1;
        weight =
          overrideWeight !== undefined
            ? overrideWeight
            : MathUtils.lerp(0, 1, lerpFactor);
      }
      const blendInTime = Math.min(duration, blendTime);

      // Find the amount and time viseme will be held for
      const holdTime = duration - blendTime;

      if (holdTime < 0) {
        // Perform in -> out animation
        this._animateSimpleViseme(
          layerName,
          animName,
          viseme,
          weight,
          blendInTime,
          blendTime,
          easingFn
        );
      } else {
        const lerpFactor =
          decayRate.seconds > 0 ? holdTime / decayRate.seconds : 1;
        // Perform in -> hold -> out animation
        const decayWeight = MathUtils.lerp(
          weight,
          weight * decayRate.amount,
          Math.min(1, lerpFactor)
        );
        this._animateHeldViseme(
          layerName,
          animName,
          viseme,
          weight,
          decayWeight,
          blendInTime,
          holdTime,
          blendTime,
          easingFn
        );
      }
    });
  }