{ .path="sound/tap3.ogg" }
};
+audio_clip audio_hits[] =
+{
+ { .path="sound/hit0.ogg" },
+ { .path="sound/hit1.ogg" },
+ { .path="sound/hit2.ogg" },
+ { .path="sound/hit3.ogg" },
+ { .path="sound/hit4.ogg" }
+};
+
audio_clip audio_splash =
{ .path = "sound/splash.ogg" };
audio_clip_loadn( audio_board, vg_list_size(audio_board), NULL );
audio_clip_loadn( audio_taps, vg_list_size(audio_taps), NULL );
+ audio_clip_loadn( audio_hits, vg_list_size(audio_hits), NULL );
audio_clip_loadn( audio_ambience, vg_list_size(audio_ambience), NULL );
audio_clip_loadn( &audio_splash, 1, NULL );
audio_clip_loadn( &audio_gate_pass, 1, NULL );
('0','concrete',''),
('1','wood',''),
('2','grass',''),
- ('3','tiles','')
+ ('3','tiles',''),
+ ('4','metal','')
])
collision: bpy.props.BoolProperty( \
v3_copy( (v3f){0.0f,1.4f,0.0f}, player->tpv_offset );
}
else{
- v3_copy( (v3f){-0.15f,1.7f,0.0f}, player->fpv_viewpoint );
+ v3_copy( (v3f){-0.15f,1.75f,0.0f}, player->fpv_viewpoint );
#if 0
v3_copy( (v3f){-0.35f,0.0f,0.0f}, player->fpv_offset );
#endif
v3_zero( anim->root_co );
q_identity( anim->root_q );
- for( int i=0; i<vg_list_size( anim->pose ); i ++ )
- {
+ for( int i=0; i<vg_list_size( anim->pose ); i ++ ){
v3_zero( anim->pose[i].co );
v3_fill( anim->pose[i].s, 1.0f );
q_identity( anim->pose[i].q );
#include "rigidbody.h"
#include "player_model.h"
#include "world.h"
+#include "audio.h"
struct player_ragdoll
{
av->sk.final_mtx[part->bone_id] );
}
+ for( u32 i=1; i<av->sk.bone_count; i++ ){
+ struct skeleton_bone *sb = &av->sk.bones[i];
+
+ if( sb->parent && !sb->collider ){
+ v3f delta;
+ v3_sub( av->sk.bones[i].co, av->sk.bones[sb->parent].co, delta );
+
+ m4x3f posemtx;
+ m3x3_identity( posemtx );
+ v3_copy( delta, posemtx[3] );
+
+ /* final matrix */
+ m4x3_mul( av->sk.final_mtx[sb->parent], posemtx, av->sk.final_mtx[i] );
+ }
+ }
+
skeleton_apply_inverses( &av->sk );
}
}
rb_solver_reset();
+
+ float contact_velocities[256];
+
for( int i=0; i<rd->part_count; i ++ ){
if( rb_global_has_space() ){
rb_ct *buf = rb_global_buffer();
/*
* PRESOLVE
*/
+ for( u32 i=0; i<rb_contact_count; i++ ){
+ rb_ct *ct = &rb_contact_buffer[i];
+
+ v3f rv, ra, rb;
+ v3_sub( ct->co, ct->rba->co, ra );
+ v3_sub( ct->co, ct->rbb->co, rb );
+ rb_rcv( ct->rba, ct->rbb, ra, rb, rv );
+ float vn = v3_dot( rv, ct->n );
+
+ contact_velocities[i] = vn;
+ }
+
rb_presolve_contacts( rb_contact_buffer, rb_contact_count );
rb_presolve_swingtwist_constraints( rd->cone_constraints,
rd->cone_constraints_count );
rd->position_constraints_count, 0.5f );
}
+ rb_ct *stress = NULL;
+ float max_stress = 1.0f;
+
+ for( u32 i=0; i<rb_contact_count; i++ ){
+ rb_ct *ct = &rb_contact_buffer[i];
+
+ v3f rv, ra, rb;
+ v3_sub( ct->co, ct->rba->co, ra );
+ v3_sub( ct->co, ct->rbb->co, rb );
+ rb_rcv( ct->rba, ct->rbb, ra, rb, rv );
+ float vn = v3_dot( rv, ct->n );
+
+ float s = fabsf(vn - contact_velocities[i]);
+ if( s > max_stress ){
+ stress = ct;
+ max_stress = s;
+ }
+ }
+
+ static u32 temp_filter = 0;
+
+ if( temp_filter ){
+ temp_filter --;
+ return;
+ }
+
+ if( stress ){
+ temp_filter = 20;
+ audio_lock();
+ audio_oneshot_3d( &audio_hits[rand()%5], stress->co, 20.0f, 1.0f );
+ audio_unlock();
+ }
}
#endif /* PLAYER_RAGDOLL_H */
if( (fabsf(v3_dot( ve, grind.dir ))>=k_grind_axel_min_vel) &&
(a >= a_min) )
{
+ vg_success( "ding\n" );
grind_located = 1;
grind_located_gravity = inf->gravity;
}
rb_ct *ct = &manifold[i];
struct world_surface *surf = world_contact_surface( world, ct );
- if( surf->info.surface_prop != k_surface_prop_concrete )
+ if( surf->info.surface_prop > s->surface )
s->surface = surf->info.surface_prop;
}
/* FIXME: Rate limit */
static int stick_frames = 0;
- if( s->state.activity == k_skate_activity_ground )
+ if( s->state.activity >= k_skate_activity_ground )
stick_frames ++;
else
stick_frames = 0;
+ if( stick_frames > 5 ) stick_frames = 5;
if( stick_frames == 4 ){
audio_lock();
- if( (fabsf(s->state.slip) > 0.75f) ){
- audio_oneshot_3d( &audio_lands[rand()%2+3], player->rb.co,
- 40.0f, 1.0f );
+
+ if( s->state.activity == k_skate_activity_ground ){
+ if( (fabsf(s->state.slip) > 0.75f) ){
+ audio_oneshot_3d( &audio_lands[rand()%2+3], player->rb.co,
+ 40.0f, 1.0f );
+ }
+ else{
+ audio_oneshot_3d( &audio_lands[rand()%3], player->rb.co,
+ 40.0f, 1.0f );
+ }
+ }
+ else if( s->surface == k_surface_prop_metal ){
+ audio_oneshot_3d( &audio_board[3], player->rb.co, 40.0f, 1.0f );
}
else{
- audio_oneshot_3d( &audio_lands[rand()%3], player->rb.co,
- 40.0f, 1.0f );
+ audio_oneshot_3d( &audio_board[8], player->rb.co, 40.0f, 1.0f );
}
+
audio_unlock();
+ } else if( stick_frames == 0 ){
+
}
}
"undefined (INVALID)",
"grind_any (INVALID)",
"grind_boardslide",
+ "grind_metallic (INVALID)",
"grind_back50",
"grind_front50",
"grind_5050"
v3_zero( s->state.trick_vel );
v3_zero( s->state.trick_euler );
v3_zero( s->state.cog_v );
+ s->grind_cooldown = 0;
+ s->surface_cooldown = 0;
v3_muladds( player->rb.co, player->rb.to_world[1], 1.0f, s->state.cog );
}
k_skate_activity_undefined,
k_skate_activity_grind_any,
k_skate_activity_grind_boardslide,
+ k_skate_activity_grind_metallic,
k_skate_activity_grind_back50,
k_skate_activity_grind_front50,
k_skate_activity_grind_5050
*/
VG_STATIC void rb_presolve_contacts( rb_ct *buffer, int len )
{
- for( int i=0; i<len; i++ )
- {
+ for( int i=0; i<len; i++ ){
rb_ct *ct = &buffer[i];
rb_prepare_contact( ct, k_rb_delta );
ct->normal_mass += v3_dot( rbCn, rbCnI );
ct->normal_mass = 1.0f/ct->normal_mass;
- for( int j=0; j<2; j++ )
- {
+ for( int j=0; j<2; j++ ){
v3f raCtI, rbCtI;
v3_cross( ct->t[j], ra, raCt );
v3_cross( ct->t[j], rb, rbCt );
*/
VG_STATIC void rb_solve_contacts( rb_ct *buf, int len )
{
- for( int i=0; i<len; i++ )
- {
+ for( int i=0; i<len; i++ ){
struct contact *ct = &buf[i];
v3f rv, ra, rb;
rb_rcv( ct->rba, ct->rbb, ra, rb, rv );
/* Friction */
- for( int j=0; j<2; j++ )
- {
+ for( int j=0; j<2; j++ ){
float f = k_friction * ct->norm_impulse,
vt = v3_dot( rv, ct->t[j] ),
lambda = ct->tangent_mass[j] * -vt;
#include "player.h"
-VG_STATIC player_instance localplayer;
+static player_instance localplayer;
VG_STATIC struct player_avatar localplayer_avatar;
VG_STATIC glmesh localplayer_meshes[3];
vg_tex2d localplayer_texture = { .path = "textures/ch_gradient.qoi" };