Fix: simulation outputs empty geometry when going to frame zero
Previously, simulation nodes would output default values when there is no current simulation state and nothing should be computed. Now, the data is just passed through which is usually less confusing. Pull Request: https://projects.blender.org/blender/blender/pulls/110800
This commit is contained in:
parent
b6ed70cd92
commit
81096abe2a
|
@ -64,16 +64,17 @@ class LazyFunctionForSimulationInputNode final : public LazyFunction {
|
|||
return;
|
||||
}
|
||||
const GeoNodesModifierData &modifier_data = *user_data.modifier_data;
|
||||
if (modifier_data.current_simulation_state == nullptr) {
|
||||
params.set_default_remaining_outputs();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!params.output_was_set(0)) {
|
||||
const float delta_time = modifier_data.simulation_time_delta;
|
||||
params.set_output(0, fn::ValueOrField<float>(delta_time));
|
||||
}
|
||||
|
||||
if (modifier_data.current_simulation_state == nullptr) {
|
||||
this->pass_through(params, user_data);
|
||||
return;
|
||||
}
|
||||
|
||||
const std::optional<bke::sim::SimulationZoneID> zone_id = get_simulation_zone_id(
|
||||
user_data, output_node_id_);
|
||||
if (!zone_id) {
|
||||
|
@ -98,22 +99,7 @@ class LazyFunctionForSimulationInputNode final : public LazyFunction {
|
|||
}
|
||||
}
|
||||
|
||||
/* When there is no previous state already, create the initial state. */
|
||||
Array<void *> input_values(simulation_items_.size(), nullptr);
|
||||
for (const int i : simulation_items_.index_range()) {
|
||||
input_values[i] = params.try_get_input_data_ptr_or_request(i);
|
||||
}
|
||||
if (input_values.as_span().contains(nullptr)) {
|
||||
/* Wait until all inputs are available. */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Instead of outputting the initial values directly, convert them to a simulation state and
|
||||
* then back. This ensures that the first frame behaves consistently with all other frames
|
||||
* which are necessarily stored in the simulation cache. */
|
||||
bke::sim::SimulationZoneState initial_zone_state;
|
||||
move_values_to_simulation_state(simulation_items_, input_values, initial_zone_state);
|
||||
this->output_simulation_state_move(params, user_data, initial_zone_state);
|
||||
this->pass_through(params, user_data);
|
||||
}
|
||||
|
||||
void output_simulation_state_copy(lf::Params ¶ms,
|
||||
|
@ -153,6 +139,24 @@ class LazyFunctionForSimulationInputNode final : public LazyFunction {
|
|||
params.output_set(i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
void pass_through(lf::Params ¶ms, const GeoNodesLFUserData &user_data) const
|
||||
{
|
||||
Array<void *> input_values(inputs_.size());
|
||||
for (const int i : inputs_.index_range()) {
|
||||
input_values[i] = params.try_get_input_data_ptr_or_request(i);
|
||||
}
|
||||
if (input_values.as_span().contains(nullptr)) {
|
||||
/* Wait for inputs to be computed. */
|
||||
return;
|
||||
}
|
||||
/* Instead of outputting the initial values directly, convert them to a simulation state and
|
||||
* then back. This ensures that some geometry processing happens on the data consistently (e.g.
|
||||
* removing anonymous attributes). */
|
||||
bke::sim::SimulationZoneState state;
|
||||
move_values_to_simulation_state(simulation_items_, input_values, state);
|
||||
this->output_simulation_state_move(params, user_data, state);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace blender::nodes::node_geo_simulation_input_cc
|
||||
|
|
|
@ -577,9 +577,9 @@ class LazyFunctionForSimulationOutputNode final : public LazyFunction {
|
|||
modifier_data.prev_simulation_state->get_zone_state(*zone_id) :
|
||||
nullptr;
|
||||
if (prev_zone_state == nullptr) {
|
||||
/* There is no previous simulation state and we also don't create a new one, so just
|
||||
* output defaults. */
|
||||
params.set_default_remaining_outputs();
|
||||
/* There is no previous simulation state and we also don't create a new one, so just pass
|
||||
* the data through. */
|
||||
this->pass_through(params, user_data);
|
||||
return;
|
||||
}
|
||||
const bke::sim::SimulationZoneState *next_zone_state =
|
||||
|
@ -674,6 +674,24 @@ class LazyFunctionForSimulationOutputNode final : public LazyFunction {
|
|||
params.output_set(i);
|
||||
}
|
||||
}
|
||||
|
||||
void pass_through(lf::Params ¶ms, GeoNodesLFUserData &user_data) const
|
||||
{
|
||||
Array<void *> input_values(inputs_.size());
|
||||
for (const int i : inputs_.index_range()) {
|
||||
input_values[i] = params.try_get_input_data_ptr_or_request(i);
|
||||
}
|
||||
if (input_values.as_span().contains(nullptr)) {
|
||||
/* Wait for inputs to be computed. */
|
||||
return;
|
||||
}
|
||||
/* Instead of outputting the initial values directly, convert them to a simulation state and
|
||||
* then back. This ensures that some geometry processing happens on the data consistently (e.g.
|
||||
* removing anonymous attributes). */
|
||||
bke::sim::SimulationZoneState state;
|
||||
move_values_to_simulation_state(simulation_items_, input_values, state);
|
||||
this->output_cached_state(params, user_data, state);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace blender::nodes::node_geo_simulation_output_cc
|
||||
|
|
Loading…
Reference in New Issue