Example #1
0
void SSBoneFrame_CreateFromModel(ss_bone_frame_p bf, skeletal_model_p model)
{
    vec3_set_zero(bf->bb_min);
    vec3_set_zero(bf->bb_max);
    vec3_set_zero(bf->centre);
    vec3_set_zero(bf->pos);
    bf->animations.type = ANIM_TYPE_BASE;
    bf->animations.anim_frame_flags = 0x0000;
    bf->animations.anim_ext_flags = 0x0000;
    bf->animations.frame_time = 0.0;
    bf->animations.period = 1.0 / 30.0;
    bf->animations.next_state = 0;
    bf->animations.lerp = 0.0;
    bf->animations.current_animation = 0;
    bf->animations.current_frame = 0;
    bf->animations.next_animation = 0;
    bf->animations.next_frame = 0;
    vec3_set_zero(bf->animations.target);
    bf->animations.bone_direction[0] = 0.0f;
    bf->animations.bone_direction[1] = 1.0f;
    bf->animations.bone_direction[2] = 0.0f;
    bf->animations.targeting_limit[0] = 0.0f;
    bf->animations.targeting_limit[1] = 1.0f;
    bf->animations.targeting_limit[2] = 0.0f;
    bf->animations.targeting_limit[3] =-1.0f;
    vec3_set_one(bf->animations.targeting_axis_mod);
    bf->animations.targeting_bone = 0x00;
    bf->animations.targeting_flags = 0x0000;

    vec4_set_zero_angle(bf->animations.current_mod);
    bf->animations.next = NULL;
    bf->animations.onFrame = NULL;
    bf->animations.onEndFrame = NULL;
    bf->transform = NULL;
    bf->animations.model = model;
    bf->bone_tag_count = model->mesh_count;
    bf->bone_tags = (ss_bone_tag_p)malloc(bf->bone_tag_count * sizeof(ss_bone_tag_t));

    bf->bone_tags[0].parent = NULL;                                             // root
    for(uint16_t i = 0; i < bf->bone_tag_count; i++)
    {
        bf->bone_tags[i].index = i;
        bf->bone_tags[i].mesh_base = model->mesh_tree[i].mesh_base;
        bf->bone_tags[i].mesh_skin = model->mesh_tree[i].mesh_skin;
        bf->bone_tags[i].mesh_slot = NULL;
        bf->bone_tags[i].alt_anim = NULL;
        bf->bone_tags[i].body_part = model->mesh_tree[i].body_part;

        vec3_copy(bf->bone_tags[i].offset, model->mesh_tree[i].offset);
        vec4_set_zero(bf->bone_tags[i].qrotate);
        Mat4_E_macro(bf->bone_tags[i].transform);
        Mat4_E_macro(bf->bone_tags[i].full_transform);

        if(i > 0)
        {
            bf->bone_tags[i].parent = bf->bone_tags + model->mesh_tree[i].parent;
        }
    }
}
Example #2
0
void SSBoneFrame_CreateFromModel(ss_bone_frame_p bf, skeletal_model_p model)
{
    vec3_set_zero(bf->bb_min);
    vec3_set_zero(bf->bb_max);
    vec3_set_zero(bf->centre);
    vec3_set_zero(bf->pos);
    bf->transform = NULL;
    bf->flags = 0x0000;
    bf->bone_tag_count = 0;
    bf->bone_tags = NULL;
    
    SSBoneFrame_InitSSAnim(&bf->animations, model, ANIM_TYPE_BASE);
    bf->animations.model = model;
    if(model)
    {
        bf->bone_tag_count = model->mesh_count;
        bf->bone_tags = (ss_bone_tag_p)malloc(bf->bone_tag_count * sizeof(ss_bone_tag_t));
        bf->bone_tags[0].parent = NULL;                                         // root
        for(uint16_t i = 0; i < bf->bone_tag_count; i++)
        {
            ss_bone_tag_p b_tag = bf->bone_tags + i;
            b_tag->index = i;
            b_tag->is_hidden = 0x00;
            b_tag->is_targeted = 0x00;
            b_tag->is_axis_modded = 0x00;
            b_tag->mesh_base = model->mesh_tree[i].mesh_base;
            b_tag->mesh_replace = NULL;
            b_tag->mesh_skin = NULL;
            b_tag->mesh_slot = NULL;
            b_tag->skin_map = NULL;
            b_tag->alt_anim = NULL;
            b_tag->body_part = model->mesh_tree[i].body_part;

            vec3_copy(b_tag->offset, model->mesh_tree[i].offset);
            vec4_set_zero(b_tag->qrotate);
            Mat4_E_macro(b_tag->local_transform);
            Mat4_E_macro(b_tag->current_transform);

            vec3_set_zero(b_tag->mod.target_pos);
            vec4_set_zero_angle(b_tag->mod.current_q);
            b_tag->mod.bone_local_direction[0] = 0.0f;
            b_tag->mod.bone_local_direction[1] = 1.0f;
            b_tag->mod.bone_local_direction[2] = 0.0f;
            b_tag->mod.limit[0] = 0.0f;
            b_tag->mod.limit[1] = 1.0f;
            b_tag->mod.limit[2] = 0.0f;
            b_tag->mod.limit[3] =-1.0f;
            b_tag->mod.current_slerp = 1.0f;
            vec3_set_one(b_tag->mod.axis_mod);
            
            if(i > 0)
            {
                b_tag->parent = bf->bone_tags + model->mesh_tree[i].parent;
            }
        }
    }
}
Example #3
0
void SSBoneFrame_InitSSAnim(struct ss_animation_s *ss_anim, uint32_t anim_type_id)
{
    ss_anim->anim_ext_flags = 0x00;
    ss_anim->anim_frame_flags = 0x00;
    ss_anim->type = anim_type_id;
    ss_anim->enabled = 1;
    ss_anim->model = NULL;
    ss_anim->onFrame = NULL;
    ss_anim->onEndFrame = NULL;
    ss_anim->targeting_bone = 0x00;
    ss_anim->targeting_flags = 0x0000;
    vec3_set_zero(ss_anim->target);
    vec4_set_zero_angle(ss_anim->current_mod);
    ss_anim->bone_direction[0] = 0.0f;
    ss_anim->bone_direction[1] = 1.0f;
    ss_anim->bone_direction[2] = 0.0f;
    ss_anim->targeting_limit[0] = 0.0f;
    ss_anim->targeting_limit[1] = 1.0f;
    ss_anim->targeting_limit[2] = 0.0f;
    ss_anim->targeting_limit[3] =-1.0f;
    vec3_set_one(ss_anim->targeting_axis_mod);

    ss_anim->frame_time = 0.0f;
    ss_anim->next_state = 0;
    ss_anim->lerp = 0.0;
    ss_anim->current_animation = 0;
    ss_anim->current_frame = 0;
    ss_anim->next_animation = 0;
    ss_anim->next_frame = 0;
    ss_anim->period = 1.0f / 30.0f;

    ss_anim->next = NULL;
    ss_anim->prev = NULL;
}
Example #4
0
void SSBoneFrame_CreateFromModel(ss_bone_frame_p bf, skeletal_model_p model)
{
    vec3_set_zero(bf->bb_min);
    vec3_set_zero(bf->bb_max);
    vec3_set_zero(bf->centre);
    vec3_set_zero(bf->pos);
    bf->transform = NULL;
    bf->bone_tag_count = 0;
    bf->bone_tags = NULL;
    
    SSBoneFrame_InitSSAnim(&bf->animations, ANIM_TYPE_BASE);
    bf->animations.model = model;
    if(model)
    {
        bf->bone_tag_count = model->mesh_count;
        bf->bone_tags = (ss_bone_tag_p)malloc(bf->bone_tag_count * sizeof(ss_bone_tag_t));
        bf->bone_tags[0].parent = NULL;                                         // root
        for(uint16_t i = 0; i < bf->bone_tag_count; i++)
        {
            bf->bone_tags[i].index = i;
            bf->bone_tags[i].mesh_base = model->mesh_tree[i].mesh_base;
            bf->bone_tags[i].mesh_skin = model->mesh_tree[i].mesh_skin;
            bf->bone_tags[i].mesh_slot = NULL;
            bf->bone_tags[i].alt_anim = NULL;
            bf->bone_tags[i].body_part = model->mesh_tree[i].body_part;

            vec3_copy(bf->bone_tags[i].offset, model->mesh_tree[i].offset);
            vec4_set_zero(bf->bone_tags[i].qrotate);
            Mat4_E_macro(bf->bone_tags[i].transform);
            Mat4_E_macro(bf->bone_tags[i].full_transform);

            if(i > 0)
            {
                bf->bone_tags[i].parent = bf->bone_tags + model->mesh_tree[i].parent;
            }
        }
    }
}
Example #5
0
struct ss_animation_s *SSBoneFrame_AddOverrideAnim(struct ss_bone_frame_s *bf, struct skeletal_model_s *sm, uint16_t anim_type)
{
    if(!sm || (sm->mesh_count == bf->bone_tag_count))
    {
        ss_animation_p ss_anim = (ss_animation_p)malloc(sizeof(ss_animation_t));

        ss_anim->anim_ext_flags = 0x00;
        ss_anim->anim_frame_flags = 0x00;
        ss_anim->type = anim_type;
        ss_anim->model = sm;
        ss_anim->onFrame = NULL;
        ss_anim->onEndFrame = NULL;
        ss_anim->targeting_bone = 0;
        ss_anim->targeting_flags = 0x0000;
        vec3_set_zero(ss_anim->target);
        vec4_set_zero_angle(ss_anim->current_mod);
        ss_anim->bone_direction[0] = 0.0f;
        ss_anim->bone_direction[1] = 1.0f;
        ss_anim->bone_direction[2] = 0.0f;
        ss_anim->targeting_limit[0] = 0.0f;
        ss_anim->targeting_limit[1] = 1.0f;
        ss_anim->targeting_limit[2] = 0.0f;
        ss_anim->targeting_limit[3] =-1.0f;
        vec3_set_one(ss_anim->targeting_axis_mod);
        ss_anim->next = bf->animations.next;
        bf->animations.next = ss_anim;

        ss_anim->frame_time = 0.0;
        ss_anim->next_state = 0;
        ss_anim->lerp = 0.0;
        ss_anim->current_animation = 0;
        ss_anim->current_frame = 0;
        ss_anim->next_animation = 0;
        ss_anim->next_frame = 0;
        ss_anim->period = 1.0f / 30.0f;
        return ss_anim;
    }

