Fix: Simulation Nodes: assert when scrubbing the timeline with simulation (Blender 3.6) #112363

Merged
Jacques Lucke merged 1 commits from JacquesLucke/blender:fix-states-around-frame into blender-v3.6-release 2023-09-14 16:53:40 +02:00
1 changed files with 14 additions and 19 deletions

View File

@ -93,7 +93,7 @@ void ModifierSimulationCache::try_discover_bake(const StringRefNull absolute_bak
}
}
static int64_t find_state_at_frame(
static int64_t find_state_at_frame_exact(
const Span<std::unique_ptr<ModifierSimulationStateAtFrame>> states, const SubFrame &frame)
{
const int64_t i = binary_search::find_predicate_begin(
@ -101,16 +101,6 @@ static int64_t find_state_at_frame(
if (i == states.size()) {
return -1;
}
return i;
}
static int64_t find_state_at_frame_exact(
const Span<std::unique_ptr<ModifierSimulationStateAtFrame>> states, const SubFrame &frame)
{
const int64_t i = find_state_at_frame(states, frame);
if (i == -1) {
return -1;
}
if (states[i]->frame != frame) {
return -1;
}
@ -162,22 +152,27 @@ ModifierSimulationState &ModifierSimulationCache::get_state_at_frame_for_write(
StatesAroundFrame ModifierSimulationCache::get_states_around_frame(const SubFrame &frame) const
{
std::lock_guard lock(states_at_frames_mutex_);
const int64_t i = find_state_at_frame(states_at_frames_, frame);
const int64_t i_at_or_after_frame = binary_search::find_predicate_begin(
states_at_frames_, [&](const auto &item) { return item->frame >= frame; });
StatesAroundFrame states_around_frame{};
if (i == -1) {
if (i_at_or_after_frame == states_at_frames_.size()) {
if (!states_at_frames_.is_empty() && states_at_frames_.last()->frame < frame) {
states_around_frame.prev = states_at_frames_.last().get();
}
return states_around_frame;
}
if (states_at_frames_[i]->frame == frame) {
states_around_frame.current = states_at_frames_[i].get();
const bool has_current_state = states_at_frames_[i_at_or_after_frame]->frame == frame;
if (has_current_state) {
states_around_frame.current = states_at_frames_[i_at_or_after_frame].get();
if (i_at_or_after_frame < states_at_frames_.size() - 1) {
states_around_frame.next = states_at_frames_[i_at_or_after_frame + 1].get();
}
}
if (i > 0) {
states_around_frame.prev = states_at_frames_[i - 1].get();
else {
states_around_frame.next = states_at_frames_[i_at_or_after_frame].get();
}
if (i < states_at_frames_.size() - 2) {
states_around_frame.next = states_at_frames_[i + 1].get();
if (i_at_or_after_frame > 0) {
states_around_frame.prev = states_at_frames_[i_at_or_after_frame - 1].get();
}
return states_around_frame;
}