ProtoTracer  1.0
Real-time 3D rendering and animation engine
Loading...
Searching...
No Matches
HertzzAnimation.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 "../../Objects/LEDStripBackground.h"
8#include "../../Morph/ProtoV2Morph.h"
9#include "../../Render/Scene.h"
10#include "../../Signals/FunctionGenerator.h"
11#include "../../Menu/Menu.h"
12#include "../../Sensors/APDS9960.h"
13#include "../../Sensors/SSD1306.h"
14
15#include "../../Materials/Animated/RainbowNoise.h"
16#include "../../Materials/Animated/RainbowSpiral.h"
17#include "../../Materials/Animated/SpectrumAnalyzer.h"
18#include "../../Materials/Animated/AudioReactiveGradient.h"
19#include "../../Materials/Animated/Oscilloscope.h"
20
21#include "../../Materials/MaterialAnimator.h"
22
23#include "../AnimationTracks/BlinkTrack.h"
24
25#include "../../Signals/FFTVoiceDetection.h"
26
27#include "../../Sensors/MicrophoneFourier_MAX9814.h"
28
29
30class HertzzAnimation : public Animation<2> {
31private:
32 ProtoV2 pM;
33 Background background;
34 EasyEaseAnimator<21> eEA = EasyEaseAnimator<21>(EasyEaseInterpolation::Overshoot, 1.0f, 0.35f);
35
36 //Materials
46
47 RGBColor gradientSpectrum[2] = {RGBColor(5, 162, 232), RGBColor(10, 170, 255)};
49
52
53 SpectrumAnalyzer sA = SpectrumAnalyzer(Vector2D(200, 100), Vector2D(100, 50), true, true);
56
57 //Animation controllers
59
66
70
73
74 SSD1306 oledDisplay;
75
77
78 float offsetFace = 0.0f;
79 float offsetFaceSA = 0.0f;
80 float offsetFaceARG = 0.0f;
81 float offsetFaceOSC = 0.0f;
82 uint8_t offsetFaceInd = 50;
83 uint8_t offsetFaceIndSA = 51;
84 uint8_t offsetFaceIndARG = 52;
85 uint8_t offsetFaceIndOSC = 53;
86
88 eEA.AddParameter(pM.GetMorphWeightReference(ProtoV2::Normal), ProtoV2::Normal, 15, 0.0f, 1.0f);
89 eEA.AddParameter(pM.GetMorphWeightReference(ProtoV2::Blush), ProtoV2::Blush, 25, 0.0f, 1.0f);
90 eEA.AddParameter(pM.GetMorphWeightReference(ProtoV2::Hideblush), ProtoV2::Hideblush, 25, 0.0f, 1.0f);
91 eEA.AddParameter(pM.GetMorphWeightReference(ProtoV2::Squint), ProtoV2::Squint, 30, 0.0f, 1.0f);
92 eEA.AddParameter(pM.GetMorphWeightReference(ProtoV2::Surprised), ProtoV2::Surprised, 10, 0.0f, 1.0f);
93 eEA.AddParameter(pM.GetMorphWeightReference(ProtoV2::Happy), ProtoV2::Happy, 20, 0.0f, 1.0f);
94 eEA.AddParameter(pM.GetMorphWeightReference(ProtoV2::Sad), ProtoV2::Sad, 45, 0.0f, 1.0f);
95 eEA.AddParameter(pM.GetMorphWeightReference(ProtoV2::Talk), ProtoV2::Talk, 2, 0.0f, 1.0f);
96 eEA.AddParameter(pM.GetMorphWeightReference(ProtoV2::Whoop), ProtoV2::Whoop, 30, 0.0f, 1.0f);
97 eEA.AddParameter(pM.GetMorphWeightReference(ProtoV2::Side1), ProtoV2::Side1, 30, 0.0f, 1.0f);
98 eEA.AddParameter(pM.GetMorphWeightReference(ProtoV2::Angry), ProtoV2::Angry, 20, 0.0f, 1.0f);
99
100 eEA.AddParameter(&offsetFace, offsetFaceInd, 40, 0.0f, 1.0f);
101 eEA.AddParameter(&offsetFaceSA, offsetFaceIndSA, 40, 0.0f, 1.0f);
104 }
105
107 blink.AddParameter(pM.GetMorphWeightReference(ProtoV2::Blink));
108 }
109
111 eEA.SetInterpolationMethod(ProtoV2::Hideblush, EasyEaseInterpolation::Cosine);
112 eEA.SetInterpolationMethod(ProtoV2::Sad, EasyEaseInterpolation::Cosine);
113
114 eEA.SetInterpolationMethod(ProtoV2::Talk, EasyEaseInterpolation::Linear);
115 }
116
134
136 blink.Update();
137 }
138
139
140 void Default(){
141 oledDisplay.Display(F("Animating..."), F("Face: "), F("Default"));
142 eEA.AddParameterFrame(ProtoV2::Hideblush, 1.0f);
143 }
144
145 void Squint(){
146 oledDisplay.Display(F("Animating..."), F("Face: "), F("Squint"));
147 eEA.AddParameterFrame(ProtoV2::Squint, 1.0f);
148 eEA.AddParameterFrame(ProtoV2::Hideblush, 1.0f);
149 }
150
151 void Surprised(){
152 oledDisplay.Display(F("Animating..."), F("Face: "), F("Surprised"));
153 eEA.AddParameterFrame(ProtoV2::Surprised, 1.0f);
154 eEA.AddParameterFrame(ProtoV2::Hideblush, 1.0f);
155 }
156
157 void Happy(){
158 oledDisplay.Display(F("Animating..."), F("Face: "), F("Happy"));
159 eEA.AddParameterFrame(ProtoV2::Happy, 1.0f);
160 eEA.AddParameterFrame(ProtoV2::Hideblush, 1.0f);
161 }
162
163 void Sad(){
164 oledDisplay.Display(F("Animating..."), F("Face: "), F("Sad"));
165 eEA.AddParameterFrame(ProtoV2::Sad, 1.0f);
166 eEA.AddParameterFrame(ProtoV2::Hideblush, 1.0f);
167 }
168
169 void Whoop(){
170 oledDisplay.Display(F("Animating..."), F("Face: "), F("Whoop"));
171 eEA.AddParameterFrame(ProtoV2::Whoop, 1.0f);
172 eEA.AddParameterFrame(ProtoV2::Hideblush, 1.0f);
173 }
174
175 void Angry(){
176 oledDisplay.Display(F("Animating..."), F("Face: "), F("Angry"));
177 eEA.AddParameterFrame(ProtoV2::Angry, 1.0f);
178 eEA.AddParameterFrame(ProtoV2::Hideblush, 1.0f);
179 }
180
181 void Blush(){
182 oledDisplay.Display(F("Animating..."), F("Face: "), F("Blush"));
183 eEA.AddParameterFrame(ProtoV2::Blush, 1.0f);
184 }
185
187 oledDisplay.Display(F("Animating..."), F("Audio: "), F("Fourier"));
190
192 }
193
195 oledDisplay.Display(F("Animating..."), F("Audio: "), F("Round"));
198
200 }
201
203 oledDisplay.Display(F("Animating..."), F("Audio: "), F("Oscillo"));
206
208 }
209
212 //eEA.AddParameterFrame(ProtoV2::Talk, MicrophoneFourierIT::GetCurrentMagnitude() / 2.0f);
213
214 if(MicrophoneFourierIT::GetCurrentMagnitude() > 0.05f){
215 /*
216 voiceDetection.Update(MicrophoneFourierIT::GetFourierFiltered(), MicrophoneFourierIT::GetSampleRate());
217
218 eEA.AddParameterFrame(ProtoV2::vrc_v_ee, voiceDetection.GetViseme(voiceDetection.EE));
219 eEA.AddParameterFrame(ProtoV2::vrc_v_ih, voiceDetection.GetViseme(voiceDetection.AH));
220 eEA.AddParameterFrame(ProtoV2::vrc_v_dd, voiceDetection.GetViseme(voiceDetection.UH));
221 eEA.AddParameterFrame(ProtoV2::vrc_v_rr, voiceDetection.GetViseme(voiceDetection.AR));
222 eEA.AddParameterFrame(ProtoV2::vrc_v_ch, voiceDetection.GetViseme(voiceDetection.ER));
223 eEA.AddParameterFrame(ProtoV2::vrc_v_aa, voiceDetection.GetViseme(voiceDetection.AH));
224 eEA.AddParameterFrame(ProtoV2::vrc_v_oh, voiceDetection.GetViseme(voiceDetection.OO));
225 */
226 }
227 }
228 }
229
231 switch(Menu::GetFaceColor()){
232 case 1: materialAnimator.AddMaterialFrame(redMaterial, 0.8f); break;
234 case 3: materialAnimator.AddMaterialFrame(whiteMaterial, 0.8f); break;
235 case 4: materialAnimator.AddMaterialFrame(greenMaterial, 0.8f); break;
236 case 5: materialAnimator.AddMaterialFrame(blueMaterial, 0.8f); break;
239 case 8: materialAnimator.AddMaterialFrame(rainbowSpiral, 0.8f); break;
240 case 9: materialAnimator.AddMaterialFrame(rainbowNoise, 0.8f); break;
241 default: break;
242 }
243 }
244
245public:
247 scene.AddObject(pM.GetObject());
248 scene.AddObject(background.GetObject());
249
250 LinkEasyEase();
252
254
256
257 pM.GetObject()->SetMaterial(&materialAnimator);
258 background.GetObject()->SetMaterial(&backgroundMaterial);
259
260 boop.Initialize(5);
261 oledDisplay.Initialize();
262
263 MicrophoneFourierIT::Initialize(22, 8000, 50.0f, 120.0f);//8KHz sample rate, 50dB min, 120dB max
264 Menu::Initialize(10, 15, 500);//7 is number of faces
265 }
266
267 void FadeIn(float stepRatio) override {}
268 void FadeOut(float stepRatio) override {}
269
271 return pM.GetObject();
272 }
273
274 void Update(float ratio) override {
275 pM.Reset();
276
277 float xOffset = fGenMatXMove.Update();
278 float yOffset = fGenMatYMove.Update();
279
280 Menu::Update(ratio);
281
283
284 bool isBooped = Menu::UseBoopSensor() ? boop.isBooped() : 0;
285 uint8_t mode = Menu::GetFaceState();//change by button press
286
287 MicrophoneFourierIT::Update();
288 sA.SetHueAngle(ratio * 360.0f * 4.0f);
291
292 aRG.SetRadius((xOffset + 2.0f) * 2.0f + 25.0f);
293 aRG.SetSize(Vector2D((xOffset + 2.0f) * 10.0f + 50.0f, (xOffset + 2.0f) * 10.0f + 50.0f));
294 aRG.SetHueAngle(ratio * 360.0f * 8.0f);
295 aRG.SetRotation(ratio * 360.0f * 2.0f);
296 aRG.SetPosition(Vector2D(80.0f + xOffset * 4.0f, 48.0f + yOffset * 4.0f));
297
298 oSC.SetSize(Vector2D(200.0f, 100.0f));
299 oSC.SetHueAngle(ratio * 360.0f * 8.0f);
300 oSC.SetPosition(Vector2D(100.0f, 50.0f));
301
302 voiceDetection.SetThreshold(map(Menu::GetMicLevel(), 0, 10, 1000, 50));
303
305
306 if (isBooped){
307 Blush();
308 }
309 else{
310 if (mode == 0) Default();
311 else if (mode == 1) Squint();
312 else if (mode == 2) Happy();
313 else if (mode == 3) Sad();
314 else if (mode == 4) Whoop();
315 else if (mode == 5) Angry();
316 else if (mode == 6) Surprised();
317 else if (mode == 7) {
318 aRG.Update(MicrophoneFourierIT::GetFourierFiltered());
320 }
321 else if (mode == 8){
322 oSC.Update(MicrophoneFourierIT::GetSamples());
324 }
325 else {
326 sA.Update(MicrophoneFourierIT::GetFourierFiltered());
328 }
329 }
330
332
333 pM.SetMorphWeight(ProtoV2::Side1, sineSidePanel.Update());
334
335 eEA.Update();
336 pM.Update();
337
338 float menuRatio = Menu::ShowMenu();
339
340 rainbowNoise.Update(ratio);
341 rainbowSpiral.Update(ratio);
344
345 uint8_t faceSize = Menu::GetFaceSize();
346
347 float scale = menuRatio * 0.5f + 0.5f;
348 float xShift = (1.0f - menuRatio) * -10.0f;
349 float yShift = (1.0f - menuRatio) * 70.0f + offsetFaceSA * -150.0f;
350 float adjustFacePos = float(4 - faceSize) * 5.0f;
351 float adjustFaceX = float(faceSize) * 0.05f;
352
353 pM.GetObject()->GetTransform()->SetPosition(Vector3D(20.0f + xOffset, 0.0f + yOffset, 600.0f));
354 //pM.GetObject()->GetTransform()->SetPosition(Vector3D(-20.0f + xOffset - xShift + adjustFacePos, 0.0f + yOffset + yShift, 600.0f));
355 //pM.GetObject()->GetTransform()->SetScale(Vector3D(-0.975f + adjustFaceX, 0.65f, 0.8f).Multiply(scale));
356 pM.GetObject()->GetTransform()->SetRotation(Vector3D(sinf(ratio * 3.14159f / 180.0f * 1440.0f) * 1.0f, sinf(ratio * 3.14159f / 180.0f * 720.0f) * 1.0f, 0.0f));
357
358 pM.GetObject()->UpdateTransform();
359 }
360};
A class for managing the Adafruit APDS9960 sensor.
Definition APDS9960.h:27
static bool Initialize(uint8_t threshold)
Initializes the APDS9960 sensor.
Definition APDS9960.cpp:14
static bool isBooped()
Checks if the sensor is "booped" (close proximity detected).
Definition APDS9960.cpp:43
void AddParameter(float *parameter)
Adds a parameter to 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
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.
void SetThreshold(float threshold)
Sets the threshold for formant calculations.
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.
FunctionGenerator fGenMatHue
SimpleMaterial greenMaterial
FunctionGenerator fGenMatYMove
SpectrumAnalyzer sA
Oscilloscope oSC
SimpleMaterial redMaterial
RainbowSpiral rainbowSpiral
SimpleMaterial blueMaterial
FunctionGenerator fGenMatRMenu
void AudioReactiveGradientFace()
SimpleMaterial yellowMaterial
BlinkTrack< 1 > blink
void ChangeInterpolationMethods()
GradientMaterial< 2 > gradientMat
FunctionGenerator fGenMatPos
FunctionGenerator fGenScale
Background background
FunctionGenerator fGenRotation
SimpleMaterial orangeMaterial
FunctionGenerator fGenMatXMenu
FunctionGenerator sineSidePanel
void FadeIn(float stepRatio) override
void FadeOut(float stepRatio) override
RainbowNoise rainbowNoise
FunctionGenerator fGenMatYMenu
FunctionGenerator fGenMatXMove
MaterialAnimator< 10 > materialAnimator
SimpleMaterial purpleMaterial
void Update(float ratio) override
FFTVoiceDetection< 128 > voiceDetection
RGBColor gradientSpectrum[2]
MaterialAnimator< 4 > backgroundMaterial
Object3D * GetObject()
EasyEaseAnimator< 21 > eEA
SimpleMaterial whiteMaterial
AudioReactiveGradient aRG
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.
@ 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
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.
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.
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