From 2c0471e79f9024cd971cc65a920f1fed03bb91c7 Mon Sep 17 00:00:00 2001 From: Daniel Wolf Date: Wed, 29 Jun 2016 22:29:17 +0200 Subject: [PATCH] Improved lip animation for B/P and L sounds --- src/mouthAnimation.cpp | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/mouthAnimation.cpp b/src/mouthAnimation.cpp index cdf9291..ed5eb38 100644 --- a/src/mouthAnimation.cpp +++ b/src/mouthAnimation.cpp @@ -25,13 +25,18 @@ AnimationResult animateDiphtong(Shape first, Shape second, centiseconds duration } // P, B -AnimationResult animateBilabialStop(centiseconds duration, centiseconds leftDuration, optional rightShape) { +AnimationResult animateBilabialStop(centiseconds duration, centiseconds leftPhoneDuration, optional rightShape) { Shape openShape = rightShape.value_or(Shape::B); if (openShape == Shape::A) { openShape = Shape::B; } + + centiseconds closedShapeDuration = leftPhoneDuration / 2; + if (closedShapeDuration.count() < 4) closedShapeDuration = centiseconds(4); + if (closedShapeDuration.count() > 16) closedShapeDuration = centiseconds(16); + return AnimationResult{ - { -leftDuration / 4, centiseconds::zero(), Shape::A }, + { -closedShapeDuration, centiseconds::zero(), Shape::A }, { centiseconds::zero(), duration, openShape } }; } @@ -47,7 +52,7 @@ AnimationResult animateFlexibleSound(std::array mapping, centiseconds return AnimationResult{ { centiseconds::zero(), duration, shape } }; } -AnimationResult animate(optional phone, centiseconds duration, centiseconds leftDuration, optional rightShape) { +AnimationResult animate(optional phone, centiseconds duration, centiseconds leftPhoneDuration, optional rightShape) { constexpr Shape A = Shape::A; constexpr Shape B = Shape::B; constexpr Shape C = Shape::C; @@ -78,7 +83,7 @@ AnimationResult animate(optional phone, centiseconds duration, centisecon case Phone::OY: return animateDiphtong(E, B, duration); case Phone::ER: return animateFixedSound(E, duration); case Phone::P: - case Phone::B: return animateBilabialStop(duration, leftDuration, rightShape); + case Phone::B: return animateBilabialStop(duration, leftPhoneDuration, rightShape); case Phone::T: case Phone::D: case Phone::K: return animateFlexibleSound({ B, B, B, B, B, F, B }, duration, rightShape); @@ -96,8 +101,8 @@ AnimationResult animate(optional phone, centiseconds duration, centisecon case Phone::HH: return animateFlexibleSound({ B, B, C, D, E, F, B }, duration, rightShape); case Phone::M: return animateFixedSound(A, duration); case Phone::N: return animateFlexibleSound({ B, B, C, C, C, F, B }, duration, rightShape); - case Phone::NG: - case Phone::L: return animateFlexibleSound({ B, B, C, D, E, F, B }, duration, rightShape); + case Phone::NG: return animateFlexibleSound({ B, B, C, D, E, F, B }, duration, rightShape); + case Phone::L: return animateFlexibleSound({ C, C, C, D, E, F, C }, duration, rightShape); case Phone::R: return animateFlexibleSound({ B, B, B, B, B, F, B }, duration, rightShape); case Phone::Y: return animateFixedSound(B, duration); case Phone::W: return animateFixedSound(F, duration); @@ -122,10 +127,11 @@ ContinuousTimeline animate(const BoundedTimeline &phones) { // Animate one phone optional phone = it->getValue(); centiseconds duration = it->getTimeRange().getLength(); - centiseconds leftDuration = std::next(it) != continuousPhones.rend() + bool hasLeftPhone = std::next(it) != continuousPhones.rend() && std::next(it)->getEnd() == it->getStart(); + centiseconds leftPhoneDuration = hasLeftPhone ? std::next(it)->getTimeRange().getLength() : centiseconds::zero(); - Timeline result = animate(phone, duration, leftDuration, lastShape); + Timeline result = animate(phone, duration, leftPhoneDuration, lastShape); // Result timing is relative to phone. Make absolute. result.shift(it->getStart());