Simulation Nodes: bake simulation states to disk #106937

Merged
Jacques Lucke merged 116 commits from JacquesLucke/blender:sim-bake into geometry-nodes-simulation 2023-04-22 14:48:56 +02:00
5 changed files with 44 additions and 17 deletions
Showing only changes of commit ccd583f098 - Show all commits

View File

@ -153,10 +153,16 @@ struct ModifierSimulationStateAtFrame {
std::unique_ptr<ModifierSimulationState> state;
};
enum class CacheState {
Valid,
Invalid,
Baked,
};
class ModifierSimulationCache {
private:
Vector<ModifierSimulationStateAtFrame> states_at_frames_;
bool invalid_ = false;
CacheState cache_state_ = CacheState::Valid;
public:
void load_baked_states(StringRefNull meta_dir, StringRefNull bdata_dir);
@ -208,18 +214,18 @@ class ModifierSimulationCache {
void invalidate()
{
invalid_ = true;
cache_state_ = CacheState::Invalid;
}
bool is_invalid() const
CacheState cache_state() const
{
return invalid_;
return cache_state_;
}
void reset()
{
states_at_frames_.clear();
invalid_ = false;
cache_state_ = CacheState::Valid;
}
};

View File

@ -39,6 +39,8 @@ void ModifierSimulationCache::load_baked_states(const StringRefNull meta_dir,
dir_entry.path, bdata_dir, *new_state.state);
states_at_frames_.append(std::move(new_state));
}
cache_state_ = CacheState::Baked;
}
} // namespace blender::bke::sim

View File

@ -911,7 +911,8 @@ void DepsgraphNodeBuilder::build_object_modifiers(Object *object)
return;
}
if (modifier_node->flag & DEPSOP_FLAG_USER_MODIFIED) {
if (nmd->simulation_cache) {
if (nmd->simulation_cache &&
nmd->simulation_cache->cache_state() == bke::sim::CacheState::Valid) {
nmd->simulation_cache->invalidate();
}
}

View File

@ -688,10 +688,21 @@ static void timeline_cache_draw_simulation_nodes(
GPU_matrix_scale_2f(1.0, height);
float color[4];
copy_v4_fl4(color, 0.8, 0.8, 0.2, 1.0);
if (cache.is_invalid()) {
color[3] = 0.3f;
switch (cache.cache_state()) {
case blender::bke::sim::CacheState::Invalid: {
copy_v4_fl4(color, 0.8, 0.8, 0.2, 0.3);
break;
}
case blender::bke::sim::CacheState::Valid: {
copy_v4_fl4(color, 0.8, 0.8, 0.2, 1.0);
break;
}
case blender::bke::sim::CacheState::Baked: {
copy_v4_fl4(color, 1.0, 0.6, 0.2, 1.0);
break;
}
}
immUniformColor4fv(color);
const int start_frame = scene->r.sfra;

View File

@ -1209,28 +1209,35 @@ static GeometrySet compute_geometry(const bNodeTree &btree,
if (nmd_orig->simulation_cache == nullptr) {
nmd_orig->simulation_cache = MEM_new<blender::bke::sim::ModifierSimulationCache>(__func__);
}
if (nmd_orig->simulation_cache->is_invalid() && current_frame == start_frame) {
nmd_orig->simulation_cache->reset();
}
if (current_frame.frame() == 150) {
nmd_orig->simulation_cache->load_baked_states(
"/home/jacques/Downloads/blendcache_mesh_deform_sim/Cube_GeometryNodes/meta",
"/home/jacques/Downloads/blendcache_mesh_deform_sim/Cube_GeometryNodes/bdata");
}
const bke::sim::CacheState last_cache_state = nmd_orig->simulation_cache->cache_state();
if (last_cache_state == bke::sim::CacheState::Invalid && current_frame == start_frame) {
nmd_orig->simulation_cache->reset();
}
const bke::sim::ModifierSimulationStateAtFrame *prev_sim_state =
nmd_orig->simulation_cache->try_get_last_state_before_frame(current_frame);
if (prev_sim_state != nullptr) {
geo_nodes_modifier_data.prev_simulation_state = prev_sim_state->state.get();
const float frame_diff = float(current_frame) - float(prev_sim_state->frame);
geo_nodes_modifier_data.simulation_time_delta = frame_diff / FPS;
if (geo_nodes_modifier_data.simulation_time_delta > 1.0f) {
if (frame_diff > 1.0f && last_cache_state != bke::sim::CacheState::Baked) {
nmd_orig->simulation_cache->invalidate();
}
}
geo_nodes_modifier_data.current_simulation_state_for_write =
&nmd_orig->simulation_cache->get_state_at_frame_for_write(current_frame);
geo_nodes_modifier_data.current_simulation_state =
geo_nodes_modifier_data.current_simulation_state_for_write;
if (last_cache_state == bke::sim::CacheState::Baked) {
geo_nodes_modifier_data.current_simulation_state =
nmd_orig->simulation_cache->get_state_at_exact_frame(current_frame);
}
else {
HooglyBoogly marked this conversation as resolved Outdated

Decide of -> Decide if

`Decide of` -> `Decide if`
geo_nodes_modifier_data.current_simulation_state_for_write =
&nmd_orig->simulation_cache->get_state_at_frame_for_write(current_frame);
geo_nodes_modifier_data.current_simulation_state =
geo_nodes_modifier_data.current_simulation_state_for_write;
}
}
else {
/* TODO: Should probably only access baked data that is not modified in the original data