Example #1
0
void SSBoneFrame_TargetBoneToSlerp(struct ss_bone_frame_s *bf, struct ss_animation_s *ss_anim)
{
    extern float engine_frame_time;
    if(ss_anim->anim_ext_flags & ANIM_EXT_TARGET_TO)
    {
        ss_bone_tag_p b_tag = bf->bone_tags + ss_anim->targeting_bone;
        float clamped_q[4], q[4], target_dir[3], target_local[3], bone_dir[3];

        Mat4_vec3_mul_inv(target_local, bf->transform, ss_anim->target);
        if(b_tag->parent)
        {
            Mat4_vec3_mul_inv(target_local, b_tag->parent->full_transform, target_local);
        }
        vec3_sub(target_dir, target_local, b_tag->transform + 12);
        if(ss_anim->targeting_flags & ANIM_TARGET_OWERRIDE_ANIM)
        {
            Mat4_vec3_rot_macro(bone_dir, b_tag->transform, ss_anim->bone_direction);
        }
        else
        {
            vec3_copy(bone_dir, ss_anim->bone_direction);
        }

        vec4_GetQuaternionRotation(q, bone_dir, target_dir);
        if(ss_anim->targeting_flags & ANIM_TARGET_USE_AXIS_MOD)
        {
            q[0] *= ss_anim->targeting_axis_mod[0];
            q[1] *= ss_anim->targeting_axis_mod[1];
            q[2] *= ss_anim->targeting_axis_mod[2];
            q[3] = 1.0f - vec3_sqabs(q);
            q[3] = sqrtf(q[3]);
        }
        if(q[3] < ss_anim->targeting_limit[3])
        {
            vec4_clampw(q, ss_anim->targeting_limit[3]);
        }
        vec4_slerp_to(clamped_q, ss_anim->current_mod, q, engine_frame_time * M_PI / 1.3f);
        vec4_copy(ss_anim->current_mod, clamped_q);
        SSBoneFrame_RotateBone(bf, ss_anim->current_mod, ss_anim->targeting_bone);
    }
    else if(ss_anim->current_mod[3] < 1.0f)
    {       
        if(ss_anim->current_mod[3] < 0.99f)
        {
            float zero_ang[4] = {0.0f, 0.0f, 0.0f, 1.0f};
            float clamped_q[4];
            vec4_slerp_to(clamped_q, ss_anim->current_mod, zero_ang, engine_frame_time * M_PI / 1.3f);
            vec4_copy(ss_anim->current_mod, clamped_q);
            SSBoneFrame_RotateBone(bf, ss_anim->current_mod, ss_anim->targeting_bone);
        }
        else
        {
            vec4_set_zero_angle(ss_anim->current_mod);
        }
    }
}
Example #2
0
void SSBoneFrame_TargetBoneToSlerp(struct ss_bone_frame_s *bf, struct ss_bone_tag_s *b_tag, float time)
{
    b_tag->mod.current_slerp = 1.0f;
    if(b_tag->is_targeted)
    {
        float clamped_q[4], q[4], target_dir[3], target_local[3], bone_dir[3];

        Mat4_vec3_mul_inv(target_local, bf->transform->M4x4, b_tag->mod.target_pos);
        if(b_tag->parent)
        {
            Mat4_vec3_mul_inv(target_local, b_tag->parent->current_transform, target_local);
        }
        vec3_sub(target_dir, target_local, b_tag->local_transform + 12);
        vec3_copy(bone_dir, b_tag->mod.bone_local_direction);

        vec4_GetQuaternionRotation(q, bone_dir, target_dir);
        if(q[3] < b_tag->mod.limit[3])
        {
            vec4_clampw(q, b_tag->mod.limit[3]);
        }
        if(b_tag->is_axis_modded)
        {
            q[0] *= b_tag->mod.axis_mod[0];
            q[1] *= b_tag->mod.axis_mod[1];
            q[2] *= b_tag->mod.axis_mod[2];
            q[3] = 1.0f - vec3_sqabs(q);
            q[3] = sqrtf(q[3]);
        }
        b_tag->mod.current_slerp = vec4_slerp_to(clamped_q, b_tag->mod.current_q, q, time * M_PI / 1.3f);
        vec4_copy(b_tag->mod.current_q, clamped_q);
        SSBoneFrame_RotateBone(bf, b_tag->mod.current_q, b_tag->index);
    }
    else if(b_tag->mod.current_q[3] < 1.0f)
    {       
        if(b_tag->mod.current_q[3] < 0.99f)
        {
            float zero_ang[4] = {0.0f, 0.0f, 0.0f, 1.0f};
            float clamped_q[4];
            vec4_slerp_to(clamped_q, b_tag->mod.current_q, zero_ang, time * M_PI / 1.3f);
            vec4_copy(b_tag->mod.current_q, clamped_q);
            SSBoneFrame_RotateBone(bf, b_tag->mod.current_q, b_tag->index);
        }
        else
        {
            vec4_set_zero_angle(b_tag->mod.current_q);
        }
    }
}