ProtoTracer  1.0
Real-time 3D rendering and animation engine
Loading...
Searching...
No Matches
MyntAnimation.h
Go to the documentation of this file.
1#pragma once
2
3#include "../Animation.h"
4#include "../KeyFrameTrack.h"
5#include "../EasyEaseAnimator.h"
6#include "../../Objects/Background.h"
7#include "../../Morph/MyntFace.h"
8#include "../../Morph/MyntFood.h"
9#include "../../Morph/MyntPacman.h"
10#include "../../Morph/MyntSOS.h"
11#include "../../Morph/MyntZZZ.h"
12#include "../../Render/Scene.h"
13#include "../../Signals/FunctionGenerator.h"
14#include "../../Sensors/MenuButtonHandler.h"
15#include "../../Sensors/BoopSensor.h"
16#include "../../Sensors/MicrophoneFourier_MAX9814.h"
17
18#include "../../Materials/Animated/SpectrumAnalyzer.h"
19#include "../../Materials/Animated/RainbowNoise.h"
20#include "../../Materials/Animated/RainbowSpiral.h"
21
22#include "../../Materials/CombineMaterial.h"
23
24#include "../AnimationTracks/BlinkTrack.h"
25
26#include "../../Signals/FFTVoiceDetection.h"
27
28class MyntAnimation : public Animation<6> {
29private:
30 MyntFace pM;
31 MyntFood pacmanFood;
32 MyntPacman pacman;
33 MyntSOS sos;
34 MyntZZZ zzz;
35 Background background;
36 //PacmanBody pacman;
37 //PacmanFood pacmanFood;
38 //SOS sos;
39 EasyEaseAnimator<30> eEA = EasyEaseAnimator<30>(EasyEaseInterpolation::Overshoot, 1.0f, 0.35f);
40
41 //Materials
48
49 //pacman food
51
53
54 SpectrumAnalyzer sA = SpectrumAnalyzer(Vector2D(250, 110), Vector2D(125, 60), true, true);
55
56 //Animation controllers
58
64
68
69 BoopSensor boop;
70 float redFaceMix = 0.0f;
71 float pinkFaceMix = 0.0f;
72 float blueFaceMix = 0.0f;
73 uint8_t redFaceIndex = 51;
74 uint8_t pinkFaceIndex = 52;
75 uint8_t blueFaceIndex = 53;
76
78 bool talk = true;
79 bool hideFace = false;
80
82 eEA.AddParameter(pM.GetMorphWeightReference(MyntFace::EyesAngry), MyntFace::EyesAngry, 60, 0.0f, 1.0f);
83 eEA.AddParameter(pM.GetMorphWeightReference(MyntFace::EyesDead), MyntFace::EyesDead, 60, 0.0f, 1.0f);
84 eEA.AddParameter(pM.GetMorphWeightReference(MyntFace::EyesHappy), MyntFace::EyesHappy, 60, 0.0f, 1.0f);
85 eEA.AddParameter(pM.GetMorphWeightReference(MyntFace::EyesHeart), MyntFace::EyesHeart, 60, 0.0f, 1.0f);
86 eEA.AddParameter(pM.GetMorphWeightReference(MyntFace::EyesHeartB), MyntFace::EyesHeartB, 60, 0.0f, 1.0f);
87 eEA.AddParameter(pM.GetMorphWeightReference(MyntFace::EyesClosed), MyntFace::EyesClosed, 60, 0.0f, 1.0f);
88 eEA.AddParameter(pM.GetMorphWeightReference(MyntFace::HideEyes), MyntFace::HideEyes, 60, 0.0f, 1.0f);
89
90 eEA.AddParameter(pM.GetMorphWeightReference(MyntFace::HideNose), MyntFace::HideNose, 60, 0.0f, 1.0f);
91
92 eEA.AddParameter(pM.GetMorphWeightReference(MyntFace::MouthAngry), MyntFace::MouthAngry, 60, 0.0f, 1.0f);
93 eEA.AddParameter(pM.GetMorphWeightReference(MyntFace::MouthDead), MyntFace::MouthDead, 60, 0.0f, 1.0f);
94 eEA.AddParameter(pM.GetMorphWeightReference(MyntFace::MouthHappy), MyntFace::MouthHappy, 60, 0.0f, 1.0f);
95 eEA.AddParameter(pM.GetMorphWeightReference(MyntFace::MouthLove), MyntFace::MouthLove, 60, 0.0f, 1.0f);
96 eEA.AddParameter(pM.GetMorphWeightReference(MyntFace::MouthSleepy), MyntFace::MouthSleepy, 60, 0.0f, 1.0f);
97 eEA.AddParameter(pM.GetMorphWeightReference(MyntFace::HideMouth), MyntFace::HideMouth, 60, 0.0f, 1.0f);
98 eEA.AddParameter(pM.GetMorphWeightReference(MyntFace::MouthTalk), MyntFace::MouthTalk, 2, 0.0f, 1.0f);
99 eEA.AddParameter(pM.GetMorphWeightReference(MyntFace::MouthTalk2), MyntFace::MouthTalk2, 2, 0.0f, 1.0f);
100
101 eEA.AddParameter(&redFaceMix, redFaceIndex, 40, 0.0f, 1.0f);
102 eEA.AddParameter(&pinkFaceMix, pinkFaceIndex, 40, 0.0f, 1.0f);
103 eEA.AddParameter(&blueFaceMix, blueFaceIndex, 40, 0.0f, 1.0f);
104 }
105
107 blink.AddParameter(pM.GetMorphWeightReference(MyntFace::Blink));
108 }
109
111 eEA.SetInterpolationMethod(redFaceIndex, EasyEaseInterpolation::Cosine);
112 eEA.SetInterpolationMethod(pinkFaceIndex, EasyEaseInterpolation::Cosine);
113 eEA.SetInterpolationMethod(blueFaceIndex, EasyEaseInterpolation::Cosine);
114
115 eEA.SetInterpolationMethod(MyntFace::EyesAngry, EasyEaseInterpolation::Cosine);
116 eEA.SetInterpolationMethod(MyntFace::MouthAngry, EasyEaseInterpolation::Cosine);
117 eEA.SetInterpolationMethod(MyntFace::EyesClosed, EasyEaseInterpolation::Cosine);
118 eEA.SetInterpolationMethod(MyntFace::MouthSleepy, EasyEaseInterpolation::Cosine);
119
120 eEA.SetInterpolationMethod(MyntFace::HideEyes, EasyEaseInterpolation::Cosine);
121 eEA.SetInterpolationMethod(MyntFace::HideMouth, EasyEaseInterpolation::Cosine);
122 eEA.SetInterpolationMethod(MyntFace::HideNose, EasyEaseInterpolation::Cosine);
123
124 eEA.SetInterpolationMethod(MyntFace::MouthTalk, EasyEaseInterpolation::Linear);
125 eEA.SetInterpolationMethod(MyntFace::MouthTalk2, EasyEaseInterpolation::Linear);
126 }
127
135
136public:
138 scene.AddObject(pM.GetObject());
139 scene.AddObject(background.GetObject());
140 scene.AddObject(pacmanFood.GetObject());
141 scene.AddObject(pacman.GetObject());
142 scene.AddObject(sos.GetObject());
143 scene.AddObject(zzz.GetObject());
144
145
146 LinkEasyEase();
148
150
151 SetMaterials();
152
153 pM.GetObject()->SetMaterial(&faceMaterial);
154 pacmanFood.GetObject()->SetMaterial(&tealMaterial);//Default color is white
155 pacman.GetObject()->SetMaterial(&yellowMaterial);
156 sos.GetObject()->SetMaterial(&yellowMaterial);
157 zzz.GetObject()->SetMaterial(&blueMaterial);
158
159 MenuButtonHandler::Initialize(0, 9, 1000);//8 is number of faces
160
161 MicrophoneFourier::Initialize(22, 8000, 50.0f, 120.0f);//8KHz sample rate, 50dB min, 120dB max
162
163 boop.Initialize(5);
164
165 background.GetObject()->SetMaterial(&sA);
166 }
167
169 blink.Update();
170 }
171
172 void Default(){}
173
174 void Angry(){
175 eEA.AddParameterFrame(MyntFace::EyesAngry, 1.0f);
176 eEA.AddParameterFrame(MyntFace::MouthAngry, 1.0f);
178 }
179
180 void Dead(){
181 blink.Pause();
182 eEA.AddParameterFrame(MyntFace::EyesDead, 1.0f);
183 eEA.AddParameterFrame(MyntFace::MouthDead, 1.0f);
185 }
186
187 void Happy(){
188 eEA.AddParameterFrame(MyntFace::EyesHappy, 1.0f);
189 eEA.AddParameterFrame(MyntFace::MouthHappy, 1.0f);
190 }
191
192 void Love(){
193 eEA.AddParameterFrame(MyntFace::EyesHeart, 1.0f);
194 eEA.AddParameterFrame(MyntFace::MouthLove, 1.0f);
196 }
197
198 void Sleepy(){
199 blink.Pause();
200 eEA.AddParameterFrame(MyntFace::EyesClosed, 1.0f);
201 eEA.AddParameterFrame(MyntFace::MouthSleepy, 1.0f);
203 }
204
205 void SleepyZZZ(){
206 zzz.Reset();
207
208 zzz.GetObject()->Enable();
209
210 blink.Pause();
211 eEA.AddParameterFrame(MyntFace::HideEyes, 1.0f);
212 eEA.AddParameterFrame(MyntFace::HideMouth, 1.0f);
213 eEA.AddParameterFrame(MyntFace::HideNose, 1.0f);
215
216 talk = false;
217 hideFace = true;
218 }
219
220 void SOSFace(){
221 sos.Reset();
222
223 sos.GetObject()->Enable();
224
225 blink.Pause();
226 eEA.AddParameterFrame(MyntFace::HideEyes, 1.0f);
227 eEA.AddParameterFrame(MyntFace::HideMouth, 1.0f);
228 eEA.AddParameterFrame(MyntFace::HideNose, 1.0f);
229
230 talk = false;
231 hideFace = true;
232 }
233
235 pacmanFood.GetObject()->Enable();
236 pacman.GetObject()->Enable();
237
238 pacmanFood.Reset();
239 pacman.Reset();
240
241 blink.Pause();
242 eEA.AddParameterFrame(MyntFace::HideEyes, 1.0f);
243 eEA.AddParameterFrame(MyntFace::HideMouth, 1.0f);
244 eEA.AddParameterFrame(MyntFace::HideNose, 1.0f);
245
246 talk = false;
247 hideFace = true;
248 }
249
251 blink.Pause();
252 pM.GetObject()->Disable();
253 background.GetObject()->Enable();
254
255 talk = false;
256 hideFace = true;
257 }
258
259 void FadeIn(float stepRatio) override {}
260 void FadeOut(float stepRatio) override {}
261
263 return pM.GetObject();
264 }
265
267 if(MenuButtonHandler::UseMicrophone() && talk){
268 float mouthOpen = MicrophoneFourier::GetCurrentMagnitude() / 3.0f;
269 float mouthForward = 0.0f;
270
273
277
278 mouthOpen = Mathematics::Constrain(mouthOpen, 0.0f, 1.0f);
279 mouthForward = Mathematics::Constrain(mouthForward, 0.0f, 1.0f);
280
281 eEA.AddParameterFrame(MyntFace::MouthTalk, mouthOpen);
282 eEA.AddParameterFrame(MyntFace::MouthTalk2, mouthForward);
283 }
284 }
285 }
286
287 void Update(float ratio) override {
288 pM.Reset();
289
290 pM.GetObject()->Enable();
291 background.GetObject()->Disable();
292 pacmanFood.GetObject()->Disable();
293 pacman.GetObject()->Disable();
294 sos.GetObject()->Disable();
295 zzz.GetObject()->Disable();
296
297 blink.Play();
298 talk = true;
299 hideFace = false;
300
301 bool isBooped = MenuButtonHandler::UseBoopSensor() ? boop.isBooped() : 0;
302 uint8_t mode = MenuButtonHandler::GetFaceState();//change by button press
303
306 sA.SetHueAngle(ratio * 360.0f * 4.0f);
307 sA.SetMirrorYState(MenuButtonHandler::MirrorSpectrumAnalyzer());
308 sA.SetFlipYState(!MenuButtonHandler::MirrorSpectrumAnalyzer());
309
310 if (isBooped && mode != 6){
311 Angry();
312 }
313 else{
314 if (mode == 0) Default();
315 else if (mode == 1) Dead();
316 else if (mode == 2) Happy();
317 else if (mode == 3) Love();
318 else if (mode == 4) Sleepy();
319 else if (mode == 5) SleepyZZZ();
320 else if (mode == 6) SOSFace();
321 else if (mode == 7) PacmanFace();
323 }
324
327
328 pM.SetMorphWeight(MyntFace::IncreaseSize, 1.0f);
329 pacman.SetMorphWeight(MyntPacman::MouthClosed, fGenMatPacman.Update());
330
331 eEA.Update();
332 pM.Update();
333 pacmanFood.Update();
334 pacman.Update();
335 zzz.Update();
336 sos.Update();
337
338 rainbowNoise.Update(ratio);
339
340 faceMaterial.SetOpacity(1, redFaceMix);//set face to angry
341 faceMaterial.SetOpacity(2, pinkFaceMix);//set face to angry
342 faceMaterial.SetOpacity(3, blueFaceMix);//set face to angry
343
344 float x = fGenMatXMove.Update();
345 float y = fGenMatYMove.Update();
346
347 if(hideFace){
348 pM.GetObject()->GetTransform()->SetPosition(Vector3D(0, -1000.0f, 600.0f));
349 }
350 else{
351 pM.GetObject()->GetTransform()->SetPosition(Vector3D(x, y, 600.0f));
352 }
353
354 pM.GetObject()->GetTransform()->SetRotation(Vector3D(0.0f, 0.0f, 0.0f));
355 pM.GetObject()->GetTransform()->SetScale(Vector3D(1.0f, 1.0f, 1.0f));
356 pM.GetObject()->UpdateTransform();
357
358 float scalePacman = fGenMatScalePacman.Update();
359 float pacmanPos = 400.0f * (0.5f - ratio);
360 int pacmanFoodPos = pacmanPos < 0 ? (int(pacmanPos) / 25) * 25 : -(int(pacmanPos) / 25) * 50;
361
362 Vector3D pCenter = pacman.GetObject()->GetCenterOffset();
363 pacmanFood.GetObject()->GetTransform()->SetRotation(Vector3D(0.0f, 0.0f, 0.0f));
364 pacmanFood.GetObject()->GetTransform()->SetPosition(Vector3D(x + pacmanFoodPos, y, 700.0f));
365 pacmanFood.GetObject()->GetTransform()->SetScale(Vector3D(scalePacman, scalePacman, scalePacman));
366 pacmanFood.GetObject()->GetTransform()->SetScaleOffset(pCenter);
367 pacmanFood.GetObject()->UpdateTransform();
368
369 pacman.GetObject()->GetTransform()->SetRotation(Vector3D(0.0f, 0.0f, 0.0f));
370 pacman.GetObject()->GetTransform()->SetPosition(Vector3D(x + pacmanPos, y, 600.0f));
371 pacman.GetObject()->GetTransform()->SetScale(Vector3D(scalePacman, scalePacman, scalePacman));
372 pacman.GetObject()->GetTransform()->SetScaleOffset(pCenter);
373 pacman.GetObject()->UpdateTransform();
374
375 float scaleAnim = fGenMatScaleAnim.Update();
376 float scaleSOS = 0.5f + scaleAnim / 2.0f;
377
378 Vector3D sosCenter = sos.GetObject()->GetCenterOffset();
379 sos.GetObject()->GetTransform()->SetRotation(Vector3D(0.0f, ratio * 360.0f, 0.0f));
380 sos.GetObject()->GetTransform()->SetRotationOffset(sosCenter);
381 sos.GetObject()->GetTransform()->SetPosition(Vector3D(x - 5.0f, y - 15.0f, 600.0f));
382 sos.GetObject()->GetTransform()->SetScale(Vector3D(scaleSOS, scaleSOS, scaleSOS));
383 sos.GetObject()->GetTransform()->SetScaleOffset(sosCenter);
384 sos.GetObject()->UpdateTransform();
385
386 float scaleZZZ = 0.9f + scaleAnim / 5.0f;
387
388 Vector3D zzzCenter = zzz.GetObject()->GetCenterOffset();
389 zzz.GetObject()->GetTransform()->SetRotation(Vector3D(0.0f, ratio * 360.0f, 0.0f));
390 zzz.GetObject()->GetTransform()->SetRotationOffset(zzzCenter);
391 zzz.GetObject()->GetTransform()->SetPosition(Vector3D(x - 15.0f, y - 15.0f, 600.0f));
392 zzz.GetObject()->GetTransform()->SetScale(Vector3D(scaleZZZ, scaleZZZ, scaleZZZ));
393 zzz.GetObject()->GetTransform()->SetScaleOffset(zzzCenter);
394 zzz.GetObject()->UpdateTransform();
395 }
396};
void AddParameter(float *parameter)
Adds a parameter to the animation track.
void Play()
Starts or resumes playback of the animation track.
void Pause()
Pauses playback of the animation track.
float Update()
Updates the animation track and returns the current parameter value.
A template class for animating eye blinking using keyframes.
Definition BlinkTrack.h:27
Combines multiple materials with specified blending methods and opacities.
void SetOpacity(uint8_t index, float opacity)
Sets the opacity for a specific material.
void AddMaterial(Method method, Material *material, float opacity)
Adds a new material to the combination.
A template class for implementing advanced animation easing.
void AddParameterFrame(uint16_t dictionaryValue, float value) override
Adds a single frame value for a parameter.
void Update() override
Updates the animator, advancing all animations.
void SetInterpolationMethod(uint16_t dictionaryValue, InterpolationMethod interpMethod) override
Sets the interpolation method for a specific parameter.
void AddParameter(float *parameter, uint16_t dictionaryValue, uint16_t frames, float basis, float goal) override
Adds a parameter to the animator.
Detects visemes based on FFT voice analysis.
float GetViseme(MouthShape viseme)
Retrieves the probability of a specific viseme.
void Update(float *peaks, float maxFrequency)
Updates the viseme probabilities based on new FFT data.
A class to generate various waveform functions with customizable parameters.
@ Sine
Sine waveform.
float Update()
Updates and calculates the next value of the waveform.
@ Lighten
Chooses the lighter color.
Definition Material.h:40
@ Add
Adds colors together.
Definition Material.h:35
@ Replace
Replaces the base color.
Definition Material.h:44
static T Constrain(T value, T minimum, T maximum)
Constrains a value between minimum and maximum.
static float GetCurrentMagnitude()
Retrieves the current signal magnitude.
static float GetSampleRate()
Retrieves the current sampling rate.
static float * GetFourierFiltered()
Retrieves the filtered FFT output data.
static void Initialize(uint8_t pin, uint32_t sampleRate, float minDB, float maxDB)
Initializes the microphone and FFT system with basic parameters.
static void Update()
Updates the microphone system, processing new samples and performing FFT.
SimpleMaterial greenMaterial
FunctionGenerator fGenMatYMove
MyntPacman pacman
SpectrumAnalyzer sA
SimpleMaterial pinkMaterial
SimpleMaterial redMaterial
SimpleMaterial tealMaterial
uint8_t blueFaceIndex
void UpdateKeyFrameTracks()
FunctionGenerator fGenMatPacman
BoopSensor boop
SimpleMaterial blueMaterial
CombineMaterial< 5 > faceMaterial
FunctionGenerator fGenMatScalePacman
SimpleMaterial yellowMaterial
void UpdateFFTVisemes()
uint8_t pinkFaceIndex
BlinkTrack< 1 > blink
void ChangeInterpolationMethods()
void SpectrumAnalyzerFace()
FunctionGenerator fGenMatPos
FunctionGenerator fGenScale
Background background
uint8_t redFaceIndex
FunctionGenerator fGenRotation
EasyEaseAnimator< 30 > eEA
void FadeIn(float stepRatio) override
void FadeOut(float stepRatio) override
RainbowNoise rainbowNoise
FunctionGenerator fGenMatXMove
void Update(float ratio) override
FFTVoiceDetection< 128 > voiceDetection
void LinkEasyEase()
void LinkParameters()
FunctionGenerator fGenMatScaleAnim
MyntFood pacmanFood
Object3D * GetObject()
Represents a 3D object with geometry, material, and transformation data.
Definition Object3D.h:28
Represents an RGB color and provides methods for manipulation.
Definition RGBColor.h:23
A dynamic material that creates a rainbow effect using simplex noise.
void Update(float ratio)
Updates the material animation based on the time ratio.
A material that applies a single, solid RGB color to surfaces.
A material that visualizes audio data as a spectrum.
void SetMirrorYState(bool state)
Sets the mirroring state for the visualization.
void Update(float *readData)
Updates the spectrum visualization with new audio data.
void SetFlipYState(bool state)
Sets the flipping state for the visualization.
void SetHueAngle(float hueAngle)
Sets the hue adjustment angle for the spectrum colors.
Represents a 2D vector (X, Y) and provides methods for vector arithmetic.
Definition Vector2D.h:27
Represents a 3D vector (X, Y, Z) and provides methods for vector arithmetic.
Definition Vector3D.h:26
@ ER
Mouth shape corresponding to the "ER" sound.
@ OO
Mouth shape corresponding to the "OO" sound.
@ AH
Mouth shape corresponding to the "AH" sound.
@ UH
Mouth shape corresponding to the "UH" sound.
@ AR
Mouth shape corresponding to the "AR" sound.
@ EE
Mouth shape corresponding to the "EE" sound.