typedef struct BakeableSystem{
Object *ob;
void *system;
DynamicsKey **keys; /* baked keys for each entity */
int *totkey; /* array of amount of keys for each entity */
int totentity; /* amount of bakeable entities */
short type, recalc_flag, flag;
/* starting frame of baking */
float (*start_frame)(Object *ob, void *system);
/* end frame of baking */
float (*end_frame)(Object *ob, void *system);
/* timestep needed for next step */
float (*timestep)(Object *ob, void *system);
int (*is_baked)(Object *ob, void *system);
int (*set_baking)(Object *ob, void *system);
int (*needs_autobake)(Object *ob, void *system);
/* return system to unbaked state, regardles of wether baking is complete or not */
void (*free_bake)(Object *ob, void *system);
/* prepare system to continue baking from cfra */
void (*set_rebaking)(Object *ob, void *system, float cfra);
/* info on the bake, like size in memory, amount of baked keys etc. */
char *(*bake_info)(Object *ob, void *system);
/* initializes and sets an editing mode for the baked data */
void (*set_bake_edit)(Object *ob, void *system);
/* clear out temporary stuff left by the edit mode etc. */
void (*end_bake_edit)(Object *ob, void *system);
/* in addition several edit mode calls can be implemented, like mouse button calls, selections etc..*/
} BakeableSystem;
typedef struct DynamicsKey{
float co[3];
float vel[3];
float time;
/* custom variables needed by some systems */
float *custom;
} DynamicsKey;
/* BakeableSystem->type */
#define BAKEABLE_PARTICLE 0
#define BAKEABLE_SOFTBODY 1
#define BAKEABLE_CLOTH 2
#define BAKEABLE_FLUID 3
#define BAKEABLE_BULLET 4
void get_all_systems_to_bake(ListBase *bakelist)
{
Object *ob;
BakeableSystem *bsys;
for(ob in scene){
for(bsys in ob->bakelist){
if(bsys.flag & BSYS_TO_BAKE)
BLI_addtail(bakelist,bsys);
}
}
}
void get_all_autobake_systems(ListBase *bakelist)
{
Object *ob;
BakeableSystem *bsys;
for(ob in scene){
for(bsys in ob->bakelist){
if(bsys.needs_autobake(..))
BLI_addtail(bakelist,bsys);
}
}
}
void unified_bake(ListBase *bakelist, int from_cfra)
{
BakeableSystem *bsys;
float start_frame=from_cfra?CFRA:MAXFRAME;
float end_frame=-MAXFRAME;
float step=1.0, cfra;
int old_cfra=CFRA;
if(bakelist==0) return;
for(bsys in bakelist){
if(from_cfra==0){
bsys.free_bake(..);
start_frame=MIN(start_frame,bsys.start_frame(..));
bsys.ob->recalc |= bsys.recalc_flag;
bsys.set_baking(..);
}
else
bsys.set_rebaking(..);
end_frame=MAX(end_frame,bsys.end_frame(..));
}
cfra=start_frame;
CFRA=(int)cfra;
set_bake_offs(cfra-(float)CFRA);
DAG_scene_flush_update();
while(cfra<=end_frame){
for(ob in scene) {
object_handle_update(ob);
}
update ui to show progress
test for escape from baking
for(bsys in bakelist){
bsys.ob->recalc |= bsys.recalc_flag
step=MIN(step,bsys.get_timestep(..))
}
cfra+=step;
CFRA=(int)cfra;
set_bake_offs(cfra-(float)CFRA);
}
for(bsys in bakelist){
if(bsys.is_baked()==0){
bsys.free_bake(..)
bsys.ob->recalc = dyn.recalc_flag
}
else
bsys.flag &= ~BSYS_TO_BAKE;
}
CFRA=old_cfra;
scene_update_for_newframe()
}