Patterns and phrase map priority
This commit is contained in:
parent
e5be1298d1
commit
5ba251012d
|
@ -1,24 +1,24 @@
|
|||
lumenarium_animation_file;
|
||||
animation_name: "voice_command";
|
||||
animation_name: "voice_anim";
|
||||
layers_count: 1;
|
||||
blocks_count: 1;
|
||||
playable_range:{
|
||||
min: 0;
|
||||
max: 360;
|
||||
max: 3600;
|
||||
};
|
||||
layers:{
|
||||
layer:{
|
||||
name: "Colors";
|
||||
name: "[New Layer]";
|
||||
blend: "Add";
|
||||
};
|
||||
};
|
||||
blocks:{
|
||||
block:{
|
||||
frame_range:{
|
||||
min: 0;
|
||||
max: 360;
|
||||
min: 1;
|
||||
max: 3599;
|
||||
};
|
||||
layer_index: 0;
|
||||
animation_name: "Pattern_Leafy";
|
||||
animation_name: "Pattern_VoicePattern";
|
||||
};
|
||||
};
|
||||
|
|
|
@ -202,6 +202,14 @@ typedef struct system_time
|
|||
s32 Second;
|
||||
} system_time;
|
||||
|
||||
internal r64
|
||||
SecondsElapsed(system_time Start, system_time End)
|
||||
{
|
||||
u64 N = End.NanosSinceEpoch - Start.NanosSinceEpoch;
|
||||
r64 S = (r64)N * NanosToSeconds;
|
||||
return S;
|
||||
}
|
||||
|
||||
struct context
|
||||
{
|
||||
gs_thread_context ThreadContext;
|
||||
|
|
|
@ -10,6 +10,10 @@
|
|||
internal pixel
|
||||
V4ToRGBPixel(v4 C)
|
||||
{
|
||||
C.x = Clamp01(C.x);
|
||||
C.y = Clamp01(C.y);
|
||||
C.z = Clamp01(C.z);
|
||||
|
||||
pixel Result = {};
|
||||
Result.R = (u8)(C.x * 255);
|
||||
Result.G = (u8)(C.y * 255);
|
||||
|
@ -488,5 +492,142 @@ Pattern_BulbMask(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r3
|
|||
}
|
||||
}
|
||||
|
||||
internal v4
|
||||
GenPatchyColor(v3 P, r32 Time, v4 C0, v4 C1, v4 C2)
|
||||
{
|
||||
r32 LedRange = 300.0f;
|
||||
r32 ScaleFactor = 1.0f / LedRange;
|
||||
v3 Pp = P + v3{150, 100, 0};
|
||||
|
||||
r32 ScaleA = 1;
|
||||
r32 NoiseA = Noise3D(((Pp / 38) + v3{0, 0, Time}) * ScaleA);
|
||||
NoiseA = PowR32(NoiseA, 3);
|
||||
NoiseA = Smoothstep(NoiseA);
|
||||
|
||||
r32 ScaleBP = 2;
|
||||
r32 ScaleB = 15;
|
||||
r32 NoiseBP = Noise3D(((Pp / 13) + v3{ 0, Time * -0.33f, 0}) * ScaleBP);
|
||||
NoiseBP = PowR32(NoiseBP, 3);
|
||||
r32 NoiseB = Noise3D(((Pp / 75) + v3{Time * 0.5f, 0, 0}) * ScaleB);
|
||||
NoiseB = PowR32(NoiseB, 3);
|
||||
NoiseB = Smoothstep(NoiseB) * NoiseBP;
|
||||
|
||||
r32 ScaleC = 1.5;
|
||||
r32 NoiseCP = Noise3D(((Pp / 132) + v3{Time * -0.33f, 0, 0}) * 0.5f);
|
||||
r32 NoiseC = Noise3D(((Pp / 164) + v3{Time * 0.25f, 0, 0}) * ScaleC);
|
||||
NoiseC = PowR32(NoiseC, 3);
|
||||
NoiseC = Smoothstep(NoiseC) * NoiseCP;
|
||||
|
||||
v4 C = (C0 * NoiseA) + (C1 * NoiseB) + (C2 * NoiseC);
|
||||
C /= (NoiseA + NoiseB + NoiseC);
|
||||
return C;
|
||||
}
|
||||
|
||||
internal r32
|
||||
GenVerticalStrips(v3 P, r32 Time)
|
||||
{
|
||||
v2 Right = v2{1, 0};
|
||||
v2 Pa = V2Normalize(v2{P.x, P.z});
|
||||
r32 Angle = .5f + (.5f * V2Dot(Pa, Right));
|
||||
|
||||
r32 HOffset = 70.0f;
|
||||
r32 O = 50.0f;
|
||||
r32 C = 10.0f;
|
||||
|
||||
r32 X = Angle;
|
||||
r32 Y = P.y;
|
||||
r32 I = FloorR32(Y / C) * C;
|
||||
I += (X * HOffset) + (Time * 25);
|
||||
|
||||
r32 V = FractR32(I / O);
|
||||
V = 2.0f * (0.5f - Abs(V - 0.5f));
|
||||
Assert(V >= 0 && V <= 1);
|
||||
|
||||
return V;
|
||||
}
|
||||
|
||||
internal v4
|
||||
GenVerticalLeaves(v3 P, r32 Time, v4 C0, v4 C1, v4 C2)
|
||||
{
|
||||
r32 A = GenVerticalStrips(P, Time * .25f);
|
||||
r32 B = GenVerticalStrips(P * .3f, Time);
|
||||
r32 C = GenVerticalStrips(P * .25f, Time * 2);
|
||||
|
||||
v4 R = (C0 * A) + (C1 * B) + (C2 * C);
|
||||
R /= A + B + C;
|
||||
return R;
|
||||
}
|
||||
|
||||
internal r32
|
||||
GenLiquidBands(v3 P, r32 Offset, r32 Time)
|
||||
{
|
||||
r32 Width = 30;
|
||||
r32 VAcc = 0;
|
||||
for (u32 i = 1; i < 3; i++)
|
||||
{
|
||||
v3 P0 = v3{P.x + (23.124f * i), 0, P.z - (-12.34f * i)};
|
||||
|
||||
r32 Y = (P.y - Offset);
|
||||
r32 S = Fbm3D(P0 * .005f, Time) * 250;
|
||||
S += ModR32((Time * 100) - (150 * i), 400);
|
||||
|
||||
r32 V = (Width - Abs(Y - S)) / Width;
|
||||
V = Clamp01(V);
|
||||
|
||||
VAcc += V;
|
||||
}
|
||||
|
||||
return VAcc;
|
||||
}
|
||||
|
||||
internal r32
|
||||
GenDotBands(v3 P, r32 Time)
|
||||
{
|
||||
r32 RowHeight = 25;
|
||||
r32 DotRadius = 20;
|
||||
|
||||
r32 Y = P.y + 150;
|
||||
s32 Row = (s32)FloorR32(Y / RowHeight);
|
||||
r32 RowH = Abs(FractR32(Y / RowHeight));
|
||||
r32 DotDistY = Max(0, .5f - RowH) * 2;
|
||||
|
||||
r32 Angle = (V2Dot(V2Normalize(v2{P.x, P.z}), v2{1,0}) * .5f) + .5f;
|
||||
r32 DotDistX = Abs(ModR32(Angle, .2f));
|
||||
|
||||
r32 DotDist = SqrtR32(PowR32(DotDistX, 2) + PowR32(RowH, 2));
|
||||
r32 B = (DotRadius - DotDist) / DotRadius;
|
||||
B = Clamp01(DotDist);
|
||||
|
||||
return DotDistY;
|
||||
|
||||
}
|
||||
|
||||
internal void
|
||||
Pattern_VoicePattern(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||
{
|
||||
blumen_lumen_state* BLState = (blumen_lumen_state*)UserData;
|
||||
Time = Time * BLState->PatternSpeed;
|
||||
|
||||
phrase_hue Hue = BlumenLumen_GetCurrentHue(BLState, Assembly);
|
||||
v4 C0 = HSVToRGB({Hue.Hue0, 1, 1, 1});
|
||||
v4 C1 = HSVToRGB({Hue.Hue1, 1, 1, 1});
|
||||
v4 C2 = HSVToRGB({Hue.Hue2, 1, 1, 1});
|
||||
|
||||
for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++)
|
||||
{
|
||||
v3 P = Leds->Positions[LedIndex].xyz;
|
||||
|
||||
v4 C = {};
|
||||
C += GenPatchyColor(P, Time, C0, C2, {});
|
||||
//C = GenVerticalLeaves((P - Assembly.Center) + v3{0, 150, 0}, Time, C0, C1, C2);
|
||||
r32 Bands = GenLiquidBands(P, -250, Time);
|
||||
//C = V4Lerp(Bands, C * .5f, C1);
|
||||
|
||||
//C = WhiteV4 * GenDotBands(P - Assembly.Center, Time);
|
||||
|
||||
Leds->Colors[LedIndex] = V4ToRGBPixel(C);
|
||||
}
|
||||
}
|
||||
|
||||
#define BLUMEN_PATTERNS_H
|
||||
#endif // BLUMEN_PATTERNS_H
|
|
@ -207,6 +207,8 @@ BlumenLumen_LoadPatterns(app_state* State)
|
|||
Patterns_PushPattern(Patterns, Pattern_Rotary, PATTERN_MULTITHREADED);
|
||||
Patterns_PushPattern(Patterns, Pattern_AllOnMask, PATTERN_MULTITHREADED);
|
||||
Patterns_PushPattern(Patterns, Pattern_BulbMask, PATTERN_MULTITHREADED);
|
||||
Patterns_PushPattern(Patterns, Pattern_VoicePattern, PATTERN_MULTITHREADED);
|
||||
|
||||
}
|
||||
|
||||
internal void
|
||||
|
@ -373,7 +375,7 @@ BlumenLumen_CustomInit(app_state* State, context Context)
|
|||
BLState->ModeAnimations[BlumenPattern_VoiceCommand] = LoadAllAnimationsInDir(VoicePatternFolder, BLState, State, Context);
|
||||
AnimationSystem_LoadAnimationFromFile(&State->AnimationSystem, State->Patterns, Context, ConstString("data/blumen_animations/anim_demo.foldanim"));
|
||||
|
||||
BlumenLumen_SetPatternMode(BlumenPattern_Standard, 5, &State->AnimationSystem, BLState);
|
||||
BlumenLumen_SetPatternMode(BlumenPattern_VoiceCommand, 5, &State->AnimationSystem, BLState);
|
||||
#endif
|
||||
State->AnimationSystem.TimelineShouldAdvance = true;
|
||||
|
||||
|
@ -390,6 +392,7 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context)
|
|||
bool SendMotorCommand = false;
|
||||
blumen_packet MotorCommand = {};
|
||||
|
||||
r64 PhraseGroupingTime = 1.0f;
|
||||
while (MessageQueue_CanRead(BLState->IncomingMsgQueue))
|
||||
{
|
||||
gs_data PacketData = MessageQueue_Read(&BLState->IncomingMsgQueue);
|
||||
|
@ -403,26 +406,17 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context)
|
|||
u32 NameLen = CStringLength(Mic.AnimationFileName);
|
||||
|
||||
phrase_hue NewHue = PhraseHueMap_Get(BLState->PhraseHueMap, NameHash);
|
||||
if (NewHue.PhraseHash != 0)
|
||||
if (BLState->NextHotHue.Phrase.Length < NewHue.Phrase.Length)
|
||||
{
|
||||
if (BLState->PatternMode == BlumenPattern_Standard)
|
||||
BLState->NextHotHue = NewHue;
|
||||
if (SecondsElapsed(BLState->TimePhraseReceptionBegan,
|
||||
Context->SystemTime_Current) > PhraseGroupingTime)
|
||||
{
|
||||
BLState->AssemblyColors[0] = NewHue;
|
||||
BLState->AssemblyColors[1] = NewHue;
|
||||
BLState->AssemblyColors[2] = NewHue;
|
||||
BLState->TimePhraseReceptionBegan = Context->SystemTime_Current;
|
||||
BLState->InPhraseReceptionMode = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
u32 AssemblyIdx = BLState->LastAssemblyColorSet;
|
||||
BLState->AssemblyColors[AssemblyIdx] = NewHue;
|
||||
BLState->LastAssemblyColorSet = (BLState->LastAssemblyColorSet + 1) % 3;
|
||||
}
|
||||
|
||||
BlumenLumen_SetPatternMode(BlumenPattern_VoiceCommand, 5, &State->AnimationSystem, BLState);
|
||||
BLState->TimeLastSetToVoiceMode = Context->SystemTime_Current;
|
||||
BLState->LastHuePhrase = NewHue;
|
||||
BLState->TimeLastPhraseReceived = Context->SystemTime_Current;
|
||||
}
|
||||
BLState->ShouldUpdateLog = true;
|
||||
}break;
|
||||
|
||||
case PacketType_MotorState:
|
||||
|
@ -473,6 +467,35 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context)
|
|||
}
|
||||
}
|
||||
|
||||
if (BLState->InPhraseReceptionMode)
|
||||
{
|
||||
r32 SecondsSincePhraseBegan = SecondsElapsed(BLState->TimePhraseReceptionBegan, Context->SystemTime_Current);
|
||||
if (SecondsSincePhraseBegan > PhraseGroupingTime)
|
||||
{
|
||||
// if we are in standard color mode, shift all flowers to the new color
|
||||
// otherwise, only shift the next flower in the sequence to the new color
|
||||
phrase_hue NewHue = BLState->NextHotHue;
|
||||
if (BLState->PatternMode == BlumenPattern_Standard)
|
||||
{
|
||||
BLState->AssemblyColors[0] = NewHue;
|
||||
BLState->AssemblyColors[1] = NewHue;
|
||||
BLState->AssemblyColors[2] = NewHue;
|
||||
}
|
||||
else
|
||||
{
|
||||
u32 AssemblyIdx = BLState->LastAssemblyColorSet;
|
||||
BLState->AssemblyColors[AssemblyIdx] = NewHue;
|
||||
BLState->LastAssemblyColorSet = (BLState->LastAssemblyColorSet + 1) % 3;
|
||||
}
|
||||
|
||||
BlumenLumen_SetPatternMode(BlumenPattern_VoiceCommand, 5, &State->AnimationSystem, BLState);
|
||||
BLState->TimeLastSetToVoiceMode = Context->SystemTime_Current;
|
||||
BLState->LastHuePhrase = NewHue;
|
||||
BLState->ShouldUpdateLog = true;
|
||||
BLState->InPhraseReceptionMode = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Update next frames Hues
|
||||
r32 AnimTime = AnimationSystem_GetCurrentTime(State->AnimationSystem);
|
||||
AnimTime = (r32)Context->TotalTime;
|
||||
|
|
|
@ -175,6 +175,12 @@ struct blumen_lumen_state
|
|||
animation_handle_array ModeAnimations[BlumenPattern_Count];
|
||||
|
||||
phrase_hue_map PhraseHueMap;
|
||||
|
||||
bool InPhraseReceptionMode;
|
||||
phrase_hue NextHotHue;
|
||||
system_time TimePhraseReceptionBegan;
|
||||
system_time TimeLastPhraseReceived;
|
||||
|
||||
system_time TimeLastSetToVoiceMode;
|
||||
phrase_hue LastHuePhrase;
|
||||
|
||||
|
|
Loading…
Reference in New Issue