Dev:Source/Physics/Unified Dynamics Baking
< Dev:Source | Physics
General ideas
- adding a dynamic system to an object also adds BakeableSystem entry to a new list of bakeable systems in the object
- the BakeableSystem struct allows unified handling of all bakeable systems
- the struct will also store the baking with a DynamicsKey struct that will hold the data points for all systems, possibly with added custom variables
- all wanted dynamic systems can be baked in a single run through the wanted time span
- systems can be manually set "to bake" and when baking is started by the user all of these systems are baked
- systems that need an autobake (atleast particles) are baked if the systems want it when asked after updating recalc flags through the depsgraph..
- a unified "bake edit mode" will allow editing of all baked dynamics
- allthough unified, the edit mode may have differing functionality depending on system sype
- in case of a "bad bake" the bake can be edited at a certain frame and then rebaked starting from that frame and at the same time preserve the bake before that frame
- editing of object's data and settings of modifiers before the baked system will be locked after the bake
- this is nescessary since the baked system can't react to changes mesh structure etc..
- alternatively atleast a warning of "losing bake" should be issued before modifications are allowed
- baking can be done with non-integer steps
- all dynamic systems get current time with bsystem_time(...)
- a new "bakeoffs" variable will be set by the baking system, similar to the "bluroffs" and "fieldoffs" that are currently in use
- unified baking is controlled from the outliner
- "bakeable systems" option for the outliner display to display only bakeable systems
- each system can be separately flagged "to bake"
- baked systems display info on the bake (memory usage etc.)
- option to free a system's bake
- a "BAKE" button and start/end frame settings to begin unified baking
- baking should also be available from the commandline like Tony Mullen suggested
- a command line option to start unified baking with set systems
- save blend after baking is complete
BakeableSystem sructure
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
Main functions
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()
}