ProtoTracer  1.0
Real-time 3D rendering and animation engine
Loading...
Searching...
No Matches
StrawberryAnimation.h
Go to the documentation of this file.
1#pragma once
2
3#include "../Animation.h"
4#include "../AnimationTracks/BlinkTrack.h"
5#include "../KeyFrameTrack.h"
6#include "../EasyEaseAnimator.h"
7#include "../../Objects/Background.h"
8#include "../../Objects/LEDStripBackground.h"
9#include "../../Morph/Commissions/StrawberryBlush.h"
10#include "../../Morph/Commissions/StrawberryFace.h"
11#include "../../Morph/Commissions/StrawberryStinky.h"
12#include "../../Morph/Commissions/StrawberryTears.h"
13#include "../../Render/Scene.h"
14#include "../../Menu/Menu.h"
15#include "../../Signals/FunctionGenerator.h"
16#include "../../Signals/FFTVoiceDetection.h"
17#include "../../Sensors/BoopSensor.h"
18#include "../../Sensors/MicrophoneFourier_MAX9814.h"
19#include "../../Render/ObjectAlign.h"
20
21#include "../../Materials/Animated/RainbowNoise.h"
22#include "../../Materials/Animated/RainbowSpiral.h"
23#include "../../Materials/Animated/SpectrumAnalyzer.h"
24#include "../../Materials/Animated/AudioReactiveGradient.h"
25#include "../../Materials/Animated/Oscilloscope.h"
26#include "../../Materials/MaterialAnimator.h"
27#include "../../Materials/MaterialMask.h"
28
29#include "../../Shapes/Circle.h"
30#include "../../Shapes/Ellipse.h"
31
32class StrawberryAnimation : public Animation<6> {
33private:
34 StrawberryFace pM;
35 StrawberryBlush pMBlush;
36 StrawberryStinky pMStinky;
37 StrawberryTears pMTears;
38 Background background;
39 LEDStripBackground ledStripBackground;
40
41 Ellipse tongue = Ellipse(Vector2D(100.0f, 5.0f), Vector2D(100.0f, 40.0f), 0.0f);
42 Circle eye = Circle(Vector2D(125.0f, 100.0f), 60.0f);
43
44 EasyEaseAnimator<30> eEA = EasyEaseAnimator<30>(EasyEaseInterpolation::Overshoot, 1.0f, 0.35f);
45
46 //Materials
57
58 RGBColor gradientSpectrum[2] = {RGBColor(100, 0, 80), RGBColor(80, 0, 60)};
60
63
66
67
68 SpectrumAnalyzer sA = SpectrumAnalyzer(Vector2D(200, 100), Vector2D(100, 50), true, true);
71
72 //Animation controllers
74
81
85
88
89 BoopSensor boop;
90
92
93 ObjectAlign objA = ObjectAlign(Vector2D(0.0f, 0.0f), Vector2D(170.0f, 115.0f), Quaternion());
94
95 float offsetFace = 0.0f;
96 float offsetFaceSA = 0.0f;
97 float offsetFaceARG = 0.0f;
98 float offsetFaceOSC = 0.0f;
99 float showTears = 0.0f;
100 float showBlush = 0.0f;
101 float showStink = 0.0f;
102 uint8_t offsetFaceInd = 50;
103 uint8_t offsetFaceIndSA = 51;
104 uint8_t offsetFaceIndARG = 52;
105 uint8_t offsetFaceIndOSC = 53;
106 uint8_t showTearsInd = 54;
107 uint8_t showBlushInd = 55;
108 uint8_t showStinkInd = 56;
109 uint8_t changeEyeColorInd = 57;
110
112 eEA.AddParameter(pM.GetMorphWeightReference(StrawberryFace::Happy), StrawberryFace::Happy, 30, 0.0f, 1.0f);
113 eEA.AddParameter(pM.GetMorphWeightReference(StrawberryFace::Happy2), StrawberryFace::Happy2, 30, 0.0f, 1.0f);
114 eEA.AddParameter(pM.GetMorphWeightReference(StrawberryFace::HappyPog), StrawberryFace::HappyPog, 20, 0.0f, 1.0f);
115 eEA.AddParameter(pM.GetMorphWeightReference(StrawberryFace::Happy3), StrawberryFace::Happy3, 30, 0.0f, 1.0f);
116 eEA.AddParameter(pM.GetMorphWeightReference(StrawberryFace::Content), StrawberryFace::Content, 45, 0.0f, 1.0f);
117 eEA.AddParameter(pM.GetMorphWeightReference(StrawberryFace::PogHeart), StrawberryFace::PogHeart, 30, 0.0f, 1.0f);
118 eEA.AddParameter(pM.GetMorphWeightReference(StrawberryFace::HappySurprised), StrawberryFace::HappySurprised, 15, 0.0f, 1.0f);
119 eEA.AddParameter(pM.GetMorphWeightReference(StrawberryFace::Nervous), StrawberryFace::Nervous, 30, 0.0f, 1.0f);
120 eEA.AddParameter(pM.GetMorphWeightReference(StrawberryFace::BlushHappy), StrawberryFace::BlushHappy, 30, 0.0f, 1.0f);
121 eEA.AddParameter(pM.GetMorphWeightReference(StrawberryFace::Stink), StrawberryFace::Stink, 30, 0.0f, 1.0f);
122
123 //eEA.AddParameter(pM.GetMorphWeightReference(StrawberryFace::Basis), StrawberryFace::Basis, 2, 0.0f, 1.0f);
124 eEA.AddParameter(pM.GetMorphWeightReference(StrawberryFace::TalkA), StrawberryFace::TalkA, 2, 0.0f, 1.0f);
125 eEA.AddParameter(pM.GetMorphWeightReference(StrawberryFace::TalkE), StrawberryFace::TalkE, 2, 0.0f, 1.0f);
126 eEA.AddParameter(pM.GetMorphWeightReference(StrawberryFace::TalkO), StrawberryFace::TalkO, 2, 0.0f, 1.0f);
127
128 eEA.AddParameter(&offsetFace, offsetFaceInd, 40, 0.0f, 1.0f);
129 eEA.AddParameter(&offsetFaceSA, offsetFaceIndSA, 40, 0.0f, 1.0f);
132 eEA.AddParameter(&showTears, showTearsInd, 40, 0.0f, 1.0f);
133 eEA.AddParameter(&showBlush, showBlushInd, 40, 0.0f, 1.0f);
134 eEA.AddParameter(&showStink, showStinkInd, 40, 0.0f, 1.0f);
136 }
137
139 blink.AddParameter(pM.GetMorphWeightReference(StrawberryFace::Blink));
140 }
141
143 eEA.SetInterpolationMethod(StrawberryFace::TalkA, EasyEaseInterpolation::Linear);
144 eEA.SetInterpolationMethod(StrawberryFace::TalkE, EasyEaseInterpolation::Linear);
145 eEA.SetInterpolationMethod(StrawberryFace::TalkO, EasyEaseInterpolation::Linear);
146
147 eEA.SetInterpolationMethod(StrawberryFace::Stink, EasyEaseInterpolation::Cosine);
148 eEA.SetInterpolationMethod(StrawberryFace::Nervous, EasyEaseInterpolation::Linear);
149 }
150
168
170 blink.Update();
171 }
172
173 void Default(){//Default mouth
174 eEA.AddParameterFrame(StrawberryFace::Happy, 1.0f);
175 blink.Pause();
176 }
177
178 void HappyOpen(){
179 eEA.AddParameterFrame(StrawberryFace::Happy2, 1.0f);
180 blink.Pause();
181 }
182
183 void HappyPOG(){
184 eEA.AddParameterFrame(StrawberryFace::HappyPog, 1.0f);
185 blink.Pause();
186 }
187
189 eEA.AddParameterFrame(StrawberryFace::Happy3, 1.0f);
190 blink.Pause();
191 }
192
193 void HappyCalm(){
194 eEA.AddParameterFrame(StrawberryFace::Content, 1.0f);
195 blink.Play();
196 }
197
198 void HeartPOG(){
199 eEA.AddParameterFrame(StrawberryFace::PogHeart, 1.0f);
200 blink.Pause();
201 }
202
204 eEA.AddParameterFrame(StrawberryFace::HappySurprised, 1.0f);
205 blink.Play();
206 }
207
208 void Nervous(){
209 eEA.AddParameterFrame(StrawberryFace::Nervous, 1.0f);
211 blink.Pause();
212 }
213
214 void Blush(){
215 eEA.AddParameterFrame(StrawberryFace::BlushHappy, 1.0f);
217 blink.Pause();
218 }
219
220 void Stinky(){
221 eEA.AddParameterFrame(StrawberryFace::Stink, 1.0f);
224 blink.Pause();
225 }
226
233
240
247
250 eEA.AddParameterFrame(StrawberryFace::TalkA, MicrophoneFourierIT::GetCurrentMagnitude() * 0.5f);
251
252 if(MicrophoneFourierIT::GetCurrentMagnitude() > 0.05f){
253 voiceDetection.Update(MicrophoneFourierIT::GetFourierFiltered(), MicrophoneFourierIT::GetSampleRate());
254
257 //eEA.AddParameterFrame(StrawberryFace::TalkA, voiceDetection.GetViseme(voiceDetection.AR));
258 //eEA.AddParameterFrame(StrawberryFace::TalkA, voiceDetection.GetViseme(voiceDetection.AH));
259 //eEA.AddParameterFrame(StrawberryFace::TalkO, voiceDetection.GetViseme(voiceDetection.OO) / 0.75f);
260 }
261 }
262 }
263
265 switch(Menu::GetFaceColor()){
266 case 1: materialAnimator.AddMaterialFrame(redMaterial, 0.8f); break;
268 case 3: materialAnimator.AddMaterialFrame(whiteMaterial, 0.8f); break;
269 case 4: materialAnimator.AddMaterialFrame(greenMaterial, 0.8f); break;
270 case 5: materialAnimator.AddMaterialFrame(blueMaterial, 0.8f); break;
273 case 8: materialAnimator.AddMaterialFrame(rainbowSpiral, 0.8f); break;
274 case 9: materialAnimator.AddMaterialFrame(rainbowNoise, 0.8f); break;
275 default: break;
276 }
277 }
278
279public:
281 scene.AddObject(pM.GetObject());
282 scene.AddObject(pMBlush.GetObject());
283 scene.AddObject(pMStinky.GetObject());
284 scene.AddObject(pMTears.GetObject());
285 scene.AddObject(background.GetObject());
286 scene.AddObject(ledStripBackground.GetObject());
287
288 LinkEasyEase();
290
292
294
295 pM.GetObject()->SetMaterial(&materialAnimator);
296 pMBlush.GetObject()->SetMaterial(&redMaterial);
297 pMStinky.GetObject()->SetMaterial(&greenMaterial);
298 pMTears.GetObject()->SetMaterial(&blueMaterial);
299 background.GetObject()->SetMaterial(&backgroundMaterial);
300 ledStripBackground.GetObject()->SetMaterial(&materialAnimator);
301
302 boop.Initialize(5);
303
304 MicrophoneFourierIT::Initialize(22, 8000, 30.0f, 100.0f);//8KHz sample rate, 50dB min, 120dB max
305 Menu::Initialize(12, 0, 500);//13 is number of faces
306
308
310 objA.SetMirrorX(true);
311 //objA.SetMirrorY(true);
312 }
313
314 void FadeIn(float stepRatio) override {}
315 void FadeOut(float stepRatio) override {}
316
318 return pM.GetObject();
319 }
320
321 void Update(float ratio) override {
322 pM.Reset();
323
324 float xOffset = fGenMatXMove.Update();
325 float yOffset = fGenMatYMove.Update();
326
327 Menu::Update();
328
330
331 bool isBooped = Menu::UseBoopSensor() ? boop.isBooped() : 0;
332 uint8_t mode = Menu::GetFaceState();//change by button press
333
334 MicrophoneFourierIT::Update();
335 sA.SetHueAngle(ratio * 360.0f * 4.0f);
338
339 aRG.SetRadius((xOffset + 2.0f) * 2.0f + 25.0f);
340 aRG.SetSize(Vector2D((xOffset + 2.0f) * 10.0f + 50.0f, (xOffset + 2.0f) * 10.0f + 50.0f));
341 aRG.SetHueAngle(ratio * 360.0f * 8.0f);
342 aRG.SetRotation(ratio * 360.0f * 2.0f);
343 aRG.SetPosition(Vector2D(80.0f + xOffset * 4.0f, 48.0f + yOffset * 4.0f));
344
345 oSC.SetSize(Vector2D(200.0f, 100.0f));
346 oSC.SetHueAngle(ratio * 360.0f * 8.0f);
347 oSC.SetPosition(Vector2D(100.0f, 50.0f));
348
349 voiceDetection.SetThreshold(map(Menu::GetMicLevel(), 0, 10, 1000, 50));
350
352
353 if (isBooped){
354 Blush();
355 }
356 else{
357 if (mode == 0) Default();
358 else if (mode == 1) HappyOpen();
359 else if (mode == 2) HappyPOG();
360 else if (mode == 3) HappyTooth();
361 else if (mode == 4) HappyCalm();
362 else if (mode == 5) HeartPOG();
363 else if (mode == 6) HappyEyeOpen();
364 else if (mode == 7) Nervous();
365 else if (mode == 8) Stinky();
366 else if (mode == 9) {
367 aRG.Update(MicrophoneFourierIT::GetFourierFiltered());
369 }
370 else if (mode == 10){
371 oSC.Update(MicrophoneFourierIT::GetSamples());
373 }
374 else {
375 sA.Update(MicrophoneFourierIT::GetFourierFiltered());
377 }
378 }
379
381
382 eEA.Update();
383 pM.Update();
384 pMBlush.Update();
385 pMTears.Update();
386 pMStinky.Update();
387
388 float menuRatio = Menu::ShowMenu();
389
390 rainbowNoise.Update(ratio);
391 rainbowSpiral.Update(ratio);
394
395 uint8_t faceSize = Menu::GetFaceSize();
396
397 float scale = menuRatio * 0.6f + 0.4f;
398 float faceSizeOffset = faceSize * 8.0f;
399
400 //objA.SetPlaneOffsetAngle(360.0f * ratio);
401 objA.SetEdgeMargin(2.0f);
402 objA.SetCameraMax(Vector2D(110.0f + faceSizeOffset, 115.0f).Multiply(scale));
403
404 objA.AlignObjects(scene.GetObjects(), 4);
405
406 pM.GetObject()->GetTransform()->SetPosition(Vector3D(xOffset + 5.0f, yOffset - 150.0f * offsetFace + 5.0f, 0.0f));
407 pM.GetObject()->UpdateTransform();
408
409 float stinkOffset = fGenMatStinkY.Update() * 15.0f;
410 float blushOffset = fGenMatBlushY.Update() * 10.0f;
411
412 pMBlush.GetObject()->GetTransform()->SetPosition(Vector3D(xOffset - 60.0f + 5.0f - stinkOffset, yOffset - 150.0f * offsetFace + blushOffset, 0.0f));
413 pMBlush.GetObject()->GetTransform()->SetScale(Vector3D(1.0f, 1.0f, 1.0f) * showBlush);
414 pMBlush.GetObject()->UpdateTransform();
415 pMStinky.GetObject()->GetTransform()->SetPosition(Vector3D(xOffset - 35.0f + 5.0f, yOffset - 150.0f * offsetFace - 10.0f - stinkOffset, 0.0f));
416 pMStinky.GetObject()->GetTransform()->SetScale(Vector3D(1.0f, 1.0f, 1.0f) * showStink);
417 pMStinky.GetObject()->UpdateTransform();
418 pMTears.GetObject()->GetTransform()->SetPosition(Vector3D(xOffset + 5.0f, yOffset - 150.0f * offsetFace - 48.0f, 0.0f));
419 pMTears.GetObject()->GetTransform()->SetScale(Vector3D(1.0f, 1.0f, 1.0f) * showTears);
420 pMTears.GetObject()->UpdateTransform();
421 }
422};
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 material class for creating an audio-reactive gradient effect.
void SetRadius(float radius)
Sets the radius for circular gradient patterns.
void SetPosition(Vector2D offset)
Sets the position of the gradient.
void Update(float *readData)
Updates the gradient based on new audio data.
void SetSize(Vector2D size)
Sets the size of the gradient.
void SetRotation(float angle)
Sets the rotation angle of the gradient.
void SetHueAngle(float hueAngle)
Sets the hue angle for color adjustments.
A template class for animating eye blinking using keyframes.
Definition BlinkTrack.h:27
Represents a circle in 2D space.
Definition Circle.h:21
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.
Represents an ellipse in 2D space.
Definition Ellipse.h:21
Detects visemes based on FFT voice analysis.
float GetViseme(MouthShape viseme)
Retrieves the probability of a specific viseme.
void SetThreshold(float threshold)
Sets the threshold for formant calculations.
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.
@ Triangle
Triangle waveform.
float Update()
Updates and calculates the next value of the waveform.
Creates a customizable gradient material for rendering.
void SetRotationAngle(float rotationAngle)
Sets the rotation angle for the gradient.
Animates transitions and blends between multiple materials.
void AddMaterial(Material::Method method, Material *material, uint16_t frames, float minOpacity, float maxOpacity)
Adds a material to the animation with specified properties.
void SetBaseMaterial(Material::Method method, Material *material)
Sets the base material for the animation.
void AddMaterialFrame(Material &material, float opacity)
Adds a specific frame for a material in the animation.
void Update()
Updates the animator, advancing the transitions.
Combines two materials using a shape as a mask.
float * GetOpacityReference()
Provides a reference to the opacity value.
@ 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 uint8_t GetFaceState()
Retrieves the current face state. In hardware mode, it is read from the MenuHandler.
Definition Menu.cpp:381
static uint8_t GetFaceColor()
Gets the current face color index.
Definition Menu.cpp:453
static uint8_t GetMicLevel()
Gets the current microphone level.
Definition Menu.cpp:417
static float ShowMenu()
Returns how much of the menu is shown, typically normalized (0.0 to 1.0).
Definition Menu.cpp:494
static Material * GetMaterial()
Provides a pointer to the material used for rendering the menu text.
Definition Menu.cpp:155
static uint8_t MirrorSpectrumAnalyzer()
Checks if the spectrum analyzer mirroring is toggled on or off.
Definition Menu.cpp:435
static uint8_t GetFaceSize()
Gets the current face size.
Definition Menu.cpp:444
static void Initialize(uint8_t faceCount, uint8_t pin, uint16_t holdingTime, Vector2D size=Vector2D(240, 50))
Initializes the Menu using a face count, input pin, holding time, and size.
Definition Menu.cpp:102
static uint8_t UseMicrophone()
Checks if the microphone usage is toggled on or off.
Definition Menu.cpp:408
static uint8_t UseBoopSensor()
Checks if the boop sensor usage is toggled on or off.
Definition Menu.cpp:426
static void Update(float ratio)
Updates the menu each frame, handling transitions, wiggle effects, and text generation.
Definition Menu.cpp:208
Represents a 3D object with geometry, material, and transformation data.
Definition Object3D.h:28
Handles aligning and transforming 3D objects to fit within specified 2D camera bounds.
Definition ObjectAlign.h:24
void SetEdgeMargin(float edgeMargin)
Sets the margin to keep from the edges when aligning objects.
@ Stretch
Attempt to scale the object(s) to fill the entire area.
Definition ObjectAlign.h:43
void SetJustification(Justification jst)
Sets the justification mode for alignment.
void SetCameraMax(Vector2D camMax)
Updates the maximum bounds for the 2D camera region.
void AlignObjects(Object3D **objs, uint8_t numObjects)
Aligns multiple objects within the camera bounds, including scale factors.
void SetMirrorX(bool mirrorX)
Enables or disables mirroring along the X-axis for the aligned objects.
A dynamic oscilloscope material for visualizing audio signals.
void SetPosition(Vector2D offset)
Sets the position of the oscilloscope visualization.
void SetSize(Vector2D size)
Sets the size of the oscilloscope visualization.
void Update(float *data)
Updates the oscilloscope visualization based on new audio data.
void SetHueAngle(float hueAngle)
Sets the hue angle for color adjustments.
A mathematical construct representing a rotation in 3D space.
Definition Quaternion.h:30
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 dynamic material creating a colorful rainbow spiral animation.
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.
FunctionGenerator fGenMatHue
SimpleMaterial greenMaterial
FunctionGenerator fGenMatYMove
SimpleMaterial blueMaterial
FunctionGenerator fGenMatRMenu
SimpleMaterial yellowMaterial
LEDStripBackground ledStripBackground
GradientMaterial< 2 > gradientMat
FunctionGenerator fGenMatPos
FunctionGenerator fGenScale
SimpleMaterial lightPinkMaterial
FunctionGenerator fGenMatBlushY
FunctionGenerator fGenRotation
EasyEaseAnimator< 30 > eEA
SimpleMaterial orangeMaterial
FunctionGenerator fGenMatXMenu
void FadeIn(float stepRatio) override
void FadeOut(float stepRatio) override
FunctionGenerator fGenMatYMenu
FunctionGenerator fGenMatXMove
MaterialAnimator< 10 > materialAnimator
SimpleMaterial purpleMaterial
void Update(float ratio) override
FFTVoiceDetection< 128 > voiceDetection
MaterialAnimator< 4 > backgroundMaterial
FunctionGenerator fGenMatStinkY
StrawberryStinky pMStinky
SimpleMaterial whiteMaterial
AudioReactiveGradient aRG
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.
@ UH
Mouth shape corresponding to the "UH" sound.
@ EE
Mouth shape corresponding to the "EE" sound.