游戏引擎 动画相关


//media - animation set
bool init_animation_set_creator() {return true;}
void shutdown_animation_set_creator() {}

struct animation_t
{
    virtual float    get_period(bool loop) = 0;
    virtual byte4    find_function(const char* func_name) = 0;
    virtual void    snapshot(bool loop, float time) = 0;
    virtual void    get_matrix_value(byte4 func_index, matrix* value) = 0;    //ensure to call snapshot() before you call this
};

struct animation_set_t
{
    virtual byte4            get_animation_count() = 0;
    virtual animation_t*    get_animation(byte4 index) = 0;
    virtual byte4            find_animation(const char* animation_name) = 0;
};

struct _animation_t : public animation_t
{
    typedef map<string, byte4>    func_map_t;
    char                        name[30];
    float                        interval;
    byte4                        frame_count;
    func_map_t                    func_map;
    vector< vector<matrix> >    func_vec;
    byte4                        frame1;
    byte4                        frame2;
    float                        ratio;

    float    get_period(bool loop) {    return loop ? interval * frame_count : interval * (frame_count - 1); }
    byte4    find_function(const char* func_name);
    void    snapshot(bool loop, float time);
    void    get_matrix_value(byte4 func_index, matrix* value) {*value = func_vec[func_index][frame1] * (1 - ratio) + func_vec[func_index][frame2] * ratio;}
};

byte4 _animation_t::find_function(const char* func_name)
{
    func_map_t::iterator p = func_map.find(func_name);
    if( p != func_map.end() )
        return p->second;
    return -1;
}

void _animation_t::snapshot(bool loop, float time)
{
    if( !loop && time >= get_period(false) )
    {
        frame1 = frame2 = frame_count - 1;
        ratio = 1;
        return;
    }

    float iterval_count_f = time / interval;
    int    interval_count_n = (int)floorf(iterval_count_f);
    frame1 = (byte4)(interval_count_n % frame_count);
    frame2 = (frame1 + 1) % frame_count;
    ratio = iterval_count_f - interval_count_n;
}

struct animation_set_media_t : public media_t, public animation_set_t
{
    //src
    string        filename;

    //loaded
    buffer_t    filedata;

    //processed = produced
    vector<_animation_t>    ani_vec;

    //ctor
    animation_set_media_t(const char* _filename) {filename = _filename; filedata = 0;}

    //media
    void load() {load_file(filename.c_str(), &filedata);}
    void process();
    void produce() {}
    void postprocess() {}
    void discard_video_objects() {}
    void clear() {SAFE_RELEASE(filedata); ani_vec.clear();}
    void destroy() {clear(); delete this;}
    void* product() {return (!ani_vec.empty()) ? (animation_set_t*)this : 0;}

    //ani set
    byte4            get_animation_count()        {return (byte4)ani_vec.size();}
    animation_t*    get_animation(byte4 index)    {return &ani_vec[index];}
    byte4            find_animation(const char* animation_name);
};

void animation_set_media_t::process()
{
    if(!filedata)    //previous step failed, return
        return;

    byte* ptr = (byte*)filedata->GetBufferPointer();
    if(*(byte4*)ptr != 0x414E494D)
    {
        clear();
        return;
    }
    ptr += 8;

    ani_vec.resize(*(byte4*)ptr);
    ptr += 4;

    byte4 real_count = 0;
    for( byte4 i = 0; i < ani_vec.size(); i++ )
    {
        byte4 ani_type = *(byte4*)ptr;
        ptr += 4;

        strcpy(ani_vec[real_count].name, (char*)ptr);
        ptr += 30;

        switch(ani_type)
        {
        case 10:
            {
                ani_vec[real_count].func_vec.resize(*(byte4*)ptr);
                ptr += 4;

                ani_vec[real_count].frame_count = *(byte4*)ptr;
                ptr += 4;

                ani_vec[real_count].interval = *(float*)ptr;
                ptr += sizeof(float);

                for( byte4 ifunc = 0; ifunc < ani_vec[real_count].func_vec.size(); ifunc++ )
                {
                    ani_vec[real_count].func_map[(char*)ptr] = ifunc;
                    ptr += 30;
                }

                for( byte4 ifunc = 0; ifunc < ani_vec[real_count].func_vec.size(); ifunc++ )
                {
                    ani_vec[real_count].func_vec[ifunc].resize(ani_vec[real_count].frame_count);
                    memcpy(&ani_vec[real_count].func_vec[ifunc][0], ptr, sizeof(matrix) * ani_vec[real_count].frame_count);
                    ptr += sizeof(matrix) * ani_vec[real_count].frame_count;
                }

                real_count++;
            }
            break;
        case 1:
        case 2:
            {
                ptr += 4;

                byte4 vcount = *(byte4*)ptr;
                ptr += 4;

                byte4 frame_count = *(byte4*)ptr;
                ptr += 4;

                ptr += 4 + 4 * vcount + sizeof(float3) * frame_count * vcount;
            }
            break;
        case 100:
            {
                ptr += 4;

                byte4 blade_count = *(byte4*)ptr;
                ptr += 4;

                byte4 frame_count = *(byte4*)ptr;
                ptr += 4;

                ptr += 4 + 8 * blade_count * frame_count;
            }
            break;
        }
    }

    ani_vec.resize(real_count);

    //clear loaded data
    SAFE_RELEASE(filedata);
}

byte4 animation_set_media_t::find_animation(const char* animation_name)
{
    for( byte4 i = 0; i < ani_vec.size(); i++ )
    {
        if( strcmp(animation_name, ani_vec[i].name) == 0 )
        {
            return i;
        }
    }
    return -1;
}

media_t* create_animation_set(const char* filename, void* arg)
{
    return new animation_set_media_t(filename);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值