randomzie playermodels
[carveJwlIkooP6JGAAIwe30JlM.git] / trail.c
diff --git a/trail.c b/trail.c
index bf23b1c56c5427a6ea371e19328b33707647c4db..6bdee69262a8d0eab261862fca9b9914263c48f7 100644 (file)
--- 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; i<sys->count; 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; i<sys->count; 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; i<sys->count; 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 );
 }