From: hgn Date: Sat, 4 Feb 2023 13:30:26 +0000 (+0000) Subject: drop-in prelim X-Git-Url: https://skaterift.com/git/?a=commitdiff_plain;h=33de52d9660ab86caafdd0ae4abb496dbc072778;p=carveJwlIkooP6JGAAIwe30JlM.git drop-in prelim --- diff --git a/blender_export.py b/blender_export.py index 515acd7..538ed6c 100644 --- a/blender_export.py +++ b/blender_export.py @@ -1241,6 +1241,8 @@ def encoder_build_scene_graph( collection ): def _extend( p, n, d ): #{ + nonlocal collection + uid = _new_uid() tree = {} tree["uid"] = uid @@ -1249,7 +1251,7 @@ def encoder_build_scene_graph( collection ): tree["obj"] = n tree["parent"] = p n.cv_data.uid = uid - + # Descend into amature # if n.type == 'ARMATURE': @@ -1257,6 +1259,7 @@ def encoder_build_scene_graph( collection ): tree["bones"] = [None] # None is the root transform tree["ik_count"] = 0 tree["collider_count"] = 0 + tree["compile_animation"] = collection.cv_data.animations # Here also collects some information about constraints, ik and # counts colliders for the armature. @@ -1305,7 +1308,6 @@ def encoder_build_scene_graph( collection ): # for obj1 in n.children: #{ - nonlocal collection for c1 in obj1.users_collection: #{ if c1 == collection: @@ -1667,7 +1669,12 @@ def encoder_compile_armature( node, node_def ): # extra info node_def['anim_start'] = len(animdata) node_def['anim_count'] = 0 - + + if not node_def['compile_animation']: + #{ + return + #} + # Compile anims # if obj.animation_data: @@ -2631,6 +2638,7 @@ class CV_SCENE_SETTINGS(bpy.types.PropertyGroup): class CV_COLLECTION_SETTINGS(bpy.types.PropertyGroup): #{ pack_textures: bpy.props.BoolProperty( name="Pack Textures", default=False ) + animations: bpy.props.BoolProperty( name="Export animation", default=True) #} class CV_MATERIAL_SETTINGS(bpy.types.PropertyGroup): @@ -2857,6 +2865,7 @@ class CV_INTERFACE(bpy.types.Panel): #{ box.label( text=col.name + ".mdl" ) box.prop( col.cv_data, "pack_textures" ) + box.prop( col.cv_data, "animations" ) box.operator( "carve.compile_this" ) #} else: diff --git a/models_src/ch_jordan.mdl b/models_src/ch_jordan.mdl index dbf1e54..56c776c 100644 Binary files a/models_src/ch_jordan.mdl and b/models_src/ch_jordan.mdl differ diff --git a/models_src/ch_new.mdl b/models_src/ch_new.mdl index a5f3447..0faad37 100644 Binary files a/models_src/ch_new.mdl and b/models_src/ch_new.mdl differ diff --git a/models_src/ch_outlaw.mdl b/models_src/ch_outlaw.mdl index 5453123..5a1caca 100644 Binary files a/models_src/ch_outlaw.mdl and b/models_src/ch_outlaw.mdl differ diff --git a/player_skate.c b/player_skate.c index 32a3670..4e354e5 100644 --- a/player_skate.c +++ b/player_skate.c @@ -1552,7 +1552,7 @@ VG_STATIC void player__skate_transition( player_instance *player, init_velocity[2] ); q_axis_angle( player->rb.q, (v3f){0.0f,1.0f,0.0f}, - atan2f( dir[0], dir[2] ) ); + atan2f( -dir[0], -dir[2] ) ); v3_muladds( player->rb.co, player->rb.to_world[1], 1.0f, s->state.cog ); v3_copy( init_velocity, s->state.cog_v ); diff --git a/player_walk.c b/player_walk.c index fe74981..0d6f873 100644 --- a/player_walk.c +++ b/player_walk.c @@ -28,6 +28,138 @@ VG_STATIC void player_walk_transfer_to_skate( player_instance *player, return; } +VG_STATIC void temp_drop_in_finish( player_instance *player ) +{ + player->subsystem = k_player_subsystem_skate; + + struct player_walk *w = &player->_walk; + struct player_skate *s = &player->_skate; + s->state.activity_prev = k_skate_activity_air; + s->state.activity = k_skate_activity_air; + + s->blend_fly = 0.0f; + s->blend_slide = 0.0f; + s->blend_z = 0.0f; + s->blend_x = 0.0f; + s->blend_stand = 0.0f; + s->blend_push = 0.0f; + s->blend_jump = 0.0f; + s->blend_airdir = 0.0f; + + v3f axis, init_dir, init_velocity; + v3_cross( (v3f){0.0f,1.0f,0.0f}, w->state.drop_in_normal, axis ); + v3_cross( axis, w->state.drop_in_normal, init_dir ); + v3_normalize( init_dir ); + v3_muls( init_dir, 7.0f, init_velocity ); + + v3_muladds( player->rb.co, player->rb.to_world[1], 1.0f, s->state.cog ); + v3_copy( init_velocity, s->state.cog_v ); + v3_copy( init_velocity, s->state.vl ); + v3_copy( init_velocity, player->rb.v ); + + rb_update_transform( &player->rb ); +} + +VG_STATIC int player_walk_scan_for_drop_in( player_instance *player ) +{ + struct player_walk *w = &player->_walk; + + v3f dir, center; + dir[0] = sinf( w->state.heading_angle ); + dir[1] = 0.0f; + dir[2] = cosf( w->state.heading_angle ); + + v3_muladds( player->rb.co, player->rb.to_world[1], -1.0f, center ); + + ray_hit samples[20]; + int sample_count = 0; + + for( int i=0; i<20; i ++ ) + { + float t = (float)i * (1.0f/19.0f), + s = sinf( t * VG_PIf * 0.25f ), + c = cosf( t * VG_PIf * 0.25f ); + + v3f ray_dir, pos; + v3_muls ( player->rb.to_world[1], -c, ray_dir ); + v3_muladds( ray_dir, dir, -s, ray_dir ); + v3_muladds( center, ray_dir, -2.0f, pos ); + + ray_hit *ray = &samples[ sample_count ]; + ray->dist = 2.0f; + + if( ray_world( pos, ray_dir, ray ) ) + { + vg_line( pos, ray->pos, VG__RED ); + vg_line_pt3( ray->pos, 0.025f, VG__BLACK ); + + sample_count ++; + } + } + + float min_a = 0.70710678118654752f; + ray_hit *candidate = NULL; + + if( sample_count >= 2 ) + { + for( int i=0; inormal, s1->normal ); + + if( (a < min_a) && (a >= -0.1f) && (s0->normal[1]>s1->normal[1]) ) + { + min_a = a; + candidate = s0; + } + } + } + + if( candidate ) + { + v4f pa, pb, pc; + + ray_hit *s0 = candidate, + *s1 = candidate+1; + + vg_line( s0->pos, s1->pos, VG__WHITE ); + + v3_copy( s0->normal, pa ); + v3_copy( s1->normal, pb ); + v3_cross( player->rb.to_world[1], dir, pc ); + v3_normalize( pc ); + + pa[3] = v3_dot( pa, s0->pos ); + pb[3] = v3_dot( pb, s1->pos ); + pc[3] = v3_dot( pc, player->rb.co ); + + v3f edge; + if( plane_intersect3( pa, pb, pc, edge ) ) + { + v3_copy( edge, w->state.drop_in_target ); + v3_copy( s1->normal, w->state.drop_in_normal ); + + return 1; + +#if 0 + v3_muladds( w->state.drop_in_target, s0->normal, 0.3f, + player->rb.co ); + + player->subsystem = k_player_subsystem_skate; + player__skate_transition( player, s1->normal, k_skate_activity_air ); +#endif + } + else + { + vg_error( "failed to find intersection of drop in\n" ); + } + } + + return 0; +} + VG_STATIC void player__walk_pre_update( player_instance *player ) { struct player_walk *w = &player->_walk; @@ -42,7 +174,14 @@ VG_STATIC void player__walk_pre_update( player_instance *player ) if( outro_time >= outro_length ) { w->state.outro_anim = NULL; - player_walk_transfer_to_skate( player, k_skate_activity_air ); + if( w->state.outro_type == k_walk_outro_drop_in ) + { + temp_drop_in_finish( player ); + } + else + { + player_walk_transfer_to_skate( player, k_skate_activity_air ); + } return; } } @@ -50,10 +189,32 @@ VG_STATIC void player__walk_pre_update( player_instance *player ) { if( w->state.activity == k_walk_activity_ground ) { - player_walk_transfer_to_skate( player, k_skate_activity_ground ); + //player_walk_transfer_to_skate( player, k_skate_activity_ground ); + if( player_walk_scan_for_drop_in( player ) ) + { + w->state.outro_type = k_walk_outro_drop_in; + w->state.outro_anim = w->anim_drop_in; + w->state.outro_start_time = vg.time; + v3_copy( player->cam.pos, player->follow_pos ); + v3_copy( player->cam.angles, player->follow_angles ); + w->state.activity = k_walk_activity_immobile; + v3_zero( player->rb.v ); + v3_copy( player->rb.co, w->state.drop_in_start ); + + w->state.drop_in_start_angle = w->state.heading_angle; + w->state.drop_in_angle = atan2f( w->state.drop_in_normal[0], + w->state.drop_in_normal[2] ); + + struct player_avatar *av = player->playeravatar; + m4x3_mulv( av->sk.final_mtx[ av->id_ik_foot_r ], + av->sk.bones[ av->id_ik_foot_r ].co, + w->state.drop_in_foot_anchor ); + } + return; } else { + w->state.outro_type = k_walk_outro_jump_to_air; w->state.outro_anim = w->anim_jump_to_air; w->state.outro_start_time = vg.time; v3_copy( player->cam.pos, player->follow_pos ); @@ -106,6 +267,9 @@ VG_STATIC void player__walk_update( player_instance *player ) struct player_walk *w = &player->_walk; v3_copy( player->rb.co, w->state.prev_pos ); + if( w->state.activity == k_walk_activity_immobile ) + return; + w->collider.height = 2.0f; w->collider.radius = 0.3f; @@ -363,6 +527,23 @@ VG_STATIC void player__walk_post_update( player_instance *player ) if( v3_length2( xy_speed ) > 0.1f * 0.1f ) w->state.heading_angle = atan2f( player->rb.v[0], player->rb.v[2] ); + + vg_line_pt3( w->state.drop_in_target, 0.1f, VG__GREEN ); + v3f p1; + v3_muladds( w->state.drop_in_target, w->state.drop_in_normal, 0.3f, p1 ); + vg_line( w->state.drop_in_target, p1, VG__GREEN ); + v3_muladds( w->state.drop_in_target, player->rb.to_world[1], 0.3f, p1 ); + vg_line( w->state.drop_in_target, p1, VG__GREEN ); + + vg_line( w->state.drop_in_target, w->state.drop_in_foot_anchor, VG__WHITE ); + vg_line_pt3( w->state.drop_in_foot_anchor, 0.08f, VG__PINK ); + + p1[0] = sinf( w->state.heading_angle ); + p1[1] = 0.0f; + p1[2] = cosf( w->state.heading_angle ); + + v3_add( player->rb.co, p1, p1 ); + vg_line( player->rb.co, p1, VG__PINK ); } VG_STATIC void player__walk_animate( player_instance *player, @@ -426,31 +607,92 @@ VG_STATIC void player__walk_animate( player_instance *player, /* Create transform */ rb_extrapolate( &player->rb, dest->root_co, dest->root_q ); - float walk_yaw = w->state.heading_angle + VG_PIf*0.5f; + float walk_yaw = w->state.heading_angle; if( w->state.outro_anim ) { + struct player_avatar *av = player->playeravatar; float outro_length = (float)w->state.outro_anim->length / w->state.outro_anim->rate, outro_time = vg.time - w->state.outro_start_time, outro_t = outro_time / outro_length; - walk_yaw += -VG_PIf*0.5f*outro_t; - /* TODO: Compression */ - v3_muladds( dest->root_co, player->rb.to_world[1], - -0.28f * outro_t, dest->root_co ); - skeleton_sample_anim_clamped( sk, w->state.outro_anim, outro_time, bpose ); skeleton_lerp_pose( sk, apose, bpose, outro_t * 10.0f, dest->pose ); + + if( w->state.outro_type == k_walk_outro_drop_in ) + { + float inv_rate = 1.0f / w->state.outro_anim->rate, + anim_frames = w->state.outro_anim->length * inv_rate, + step_frames = 12.0f * inv_rate, + commit_frames = 6.0f * inv_rate, + drop_frames = anim_frames - step_frames, + step_t = vg_minf( 1.0f, outro_time / step_frames ), + remaind_time = vg_maxf( 0.0f, outro_time - step_frames ), + dop_t = vg_minf( 1.0f, remaind_time / drop_frames ), + commit_t = vg_minf( 1.0f, remaind_time / commit_frames ); + + walk_yaw = vg_alerpf( w->state.drop_in_start_angle, + w->state.drop_in_angle, step_t ); + w->state.heading_angle = walk_yaw; + + v3_lerp( w->state.drop_in_start, w->state.drop_in_target, + step_t, player->rb.co ); + q_axis_angle( dest->root_q, (v3f){0.0f,1.0f,0.0f}, walk_yaw + VG_PIf ); + + m4x3f transform, inverse; + q_m3x3( dest->root_q, transform ); + v3_copy( dest->root_co, transform[3] ); + m4x3_invert_affine( transform, inverse ); + + v3f anchored_pos; + m4x3_mulv( inverse, w->state.drop_in_foot_anchor, anchored_pos ); + + v3_lerp( dest->pose[ av->id_ik_foot_r-1 ].co, anchored_pos, + 1.0f-commit_t, + dest->pose[ av->id_ik_foot_r-1 ].co ); + + + /* the drop in bit */ + v4f final_q; + v3f axis; + v3_cross( (v3f){0.0f,1.0f,0.0f}, w->state.drop_in_normal, axis ); + v3_normalize( axis ); + + float a = acosf( w->state.drop_in_normal[1] ) * dop_t; + + q_axis_angle( final_q, axis, a ); + q_mul( final_q, dest->root_q, dest->root_q ); + + float l = dop_t * 0.7f; + + v3f overhang; + overhang[0] = sinf( w->state.heading_angle ) * l; + overhang[1] = 0.28f * l; + overhang[2] = cosf( w->state.heading_angle ) * l; + + m3x3f tmp; + q_m3x3( final_q, tmp ); + m3x3_mulv( tmp, overhang, overhang ); + v3_add( player->rb.co, overhang, player->rb.co ); + v3_copy( player->rb.co, dest->root_co ); + v4_copy( dest->root_q, player->rb.q ); + return; + } + else + { + v3_muladds( dest->root_co, player->rb.to_world[1], + -0.28f * outro_t, dest->root_co ); + } } else { skeleton_copy_pose( sk, apose, dest->pose ); } - q_axis_angle( dest->root_q, (v3f){0.0f,1.0f,0.0f}, walk_yaw ); + q_axis_angle( dest->root_q, (v3f){0.0f,1.0f,0.0f}, walk_yaw + VG_PIf ); } VG_STATIC void player__walk_post_animate( player_instance *player ) @@ -530,7 +772,8 @@ VG_STATIC void player__walk_im_gui( player_instance *player ) player__debugtext( 1, "activity: %s\n", (const char *[]){ "k_walk_activity_air", "k_walk_activity_ground", - "k_walk_activity_sleep" } + "k_walk_activity_sleep", + "k_walk_activity_immobile" } [w->state.activity] ); if( w->state.outro_anim ) @@ -548,17 +791,19 @@ VG_STATIC void player__walk_bind( player_instance *player ) struct player_avatar *av = player->playeravatar; struct skeleton *sk = &av->sk; - w->anim_idle = skeleton_get_anim( sk, "idle_cycle" ); - w->anim_walk = skeleton_get_anim( sk, "walk" ); - w->anim_run = skeleton_get_anim( sk, "run" ); - w->anim_jump = skeleton_get_anim( sk, "jump" ); + w->anim_idle = skeleton_get_anim( sk, "idle_cycle+y" ); + w->anim_walk = skeleton_get_anim( sk, "walk+y" ); + w->anim_run = skeleton_get_anim( sk, "run+y" ); + w->anim_jump = skeleton_get_anim( sk, "jump+y" ); w->anim_jump_to_air = skeleton_get_anim( sk, "jump_to_air" ); + w->anim_drop_in = skeleton_get_anim( sk, "drop_in" ); } VG_STATIC void player__walk_transition( player_instance *player, v3f angles ) { struct player_walk *w = &player->_walk; v3_copy( angles, w->state.angles ); + w->state.activity = k_walk_activity_air; } #endif /* PLAYER_DEVICE_WALK_H */ diff --git a/player_walk.h b/player_walk.h index f1efabc..726623d 100644 --- a/player_walk.h +++ b/player_walk.h @@ -13,15 +13,31 @@ struct player_walk float heading_angle; v3f prev_pos; + v3f drop_in_target, + drop_in_foot_anchor, + drop_in_start, + drop_in_normal; + + float drop_in_start_angle, + drop_in_angle; enum walk_activity { k_walk_activity_air, k_walk_activity_ground, - k_walk_activity_sleep + k_walk_activity_sleep, + k_walk_activity_immobile } activity; + enum walk_outro + { + k_walk_outro_none, + k_walk_outro_jump_to_air, + k_walk_outro_drop_in + } + outro_type; + struct skeleton_anim *outro_anim; double outro_start_time; } @@ -30,7 +46,7 @@ struct player_walk enum mdl_surface_prop surface; struct skeleton_anim *anim_walk, *anim_run, *anim_idle, *anim_jump, - *anim_jump_to_air; + *anim_jump_to_air, *anim_drop_in; float blend_fly, blend_run, diff --git a/skaterift.c b/skaterift.c index 574f3a6..1851a73 100644 --- a/skaterift.c +++ b/skaterift.c @@ -59,7 +59,7 @@ static int cl_ui = 1, int main( int argc, char *argv[] ) { vg_mem.use_libc_malloc = 0; - vg_set_mem_quota( 128*1024*1024 ); + vg_set_mem_quota( 160*1024*1024 ); vg_enter( argc, argv, "Voyager Game Engine" ); return 0;