foot alignment
[carveJwlIkooP6JGAAIwe30JlM.git] / character.h
index 762511ffa61af735b80e84c16fc6461db108febe..70c1727a8c68308002c34ad7cb9b57edfd47846d 100644 (file)
@@ -11,7 +11,7 @@ SHADER_DEFINE( shader_player,
 
        "uniform mat4 uPv;"
    "uniform mat4x3 uMdl;"
-   "uniform vec3 uOpacityLight;"
+   "uniform float uOpacity;"
    ""
    "out vec4 aColour;"
    "out vec2 aUv;"
@@ -28,7 +28,7 @@ SHADER_DEFINE( shader_player,
       "aUv = a_uv;"
       "aNorm = mat3(uMdl) * a_norm;"
       "aCo = a_co;"
-      "aOpacity = 1.0-(gl_Position.y+0.5);"
+      "aOpacity = 1.0-(gl_Position.y+0.5)*uOpacity;"
        "}",
    /* Fragment */
        "out vec4 FragColor;"
@@ -48,7 +48,7 @@ SHADER_DEFINE( shader_player,
       "FragColor = vec4(pow(diffuse,vec3(1.0)),aOpacity);"
        "}"
        ,
-       UNIFORMS({ "uTexMain", "uPv", "uMdl", "uOpacityLight" })
+       UNIFORMS({ "uTexMain", "uPv", "uMdl", "uOpacity" })
 )
 
 #define FOREACH_PART(FN) \
@@ -205,6 +205,37 @@ static int character_load( struct character *ch, const char *name )
    return 1;
 }
 
+static void align_to_board( struct character *ch, enum character_part id )
+{
+   /* Calculate rotation between board and feet */
+   m4x3f *mats = ch->matrices;
+
+   v3f foot_pos, foot_fwd, foot_target, board_norm, board_origin;
+   v3_copy( mats[id][3], foot_pos );
+   m3x3_mulv( mats[id], (v3f){1.0f,0.0f,0.0f}, foot_fwd );
+   v3_add( foot_fwd, foot_pos, foot_target );
+
+   m3x3_mulv( mats[k_chpart_board], (v3f){0.0f,1.0f,0.0f}, board_norm );
+   m4x3_mulv( mats[k_chpart_board], (v3f){0.0f,0.13f,0.0f}, board_origin ); 
+
+   vg_line( foot_pos, foot_target, 0xff00ff00 );
+
+   v3f v0;
+   v3_sub( board_origin, foot_target, v0 );
+   float t = v3_dot( v0, board_norm ) / board_norm[1];
+   foot_target[1] += t;
+   vg_line( foot_pos, foot_target, 0xff00ffff );
+   
+   v3_sub( foot_target, foot_pos, foot_target );
+   v3_normalize( foot_target );
+   float ang = acosf( v3_dot( foot_target, foot_fwd ) );
+
+   v4f qcorrection; m3x3f correction;
+   q_axis_angle( qcorrection, (v3f){0.0f,0.0f,1.0f}, -ang );
+   q_m3x3( qcorrection, correction );
+   m3x3_mul( mats[id], correction, mats[id] );
+}
+
 static void character_eval( struct character *ch )
 {
    m4x3f *mats = ch->matrices;
@@ -240,14 +271,6 @@ static void character_eval( struct character *ch )
          k_ikY, k_iknX );
    ik_basic( &ch->ik_leg_r, mats[k_chpart_leg_r0], mats[k_chpart_leg_r1],
          k_ikY, k_iknX );
-
-   /* Feet */
-   m3x3_copy( mats[k_chpart_leg_l1], mats[k_chpart_foot_l] );
-   m3x3_copy( mats[k_chpart_leg_r1], mats[k_chpart_foot_r] );
-   m4x3_mulv( mats[k_chpart_leg_l1], offs[k_chpart_foot_l], 
-         mats[k_chpart_foot_l][3] );
-   m4x3_mulv( mats[k_chpart_leg_r1], offs[k_chpart_foot_r], 
-         mats[k_chpart_foot_r][3] );
    
    /* Hands */
    m3x3_copy( mats[k_chpart_arm_l1], mats[k_chpart_hand_l] );
@@ -268,18 +291,30 @@ static void character_eval( struct character *ch )
    //m3x3_mul( mats[k_chpart_neck], mats[k_chpart_head], mats[k_chpart_head] );
    m4x3_mulv( mats[k_chpart_neck], offs[k_chpart_head], mats[k_chpart_head][3]);
 
+   /* Feet */
+   m3x3_copy( mats[k_chpart_leg_l1], mats[k_chpart_foot_l] );
+   m3x3_copy( mats[k_chpart_leg_r1], mats[k_chpart_foot_r] );
+   m4x3_mulv( mats[k_chpart_leg_l1], offs[k_chpart_foot_l], 
+         mats[k_chpart_foot_l][3] );
+   m4x3_mulv( mats[k_chpart_leg_r1], offs[k_chpart_foot_r], 
+         mats[k_chpart_foot_r][3] );
+
+   align_to_board( ch, k_chpart_foot_l );
+   align_to_board( ch, k_chpart_foot_r );
+   
    for( int i=0; i<PART_COUNT; i++ )
       m4x3_mul( ch->mroot, ch->matrices[i], ch->matrices[i] );
 }
 
 #define B3D_CO( X, Y, Z ) (v3f){ X, Z, -Y }
 
