accurate path/curve following
authorhgn <hgodden00@gmail.com>
Tue, 19 Oct 2021 19:55:46 +0000 (20:55 +0100)
committerhgn <hgodden00@gmail.com>
Tue, 19 Oct 2021 19:55:46 +0000 (20:55 +0100)
fishladder.c
vg/vg_lines.h

index 21fe2ff088fb87c5af4d6ebe642d48670f3c02a8..bf877e33b19e04f21bf4102ea50a8171f77a7381 100644 (file)
@@ -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 );
                }
        }
index 469664a9553790225660e7c8ec4960b84c3d8390..b6f52bd385a685358b7ab3e429de9da1e460c058 100644 (file)
@@ -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 );
+}