Simulation Nodes: bake simulation states to disk #106937
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue