-static void player_walkgrid_getsurface(void)
-{
- 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 );
-}
-
-static void player_walkgrid(void)
-{
- player_walkgrid_getsurface();
-
- m4x3_mulv( player.to_world, (v3f){0.0f,1.8f,0.0f}, player.camera_pos );
- player_mouseview();
- player_transform_update();
-}
-
-static void player_animate(void)
-{
- /* Camera position */
- v3_sub( player.v, player.v_last, player.a );
- v3_copy( player.v, player.v_last );
-
- v3_add( player.m, player.a, player.m );
- v3_lerp( player.m, (v3f){0.0f,0.0f,0.0f}, 0.1f, player.m );
- v3f target;
-
- player.m[0] = vg_clampf( player.m[0], -2.0f, 2.0f );
- player.m[1] = vg_clampf( player.m[1], -0.2f, 5.0f );
- player.m[2] = vg_clampf( player.m[2], -2.0f, 2.0f );
- v3_copy( player.m, target );
- v3_lerp( player.bob, target, 0.2f, player.bob );
-
- /* Head */
- float lslip = fabsf(player.slip); //vg_minf( 0.4f, slip );
-
- float grabt = vg_get_axis( "grabr" )*0.5f+0.5f;
- player.grab = vg_lerpf( player.grab, grabt, 0.04f );
-
- float kheight = 2.0f,
- kleg = 0.6f;
-
- v3f head;
- head[0] = 0.0f;
- head[1] = (0.3f+cosf(lslip)*0.5f*(1.0f-player.grab*0.7f)) * kheight;
- head[2] = 0.0f;
-
- v3f offset;
- m3x3_mulv( player.to_local, player.bob, offset );
-
- offset[0] *= 0.3333f;
- offset[1] *= -0.25f;
- offset[2] *= 0.7f;
- v3_muladds( head, offset, 0.7f, head );
- head[1] = vg_clampf( head[1], 0.3f, kheight );
-
-#if 0
- if( !freecam )
- {
- v3_copy( head, player.view );
- v3f camoffs = {-0.2f,-0.6f,0.00f};
- v3_add( player.view, camoffs, player.view );
- }
-#endif
-
- /*
- * Animation blending
- * ===========================================
- */
-
- static float fslide = 0.0f;
- static float fdirz = 0.0f;
- static float fdirx = 0.0f;
- static float fstand = 0.0f;
- static float ffly = 0.0f;
-
- float speed = v3_length( player.v );
-
- fstand = vg_lerpf(fstand, 1.0f-vg_clampf(speed*0.03f,0.0f,1.0f),0.1f);
- fslide = vg_lerpf(fslide, vg_clampf(lslip+fabsf(offset[0])*0.2f,
- 0.0f,1.0f), 0.04f);
- fdirz = vg_lerpf(fdirz, player.reverse > 0.0f? 1.0f: 0.0f, 0.04f );
- fdirx = vg_lerpf(fdirx, player.slip < 0.0f? 1.0f: 0.0f, 0.04f );
- ffly = vg_lerpf(ffly, player.in_air? 1.0f: 0.0f, 0.04f );
-
- character_pose_reset( &player.mdl );
-
- float amt_air = ffly*ffly,
- amt_ground = 1.0f-amt_air,
- amt_std = (1.0f-fslide) * amt_ground,
- amt_stand = amt_std * fstand,
- amt_aero = amt_std * (1.0f-fstand),
- amt_slide = amt_ground * fslide;
-
- character_final_pose( &player.mdl, offset, &pose_stand, amt_stand*fdirz );
- character_final_pose( &player.mdl, offset,
- &pose_stand_reverse, amt_stand * (1.0f-fdirz) );
-
- character_final_pose( &player.mdl, offset, &pose_aero, amt_aero*fdirz );
- character_final_pose( &player.mdl, offset,
- &pose_aero_reverse, amt_aero * (1.0f-fdirz) );
-
- character_final_pose( &player.mdl, offset, &pose_slide, amt_slide*fdirx );
- character_final_pose( &player.mdl, offset,
- &pose_slide1, amt_slide*(1.0f-fdirx) );
-
- character_final_pose( &player.mdl, (v3f){0.0f,0.0f,0.0f},
- &pose_fly, amt_air );
-
- /* Camera position */
- v3_lerp( player.smooth_localcam, player.mdl.cam_pos, 0.08f,
- player.smooth_localcam );
- v3_muladds( player.smooth_localcam, offset, 0.7f, player.camera_pos );
- player.camera_pos[1] = vg_clampf( player.camera_pos[1], 0.3f, kheight );
- m4x3_mulv( player.to_world, player.camera_pos, player.camera_pos );
-
- player.air_blend = vg_lerpf( player.air_blend, player.in_air, 0.04f );
- v3_muladds( player.camera_pos, player.v, -0.05f*player.air_blend,
- player.camera_pos );
-
- /*
- * Additive effects
- * ==========================
- */
- struct ik_basic *arm_l = &player.mdl.ik_arm_l,
- *arm_r = &player.mdl.ik_arm_r;
-
- v3f localv;
- m3x3_mulv( player.to_local, player.v, localv );
- v3_muladds( arm_l->end, localv, -0.01f, arm_l->end );
- v3_muladds( arm_r->end, localv, -0.01f, arm_r->end );
-
- /* New board transformation */
- v4f board_rotation; v3f board_location;
-
- v4f rz, rx;
- q_axis_angle( rz, (v3f){ 0.0f, 0.0f, 1.0f }, player.board_xy[0] );
- q_axis_angle( rx, (v3f){ 1.0f, 0.0f, 0.0f }, player.board_xy[1] );
- q_mul( rx, rz, board_rotation );
-
- v3f *mboard = player.mdl.matrices[k_chpart_board];// player.mboard;
- q_m3x3( board_rotation, mboard );
- m3x3_mulv( mboard, (v3f){ 0.0f, -0.5f, 0.0f }, board_location );
- v3_add( (v3f){0.0f,0.5f,0.0f}, board_location, board_location );
- v3_copy( board_location, mboard[3] );
-
-
- float wheel_r = offset[0]*-0.4f;
- v4f qwheel;
- q_axis_angle( qwheel, (v3f){0.0f,1.0f,0.0f}, wheel_r );
-
- q_m3x3( qwheel, player.mdl.matrices[k_chpart_wb] );
-
- m3x3_transpose( player.mdl.matrices[k_chpart_wb],
- player.mdl.matrices[k_chpart_wf] );
- v3_copy( player.mdl.offsets[k_chpart_wb],
- player.mdl.matrices[k_chpart_wb][3] );
- v3_copy( player.mdl.offsets[k_chpart_wf],
- player.mdl.matrices[k_chpart_wf][3] );
-
- m4x3_mul( mboard, player.mdl.matrices[k_chpart_wb],
- player.mdl.matrices[k_chpart_wb] );
- m4x3_mul( mboard, player.mdl.matrices[k_chpart_wf],
- player.mdl.matrices[k_chpart_wf] );
-
- m4x3_mulv( mboard, player.mdl.ik_leg_l.end, player.mdl.ik_leg_l.end );
- m4x3_mulv( mboard, player.mdl.ik_leg_r.end, player.mdl.ik_leg_r.end );
-
-
- v3_copy( player.mdl.ik_arm_l.end, player.handl_target );
- v3_copy( player.mdl.ik_arm_r.end, player.handr_target );
-
- if( 1||player.in_air )
- {
- float tuck = player.board_xy[1],
- tuck_amt = fabsf( tuck ) * (1.0f-fabsf(player.board_xy[0]));
-
- float crouch = player.grab*0.3f;
- v3_muladds( player.mdl.ik_body.base, (v3f){0.0f,-1.0f,0.0f},
- crouch, player.mdl.ik_body.base );
- v3_muladds( player.mdl.ik_body.end, (v3f){0.0f,-1.0f,0.0f},
- crouch*1.2f, player.mdl.ik_body.end );
-
- if( tuck < 0.0f )
- {
- //foot_l *= 1.0f-tuck_amt*1.5f;
-
- if( player.grab > 0.1f )
- {
- m4x3_mulv( mboard, (v3f){0.1f,0.14f,0.6f},
- player.handl_target );
- }
- }
- else
- {
- //foot_r *= 1.0f-tuck_amt*1.4f;
-
- if( player.grab > 0.1f )
- {
- m4x3_mulv( mboard, (v3f){0.1f,0.14f,-0.6f},
- player.handr_target );
- }
- }
- }
-
- v3_lerp( player.handl, player.handl_target, 0.1f, player.handl );
- v3_lerp( player.handr, player.handr_target, 0.1f, player.handr );
-
- v3_copy( player.handl, player.mdl.ik_arm_l.end );
- v3_copy( player.handr, player.mdl.ik_arm_r.end );
-
- /* Head rotation */
-
- static float rhead = 0.0f;
- rhead = vg_lerpf( rhead,
- vg_clampf(atan2f( localv[2], -localv[0] ),-1.0f,1.0f), 0.04f );
- player.mdl.rhead = rhead;
-}
-
-static int giftwrapXZ( v3f *points, int *output, int len )
-{
- int l, p, q, count;
-
- if( len < 3 )
- return 0;
-
- l = 0;
- for( int i=1; i<len; i++ )
- if( points[i][0] < points[l][0] )
- l = i;
-
- p = l;
- count = 0;
- do
- {
- if( count >= len )
- {
- vg_error ("MANIFOLD ERR (%d)\n", count );
- return 0;
- }
- output[ count ++ ] = p;
-
- q = (p+1)%len;
-
- for( int i=0; i<len; i++ )
- {
- float orient =
- (points[i][2]-points[p][2])*(points[q][0]-points[i][0]) -
- (points[i][0]-points[p][0])*(points[q][2]-points[i][2]);
-
- if( orient > 0.0001f )
- {
- q = i;
- }
- }
- p = q;
- }
- while( p != l );
-
- return count;
-}
-
-static void player_do_collision( rigidbody *rb )
-{
- /*
- * If point is inside box
- * find normal (theres 8 simple pyramid regions for this, x>y/dim .. etc)
- * find distance (same sorta thing)
- *
- * apply normal impulse to rotation
- * correct position based on new penetration amount if needed
- * apply normal impulse to velocity
- */
-
- v3f pfront, pback;
- m4x3_mulv( player.to_world, (v3f){ 0.0f,0.0f,-1.0f }, pfront );
- m4x3_mulv( player.to_world, (v3f){ 0.0f,0.0f, 1.0f }, pback );
-
- float const kheight = 2.0f;
-
- v3f verts[8];
-
- v3f a, b;
- v3_copy( rb->bbx[0], a );
- v3_copy( rb->bbx[1], b );
-
- m4x3f compound;
- m4x3_mul( player.to_local, rb->to_world, compound );
-
- m4x3_mulv( compound, (v3f){ a[0], a[1], a[2] }, verts[0] );
- m4x3_mulv( compound, (v3f){ a[0], b[1], a[2] }, verts[1] );
- m4x3_mulv( compound, (v3f){ b[0], b[1], a[2] }, verts[2] );
- m4x3_mulv( compound, (v3f){ b[0], a[1], a[2] }, verts[3] );
- m4x3_mulv( compound, (v3f){ a[0], a[1], b[2] }, verts[4] );
- m4x3_mulv( compound, (v3f){ a[0], b[1], b[2] }, verts[5] );
- m4x3_mulv( compound, (v3f){ b[0], b[1], b[2] }, verts[6] );
- m4x3_mulv( compound, (v3f){ b[0], a[1], b[2] }, verts[7] );
-
- int const indices[12][2] = {
- {0,1},{1,2},{2,3},{3,0},{4,5},{5,6},{6,7},{7,4},
- {0,4},{1,5},{2,6},{3,7}
- };
-
- v3f hull[12*2 + 8];
- int hull_indices[12*2 + 8];
- int hull_len = 0;
-
- for( int i=0; i<8; i++ )
- {
- int ia = indices[i][0];
- float ya = verts[ia][1];
-
- if( ya > 0.2f && ya < kheight )
- {
- int add_point = 1;
- for( int j=0; j<hull_len; j++ )
- {
- v2f delta = { verts[ia][0]-hull[j][0], verts[ia][2]-hull[j][2] };
- if( v2_length2( delta ) < 0.0004f )
- {
- add_point = 0;
- break;
- }
- }
-
- if( add_point )
- v3_copy( verts[ia], hull[hull_len] );
-
- hull[hull_len ++][1] = 0.2f;
- }
- }
-
- for( int i=0; i<vg_list_size(indices); i++ )
- {
- int ia = indices[i][0],
- ib = indices[i][1];
-
- v3f p0, p1;
-
- float ya = verts[ia][1],
- yb = verts[ib][1],
- d = 1.0f/(yb-ya),
- qa;
-
- float planes[] = { 0.2f, kheight };
-
- for( int k=0; k<vg_list_size(planes); k++ )
- {
- float clip = planes[k];
-
- if( (ya-clip) * (yb-clip) < 0.0f )
- {
- v3_muls( verts[ia], (yb-clip)*d, p0 );
- v3_muladds( p0, verts[ib], -(ya-clip)*d, p0 );
-
- int add_point = 1;
- for( int j=0; j<hull_len; j++ )
- {
- v2f delta = { p0[0]-hull[j][0], p0[2]-hull[j][2] };
- if( v2_length2( delta ) < 0.0004f )
- {
- add_point = 0;
- break;
- }
- }
-
- if( add_point )
- v3_copy( p0, hull[hull_len ++] );
-
- m4x3_mulv( player.to_world, p0, p0 );
- vg_line_pt3( p0, 0.1f, 0xffffff00 );
- }
- }
- }
-
- if( hull_len < 3 )
- return;
-
- int len = giftwrapXZ( hull, hull_indices, hull_len );
- for( int i=0; i<len; i++ )
- {
- v3f p0, p1, p2, p3;
- v3_copy( hull[hull_indices[i]], p0 );
- v3_copy( hull[hull_indices[(i+1)%len]], p1 );
- p0[1] = 0.2f;
- p1[1] = 0.2f;
- v3_add( p0, (v3f){0,kheight-0.2f,0}, p2 );
- v3_add( p1, (v3f){0,kheight-0.2f,0}, p3 );
-
- m4x3_mulv( player.to_world, p0, p0 );
- m4x3_mulv( player.to_world, p1, p1 );
- m4x3_mulv( player.to_world, p2, p2 );
- m4x3_mulv( player.to_world, p3, p3 );
-
- vg_line2( p0, p1, 0xff00ffff, 0xff000000 );
- vg_line( p2, p3, 0xff00ffff );
- vg_line( p0, p2, 0xff00ffa0 );
- }
-
- v2f endpoints[] = {{ 0.0f, -1.0f },{ 0.0f, 1.0f }};
-
- for( int j=0; j<vg_list_size(endpoints); j++ )
- {
- v2f point;
- v2_copy( endpoints[j], point );
-
- int collide = 1;
- float min_dist = 99999.9f;
- v2f normal;
- for( int i=0; i<len; i++ )
- {
- v2f p0, p1;
- p0[0] = hull[hull_indices[i]][0];
- p0[1] = hull[hull_indices[i]][2];
- p1[0] = hull[hull_indices[(i+1)%len]][0];
- p1[1] = hull[hull_indices[(i+1)%len]][2];
-
- v2f t,n, rel;
- v2_sub( p1, p0, t );
- n[0] = -t[1];
- n[1] = t[0];
- v2_normalize(n);
-
- v2_sub( point, p0, rel );
- float d = -v2_dot( n, rel ) + 0.5f;
-
- if( d < 0.0f )
- {
- collide = 0;
- break;
- }
-
- if( d < min_dist )
- {
- min_dist = d;
- v2_copy( n, normal );
- }
- }
-
- if( collide )
- {
- v3f p0, p1;
- p0[0] = 0.0f;
- p0[1] = 0.2f;
- p0[2] = -1.0f;
-
- p1[0] = p0[0] + normal[0]*min_dist;
- p1[1] = p0[1];
- p1[2] = p0[2] + normal[1]*min_dist;
-
- m4x3_mulv( player.to_world, p0, p0 );
- m4x3_mulv( player.to_world, p1, p1 );
-
- vg_line( p0, p1, 0xffffffff );
-
- v3f vel;
- m3x3_mulv( player.to_local, player.v, vel );
- vel[1] = vel[2];
-
- float vn = vg_maxf( -v2_dot( vel, normal ), 0.0f );
- vn += -0.2f * (1.0f/k_rb_delta) * vg_minf( 0.0f, -min_dist+0.04f );
-
- v2f impulse;
- if( vn > 14.0f )
- {
- player.is_dead = 1;
- character_ragdoll_copypose( &player.mdl, player.v );
- return;
- }
-
- if( vn > 0.0f )
- {
- v2_muls( normal, min_dist, impulse );
- float rotation = v2_cross( point, impulse )*0.08f;
- v4f rot;
- v3f up = {0.0f,1.0f,0.0f};
- m3x3_mulv( player.to_world, up, up );
- q_axis_angle( rot, up, -rotation );
- q_mul( rot, player.rot, player.rot );
- }
-
- v2_muls( normal, vn*0.03f, impulse );
- v3f impulse_world = { impulse[0], 0.0f, impulse[1] };
-
- m3x3_mulv( player.to_world, impulse_world, impulse_world );
- v3_add( impulse_world, player.v, player.v );
- }
- }
-}
-
-static void player_update(void)
-{
- for( int i=0; i<player.land_log_count; i++ )
- draw_cross( player.land_target_log[i], player.land_target_colours[i], 1);
-
- if( vg_get_axis("grabl")>0.0f)
- reset_player(0,NULL);
-
- if( freecam )
- {
- player_freecam();
- }
- else
- {
- if( player.is_dead )
- {
- character_ragdoll_iter( &player.mdl );
- character_debug_ragdoll( &player.mdl );
- }
- else
- {
- if( player.on_board )
- {
- bh_debug_node(&world.bhcubes, 0,
- player.camera_pos, 0xff80ff00 );
-
- u32 colliders[16];
- boxf wbox = {{ -2.0f, -2.0f, -2.0f },
- { 2.0f, 2.0f, 2.0f }};
- m4x3_transform_aabb( player.to_world, wbox );
- int len = bh_select( &world.bhcubes, wbox, colliders, 32 );
-
- for( int i=0; i<len; i++ )
- player_do_collision( &world.temp_rbs[colliders[i]] );
-
- player_do_motion();
- player_animate();
- }
- else
- {
- player_walkgrid();
- }
- }
- }
-
- /* Update camera matrices */
- m4x3_identity( player.camera );
- m4x3_rotate_y( player.camera, -player.angles[0] );
- m4x3_rotate_x( player.camera, -0.33f -player.angles[1] );
- v3_copy( player.camera_pos, player.camera[3] );
- m4x3_invert_affine( player.camera, player.camera_inverse );
-}
-
-static void draw_player(void)
-{
- /* Draw */
- m4x3_copy( player.to_world, player.mdl.mroot );
-
- if( player.is_dead )
- character_mimic_ragdoll( &player.mdl );
- else
- character_eval( &player.mdl );
-
- character_draw( &player.mdl, (player.is_dead|player.in_air)? 0.0f: 1.0f );
-}