    return NULL;
}
Example #6
0
void SSBoneFrame_Update(struct ss_bone_frame_s *bf)
{
    float cmd_tr[3], tr[3], t;
    ss_bone_tag_p btag = bf->bone_tags;
    bone_tag_p src_btag, next_btag;
    skeletal_model_p model = bf->animations.model;
    bone_frame_p curr_bf, next_bf;

    next_bf = model->animations[bf->animations.next_animation].frames + bf->animations.next_frame;
    curr_bf = model->animations[bf->animations.current_animation].frames + bf->animations.current_frame;

    t = 1.0 - bf->animations.lerp;
    if(bf->transform && (curr_bf->command & ANIM_CMD_MOVE))
    {
        Mat4_vec3_rot_macro(tr, bf->transform, curr_bf->move);
        vec3_mul_scalar(cmd_tr, tr, bf->animations.lerp);
    }
    else
    {
        vec3_set_zero(tr);
        vec3_set_zero(cmd_tr);
    }

    vec3_interpolate_macro(bf->bb_max, curr_bf->bb_max, next_bf->bb_max, bf->animations.lerp, t);
    vec3_add(bf->bb_max, bf->bb_max, cmd_tr);
    vec3_interpolate_macro(bf->bb_min, curr_bf->bb_min, next_bf->bb_min, bf->animations.lerp, t);
    vec3_add(bf->bb_min, bf->bb_min, cmd_tr);
    vec3_interpolate_macro(bf->centre, curr_bf->centre, next_bf->centre, bf->animations.lerp, t);
    vec3_add(bf->centre, bf->centre, cmd_tr);

    vec3_interpolate_macro(bf->pos, curr_bf->pos, next_bf->pos, bf->animations.lerp, t);
    vec3_add(bf->pos, bf->pos, cmd_tr);
    next_btag = next_bf->bone_tags;
    src_btag = curr_bf->bone_tags;
    for(uint16_t k = 0; k < curr_bf->bone_tag_count; k++, btag++, src_btag++, next_btag++)
    {
        vec3_interpolate_macro(btag->offset, src_btag->offset, next_btag->offset, bf->animations.lerp, t);
        vec3_copy(btag->transform+12, btag->offset);
        btag->transform[15] = 1.0;
        if(k == 0)
        {
            vec3_add(btag->transform+12, btag->transform+12, bf->pos);
            vec4_slerp(btag->qrotate, src_btag->qrotate, next_btag->qrotate, bf->animations.lerp);
        }
        else
        {
            bone_tag_p ov_src_btag = src_btag;
            bone_tag_p ov_next_btag = next_btag;
            float ov_lerp = bf->animations.lerp;
            if(btag->alt_anim && btag->alt_anim->model && (btag->alt_anim->model->mesh_tree[k].replace_anim != 0))
            {
                bone_frame_p ov_curr_bf = btag->alt_anim->model->animations[btag->alt_anim->current_animation].frames + btag->alt_anim->current_frame;
                bone_frame_p ov_next_bf = btag->alt_anim->model->animations[btag->alt_anim->next_animation].frames + btag->alt_anim->next_frame;
                ov_src_btag = ov_curr_bf->bone_tags + k;
                ov_next_btag = ov_next_bf->bone_tags + k;
                ov_lerp = btag->alt_anim->lerp;
            }
            vec4_slerp(btag->qrotate, ov_src_btag->qrotate, ov_next_btag->qrotate, ov_lerp);
        }
        Mat4_set_qrotation(btag->transform, btag->qrotate);
    }

    /*
     * build absolute coordinate matrix system
     */
    btag = bf->bone_tags;
    Mat4_Copy(btag->full_transform, btag->transform);
    btag++;
    for(uint16_t k = 1; k < curr_bf->bone_tag_count; k++, btag++)
    {
        Mat4_Mat4_mul(btag->full_transform, btag->parent->full_transform, btag->transform);
    }

    for(ss_animation_p ss_anim = &bf->animations; ss_anim; ss_anim = ss_anim->next)
    {
        SSBoneFrame_TargetBoneToSlerp(bf, ss_anim);
    }
}
Example #7
0
void SkeletalModel_InterpolateFrames(skeletal_model_p model)
{
    uint16_t new_frames_count;
    animation_frame_p anim = model->animations;
    bone_frame_p bf, new_bone_frames;
    float lerp, t;

    for(uint16_t i = 0; i < model->animation_count; i++, anim++)
    {
        if(anim->frames_count > 1 && anim->original_frame_rate > 1)             // we can't interpolate one frame or rate < 2!
        {
            new_frames_count = (uint16_t)anim->original_frame_rate * (anim->frames_count - 1) + 1;
            bf = new_bone_frames = (bone_frame_p)malloc(new_frames_count * sizeof(bone_frame_t));

            /*
             * the first frame does not changes
             */
            bf->bone_tags = (bone_tag_p)malloc(model->mesh_count * sizeof(bone_tag_t));
            bf->bone_tag_count = model->mesh_count;
            vec3_set_zero(bf->pos);
            vec3_set_zero(bf->move);
            bf->command = 0x00;
            vec3_copy(bf->centre, anim->frames[0].centre);
            vec3_copy(bf->pos, anim->frames[0].pos);
            vec3_copy(bf->bb_max, anim->frames[0].bb_max);
            vec3_copy(bf->bb_min, anim->frames[0].bb_min);
            for(uint16_t k = 0; k < model->mesh_count; k++)
            {
                vec3_copy(bf->bone_tags[k].offset, anim->frames[0].bone_tags[k].offset);
                vec4_copy(bf->bone_tags[k].qrotate, anim->frames[0].bone_tags[k].qrotate);
            }
            bf++;

            for(uint16_t j = 1; j < anim->frames_count; j++)
            {
                for(uint16_t lerp_index = 1; lerp_index <= anim->original_frame_rate; lerp_index++)
                {
                    vec3_set_zero(bf->pos);
                    vec3_set_zero(bf->move);
                    bf->command = 0x00;
                    lerp = ((float)lerp_index) / (float)anim->original_frame_rate;
                    t = 1.0 - lerp;

                    bf->bone_tags = (bone_tag_p)malloc(model->mesh_count * sizeof(bone_tag_t));
                    bf->bone_tag_count = model->mesh_count;

                    bf->centre[0] = t * anim->frames[j-1].centre[0] + lerp * anim->frames[j].centre[0];
                    bf->centre[1] = t * anim->frames[j-1].centre[1] + lerp * anim->frames[j].centre[1];
                    bf->centre[2] = t * anim->frames[j-1].centre[2] + lerp * anim->frames[j].centre[2];

                    bf->pos[0] = t * anim->frames[j-1].pos[0] + lerp * anim->frames[j].pos[0];
                    bf->pos[1] = t * anim->frames[j-1].pos[1] + lerp * anim->frames[j].pos[1];
                    bf->pos[2] = t * anim->frames[j-1].pos[2] + lerp * anim->frames[j].pos[2];

                    bf->bb_max[0] = t * anim->frames[j-1].bb_max[0] + lerp * anim->frames[j].bb_max[0];
                    bf->bb_max[1] = t * anim->frames[j-1].bb_max[1] + lerp * anim->frames[j].bb_max[1];
                    bf->bb_max[2] = t * anim->frames[j-1].bb_max[2] + lerp * anim->frames[j].bb_max[2];

                    bf->bb_min[0] = t * anim->frames[j-1].bb_min[0] + lerp * anim->frames[j].bb_min[0];
                    bf->bb_min[1] = t * anim->frames[j-1].bb_min[1] + lerp * anim->frames[j].bb_min[1];
                    bf->bb_min[2] = t * anim->frames[j-1].bb_min[2] + lerp * anim->frames[j].bb_min[2];

                    for(uint16_t k = 0; k < model->mesh_count; k++)
                    {
                        bf->bone_tags[k].offset[0] = t * anim->frames[j-1].bone_tags[k].offset[0] + lerp * anim->frames[j].bone_tags[k].offset[0];
                        bf->bone_tags[k].offset[1] = t * anim->frames[j-1].bone_tags[k].offset[1] + lerp * anim->frames[j].bone_tags[k].offset[1];
                        bf->bone_tags[k].offset[2] = t * anim->frames[j-1].bone_tags[k].offset[2] + lerp * anim->frames[j].bone_tags[k].offset[2];

                        vec4_slerp(bf->bone_tags[k].qrotate, anim->frames[j-1].bone_tags[k].qrotate, anim->frames[j].bone_tags[k].qrotate, lerp);
                    }
                    bf++;
                }
            }

            /*
             * swap old and new animation bone brames
             * free old bone frames;
             */
            for(uint16_t j = 0; j < anim->frames_count; j++)
            {
                if(anim->frames[j].bone_tag_count)
                {
                    anim->frames[j].bone_tag_count = 0;
                    free(anim->frames[j].bone_tags);
                    anim->frames[j].bone_tags = NULL;
                }
            }
            free(anim->frames);
            anim->frames = new_bone_frames;
            anim->frames_count = new_frames_count;
        }
    }
}