2022-03-22 18:13:06 +00:00
|
|
|
|
|
|
|
internal void
|
2022-03-27 10:47:18 +00:00
|
|
|
en_init(App_State* state, App_Init_Desc desc)
|
2022-03-22 18:13:06 +00:00
|
|
|
{
|
2022-04-16 11:00:32 +00:00
|
|
|
lumenarium_env_validate();
|
|
|
|
|
2022-03-27 10:47:18 +00:00
|
|
|
state->assemblies = assembly_array_create(permanent, desc.assembly_cap);
|
2022-04-06 18:29:32 +00:00
|
|
|
|
|
|
|
Output* o = &state->output;
|
2022-04-22 18:57:52 +00:00
|
|
|
register_output_method(o, OutputData_Invalid, 0, 0, 0);
|
|
|
|
register_output_method(o, OutputData_NetworkSACN, output_network_sacn_update, output_network_sacn_build, output_network_sacn_init());
|
|
|
|
register_output_method(o, OutputData_ComUART, 0, output_network_sacn_build, output_com_uart_init());
|
2022-04-16 11:00:32 +00:00
|
|
|
|
|
|
|
lumenarium_env_validate();
|
2022-03-22 18:13:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
internal void
|
|
|
|
en_frame_prepare(App_State* state)
|
|
|
|
{
|
2022-04-16 11:00:32 +00:00
|
|
|
lumenarium_env_validate();
|
2022-03-22 18:13:06 +00:00
|
|
|
}
|
|
|
|
|
2022-04-13 14:23:53 +00:00
|
|
|
global r32 tt = 0;
|
|
|
|
|
2022-04-23 13:55:53 +00:00
|
|
|
r32
|
|
|
|
curve_ease_in_out(r32 t)
|
|
|
|
{
|
|
|
|
r32 tc = clamp(0, t, 1);
|
|
|
|
r32 theta = (tc * r32_pi) - (r32_pi / 2.0f);
|
|
|
|
r32 s = sinf(theta);
|
|
|
|
r32 result = 0.5f + (s / 2.0f);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define incenter_pos_to_unit(p) (v4){ ((p.x / 6.0f) + 0.5f), ((p.y / 6.0f) + 0.5f), ((p.z / 6.0f) + 0.5f), 1.0f }
|
|
|
|
|
|
|
|
void
|
|
|
|
test_pattern(Assembly_Pixel_Buffer pixels)
|
|
|
|
{
|
|
|
|
for (u32 j = 0; j < pixels.len; j++)
|
|
|
|
{
|
|
|
|
v4 p = pixels.positions[j];
|
|
|
|
pixels.pixels[j].r = (u8)(((sinf((5 * tt) + (p.x * 10)) + 1) * 0.5f) * 255);
|
|
|
|
pixels.pixels[j].b = (u8)(((sinf((5 * tt) + (p.z * 10)) + 1) * 0.5f) * 255);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
pattern_debug(Assembly_Pixel_Buffer pixels)
|
|
|
|
{
|
|
|
|
r32 scale = 6;
|
|
|
|
r32 offset = 0;
|
|
|
|
|
|
|
|
for (u32 j = 0; j < pixels.len; j++)
|
|
|
|
{
|
|
|
|
v4 p = pixels.positions[j];
|
|
|
|
v4 pp = incenter_pos_to_unit(p);
|
|
|
|
pixels.pixels[j].r = pp.x * 255;
|
|
|
|
pixels.pixels[j].g = pp.y * 255;
|
|
|
|
pixels.pixels[j].b = pp.z * 255;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
grow_pattern_sphere_function(Assembly_Pixel_Buffer pixels, v4 center, r32 radius, r32 falloff)
|
|
|
|
{
|
|
|
|
for (u32 j = 0; j < pixels.len; j++)
|
|
|
|
{
|
|
|
|
v4 p = incenter_pos_to_unit(pixels.positions[j]);
|
|
|
|
r32 d0 = HMM_LengthVec4(HMM_SubtractVec4(p, center));
|
|
|
|
r32 d1 = falloff - fabsf(d0 - radius);
|
|
|
|
r32 b = d1 / falloff;
|
|
|
|
|
|
|
|
v3 color = {
|
|
|
|
.x = 0.5f + 0.5f * sinf(p.x * r32_tau * 4.313f + tt * 0.53f),
|
|
|
|
.y = 0.5f + 0.5f * cosf(0.2314f + p.y * r32_tau * 3.915f + tt * 0.5f),
|
|
|
|
.z = 0.2f + 0.8f * p.z,
|
|
|
|
};
|
|
|
|
v3 color_b = HMM_MultiplyVec3f(color, b);
|
|
|
|
|
|
|
|
pixels.pixels[j].r = color_b.x * 255;
|
|
|
|
pixels.pixels[j].g = color_b.y * 255;
|
|
|
|
pixels.pixels[j].b = color_b.z * 255;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void
|
|
|
|
grow_pattern(Assembly_Pixel_Buffer pixels)
|
|
|
|
{
|
|
|
|
v4 center = (v4){};
|
|
|
|
r32 radius = 0;
|
|
|
|
r32 falloff = 0;
|
|
|
|
//phase 1 - light up to center
|
|
|
|
if (tt < 8)
|
|
|
|
{
|
|
|
|
r32 height = -0.2f + curve_ease_in_out(tt / 6) * 0.5f;
|
|
|
|
center = (v4){ 0.5f, 0.2f + height, 0.5f, 1 };
|
|
|
|
radius = 0.1f;
|
|
|
|
falloff = 0.2f;
|
|
|
|
}
|
|
|
|
else if (tt >= 8)
|
|
|
|
{
|
|
|
|
r32 t = (tt - 8) / 5;
|
|
|
|
center = (v4){ 0.5f, 0.5f, 0.5f, 1 };
|
|
|
|
radius = 0.1f + curve_ease_in_out(t) * 0.27f;
|
|
|
|
falloff = 0.2 - (curve_ease_in_out(t) * 0.1f);
|
|
|
|
}
|
|
|
|
|
|
|
|
grow_pattern_sphere_function(pixels, center, radius, falloff);
|
|
|
|
}
|
|
|
|
|
2022-03-22 18:13:06 +00:00
|
|
|
internal void
|
|
|
|
en_frame(App_State* state)
|
|
|
|
{
|
2022-04-16 11:00:32 +00:00
|
|
|
lumenarium_env_validate();
|
|
|
|
|
2022-04-13 14:23:53 +00:00
|
|
|
scratch_get(scratch);
|
|
|
|
Assembly_Array assemblies = state->assemblies;
|
|
|
|
|
|
|
|
///////////////////////////////////////
|
|
|
|
// Temp Pattern Simulation
|
|
|
|
|
|
|
|
tt += 1.0f / 60.0f;
|
2022-04-23 13:55:53 +00:00
|
|
|
if (tt > 50) tt = 0;
|
2022-04-13 14:23:53 +00:00
|
|
|
|
|
|
|
r32 hrange = 1;
|
|
|
|
r32 range = hrange * 2;
|
|
|
|
for (u32 i = 0; i < assemblies.len; i++)
|
|
|
|
{
|
|
|
|
Assembly_Pixel_Buffer pixels = assemblies.pixel_buffers[i];
|
2022-04-23 13:55:53 +00:00
|
|
|
grow_pattern(pixels);
|
2022-04-13 14:23:53 +00:00
|
|
|
}
|
|
|
|
|
2022-04-06 18:29:32 +00:00
|
|
|
///////////////////////////////////////
|
|
|
|
// Output Data
|
2022-04-22 18:57:52 +00:00
|
|
|
Output_Methods methods = state->output.methods;
|
|
|
|
|
|
|
|
// update each method that has an update method
|
|
|
|
for (u32 i = 0; i < OutputData_Count; i++)
|
|
|
|
{
|
|
|
|
if (methods.update_procs[i] == 0) continue;
|
|
|
|
methods.update_procs[i](methods.method_data[i]);
|
|
|
|
}
|
|
|
|
|
2022-04-06 18:29:32 +00:00
|
|
|
Output_Data_Queue output_queue = {};
|
2022-04-13 14:23:53 +00:00
|
|
|
output_queue.a = scratch.a;
|
2022-04-06 18:29:32 +00:00
|
|
|
|
|
|
|
// build output data buffers
|
|
|
|
for (u32 i = 0; i < assemblies.len; i++)
|
|
|
|
{
|
|
|
|
Assembly_Strip_Array strips = assemblies.strip_arrays[i];
|
2022-04-22 18:57:52 +00:00
|
|
|
Assembly_Pixel_Buffer* pixels = assemblies.pixel_buffers + i;
|
2022-04-06 18:29:32 +00:00
|
|
|
for (u32 j = 0; j < strips.len; j++)
|
|
|
|
{
|
|
|
|
Assembly_Strip* strip = strips.strips + j;
|
|
|
|
Build_Output_Data_Buffer* method_proc = methods.procs[strip->output_kind];
|
|
|
|
u8* method_data = methods.method_data[strip->output_kind];
|
|
|
|
if (method_proc == 0) continue;
|
2022-04-22 18:57:52 +00:00
|
|
|
method_proc(state, i, pixels, strip, method_data, &output_queue);
|
2022-04-06 18:29:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// output the buffers
|
|
|
|
// TODO(PS): we could sort these first if switchig between output
|
|
|
|
// types is time consuming
|
2022-04-22 18:57:52 +00:00
|
|
|
|
|
|
|
Sacn* sacn = (Sacn*)state->output.methods.method_data[OutputData_NetworkSACN];
|
2022-04-06 18:29:32 +00:00
|
|
|
for (Output_Data* at = output_queue.first; at != 0; at = at->next)
|
|
|
|
{
|
|
|
|
// NOTE(PS): we can overload each switch case as more methods come in
|
|
|
|
// ie. OutputData_NetworkSACN and OutputData_NetworkArtNet could use
|
|
|
|
// the same case since at this point they just need to push data out
|
|
|
|
// over a socket
|
|
|
|
switch (at->kind)
|
|
|
|
{
|
|
|
|
case OutputData_NetworkSACN:
|
|
|
|
{
|
2022-04-22 18:57:52 +00:00
|
|
|
os_socket_send_to(
|
|
|
|
sacn->socket,
|
|
|
|
at->network.v4_addr,
|
|
|
|
at->network.port,
|
|
|
|
at->data,
|
|
|
|
0
|
|
|
|
);
|
2022-04-06 18:29:32 +00:00
|
|
|
} break;
|
|
|
|
|
|
|
|
case OutputData_ComUART:
|
|
|
|
{
|
|
|
|
// TODO(PS): platform com io
|
|
|
|
} break;
|
|
|
|
|
|
|
|
invalid_code_path;
|
|
|
|
}
|
|
|
|
}
|
2022-04-16 11:00:32 +00:00
|
|
|
|
|
|
|
scratch_release(scratch);
|
|
|
|
lumenarium_env_validate();
|
2022-03-22 18:13:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
internal void
|
|
|
|
en_cleanup(App_State* state)
|
|
|
|
{
|
2022-04-16 11:00:32 +00:00
|
|
|
lumenarium_env_validate();
|
2022-03-22 18:13:06 +00:00
|
|
|
}
|
|
|
|
|