- int tri_count = bvh_select_triangles( &world.geo, region, geo, 128 );
-
- v3f tri[3];
- for( int i=0; i<tri_count; i++ )
- {
- for( int j=0; j<3; j++ )
- v3_copy( world.geo.verts[ world.geo.indices[geo[i]+j] ].co, tri[j] );
-
-#if 0
- vg_line( tri[0], tri[1], 0xffa2ff30 );
- vg_line( tri[1], tri[2], 0xffa2ff30 );
- vg_line( tri[2], tri[0], 0xffa2ff30 );
-#endif
- }
-
- struct grid_sample
- {
- int valid;
- v3f clip[2];
- v3f pos;
- }
- samples[ k_gridamt ][ k_gridamt ];
-
- /* Get surface samples */
- for( int y=0; y<k_gridamt; y++ )
- {
- for( int x=0; x<k_gridamt; x++ )
- {
- struct grid_sample *s = &samples[y][x];
- v3_muladds( region[0], (v3f){ x, 0, y }, k_gridscale, s->pos );
- s->pos[1] = player.co[1] + k_height;
-
- s->valid = player_walkgrid_samplepole( geo, tri_count, s->pos )? 1: 0;
- }
- }
-
- /*
- * Calculate h+v clipping distances.
- * Distances are stored in A always, so you know that if the sample is
- * invalid, this signifies the start of the manifold as opposed to the
- * extent or bounds of it.
- */
- for( int i=0; i<2; i++ )
- {
- for( int x=0; x<k_gridamt; x++ )
- {
- for( int z=0; z<k_gridamt-1; z++ )
- {
- v3f clipdir = { 0.0f, 0.0f, 0.0f };
-
- struct grid_sample *sa, *sb;
- if( i == 1 )
- {
- sa = &samples[z][x];
- sb = &samples[z+1][x];
- }
- else
- {
- sa = &samples[x][z];
- sb = &samples[x][z+1];
- }
-
- if( sa->valid != sb->valid )
- {
- clipdir[i*2] = (float)(sa->valid - sb->valid)*k_gridscale;
- player_walkgrid_clip( geo, tri_count,
- sa->valid? sa->pos: sb->pos,
- clipdir, sa->clip[i] );
- }
- else
- {
- if( sa->valid )
- {
- vg_line( sa->pos, sb->pos, 0xffffffff );
- }
- }
- }
- }
- }
-
- /* Draw connections */
- for( int x=0; x<k_gridamt-1; x++ )
- {
- for( int z=0; z<k_gridamt-1; z++ )
- {
- static const struct conf
- {
- struct confedge
- {
- /* i: sample index
- * d: data index
- * a: axis index
- */
- int i0, i1,
- d0, d1,
- a0, a1;
- }
- edges[2];
- int edge_count;
- }
- k_configs[16] = {
- {{},0},
- {{{ 3, 3, 3, 0, 1,0 }}, 1},
- {{{ 2, 2, 1, 3, 0,1 }}, 1},
- {{{ 2, 3, 1, 0, 0,0 }}, 1},
-
- {{{ 1, 1, 0, 1, 1,0 }}, 1},
- {{{ 3, 3, 3, 0, 1,0 },
- { 1, 1, 0, 1, 1,0 }}, 2},
- {{{ 1, 2, 0, 3, 1,1 }}, 1},
- {{{ 1, 3, 0, 0, 1,0 }}, 1},
-
- {{{ 0, 0, 0, 0, 0,1 }}, 1},
- {{{ 3, 0, 3, 0, 1,1 }}, 1},
- {{{ 2, 2, 1, 3, 0,1 },
- { 0, 0, 0, 0, 0,1 }}, 2},
- {{{ 2, 0, 1, 0, 0,1 }}, 1},
-
- {{{ 0, 1, 0, 1, 0,0 }}, 1},
- {{{ 3, 1, 3, 1, 1,0 }}, 1},
- {{{ 0, 2, 0, 3, 0,1 }}, 1},
- {{},0},
- };
-
- struct grid_sample *corners[4] =
- {
- &samples[z][x],
- &samples[z+1][x],
- &samples[z+1][x+1],
- &samples[z][x+1]
- };
-
- u32 config = (corners[0]->valid<<3) | (corners[1]->valid<<2) |
- (corners[2]->valid<<1) | corners[3]->valid;
-
- const struct conf *conf = &k_configs[ config ];
-
- for( int i=0; i<conf->edge_count; i++ )
- {
- const struct confedge *edge = &conf->edges[i];
-
- v3f p0, p1;
- v3_add( corners[edge->i0]->pos,
- corners[edge->d0]->clip[edge->a0], p0 );
- v3_add( corners[edge->i1]->pos,
- corners[edge->d1]->clip[edge->a1], p1 );
- vg_line( p0, p1, 0xff0000ff );
-
- vg_line( corners[edge->i0]->pos, p0, 0xffffffff );
- vg_line( corners[edge->i1]->pos, p1, 0xffffffff );
- }
- }
- }
-}
-
-static void player_walkgrid(void)