- /*
- * NOTE: as opposed to the other function which is done in discretized space
- * this use a combination of both.
- */
-
- v3f world;
- world[0] = wg->region[0][0]+((float)wg->cell_id[0]+wg->pos[0])*k_gridscale;
- world[1] = player.co[1];
- world[2] = wg->region[0][2]+((float)wg->cell_id[1]+wg->pos[1])*k_gridscale;
-
- struct grid_sample *corners[4];
- const struct conf *conf = player_walkgrid_conf( wg, wg->cell_id, corners );
-
- if( conf != k_walkgrid_configs )
- {
- if( conf->edge_count == 0 )
- {
- v3f v0;
-
- /* Split the basic quad along the shortest diagonal */
- if( fabsf(corners[2]->pos[1] - corners[0]->pos[1]) <
- fabsf(corners[3]->pos[1] - corners[1]->pos[1]) )
- {
- vg_line( corners[2]->pos, corners[0]->pos, 0xffaaaaaa );
-
- if( wg->pos[0] > wg->pos[1] )
- player_walkgrid_stand_tri( corners[0]->pos,
- corners[3]->pos,
- corners[2]->pos, world );
- else
- player_walkgrid_stand_tri( corners[0]->pos,
- corners[2]->pos,
- corners[1]->pos, world );
- }
- else
- {
- vg_line( corners[3]->pos, corners[1]->pos, 0xffaaaaaa );
-
- if( wg->pos[0] < 1.0f-wg->pos[1] )
- player_walkgrid_stand_tri( corners[0]->pos,
- corners[3]->pos,
- corners[1]->pos, world );
- else
- player_walkgrid_stand_tri( corners[3]->pos,
- corners[2]->pos,
- corners[1]->pos, world );
- }
- }
- else
- {
- 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 );
-
- /*
- * Find penetration distance between player position and the edge
- */
-
- v2f normal = { -(p1[2]-p0[2]), p1[0]-p0[0] },
- rel = { world[0]-p0[0], world[2]-p0[2] };
-
- if( edge->o0 == -1 )
- {
- /* No subregions (default case), just use triangle created by
- * i0, e0, e1 */
- player_walkgrid_stand_tri( corners[edge->i0]->pos,
- p0,
- p1, world );
- }
- else
- {
- /*
- * Test if we are in the first region, which is
- * edge.i0, edge.e0, edge.o0,
- */
- v3f v0, ref;
- v3_sub( p0, corners[edge->o0]->pos, ref );
- v3_sub( world, corners[edge->o0]->pos, v0 );
-
- vg_line( corners[edge->o0]->pos, p0, 0xffffff00 );
- vg_line( corners[edge->o0]->pos, world, 0xff000000 );
-
- if( ref[0]*v0[2] - ref[2]*v0[0] < 0.0f )
- {
- player_walkgrid_stand_tri( corners[edge->i0]->pos,
- p0,
- corners[edge->o0]->pos, world );
- }
- else
- {
- if( edge->o1 == -1 )
- {
- /*
- * No other edges mean we just need to use the opposite
- *
- * e0, e1, o0 (in our case, also i1)
- */
- player_walkgrid_stand_tri( p0,
- p1,
- corners[edge->o0]->pos, world );
- }
- else
- {
- /*
- * Note: this v0 calculation can be ommited with the
- * current tileset.
- *
- * the last two triangles we have are:
- * e0, e1, o1
- * and
- * e1, i1, o1
- */
- v3_sub( p1, corners[edge->o1]->pos, ref );
- v3_sub( world, corners[edge->o1]->pos, v0 );
- vg_line( corners[edge->o1]->pos, p1, 0xff00ffff );
-
- if( ref[0]*v0[2] - ref[2]*v0[0] < 0.0f )
- {
- player_walkgrid_stand_tri( p0,
- p1,
- corners[edge->o1]->pos,
- world );
- }
- else
- {
- player_walkgrid_stand_tri( p1,
- corners[edge->i1]->pos,
- corners[edge->o1]->pos,
- world );
- }
- }
- }
- }
- }
- }
- }
-
- v3_copy( world, player.co );