From 85e0098733bc5fa6545590a285f046e668ed5a21 Mon Sep 17 00:00:00 2001 From: hgn Date: Tue, 19 Oct 2021 20:55:46 +0100 Subject: [PATCH] accurate path/curve following --- fishladder.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++-- vg/vg_lines.h | 8 ++++++ 2 files changed, 81 insertions(+), 2 deletions(-) diff --git a/fishladder.c b/fishladder.c index 21fe2ff..bf877e3 100644 --- a/fishladder.c +++ b/fishladder.c @@ -1051,7 +1051,7 @@ void vg_render(void) if( world.simulating ) { float scaled_time = (vg_time-world.sim_start)*2.0f; - float lerp = 1.0f-(scaled_time - (float)world.sim_frame); + float lerp = scaled_time - (float)world.sim_frame; v4f dot_colour = { 0.0f, 0.0f, 0.0f, 1.0f }; @@ -1065,7 +1065,78 @@ void vg_render(void) colour_code_v3( fish->payload, dot_colour ); glUniform4fv( SHADER_UNIFORM( shader_tile_colour, "uColour" ), 1, dot_colour ); - glUniform3f( SHADER_UNIFORM( shader_tile_colour, "uOffset" ), (float)fish->pos[0] + 0.5f - (float)fish->dir[0]*lerp, (float)fish->pos[1] + 0.5f - (float)fish->dir[1]*lerp, 0.125f ); + // Evaluate position + struct cell *cell = pcell(fish->pos); + v2f fish_pos; + + v2f const curve_3[] = {{0.5f,1.0f},{0.5f,0.625f},{0.625f,0.5f},{1.0f,0.5f}}; + v2f const curve_6[] = {{0.5f,1.0f},{0.5f,0.625f},{0.375f,0.5f},{0.0f,0.5f}}; + v2f const curve_9[] = {{1.0f,0.5f},{0.625f,0.5f},{0.5f,0.375f},{0.5f,0.0f}}; + v2f const curve_12[]= {{0.0f,0.5f},{0.375f,0.5f},{0.5f,0.375f},{0.5f,0.0f}}; + + v2f const curve_7[] = {{0.5f,0.8438f},{0.875f,0.8438f},{0.625f,0.5f},{1.0f,0.5f}}; + v2f const curve_7_1[] = {{0.5f,0.8438f},{1.0f-0.875f,0.8438f},{1.0-0.625f,0.5f},{0.0f,0.5f}}; + + float const linear_section = 0.1562f; + + v2f const *curve; + + float t = lerp; + + switch( cell->config ) + { + case 13: + if( fish->dir[0] == 1 ) + curve = curve_12; + else + curve = curve_9; + break; + case 3: curve = curve_3; break; + case 6: curve = curve_6; break; + case 9: curve = curve_9; break; + case 12: curve = curve_12; break; + case 7: + if( t > linear_section ) + { + t -= linear_section; + t *= (1.0f/(1.0f-linear_section)); + + curve = cell->state & FLAG_FLIP_FLOP? curve_7: curve_7_1; + } + else curve = NULL; + break; + default: curve = NULL; break; + } + + if( curve ) + { + // bezier thing + float t2 = t * t; + float t3 = t * t * t; + + float cA = 3.0f*t2 - 3.0f*t3; + float cB = 3.0f*t3 - 6.0f*t2 + 3.0f*t; + float cC = 3.0f*t2 - t3 - 3.0f*t + 1.0f; + + fish_pos[0] = t3*curve[3][0] + cA*curve[2][0] + cB*curve[1][0] + cC*curve[0][0]; + fish_pos[1] = t3*curve[3][1] + cA*curve[2][1] + cB*curve[1][1] + cC*curve[0][1]; + fish_pos[0] += (float)fish->pos[0]; + fish_pos[1] += (float)fish->pos[1]; + } + else + { + v2f origin; + origin[0] = (float)fish->pos[0] + (float)fish->dir[0]*-0.5f + 0.5f; + origin[1] = (float)fish->pos[1] + (float)fish->dir[1]*-0.5f + 0.5f; + + fish_pos[0] = origin[0] + (float)fish->dir[0]*t; + fish_pos[1] = origin[1] + (float)fish->dir[1]*t; + } + + vg_line_box( (v2f){fish->pos[0],fish->pos[1]}, + (v2f){ (float)fish->pos[0]+1.0f, (float)fish->pos[1]+1.0f }, 0xffffffff ); + + glUniform3f( SHADER_UNIFORM( shader_tile_colour, "uOffset" ), fish_pos[0], fish_pos[1], 0.125f ); draw_mesh( 0, 32 ); } } diff --git a/vg/vg_lines.h b/vg/vg_lines.h index 469664a..b6f52bd 100644 --- a/vg/vg_lines.h +++ b/vg/vg_lines.h @@ -123,3 +123,11 @@ static void vg_line( v2f from, v2f to, u32 colour ) { vg_line2( from, to, colour, colour ); } + +static void vg_line_box( v2f min, v2f max, u32 colour ) +{ + vg_line( min, (v2f){min[0],max[1]}, colour ); + vg_line( (v2f){min[0],max[1]}, max, colour ); + vg_line( max, (v2f){max[0],min[1]}, colour ); + vg_line( (v2f){max[0],min[1]}, min, colour ); +} -- 2.25.1