-struct character_rig_lower
+typedef struct character_pose character_pose;
+struct character_pose
 {
    v3f b0, b1, p, fr, fl, pl, pr, hl, hr, apl, apr, cam;
 };
 
-static struct character_rig_lower character_pose_aero =
+static character_pose pose_aero =
 {
   .b0 =  {0.0721f, 0.8167f, 0.1365f},
   .b1 =  {-0.0773f, 1.1559f, -0.1699f},
@@ -295,7 +330,7 @@ static struct character_rig_lower character_pose_aero =
   .cam = {-0.3394f, 1.2661f, 0.2936f}
 };
 
-static struct character_rig_lower character_pose_slide =
+static character_pose pose_slide =
 {
   .b0 =  {0.6732f, 0.5565f, -0.0000f},
   .b1 =  {0.8116f, 1.0547f, 0.0613f},
@@ -311,7 +346,7 @@ static struct character_rig_lower character_pose_slide =
   .cam = {0.9888f, 1.4037f, 0.6081f}
 };
 
-static struct character_rig_lower character_pose_slide1 =
+static character_pose pose_slide1 =
 {
   .b0 =  {-0.2385f, 0.6403f, 0.1368f},
   .b1 =  {-0.5151f, 1.1351f, 0.1380f},
@@ -327,7 +362,7 @@ static struct character_rig_lower character_pose_slide1 =
   .cam = {-1.0508f, 1.0769f, 0.0528f}
 };
 
-static struct character_rig_lower character_pose_aero_reverse =
+static character_pose pose_aero_reverse =
 {
   .b0 =  {0.0616f, 0.8167f, -0.1415f},
   .b1 =  {0.0148f, 1.1559f, 0.1861f},
@@ -343,7 +378,7 @@ static struct character_rig_lower character_pose_aero_reverse =
   .cam = {-0.3394f, 1.2661f, -0.2936f}
 };
 
-static struct character_rig_lower character_pose_stand =
+static character_pose pose_stand =
 {
   .b0 =  {0.1877f, 1.0663f, 0.0063f},
   .b1 =  {0.0499f, 1.5564f, -0.0584f},
@@ -359,7 +394,7 @@ static struct character_rig_lower character_pose_stand =
   .cam = {-0.3477f, 1.5884f, -0.0019f}
 };
 
-static struct character_rig_lower character_pose_fly =
+static character_pose pose_fly =
 {
   .b0 =  {0.2995f, 0.6819f, -0.1369f},
   .b1 =  {0.1618f, 1.1720f, -0.2016f},
@@ -375,8 +410,8 @@ static struct character_rig_lower character_pose_fly =
   .cam = {-0.2727f, 1.2606f, 0.3564f}
 };
 
-static void character_rig_lower_blend( struct character *ch, 
-      struct character_rig_lower *pose, float q )
+static 
+void character_pose_blend( struct character *ch, character_pose *pose, float q )
 {
    v3_muladds( ch->ik_body.base, pose->b0, q, ch->ik_body.base );
    v3_muladds( ch->ik_body.end, pose->b1, q, ch->ik_body.end );
@@ -392,10 +427,11 @@ static void character_rig_lower_blend( struct character *ch,
    v3_muladds( ch->cam_pos, pose->cam, q, ch->cam_pos );
 }
 
-static void character_pose_with_tilt( struct character *ch, v3f cog,
-      struct character_rig_lower *pose, float q )
+static 
+void character_final_pose( struct character *ch, v3f cog,
+      character_pose *pose, float q )
 {
-   struct character_rig_lower npose;
+   character_pose npose;
    float dip = vg_clampf(cog[1], -1.0f, 0.3f) * 0.35f,
          tilt = vg_clampf(cog[2], -1.0f, 1.0f) * 0.3f;
 
@@ -418,7 +454,7 @@ static void character_pose_with_tilt( struct character *ch, v3f cog,
    v3_copy( pose->fl, npose.fl );
    v3_copy( pose->cam, npose.cam );
    
-   character_rig_lower_blend( ch, &npose, q );
+   character_pose_blend( ch, &npose, q );
 }
 
 static void zero_ik_basic( struct ik_basic *ik )
@@ -500,15 +536,14 @@ static void character_testpose( struct character *ch, float t )
    m4x3_identity( ch->matrices[k_chpart_wf] );
 }
 
-static void character_draw( struct character *ch )
+static void character_draw( struct character *ch, float temp )
 {
    SHADER_USE(shader_player);
        glUniformMatrix4fv( SHADER_UNIFORM( shader_player, "uPv" ), 
          1, GL_FALSE, (float *)vg_pv );
 
    glUniform1i( SHADER_UNIFORM( shader_player, "uTexMain" ), 0 );
-   glUniform3fv( SHADER_UNIFORM( shader_player, "uOpacityLight" ), 1,
-         ch->matrices[k_chpart_neck][3] );
+   glUniform1f( SHADER_UNIFORM( shader_player, "uOpacity" ), temp );
 
    GLint kuMdl = SHADER_UNIFORM( shader_player, "uMdl" );
    
@@ -529,8 +564,4 @@ static void character_shader_register(void)
    SHADER_INIT(shader_player);
 }
 
-#undef FOREACH_PART
-#undef MAKE_ENUM
-#undef MAKE_STRING
-#undef ADD_ONE
 #endif