ProtoTracer  1.0
Real-time 3D rendering and animation engine
Loading...
Searching...
No Matches
ProtogenSplitWS35Project.h
Go to the documentation of this file.
1//Inherit from protogen animation, adding additional function for splitting the face render
2//Implement ws35/hub75#pragma once
3
4#include "Animation.h"
5#include "KeyFrameTrack.h"
6#include "EasyEaseAnimator.h"
7#include "../Objects/Background.h"
8#include "../Objects/LEDStripBackground.h"
9#include "../Morph/NukudeFlat.h"
10#include "../Render/Scene.h"
11#include "../Signals/FunctionGenerator.h"
12#include "../Menu/SingleButtonMenu.h"
13#include "../Sensors/APDS9960.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
24
25#include "../Signals/FFTVoiceDetection.h"
26
27#include "../Sensors/MicrophoneFourier_MAX9814.h"
28
29#include "../Render/ObjectAlign.h"
30
31#include "../Screenspace/GlitchX.h"
32#include "../Screenspace/Fisheye.h"
33#include "../Screenspace/HorizontalBlur.h"
34#include "../Screenspace/PhaseOffsetX.h"
35#include "../Screenspace/PhaseOffsetY.h"
36#include "../Screenspace/PhaseOffsetR.h"
37#include "../Screenspace/Magnet.h"
38#include "../Screenspace/Overflow.h"
39#include "../Screenspace/RadialBlur.h"
40#include "../Screenspace/ShiftR.h"
41#include "../Screenspace/VerticalBlur.h"
42
43class WS35AnimationSplit : public Animation<3> {
44private:
45 static const uint8_t faceCount = 9;
46 NukudeFace pM;
47 Background background;
48 LEDStripBackground ledStripBackground;
49 EasyEaseAnimator<25> eEA = EasyEaseAnimator<25>(EasyEaseInterpolation::Overshoot, 1.0f, 0.35f);
50
51 //Materials
61
62 RGBColor gradientSpectrum[2] = {RGBColor(58, 254, 80), RGBColor(29, 128, 20)};
64
67
68 SpectrumAnalyzer sA = SpectrumAnalyzer(Vector2D(200, 100), Vector2D(100, 50), true, true);
71
72 //Animation controllers
74
81
85
87
89
91
92 ObjectAlign objA = ObjectAlign(Vector2D(0.0f, 0.0f), Vector2D(189.0f, 93.0f), Quaternion());
93
105
106 float offsetFace = 0.0f;
107 float offsetFaceSA = 0.0f;
108 float offsetFaceARG = 0.0f;
109 float offsetFaceOSC = 0.0f;
110 uint8_t offsetFaceInd = 50;
111 uint8_t offsetFaceIndSA = 51;
112 uint8_t offsetFaceIndARG = 52;
113 uint8_t offsetFaceIndOSC = 53;
114 bool mirror = false;
115
117 eEA.AddParameter(pM.GetMorphWeightReference(NukudeFace::Anger), NukudeFace::Anger, 15, 0.0f, 1.0f);
118 eEA.AddParameter(pM.GetMorphWeightReference(NukudeFace::Sadness), NukudeFace::Sadness, 50, 0.0f, 1.0f);
119 eEA.AddParameter(pM.GetMorphWeightReference(NukudeFace::Surprised), NukudeFace::Surprised, 10, 0.0f, 1.0f);
120 eEA.AddParameter(pM.GetMorphWeightReference(NukudeFace::Doubt), NukudeFace::Doubt, 25, 0.0f, 1.0f);
121 eEA.AddParameter(pM.GetMorphWeightReference(NukudeFace::Frown), NukudeFace::Frown, 45, 0.0f, 1.0f);
122 eEA.AddParameter(pM.GetMorphWeightReference(NukudeFace::LookUp), NukudeFace::LookUp, 30, 0.0f, 1.0f);
123 eEA.AddParameter(pM.GetMorphWeightReference(NukudeFace::LookDown), NukudeFace::LookDown, 30, 0.0f, 1.0f);
124
125 eEA.AddParameter(pM.GetMorphWeightReference(NukudeFace::vrc_v_ee), NukudeFace::vrc_v_ee, 2, 0.0f, 1.0f);
126 eEA.AddParameter(pM.GetMorphWeightReference(NukudeFace::vrc_v_ih), NukudeFace::vrc_v_ih, 2, 0.0f, 1.0f);
127 eEA.AddParameter(pM.GetMorphWeightReference(NukudeFace::vrc_v_dd), NukudeFace::vrc_v_dd, 2, 0.0f, 1.0f);
128 eEA.AddParameter(pM.GetMorphWeightReference(NukudeFace::vrc_v_rr), NukudeFace::vrc_v_rr, 2, 0.0f, 1.0f);
129 eEA.AddParameter(pM.GetMorphWeightReference(NukudeFace::vrc_v_ch), NukudeFace::vrc_v_ch, 2, 0.0f, 1.0f);
130 eEA.AddParameter(pM.GetMorphWeightReference(NukudeFace::vrc_v_aa), NukudeFace::vrc_v_aa, 2, 0.0f, 1.0f);
131 eEA.AddParameter(pM.GetMorphWeightReference(NukudeFace::vrc_v_oh), NukudeFace::vrc_v_oh, 2, 0.0f, 1.0f);
132 eEA.AddParameter(pM.GetMorphWeightReference(NukudeFace::vrc_v_ss), NukudeFace::vrc_v_ss, 2, 0.0f, 1.0f);
133
134 eEA.AddParameter(pM.GetMorphWeightReference(NukudeFace::HideBlush), NukudeFace::HideBlush, 30, 1.0f, 0.0f);
135 eEA.AddParameter(pM.GetMorphWeightReference(NukudeFace::HideBlush), NukudeFace::HideBlush, 30, 1.0f, 0.0f);
136
137 eEA.AddParameter(&offsetFace, offsetFaceInd, 40, 0.0f, 1.0f);
138 eEA.AddParameter(&offsetFaceSA, offsetFaceIndSA, 40, 0.0f, 1.0f);
141 }
142
144 blink.AddParameter(pM.GetMorphWeightReference(NukudeFace::Blink));
145 }
146
148 eEA.SetInterpolationMethod(NukudeFace::HideBlush, EasyEaseInterpolation::Cosine);
149 eEA.SetInterpolationMethod(NukudeFace::Sadness, EasyEaseInterpolation::Cosine);
150
151 eEA.SetInterpolationMethod(NukudeFace::vrc_v_ee, EasyEaseInterpolation::Linear);
152 eEA.SetInterpolationMethod(NukudeFace::vrc_v_ih, EasyEaseInterpolation::Linear);
153 eEA.SetInterpolationMethod(NukudeFace::vrc_v_dd, EasyEaseInterpolation::Linear);
154 eEA.SetInterpolationMethod(NukudeFace::vrc_v_rr, EasyEaseInterpolation::Linear);
155 eEA.SetInterpolationMethod(NukudeFace::vrc_v_ch, EasyEaseInterpolation::Linear);
156 eEA.SetInterpolationMethod(NukudeFace::vrc_v_aa, EasyEaseInterpolation::Linear);
157 eEA.SetInterpolationMethod(NukudeFace::vrc_v_oh, EasyEaseInterpolation::Linear);
158 eEA.SetInterpolationMethod(NukudeFace::vrc_v_ss, EasyEaseInterpolation::Linear);
159 }
160
178
180 blink.Update();
181 }
182
183 void Default(){
184 scene.DisableEffect();
185 }
186
187 void Angry(){
188 eEA.AddParameterFrame(NukudeFace::Anger, 1.0f);
190 }
191
192 void Sad(){
193 eEA.AddParameterFrame(NukudeFace::Sadness, 1.0f);
194 eEA.AddParameterFrame(NukudeFace::Frown, 1.0f);
196 }
197
198 void Surprised(){
199 scene.SetEffect(&glitchX);
200 scene.DisableEffect();
201
202 eEA.AddParameterFrame(NukudeFace::Surprised, 1.0f);
203 eEA.AddParameterFrame(NukudeFace::HideBlush, 0.0f);
205 }
206
207 void Doubt(){
208 eEA.AddParameterFrame(NukudeFace::Doubt, 1.0f);
209 }
210
211 void Frown(){
212 eEA.AddParameterFrame(NukudeFace::Frown, 1.0f);
213 }
214
215 void LookUp(){
216 eEA.AddParameterFrame(NukudeFace::LookUp, 1.0f);
217 }
218
219 void LookDown(){
220 eEA.AddParameterFrame(NukudeFace::LookDown, 1.0f);
221 }
222
229
236
243
246 eEA.AddParameterFrame(NukudeFace::vrc_v_ss, MicrophoneFourierIT::GetCurrentMagnitude() / 2.0f);
247
248 if(MicrophoneFourierIT::GetCurrentMagnitude() > 0.05f){
249 voiceDetection.Update(MicrophoneFourierIT::GetFourierFiltered(), MicrophoneFourierIT::GetSampleRate());
250
258 }
259 }
260 }
261
263 switch(Menu::GetFaceColor()){
264 case 1: materialAnimator.AddMaterialFrame(redMaterial, 0.8f); break;
266 case 3: materialAnimator.AddMaterialFrame(whiteMaterial, 0.8f); break;
267 case 4: materialAnimator.AddMaterialFrame(greenMaterial, 0.8f); break;
268 case 5: materialAnimator.AddMaterialFrame(blueMaterial, 0.8f); break;
271 case 8: materialAnimator.AddMaterialFrame(rainbowSpiral, 0.8f); break;
272 case 9: materialAnimator.AddMaterialFrame(rainbowNoise, 0.8f); break;
273 default: break;
274 }
275 }
276
277public:
279 scene.AddObject(pM.GetObject());
280 scene.AddObject(background.GetObject());
281 scene.AddObject(ledStripBackground.GetObject());
282
283 LinkEasyEase();
285
287
289
290 pM.GetObject()->SetMaterial(&materialAnimator);
291 background.GetObject()->SetMaterial(&backgroundMaterial);
292 ledStripBackground.GetObject()->SetMaterial(&materialAnimator);
293
295 objA.SetMirrorX(true);
296 }
297
298 void Initialize() override {
299 boop.Initialize(5);
300
301 MicrophoneFourierIT::Initialize(22, 8000, 50.0f, 120.0f);//8KHz sample rate, 50dB min, 120dB max
302 //Menu::Initialize(9);//NeoTrellis
303 Menu::Initialize(9, 0, 500);//7 is number of faces
304 }
305
306
309 };
310
311 uint8_t GetBrightness(){
312 return Menu::GetBrightness();
313 };
314
315 void FadeIn(float stepRatio) override {}
316 void FadeOut(float stepRatio) override {}
317
319 return pM.GetObject();
320 }
321
323 this->mirror = mirror;
324 }
325
326 void Update(float ratio) override {
327 if(!mirror){
328 gradientSpectrum[0] = RGBColor(255, 0, 0).HueShift(Menu::GetHueF() * 36);
329 gradientSpectrum[1] = RGBColor(255, 0, 0).HueShift(Menu::GetHueB() * 36);
330
333
334 pM.Reset();
335
336 float xOffset = fGenMatXMove.Update();
337 float yOffset = fGenMatYMove.Update();
338
339 Menu::Update(ratio);
340
341 //Menu::SetSize(Vector2D(280, 60));
342 //Menu::SetPositionOffset(Vector2D(0.0f, -30.0f * yOffset));
343
344 //glitchX.SetRatio(fGenBlur.Update());
345 magnet.SetRatio(ratio);
354
356
357 bool isBooped = Menu::UseBoopSensor() ? boop.isBooped() : 0;
358 uint8_t mode = Menu::GetFaceState();//change by button press
359
360 MicrophoneFourierIT::Update();
361 sA.SetHueAngle(ratio * 360.0f * 4.0f);
364
365 aRG.SetRadius((xOffset + 2.0f) * 2.0f + 25.0f);
366 aRG.SetSize(Vector2D((xOffset + 2.0f) * 10.0f + 50.0f, (xOffset + 2.0f) * 10.0f + 50.0f));
367 aRG.SetHueAngle(ratio * 360.0f * 8.0f);
368 aRG.SetRotation(ratio * 360.0f * 2.0f);
369 aRG.SetPosition(Vector2D(80.0f + xOffset * 4.0f, 48.0f + yOffset * 4.0f));
370
371 oSC.SetSize(Vector2D(200.0f, 100.0f));
372 oSC.SetHueAngle(ratio * 360.0f * 8.0f);
373 oSC.SetPosition(Vector2D(100.0f, 50.0f));
374
375 voiceDetection.SetThreshold(map(Menu::GetMicLevel(), 0, 10, 1000, 50));
376
378
379 if (isBooped && mode != 6){
380 Surprised();
381 }
382 else{
383 if (mode == 0) Default();
384 else if (mode == 1) Angry();
385 else if (mode == 2) Doubt();
386 else if (mode == 3) Frown();
387 else if (mode == 4) LookUp();
388 else if (mode == 5) Sad();
389 else if (mode == 6) {
390 aRG.Update(MicrophoneFourierIT::GetFourierFiltered());
392 }
393 else if (mode == 7){
394 oSC.Update(MicrophoneFourierIT::GetSamples());
396 }
397 else {
398 sA.Update(MicrophoneFourierIT::GetFourierFiltered());
400 }
401 }
402
404
405 pM.SetMorphWeight(NukudeFace::BiggerNose, 1.0f);
406 pM.SetMorphWeight(NukudeFace::MoveEye, 1.0f);
407
408 eEA.Update();
409 pM.Update();
410
411 //phaseR.SetRatio(eEA.GetValue(NukudeFace::Surprised));
412 glitchX.SetRatio(eEA.GetValue(NukudeFace::Surprised));
413
414 rainbowNoise.Update(ratio);
415 rainbowSpiral.Update(ratio);
418
419 uint8_t faceSize = Menu::GetFaceSize();
420 float scale = Menu::ShowMenu() * 0.6f + 0.4f;
421 float faceSizeOffset = faceSize * 8.0f;
422
424 objA.SetEdgeMargin(4.0f);
425 objA.SetCameraMax(Vector2D(110.0f + faceSizeOffset, 115.0f - 115.0f * offsetFace).Multiply(scale));
426
427 objA.AlignObjects(scene.GetObjects(), 1);
428
429 pM.GetObject()->GetTransform()->SetPosition(Vector3D(xOffset, yOffset, 0.0f));
430 pM.GetObject()->UpdateTransform();
431 }
432 else{
433 gradientSpectrum[0] = RGBColor(255, 0, 0).HueShift(Menu::GetHueF() * 36);
434 gradientSpectrum[1] = RGBColor(255, 0, 0).HueShift(Menu::GetHueB() * 36);
435
438 }
439 }
440};
Declares the BlinkTrack template class for animating eye blinking.
Declares the EasyEaseAnimator template class for advanced animation easing.
Declares the KeyFrameTrack template class for managing keyframe-based animations.
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.
float GetValue(uint16_t dictionaryValue) override
Gets the current value of a parameter.
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.
void SetRatio(float ratio)
Sets the scaling ratio for the effect.
Definition Effect.cpp:5
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.
Implements a fisheye distortion effect for pixel groups.
Definition Fisheye.h:26
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.
Implements a glitch effect along the X-axis for pixel groups.
Definition GlitchX.h:26
Creates a customizable gradient material for rendering.
void UpdateGradient(RGBColor *rgbColors)
Updates the colors of the gradient.
void UpdateRGB()
Updates the RGB colors in the gradient.
Implements a horizontal blur effect for pixel groups.
Implements a magnetic distortion effect for pixel groups.
Definition Magnet.h:25
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.
@ 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 GetHueF()
Gets the front hue value.
Definition Menu.cpp:462
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
static uint8_t GetHueB()
Gets the back hue value.
Definition Menu.cpp:471
static uint8_t GetBrightness()
Gets the current brightness level. In hardware mode, it is read from the MenuHandler.
Definition Menu.cpp:390
static uint8_t GetAccentBrightness()
Gets the current accent brightness level.
Definition Menu.cpp:399
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 SetPlaneOffsetAngle(float offsetPlaneAngle)
Sets the additional rotation offset (plane offset angle), in degrees or radians, that will be applied...
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.
Implements an overflow distortion effect for pixel groups.
Definition Overflow.h:24
Applies rotational phase offsets to pixel groups.
Applies horizontal phase offsets to pixel groups.
Applies vertical phase offsets to pixel groups.
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
RGBColor HueShift(const float &hueDeg)
Shifts the hue of the color by a specified angle in degrees.
Definition RGBColor.cpp:65
Applies a radial blur effect to pixel groups.
Definition RadialBlur.h:26
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.
Radially shifts the red, green, and blue channels of the pixels.
Definition ShiftR.h:26
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
An effect that applies a vertical blur to a pixel group.
@ 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.
FunctionGenerator fGenMatYMove
FunctionGenerator fGenMatRMenu
EasyEaseAnimator< 25 > eEA
LEDStripBackground ledStripBackground
GradientMaterial< 2 > gradientMat
FunctionGenerator fGenRotation
FunctionGenerator fGenMatXMenu
void SetCameraMirror(bool mirror)
void FadeIn(float stepRatio) override
void FadeOut(float stepRatio) override
FunctionGenerator fGenMatYMenu
FunctionGenerator fGenMatXMove
MaterialAnimator< 10 > materialAnimator
void Update(float ratio) override
static const uint8_t faceCount
FFTVoiceDetection< 128 > voiceDetection
MaterialAnimator< 4 > backgroundMaterial
AudioReactiveGradient aRG