- float const k_stepheight = 0.5f;
- float const k_miny = 0.6f;
- float const k_height = 1.78f;
- float const k_region_size = (float)WALKGRID_SIZE/2.0f * k_gridscale;
-
- static struct walkgrid wg;
-
- v3f cell;
- v3_copy( player.co, cell );
- player_walkgrid_floor( cell );
-
- v3_muladds( cell, (v3f){-1.0f,-1.0f,-1.0f}, k_region_size, wg.region[0] );
- v3_muladds( cell, (v3f){ 1.0f, 1.0f, 1.0f}, k_region_size, wg.region[1] );
-
-
- /*
- * Create player input vector
- */
- v3f delta = {0.0f,0.0f,0.0f};
- v3f fwd = { -sinf(-player.angles[0]), 0.0f, -cosf(-player.angles[0]) },
- side = { -fwd[2], 0.0f, fwd[0] };
-
- /* Temp */
- if( !vg_console_enabled() )
- {
- if( glfwGetKey( vg_window, GLFW_KEY_W ) )
- v3_muladds( delta, fwd, ktimestep*k_walkspeed, delta );
- if( glfwGetKey( vg_window, GLFW_KEY_S ) )
- v3_muladds( delta, fwd, -ktimestep*k_walkspeed, delta );
-
- if( glfwGetKey( vg_window, GLFW_KEY_A ) )
- v3_muladds( delta, side, -ktimestep*k_walkspeed, delta );
- if( glfwGetKey( vg_window, GLFW_KEY_D ) )
- v3_muladds( delta, side, ktimestep*k_walkspeed, delta );
- }
-
- /*
- * Create our move in grid space
- */
- wg.dir[0] = delta[0] * (1.0f/k_gridscale);
- wg.dir[1] = delta[2] * (1.0f/k_gridscale);
- wg.move = 1.0f;
-
- v2f region_pos =
- {
- (player.co[0] - wg.region[0][0]) * (1.0f/k_gridscale),
- (player.co[2] - wg.region[0][2]) * (1.0f/k_gridscale)
- };
- v2f region_cell_pos;
- v2_floor( region_pos, region_cell_pos );
- v2_sub( region_pos, region_cell_pos, wg.pos );
-
- wg.cell_id[0] = region_cell_pos[0];
- wg.cell_id[1] = region_cell_pos[1];
-
-
-#if 0
- /* Get surface samples
- *
- * TODO: Replace this with a spiral starting from the player position
- */
- for( int y=0; y<WALKGRID_SIZE; y++ )
- {
- for( int x=0; x<WALKGRID_SIZE; x++ )
- {
- struct grid_sample *s = &wg.samples[y][x];
- v3_muladds( wg.region[0], (v3f){ x, 0, y }, k_gridscale, s->pos );
- s->pos[1] = cell[1];
- player_walkgrid_samplepole( s );
- }
- }
-
- /*
- * 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<WALKGRID_SIZE; x++ )
- {
- for( int z=0; z<WALKGRID_SIZE-1; z++ )
- {
- struct grid_sample *sa, *sb;
- if( i == 1 )
- {
- sa = &wg.samples[z][x];
- sb = &wg.samples[z+1][x];
- }
- else
- {
- sa = &wg.samples[x][z];
- sb = &wg.samples[x][z+1];
- }
-
- player_walkgrid_clip( sa, sb, i );
-
- if( sa->type == k_sample_type_valid &&
- sb->type == k_sample_type_valid )
- vg_line( sa->pos, sb->pos, 0xffffffff );
-#if 0
- if( sa->valid != sb->valid )
- {
- clipdir[i*2] = (float)(sa->valid - sb->valid) * k_gridscale;
-
- player_walkgrid_clip( sa->valid? sa->pos: sb->pos,
- clipdir, sa->clip[i] );
- }
- else
- {
- if( sa->valid )
- {
- vg_line( sa->pos, sb->pos, 0xffffffff );
- }
- }
-#endif
- }
- }
- }
-#endif
-
- for(int y=0; y<WALKGRID_SIZE; y++ )
- {
- for(int x=0; x<WALKGRID_SIZE; x++ )
- {
- struct grid_sample *s = &wg.samples[y][x];
- v3_muladds( wg.region[0], (v3f){ x, 0, y }, k_gridscale, s->pos );
- s->state = k_traverse_none;
- s->type = k_sample_type_air;
- v3_zero( s->clip[0] );
- v3_zero( s->clip[1] );
- }
- }
-
- v2i border[WALKGRID_SIZE*WALKGRID_SIZE];
- v2i *cborder = border;
- u32 border_length = 1;
-
- struct grid_sample *base = NULL;
-
- v2i starters[] = {{0,0},{1,1},{0,1},{1,0}};
-
- for( int i=0;i<4;i++ )
- {
- v2i test;
- v2i_add( wg.cell_id, starters[i], test );
- v2i_copy( test, border[0] );
- base = &wg.samples[test[1]][test[0]];
-
- base->pos[1] = cell[1];
- player_walkgrid_samplepole( base );
-
- if( base->type == k_sample_type_valid )
- break;
- else
- base->type = k_sample_type_air;
- }
-
- vg_line_pt3( base->pos, 0.1f, 0xffffffff );
-
- int iter = 0;
-
- while( border_length )
- {
- v2i directions[] = {{1,0},{0,1},{-1,0},{0,-1}};
-
- v2i *old_border = cborder;
- int len = border_length;
-
- border_length = 0;
- cborder = old_border+len;
-
- for( int i=0; i<len; i++ )
- {
- v2i co;
- v2i_copy( old_border[i], co );
- struct grid_sample *sa = &wg.samples[co[1]][co[0]];
-
- for( int j=0; j<4; j++ )
- {
- v2i newp;
- v2i_add( co, directions[j], newp );
-
- if( newp[0] < 0 || newp[1] < 0 ||
- newp[0] == WALKGRID_SIZE || newp[1] == WALKGRID_SIZE )
- continue;
-
- struct grid_sample *sb = &wg.samples[newp[1]][newp[0]];
- enum traverse_state thismove = j%2==0? 1: 2;
-
- if( (sb->state & thismove) == 0x00 ||
- sb->type == k_sample_type_air )
- {
- sb->pos[1] = sa->pos[1];
-
- player_walkgrid_samplepole( sb );
-
- if( sb->type != k_sample_type_air )
- {
- /*
- * Need to do a blocker pass
- */
-
- struct grid_sample *store = (j>>1 == 0)? sa: sb;
- player_walkgrid_clip_blocker( sa, sb, store, j%2 );
-
-
- if( sb->type != k_sample_type_air )
- {
- vg_line( sa->pos, sb->pos, 0xffffffff );
-
- if( sb->state == k_traverse_none )
- v2i_copy( newp, cborder[ border_length ++ ] );
- }
- else
- {
- v3f p1;
- v3_muladds( sa->pos, store->clip[j%2], k_gridscale, p1 );
- vg_line( sa->pos, p1, 0xffffffff );
- }
- }
- else
- {
- /*
- * A clipping pass is now done on the edge of the walkable
- * surface
- */
-
- struct grid_sample *store = (j>>1 == 0)? sa: sb;
- player_walkgrid_clip_edge( sa, sb, store, j%2 );
-
- v3f p1;
- v3_muladds( sa->pos, store->clip[j%2], k_gridscale, p1 );
- vg_line( sa->pos, p1, 0xffffffff );
- }
-
- sb->state |= thismove;
- }
- }
-
- sa->state = k_traverse_h|k_traverse_v;
- }
-
- iter ++;
- if( iter == walk_grid_iterations )
- break;
- }
-
-#if 0
- player.co[0] += wg.dir[0];
- player.co[2] += wg.dir[1];
-#endif
-
-
-
- /* Draw connections */
- struct grid_sample *corners[4];
- for( int x=0; x<WALKGRID_SIZE-1; x++ )
- {
- for( int z=0; z<WALKGRID_SIZE-1; z++ )
- {
- const struct conf *conf =
- player_walkgrid_conf( &wg, (v2i){x,z}, corners );
-
- for( int i=0; i<conf->edge_count; i++ )
- {
- const struct confedge *edge = &conf->edges[i];
-
- v3f p0, p1;
- v3_muladds( corners[edge->i0]->pos,
- corners[edge->d0]->clip[edge->a0], k_gridscale, p0 );
- v3_muladds( corners[edge->i1]->pos,
- corners[edge->d1]->clip[edge->a1], k_gridscale, p1 );
-
- vg_line( p0, p1, 0xff0000ff );
- }
- }
- }
-
- /*
- * Commit player movement into the grid
- */
-
- if( v3_length2(delta) <= 0.00001f )
- return;
-
- int i=0;
- for(; i<8 && wg.move > 0.001f; i++ )
- player_walkgrid_iter( &wg, i );
-
- player_walkgrid_stand_cell( &wg );
-}