X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=trail.c;h=6bdee69262a8d0eab261862fca9b9914263c48f7;hb=refs%2Fheads%2Fmenu2;hp=bf23b1c56c5427a6ea371e19328b33707647c4db;hpb=6538d63bbe4c4d5efb08bd207498ef57a6657e4d;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/trail.c b/trail.c index bf23b1c..6bdee69 100644 --- a/trail.c +++ b/trail.c @@ -1,8 +1,28 @@ #pragma once +#include "vg/vg_engine.h" +#include "vg/vg_platform.h" +#include "vg/vg_m.h" +#include "vg/vg_lines.h" +#include "vg/vg_async.h" +#include "vg/vg_camera.h" #include "trail.h" +#include "shaders/particle.h" +#include "shaders/trail.h" -static void trail_system_update( trail_system *sys, f32 dt, - v3f co, v3f normal, f32 alpha ){ +static void trail_increment( trail_system *sys ){ + sys->head ++; + + if( sys->head == sys->max ) + sys->head = 0; + + /* undesirable effect: will remove active points if out of space! */ + if( sys->count < sys->max ) + sys->count ++; +} + +void trail_system_update( trail_system *sys, f32 dt, + v3f co, v3f normal, f32 alpha ) +{ /* update existing points and clip dead ones */ bool clip_allowed = 1; for( i32 i=0; icount; i ++ ){ @@ -20,65 +40,57 @@ static void trail_system_update( trail_system *sys, f32 dt, } } - bool add_point = 1; - i32 index_current = sys->head; - if( sys->count >= 2 ) index_current = sys->head -1; + i32 icur = sys->head -1, + iprev = sys->head -2, + ihead = sys->head; - i32 index_prev = index_current -1; + if( icur < 0 ) icur += sys->max; + if( iprev < 0 ) iprev += sys->max; - if( index_current < 0 ) index_current += sys->max; - if( index_prev < 0 ) index_prev += sys->max; + trail_point *pcur = &sys->array[ icur ], + *pprev = &sys->array[ iprev ], + *phead = &sys->array[ ihead ], + *pdest = NULL; + v3f dir; - /* always enforced non-zero distance */ - if( sys->count >= 1 ){ - if( v3_dist2( sys->array[index_prev].co, co ) < 0.001f*0.001f ) - return; - } + f32 k_min = 0.001f; - /* copy new info in */ - trail_point *p_current = &sys->array[index_current]; - v3_copy( co, p_current->co ); - v3_copy( normal, p_current->normal ); - p_current->alpha = alpha; - - /* update direction */ - if( sys->count >= 2 ){ - trail_point *p_prev = &sys->array[index_prev]; - - v3f dir; - v3_sub( co, p_prev->co, dir ); - v3_normalize( dir ); - v3_cross( dir, normal, p_current->right ); - v3_copy( p_current->right, p_prev->right ); - - /* decide if to prevent split based on user min-distance */ - if( v3_dist2( p_prev->co, co ) < sys->min_dist*sys->min_dist ) - add_point = 0; + if( sys->count == 0 ){ + trail_increment( sys ); + v3_copy( (v3f){0,0,-1}, dir ); + pdest = phead; } - else - v3_zero( p_current->right ); - - if( add_point ){ - sys->head ++; + else if( sys->count == 1 ){ + if( v3_dist2( pcur->co, co ) < k_min*k_min ) + return; - if( sys->head == sys->max ) - sys->head = 0; + trail_increment( sys ); + pdest = phead; + v3_sub( co, pcur->co, dir ); + } + else { + if( v3_dist2( pprev->co, co ) < k_min*k_min ) + return; - /* undesirable effect: will remove active points if out of space! */ - if( sys->count < sys->max ) - sys->count ++; + if( v3_dist2( pprev->co, co ) > sys->min_dist*sys->min_dist ){ + trail_increment( sys ); + pdest = phead; + } + else + pdest = pcur; - index_current = sys->head; + v3_sub( co, pprev->co, dir ); } - p_current = &sys->array[index_current]; - v3_copy( co, p_current->co ); - v3_copy( normal, p_current->normal ); - p_current->alpha = alpha; - v3_zero( p_current->right ); + v3_cross( dir, normal, pdest->right ); + v3_normalize( pdest->right ); + v3_copy( co, pdest->co ); + v3_copy( normal, pdest->normal ); + pdest->alpha = alpha; } -static void trail_system_debug( trail_system *sys ){ +void trail_system_debug( trail_system *sys ) +{ for( i32 i=0; icount; i ++ ){ i32 i0 = sys->head - sys->count + i; if( i0 < 0 ) i0 += sys->max; @@ -101,7 +113,8 @@ struct trail_init_args { trail_system *sys; }; -static void async_trail_init( void *payload, u32 size ){ +void async_trail_init( void *payload, u32 size ) +{ struct trail_init_args *args = payload; trail_system *sys = args->sys; @@ -121,7 +134,8 @@ static void async_trail_init( void *payload, u32 size ){ VG_CHECK_GL_ERR(); } -static void trail_alloc( trail_system *sys, u32 max ){ +void trail_alloc( trail_system *sys, u32 max ) +{ size_t stride = sizeof(trail_vert); sys->max = max; sys->array = vg_linear_alloc( vg_mem.rtmemory, max*sizeof(trail_point) ); @@ -134,26 +148,42 @@ static void trail_alloc( trail_system *sys, u32 max ){ vg_async_dispatch( call, async_trail_init ); } -static void trail_system_prerender( trail_system *sys ){ -#if 0 +void trail_system_prerender( trail_system *sys ) +{ + if( sys->count < 2 ) return; + + for( i32 i=0; icount; i ++ ){ + i32 i0 = sys->head - sys->count + i; + if( i0 < 0 ) i0 += sys->max; + + trail_point *p0 = &sys->array[i0]; + trail_vert *v0 = &sys->vertices[i*2+0], + *v1 = &sys->vertices[i*2+1]; + + v3_muladds( p0->co, p0->right, -sys->width, v0->co ); + v3_muladds( p0->co, p0->right, sys->width, v1->co ); + v0->co[3] = p0->alpha; + v1->co[3] = p0->alpha; + } + glBindVertexArray( sys->vao ); size_t stride = sizeof(trail_vert); glBindBuffer( GL_ARRAY_BUFFER, sys->vbo ); - glBufferSubData( GL_ARRAY_BUFFER, 0, sys->alive*stride*4, sys->vertices ); -#endif + glBufferSubData( GL_ARRAY_BUFFER, 0, sys->count*stride*2, sys->vertices ); } -static void trail_system_render( trail_system *sys, camera *cam ){ -#if 0 +void trail_system_render( trail_system *sys, vg_camera *cam ) +{ + if( sys->count < 2 ) return; glDisable( GL_CULL_FACE ); glEnable( GL_DEPTH_TEST ); shader_trail_use(); shader_trail_uPv( cam->mtx.pv ); shader_trail_uPvPrev( cam->mtx_prev.pv ); + shader_trail_uColour( (v4f){1.0f,1.0f,1.0f,1.0f} ); glBindVertexArray( sys->vao ); - glDrawElements( GL_TRIANGLES, sys->alive*6, GL_UNSIGNED_SHORT, NULL ); -#endif + glDrawArrays( GL_TRIANGLE_STRIP, 0, sys->count*2 ); }