VG_VAR_I32( cl_thirdperson );
VG_VAR_F32_PERSISTENT( fc_speed );
- /* TODO: NOT PERSISTENT */
VG_VAR_F32( k_ragdoll_limit_scale );
VG_VAR_I32( k_ragdoll_div );
VG_VAR_I32( k_ragdoll_debug_collider );
struct player_walk *w = &player->_walk;
v3_copy( player->rb.co, w->state.prev_pos );
+ enum walk_activity prev_state = w->state.activity;
+
if( w->state.activity == k_walk_activity_immobile )
return;
v2_normalize_clamp( walk );
w->move_speed = v2_length( walk );
+ world_instance *world = get_active_world();
/*
* Collision detection
*/
- world_instance *world = get_active_world();
len = rb_capsule__scene( mtx, &w->collider, NULL,
&world->rb_geo.inf.scene, manifold );
w->surface = k_surface_prop_concrete;
- for( int i=0; i<len; i++ )
- {
+ for( int i=0; i<len; i++ ){
struct contact *ct = &manifold[i];
rb_debug_contact( ct );
- if( player_walk_normal_standable( player, ct->n ) )
- {
+ if( player_walk_normal_standable( player, ct->n ) ){
if( w->state.activity != k_walk_activity_lockedmove )
w->state.activity = k_walk_activity_ground;
/* jump */
if( player->input_jump->button.value ){
+ float d = v3_dot( player->basis[1], player->rb.v );
+ v3_muladds( player->rb.v, player->basis[1], -d, player->rb.v );
v3_muladds( player->rb.v, player->basis[1], 5.0f, player->rb.v );
w->state.activity = k_walk_activity_air;
+ prev_state = k_walk_activity_air;
accel_speed = k_walk_air_accel;
nominal_speed = k_airspeed;
}
}
}
- /*
- * Depenetrate
- */
- v3f dt;
- rb_depenetrate( manifold, len, dt );
- v3_add( dt, player->rb.co, player->rb.co );
-
- /* TODO: Stepping......
- *
- * ideas; walkgrid style steps
- */
-#if 0
- if( w->state.activity == k_walk_activity_ground )
- {
- /* step */
+ /* stepping */
+ if( w->state.activity == k_walk_activity_ground||
+ prev_state == k_walk_activity_ground ){
float max_dist = 0.4f;
v3f pa, pb;
v3_copy( player->rb.co, pa );
- pa[1] += w->collider.radius + max_dist;
-
- v3_muladds( pa, (v3f){0.0f,1.0f,0.0f}, -max_dist * 2.0f, pb );
+ v3_muladds( pa, player->basis[1], w->collider.radius + max_dist, pa );
+ v3_muladds( pa, player->basis[1], -max_dist * 2.0f, pb );
vg_line( pa, pb, 0xff000000 );
v3f n;
float t;
- if( spherecast_world( pa, pb, w->collider.radius, &t, n ) != -1 )
- {
- if( player_walk_normal_standable( n ) )
- {
+ if( spherecast_world( world, pa, pb, w->collider.radius, &t, n ) != -1 ){
+ if( player_walk_normal_standable( player, n ) ){
v3_lerp( pa, pb, t, player->rb.co );
- player->rb.co[1] -= w->collider.radius;
+ v3_muladds( player->rb.co, player->basis[1],
+ -w->collider.radius - k_penetration_slop,
+ player->rb.co );
+ w->state.activity = k_walk_activity_ground;
+
+ float d = -v3_dot(n,player->rb.v),
+ g = -k_gravity * k_rb_delta;
+ v3_muladds( player->rb.v, n, d, player->rb.v );
+ v3_muladds( player->rb.v, player->basis[1], g, player->rb.v );
}
}
}
-#endif
+ /*
+ * Depenetrate
+ */
+ v3f dt;
+ rb_depenetrate( manifold, len, dt );
+ v3_add( dt, player->rb.co, player->rb.co );
/* integrate */
- if( w->state.activity == k_walk_activity_air )
- {
+ if( w->state.activity == k_walk_activity_air ){
v3_muladds( player->rb.v, player->basis[1], -k_gravity*k_rb_delta,
player->rb.v );
}
float movedist = v3_length( movedelta );
- if( movedist > 0.3f )
- {
+ if( movedist > 0.3f ){
float t, sr = w->collider.radius-0.04f;
v3f n;
- if( spherecast_world( world, lwr_prev, lwr_now, sr, &t, n ) != -1 )
- {
+ if( spherecast_world( world, lwr_prev, lwr_now, sr, &t, n ) != -1 ){
v3_lerp( lwr_prev, lwr_now, vg_maxf(0.01f,t), player->rb.co );
player->rb.co[1] -= w->collider.radius;
rb_update_transform( &player->rb );
" aCo = a_co;\n"
" aWorldCo = world_pos;\n"
"\n"
-" // TODO:\n"
+" // TODO: motion vectors\n"
" aMotionVec0 = vec3(1.0);\n"
" aMotionVec1 = vec3(1.0);\n"
"}\n"
"\n"
"float world_water_depth( vec3 pos )\n"
"{\n"
-" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
-" return texture( g_world_depth, depth_coord ).g-ref_depth;\n"
+" return world_depth_sample( pos ) - ref_depth;\n"
"}\n"
"\n"
"float shadow_sample( vec3 vdir )\n"
aCo = a_co;
aWorldCo = world_pos;
- // TODO:
+ // TODO: motion vectors
aMotionVec0 = vec3(1.0);
aMotionVec1 = vec3(1.0);
}
"\n"
"float world_water_depth( vec3 pos )\n"
"{\n"
-" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
-" return texture( g_world_depth, depth_coord ).g-ref_depth;\n"
+" return world_depth_sample( pos ) - ref_depth;\n"
"}\n"
"\n"
"float shadow_sample( vec3 vdir )\n"
"\n"
"float world_water_depth( vec3 pos )\n"
"{\n"
-" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
-" return texture( g_world_depth, depth_coord ).g-ref_depth;\n"
+" return world_depth_sample( pos ) - ref_depth;\n"
"}\n"
"\n"
"float shadow_sample( vec3 vdir )\n"
"\n"
"float world_water_depth( vec3 pos )\n"
"{\n"
-" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
-" return texture( g_world_depth, depth_coord ).g-ref_depth;\n"
+" return world_depth_sample( pos ) - ref_depth;\n"
"}\n"
"\n"
"float shadow_sample( vec3 vdir )\n"
"\n"
"float world_water_depth( vec3 pos )\n"
"{\n"
-" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
-" return texture( g_world_depth, depth_coord ).g-ref_depth;\n"
+" return world_depth_sample( pos ) - ref_depth;\n"
"}\n"
"\n"
"float shadow_sample( vec3 vdir )\n"
"\n"
"float world_water_depth( vec3 pos )\n"
"{\n"
-" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
-" return texture( g_world_depth, depth_coord ).g-ref_depth;\n"
+" return world_depth_sample( pos ) - ref_depth;\n"
"}\n"
"\n"
"float shadow_sample( vec3 vdir )\n"
"\n"
"float world_water_depth( vec3 pos )\n"
"{\n"
-" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
-" return texture( g_world_depth, depth_coord ).g-ref_depth;\n"
+" return world_depth_sample( pos ) - ref_depth;\n"
"}\n"
"\n"
"float shadow_sample( vec3 vdir )\n"
"\n"
"float world_water_depth( vec3 pos )\n"
"{\n"
-" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
-" return texture( g_world_depth, depth_coord ).g-ref_depth;\n"
+" return world_depth_sample( pos ) - ref_depth;\n"
"}\n"
"\n"
"float shadow_sample( vec3 vdir )\n"
"\n"
"float world_water_depth( vec3 pos )\n"
"{\n"
-" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
-" return texture( g_world_depth, depth_coord ).g-ref_depth;\n"
+" return world_depth_sample( pos ) - ref_depth;\n"
"}\n"
"\n"
"float shadow_sample( vec3 vdir )\n"
"\n"
"float world_water_depth( vec3 pos )\n"
"{\n"
-" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
-" return texture( g_world_depth, depth_coord ).g-ref_depth;\n"
+" return world_depth_sample( pos ) - ref_depth;\n"
"}\n"
"\n"
"float shadow_sample( vec3 vdir )\n"
"\n"
"float world_water_depth( vec3 pos )\n"
"{\n"
-" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
-" return texture( g_world_depth, depth_coord ).g-ref_depth;\n"
+" return world_depth_sample( pos ) - ref_depth;\n"
"}\n"
"\n"
"float shadow_sample( vec3 vdir )\n"
" vec2 ssuv = gl_FragCoord.xy*uInvRes;\n"
" \n"
" // Surface colour composite\n"
-" float depthvalue = clamp( -world_water_depth(aWorldCo)*(1.0/25.0), 0.0,1.0 );\n"
+" float depthvalue = clamp( -world_water_depth(aCo)*(1.0/25.0), 0.0,1.0 );\n"
"\n"
" vec2 world_coord = aCo.xz * 0.008;\n"
" vec4 time_offsets = vec4( uTime ) * vec4( 0.008, 0.006, 0.003, 0.03 );\n"
"\n"
"float world_water_depth( vec3 pos )\n"
"{\n"
-" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
-" return texture( g_world_depth, depth_coord ).g-ref_depth;\n"
+" return world_depth_sample( pos ) - ref_depth;\n"
"}\n"
"\n"
"float shadow_sample( vec3 vdir )\n"
VG_STATIC void steam_store_achievements(void)
{
- if( steam_ready && steam_stats_ready )
- {
+ if( steam_ready && steam_stats_ready ){
SteamAPI_ISteamUserStats_StoreStats( hSteamUserStats );
}
}
VG_STATIC void steam_set_achievement( const char *name )
{
- if( steam_ready && steam_stats_ready )
- {
- if( SteamAPI_ISteamUserStats_SetAchievement( hSteamUserStats, name ) )
- {
+ if( steam_ready && steam_stats_ready ){
+ if( SteamAPI_ISteamUserStats_SetAchievement( hSteamUserStats, name ) ){
vg_success( "Achievement set! '%s'\n", name );
}
- else
- {
+ else{
vg_warn( "Failed to set achievement: %s\n", name );
}
}
- else
- {
+ else{
vg_warn( "Failed to set achievement (steam not ready): %s\n", name );
}
}
VG_STATIC void steam_clear_achievement( const char *name )
{
- if( steam_ready && steam_stats_ready )
- {
- if( SteamAPI_ISteamUserStats_ClearAchievement( hSteamUserStats, name ) )
- {
+ if( steam_ready && steam_stats_ready ){
+ if( SteamAPI_ISteamUserStats_ClearAchievement( hSteamUserStats, name ) ){
vg_info( "Achievement cleared: '%s'\n", name );
}
- else
- {
+ else{
vg_warn( "Failed to clear achievement: %s\n", name );
}
}
- else
- {
+ else{
vg_warn( "Failed to clear achievement (steam not ready): %s\n", name );
}
}
{
vg_info( "Achievements: \n" );
- if( steam_ready && steam_stats_ready )
- {
- for( int i=0; i<vg_list_size(steam_achievement_names); i++ )
- {
+ if( steam_ready && steam_stats_ready ){
+ for( int i=0; i<vg_list_size(steam_achievement_names); i++ ){
int set = 0;
const char *name = steam_achievement_names[i];
{
vg_info( " %s %s\n", (set? "[YES]": "[ ]"), name );
}
- else
- {
+ else{
vg_warn( " Error while fetching achievement status '%s'\n", name );
}
}
}
- else
- {
+ else{
vg_warn( " Steam is not initialized, no results\n" );
}
VG_STATIC int steam_clear_all_achievements( int argc, char const *argv[] )
{
- if( steam_ready && steam_stats_ready )
- {
- for( int i=0; i<vg_list_size(steam_achievement_names); i++ )
- {
+ if( steam_ready && steam_stats_ready ){
+ for( int i=0; i<vg_list_size(steam_achievement_names); i++ ){
steam_clear_achievement( steam_achievement_names[i] );
}
steam_store_achievements();
}
- else
- {
+ else{
vg_warn( "steam is not initialized, cannot clear\n" );
}
{
UserStatsReceived_t *rec = (UserStatsReceived_t *)msg->m_pubParam;
- if( rec->m_eResult == k_EResultOK )
- {
+ if( rec->m_eResult == k_EResultOK ){
vg_info( "Recieved stats for: %lu (user: %lu)\n", rec->m_nGameID,
rec->m_steamIDUser );
steam_stats_ready = 1;
}
- else
- {
+ else{
vg_error( "Error recieveing stats for user (%u)\n", rec->m_eResult );
}
}
VG_STATIC u32 utf8_byte0_byte_count( u8 char0 )
{
- for( u32 k=2; k<4; k++ )
- {
+ for( u32 k=2; k<4; k++ ){
if( !(char0 & (0x80 >> k)) )
return k;
}
u32 utf32_code = 0x00000000;
u32 i=0, j=0, utf32_byte_ct=0;
- for(;i < length-1;)
- {
+ for(;i < length-1;){
if( ustr[i] == 0x00 )
break;
- if( ustr[i] & 0x80 )
- {
- if( utf32_byte_ct )
- {
+ if( ustr[i] & 0x80 ){
+ if( utf32_byte_ct ){
utf32_byte_ct --;
utf32_code |= (ustr[i] & 0x3F) << (utf32_byte_ct*6);
- if( !utf32_byte_ct )
- {
+ if( !utf32_byte_ct ){
const char *match;
size_t chars = anyascii( utf32_code, &match );
- for( u32 k=0; k<VG_MIN(chars, length-1-j); k++ )
- {
+ for( u32 k=0; k<VG_MIN(chars, length-1-j); k++ ){
buf[ j++ ] = (u8)match[k];
}
}
}
- else
- {
+ else{
utf32_byte_ct = utf8_byte0_byte_count( ustr[i] )-1;
utf32_code = ustr[i] & (0x3F >> utf32_byte_ct);
utf32_code <<= utf32_byte_ct*6;
}
}
- else
- {
+ else{
utf32_byte_ct = 0x00;
buf[j ++] = str[i];
}
#ifdef SR_NETWORKED
vg_info( "Initializing steamworks\n" );
- if( !SteamAPI_Init() )
- {
+ if( !SteamAPI_Init() ){
printf("\n");
vg_error( "Steamworks failed to initialize\n" );
return 1;
VG_STATIC void steam_update(void)
{
- if( steam_ready )
- {
+ if( steam_ready ){
steamworks_event_loop( hSteamClientPipe );
/* TODO
* We can probably request this from SDL too
*/
- if( steam_hInput )
- {
+ if( steam_hInput ){
SteamAPI_ISteamInput_RunFrame( steam_hInput, 0 );
InputHandle_t joy0 = SteamAPI_ISteamInput_GetControllerForGamepadIndex(
steam_hInput, 0 );
vg_input.controller_should_use_trackpad_look = 0;
- if( joy0 != 0 )
- {
+ if( joy0 != 0 ){
ESteamInputType type = SteamAPI_ISteamInput_GetInputTypeForHandle(
steam_hInput, joy0 );
- if( type == k_ESteamInputType_SteamController )
- {
+ if( type == k_ESteamInputType_SteamController ){
vg_input.controller_should_use_trackpad_look = 1;
menu_display_controller = k_menu_controller_type_steam;
}
- else if( type == k_ESteamInputType_SteamDeckController )
- {
+ else if( type == k_ESteamInputType_SteamDeckController ){
menu_display_controller = k_menu_controller_type_steam_deck;
}
else if( type == k_ESteamInputType_PS3Controller ||
{
menu_display_controller = k_menu_controller_type_xbox;
}
- else
- {
+ else{
/* currently unsupported controller */
menu_display_controller = k_menu_controller_type_xbox;
}
VG_STATIC void steam_end(void)
{
- if( steam_ready )
- {
+ if( steam_ready ){
vg_info( "Shutting down\n..." );
SteamAPI_Shutdown();
}
#if 0
-VG_STATIC void world_pct_spawn( world_instance *world, mdl_node *pnode )
-{
- struct respawn_point *rp = &world->spawns[ world->spawn_count ++ ];
-
- v3_copy( pnode->co, rp->co );
- v4_copy( pnode->q, rp->q );
- rp->name = mdl_pstr( world->meta, pnode->pstr_name );
-}
VG_STATIC void world_pct_audio( world_instance *world, mdl_node *pnode )
{
world->audio_things_count ++;
}
-VG_STATIC void world_pct_world_light( world_instance *world, mdl_node *pnode )
-{
- struct world_light *light = &world->lights[ world->light_count ++ ];
- light->node = pnode;
- light->inf = mdl_get_entdata( world->meta, pnode );
-
- q_m3x3( pnode->q, light->inverse_world );
- v3_copy( pnode->co, light->inverse_world[3] );
- m4x3_invert_affine( light->inverse_world, light->inverse_world );
-
- light->angle_sin_cos[0] = sinf( light->inf->angle * 0.5f );
- light->angle_sin_cos[1] = cosf( light->inf->angle * 0.5f );
-}
-
VG_STATIC void world_pct_nonlocal_gate( world_instance *world, mdl_node *pnode )
{
struct nonlocal_gate *gate = &world->nonlocal_gates[
v2_copy( inf->dims, gate->gate.dims );
}
-VG_STATIC void world_entities_process( world_instance *world )
-{
- struct entity_instruction
- {
- enum classtype ct;
- void (*process)( world_instance *world, mdl_node *pnode );
- }
- entity_instructions[] =
- {
- { k_classtype_spawn, world_pct_spawn },
- { k_classtype_water, world_pct_water },
- { k_classtype_audio, world_pct_audio },
- { k_classtype_world_light, world_pct_world_light },
- { k_classtype_nonlocal_gate, world_pct_nonlocal_gate }
- };
-
- for( int i=0; i<world->meta->info.node_count; i++ )
- {
- mdl_node *pnode = mdl_node_from_id( world->meta, i );
-
- for( int j=0; j<vg_list_size(entity_instructions); j++ )
- {
- struct entity_instruction *instr = &entity_instructions[j];
-
- if( pnode->classtype == instr->ct )
- {
- instr->process( world, pnode );
- break;
- }
- }
- }
-}
VG_STATIC void world_link_nonlocal_gates( int index_a, int index_b )
{
vg_info( "Linking non-local gates\n" );
}
#endif
-#if 0
-VG_STATIC float colour_luminance( v3f v )
-{
- return v3_dot( v, (v3f){0.2126f, 0.7152f, 0.0722f} );
-}
-
-VG_STATIC float calc_light_influence( world_instance *world, v3f position,
- int light )
-{
- struct world_light *world_light = &world->lights[ light ];
- struct classtype_world_light *inf = world_light->inf;
-
- v3f light_delta;
- v3_sub( world_light->node->co, position, light_delta );
- v3_muls( light_delta, 10.0f, light_delta );
-
- float quadratic = v3_dot( light_delta, light_delta ),
- attenuation = 1.0f/( 1.0f + quadratic );
-
- float quadratic_light = attenuation * colour_luminance( inf->colour );
-
- if( (inf->type == k_light_type_point) ||
- (inf->type == k_light_type_point_nighttime_only) )
- {
- return quadratic_light;
- }
- else if( (inf->type == k_light_type_spot) ||
- (inf->type == k_light_type_spot_nighttime_only) )
- {
- v3f dir;
- q_mulv( world_light->node->q, (v3f){0.0f,1.0f,0.0f}, dir );
-
- float spot_theta = vg_maxf( 0.0f, v3_dot( light_delta, dir ) ),
- falloff = spot_theta >= 0.0f? 1.0f: 0.0f;
-
- return quadratic_light * falloff;
- }
- else
- return 0.0f;
-}
-#endif
-
VG_STATIC void world_generate( world_instance *world )
{
/*