//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);
}