diff options
Diffstat (limited to 'source/blender/simulation')
21 files changed, 464 insertions, 142 deletions
diff --git a/source/blender/simulation/SIM_mass_spring.h b/source/blender/simulation/SIM_mass_spring.h index d30a7160fd8..219ead477c2 100644 --- a/source/blender/simulation/SIM_mass_spring.h +++ b/source/blender/simulation/SIM_mass_spring.h @@ -21,8 +21,7 @@ * \ingroup bph */ -#ifndef __SIM_MASS_SPRING_H__ -#define __SIM_MASS_SPRING_H__ +#pragma once #ifdef __cplusplus extern "C" { @@ -58,5 +57,3 @@ void SIM_cloth_solver_set_volume(ClothModifierData *clmd); #ifdef __cplusplus } #endif - -#endif diff --git a/source/blender/simulation/SIM_simulation_update.hh b/source/blender/simulation/SIM_simulation_update.hh index efdfde8a4de..7c2726f038e 100644 --- a/source/blender/simulation/SIM_simulation_update.hh +++ b/source/blender/simulation/SIM_simulation_update.hh @@ -14,8 +14,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#ifndef __SIM_SIMULATION_UPDATE_HH__ -#define __SIM_SIMULATION_UPDATE_HH__ +#pragma once struct Depsgraph; struct Scene; @@ -30,5 +29,3 @@ void update_simulation_in_depsgraph(Depsgraph *depsgraph, bool update_simulation_dependencies(Simulation *simulation); } // namespace blender::sim - -#endif /* __SIM_SIMULATION_UPDATE_HH__ */ diff --git a/source/blender/simulation/intern/ConstrainedConjugateGradient.h b/source/blender/simulation/intern/ConstrainedConjugateGradient.h index c924490f97d..b0f2bb037d2 100644 --- a/source/blender/simulation/intern/ConstrainedConjugateGradient.h +++ b/source/blender/simulation/intern/ConstrainedConjugateGradient.h @@ -17,8 +17,7 @@ * All rights reserved. */ -#ifndef __CONSTRAINEDCONJUGATEGRADIENT_H__ -#define __CONSTRAINEDCONJUGATEGRADIENT_H__ +#pragma once #include <Eigen/Core> @@ -331,5 +330,3 @@ struct solve_retval<ConstrainedConjugateGradient<_MatrixType, _UpLo, _Filter, _P } // end namespace internal } // end namespace Eigen - -#endif // __CONSTRAINEDCONJUGATEGRADIENT_H__ diff --git a/source/blender/simulation/intern/eigen_utils.h b/source/blender/simulation/intern/eigen_utils.h index c186cf567df..897ba8b2a67 100644 --- a/source/blender/simulation/intern/eigen_utils.h +++ b/source/blender/simulation/intern/eigen_utils.h @@ -17,8 +17,7 @@ * All rights reserved. */ -#ifndef __EIGEN_UTILS_H__ -#define __EIGEN_UTILS_H__ +#pragma once /** \file * \ingroup bph @@ -232,5 +231,3 @@ BLI_INLINE void print_lmatrix(const lMatrix &m) printf("\n"); } } - -#endif diff --git a/source/blender/simulation/intern/hair_volume.cpp b/source/blender/simulation/intern/hair_volume.cpp index c80ae69ce73..c24b7154d13 100644 --- a/source/blender/simulation/intern/hair_volume.cpp +++ b/source/blender/simulation/intern/hair_volume.cpp @@ -710,9 +710,8 @@ BLI_INLINE float hair_volume_density_divergence(float density, if (density > density_threshold && density > target_density) { return strength * logf(target_density / density); } - else { - return 0.0f; - } + + return 0.0f; } bool SIM_hair_volume_solve_divergence(HairGrid *grid, @@ -1030,14 +1029,13 @@ bool SIM_hair_volume_solve_divergence(HairGrid *grid, return true; } - else { - /* Clear result in case of error */ - for (i = 0, vert = grid->verts; i < num_cells; i++, vert++) { - zero_v3(vert->velocity_smooth); - } - return false; + /* Clear result in case of error */ + for (i = 0, vert = grid->verts; i < num_cells; i++, vert++) { + zero_v3(vert->velocity_smooth); } + + return false; } #if 0 /* XXX weighting is incorrect, disabled for now */ diff --git a/source/blender/simulation/intern/implicit.h b/source/blender/simulation/intern/implicit.h index 17dfb8b88b9..a3c8e5f34c4 100644 --- a/source/blender/simulation/intern/implicit.h +++ b/source/blender/simulation/intern/implicit.h @@ -17,8 +17,7 @@ * All rights reserved. */ -#ifndef __IMPLICIT_H__ -#define __IMPLICIT_H__ +#pragma once /** \file * \ingroup bph @@ -268,5 +267,3 @@ void SIM_hair_volume_vertex_grid_forces(struct HairGrid *grid, #ifdef __cplusplus } #endif - -#endif diff --git a/source/blender/simulation/intern/implicit_blender.c b/source/blender/simulation/intern/implicit_blender.c index 856572aa3f5..b4912492678 100644 --- a/source/blender/simulation/intern/implicit_blender.c +++ b/source/blender/simulation/intern/implicit_blender.c @@ -98,7 +98,7 @@ DO_INLINE void mul_fvector_S(float to[3], const float from[3], float scalar) } /* simple v^T * v product ("outer product") */ /* STATUS: HAS TO BE verified (*should* work) */ -DO_INLINE void mul_fvectorT_fvector(float to[3][3], float vectorA[3], float vectorB[3]) +DO_INLINE void mul_fvectorT_fvector(float to[3][3], const float vectorA[3], const float vectorB[3]) { mul_fvector_S(to[0], vectorB, vectorA[0]); mul_fvector_S(to[1], vectorB, vectorA[1]); @@ -156,7 +156,7 @@ DO_INLINE void cp_lfvector(float (*to)[3], float (*from)[3], unsigned int verts) memcpy(to, from, verts * sizeof(lfVector)); } /* init long vector with float[3] */ -DO_INLINE void init_lfvector(float (*fLongVector)[3], float vector[3], unsigned int verts) +DO_INLINE void init_lfvector(float (*fLongVector)[3], const float vector[3], unsigned int verts) { unsigned int i = 0; for (i = 0; i < verts; i++) { @@ -360,9 +360,9 @@ static void print_bfmatrix(fmatrix3x3 *m) # endif /* copy 3x3 matrix */ -DO_INLINE void cp_fmatrix(float to[3][3], float from[3][3]) +DO_INLINE void cp_fmatrix(float to[3][3], const float from[3][3]) { - // memcpy(to, from, sizeof (float) * 9); + // memcpy(to, from, sizeof(float[3][3])); copy_v3_v3(to[0], from[0]); copy_v3_v3(to[1], from[1]); copy_v3_v3(to[2], from[2]); @@ -429,7 +429,7 @@ DO_INLINE void mul_fmatrix_S(float matrix[3][3], float scalar) /* a vector multiplied by a 3x3 matrix */ /* STATUS: verified */ -DO_INLINE void mul_fvector_fmatrix(float *to, const float *from, float matrix[3][3]) +DO_INLINE void mul_fvector_fmatrix(float *to, const float *from, const float matrix[3][3]) { to[0] = matrix[0][0] * from[0] + matrix[1][0] * from[1] + matrix[2][0] * from[2]; to[1] = matrix[0][1] * from[0] + matrix[1][1] * from[1] + matrix[2][1] * from[2]; @@ -438,14 +438,16 @@ DO_INLINE void mul_fvector_fmatrix(float *to, const float *from, float matrix[3] /* 3x3 matrix multiplied by a vector */ /* STATUS: verified */ -DO_INLINE void mul_fmatrix_fvector(float *to, float matrix[3][3], float from[3]) +DO_INLINE void mul_fmatrix_fvector(float *to, const float matrix[3][3], const float from[3]) { to[0] = dot_v3v3(matrix[0], from); to[1] = dot_v3v3(matrix[1], from); to[2] = dot_v3v3(matrix[2], from); } /* 3x3 matrix addition with 3x3 matrix */ -DO_INLINE void add_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3]) +DO_INLINE void add_fmatrix_fmatrix(float to[3][3], + const float matrixA[3][3], + const float matrixB[3][3]) { add_v3_v3v3(to[0], matrixA[0], matrixB[0]); add_v3_v3v3(to[1], matrixA[1], matrixB[1]); @@ -453,14 +455,16 @@ DO_INLINE void add_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float ma } /* A -= B*x + C*y (3x3 matrix sub-addition with 3x3 matrix) */ DO_INLINE void subadd_fmatrixS_fmatrixS( - float to[3][3], float matrixA[3][3], float aS, float matrixB[3][3], float bS) + float to[3][3], const float matrixA[3][3], float aS, const float matrixB[3][3], float bS) { VECSUBADDSS(to[0], matrixA[0], aS, matrixB[0], bS); VECSUBADDSS(to[1], matrixA[1], aS, matrixB[1], bS); VECSUBADDSS(to[2], matrixA[2], aS, matrixB[2], bS); } /* A = B - C (3x3 matrix subtraction with 3x3 matrix) */ -DO_INLINE void sub_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3]) +DO_INLINE void sub_fmatrix_fmatrix(float to[3][3], + const float matrixA[3][3], + const float matrixB[3][3]) { sub_v3_v3v3(to[0], matrixA[0], matrixB[0]); sub_v3_v3v3(to[1], matrixA[1], matrixB[1]); @@ -471,14 +475,14 @@ DO_INLINE void sub_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float ma ///////////////////////////////////////////////////////////////// /* 3x3 matrix multiplied+added by a vector */ /* STATUS: verified */ -DO_INLINE void muladd_fmatrix_fvector(float to[3], float matrix[3][3], float from[3]) +DO_INLINE void muladd_fmatrix_fvector(float to[3], const float matrix[3][3], const float from[3]) { to[0] += dot_v3v3(matrix[0], from); to[1] += dot_v3v3(matrix[1], from); to[2] += dot_v3v3(matrix[2], from); } -DO_INLINE void muladd_fmatrixT_fvector(float to[3], float matrix[3][3], const float from[3]) +DO_INLINE void muladd_fmatrixT_fvector(float to[3], const float matrix[3][3], const float from[3]) { to[0] += matrix[0][0] * from[0] + matrix[1][0] * from[1] + matrix[2][0] * from[2]; to[1] += matrix[0][1] * from[0] + matrix[1][1] * from[1] + matrix[2][1] * from[2]; @@ -492,7 +496,7 @@ BLI_INLINE void outerproduct(float r[3][3], const float a[3], const float b[3]) mul_v3_v3fl(r[2], a, b[2]); } -BLI_INLINE void cross_m3_v3m3(float r[3][3], const float v[3], float m[3][3]) +BLI_INLINE void cross_m3_v3m3(float r[3][3], const float v[3], const float m[3][3]) { cross_v3_v3v3(r[0], v, m[0]); cross_v3_v3v3(r[1], v, m[1]); @@ -512,7 +516,7 @@ BLI_INLINE void cross_v3_identity(float r[3][3], const float v[3]) r[2][2] = 0.0f; } -BLI_INLINE void madd_m3_m3fl(float r[3][3], float m[3][3], float f) +BLI_INLINE void madd_m3_m3fl(float r[3][3], const float m[3][3], float f) { r[0][0] += m[0][0] * f; r[0][1] += m[0][1] * f; @@ -744,7 +748,10 @@ BLI_INLINE void root_to_world_v3(Implicit_Data *data, int index, float r[3], con mul_v3_m3v3(r, data->tfm[index].m, v); } -BLI_INLINE void world_to_root_m3(Implicit_Data *data, int index, float r[3][3], float m[3][3]) +BLI_INLINE void world_to_root_m3(Implicit_Data *data, + int index, + float r[3][3], + const float m[3][3]) { float trot[3][3]; copy_m3_m3(trot, data->tfm[index].m); @@ -752,7 +759,10 @@ BLI_INLINE void world_to_root_m3(Implicit_Data *data, int index, float r[3][3], mul_m3_m3m3(r, trot, m); } -BLI_INLINE void root_to_world_m3(Implicit_Data *data, int index, float r[3][3], float m[3][3]) +BLI_INLINE void root_to_world_m3(Implicit_Data *data, + int index, + float r[3][3], + const float m[3][3]) { mul_m3_m3m3(r, data->tfm[index].m, m); } @@ -1469,7 +1479,7 @@ void SIM_mass_spring_force_face_wind( Implicit_Data *data, int v1, int v2, int v3, const float (*winvec)[3]) { const float effector_scale = 0.02f; - int vs[3] = {v1, v2, v3}; + const int vs[3] = {v1, v2, v3}; float win[3], nor[3], area; float factor, base_force; float force[3]; @@ -1509,7 +1519,7 @@ void SIM_mass_spring_force_face_extern( Implicit_Data *data, int v1, int v2, int v3, const float (*forcevec)[3]) { const float effector_scale = 0.02f; - int vs[3] = {v1, v2, v3}; + const int vs[3] = {v1, v2, v3}; float nor[3], area; float factor, base_force[3]; float force[3][3]; @@ -1711,9 +1721,8 @@ BLI_INLINE float fbstar(float length, float L, float kb, float cb) if (tempfb_fl < fbstar_fl) { return fbstar_fl; } - else { - return tempfb_fl; - } + + return tempfb_fl; } // function to calculae bending spring force (taken from Choi & Co) @@ -1725,9 +1734,8 @@ BLI_INLINE float fbstar_jacobi(float length, float L, float kb, float cb) if (tempfb_fl < fbstar_fl) { return -cb; } - else { - return -kb * fbderiv(length, L); - } + + return -kb * fbderiv(length, L); } /* calculate elonglation */ @@ -1763,8 +1771,12 @@ BLI_INLINE bool spring_length(Implicit_Data *data, return true; } -BLI_INLINE void apply_spring( - Implicit_Data *data, int i, int j, const float f[3], float dfdx[3][3], float dfdv[3][3]) +BLI_INLINE void apply_spring(Implicit_Data *data, + int i, + int j, + const float f[3], + const float dfdx[3][3], + const float dfdv[3][3]) { int block_ij = SIM_mass_spring_add_block(data, i, j); @@ -1864,9 +1876,8 @@ bool SIM_mass_spring_force_spring_bending( return true; } - else { - return false; - } + + return false; } BLI_INLINE void poly_avg(lfVector *data, const int *inds, int len, float r_avg[3]) @@ -1902,7 +1913,7 @@ BLI_INLINE void edge_norm(lfVector *data, int i, int j, float r_dir[3]) normalize_v3(r_dir); } -BLI_INLINE float bend_angle(float dir_a[3], float dir_b[3], float dir_e[3]) +BLI_INLINE float bend_angle(const float dir_a[3], const float dir_b[3], const float dir_e[3]) { float cos, sin; float tmp[3]; @@ -2352,9 +2363,8 @@ bool SIM_mass_spring_force_spring_goal(Implicit_Data *data, return true; } - else { - return false; - } + + return false; } #endif /* IMPLICIT_SOLVER_BLENDER */ diff --git a/source/blender/simulation/intern/particle_allocator.cc b/source/blender/simulation/intern/particle_allocator.cc index e47a6354d81..91ca667a239 100644 --- a/source/blender/simulation/intern/particle_allocator.cc +++ b/source/blender/simulation/intern/particle_allocator.cc @@ -71,9 +71,9 @@ fn::MutableAttributesRef ParticleAllocator::allocate(int size) } else if (name == "Hash") { MutableSpan<int> hashes = attributes.get<int>("Hash"); - RandomNumberGenerator rng(hash_seed_ ^ (uint32_t)next_id_); + RandomNumberGenerator rng(hash_seed_ ^ static_cast<uint32_t>(next_id_)); for (int pindex : IndexRange(size)) { - hashes[pindex] = (int)rng.get_uint32(); + hashes[pindex] = static_cast<int>(rng.get_uint32()); } } else { diff --git a/source/blender/simulation/intern/particle_allocator.hh b/source/blender/simulation/intern/particle_allocator.hh index 1c412508fe6..c0bbdb845d9 100644 --- a/source/blender/simulation/intern/particle_allocator.hh +++ b/source/blender/simulation/intern/particle_allocator.hh @@ -14,8 +14,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#ifndef __SIM_PARTICLE_ALLOCATOR_HH__ -#define __SIM_PARTICLE_ALLOCATOR_HH__ +#pragma once #include "BLI_array.hh" #include "BLI_vector.hh" @@ -97,5 +96,3 @@ class ParticleAllocator : NonCopyable, NonMovable { }; } // namespace blender::sim - -#endif /* __SIM_PARTICLE_ALLOCATOR_HH__ */ diff --git a/source/blender/simulation/intern/particle_function.cc b/source/blender/simulation/intern/particle_function.cc index 035e6d50e21..69977eb2054 100644 --- a/source/blender/simulation/intern/particle_function.cc +++ b/source/blender/simulation/intern/particle_function.cc @@ -102,9 +102,8 @@ fn::GVSpan ParticleFunctionEvaluator::get(int output_index, StringRef expected_n if (particle_fn_.output_is_global_[output_index]) { return fn::GVSpan::FromSingleWithMaxSize(type, buffer); } - else { - return fn::GVSpan(fn::GSpan(type, buffer, mask_.min_array_size())); - } + + return fn::GVSpan(fn::GSpan(type, buffer, mask_.min_array_size())); } void ParticleFunctionEvaluator::compute_globals() diff --git a/source/blender/simulation/intern/particle_function.hh b/source/blender/simulation/intern/particle_function.hh index c9b35640b47..ead4e6f3c31 100644 --- a/source/blender/simulation/intern/particle_function.hh +++ b/source/blender/simulation/intern/particle_function.hh @@ -14,8 +14,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#ifndef __SIM_PARTICLE_FUNCTION_HH__ -#define __SIM_PARTICLE_FUNCTION_HH__ +#pragma once #include "FN_attributes_ref.hh" #include "FN_multi_function.hh" @@ -93,5 +92,3 @@ class ParticleFunctionEvaluator { }; } // namespace blender::sim - -#endif /* __SIM_PARTICLE_FUNCTION_HH__ */ diff --git a/source/blender/simulation/intern/particle_mesh_emitter.cc b/source/blender/simulation/intern/particle_mesh_emitter.cc index c1482a29cb7..3d43d4d8001 100644 --- a/source/blender/simulation/intern/particle_mesh_emitter.cc +++ b/source/blender/simulation/intern/particle_mesh_emitter.cc @@ -233,14 +233,14 @@ static BLI_NOINLINE bool compute_new_particle_attributes(ParticleEmitterContext if (settings.object->type != OB_MESH) { return false; } - Mesh &mesh = *(Mesh *)settings.object->data; + Mesh &mesh = *static_cast<Mesh *>(settings.object->data); if (mesh.totvert == 0) { return false; } const float start_time = context.emit_interval.start(); const uint32_t seed = DefaultHash<StringRef>{}(state.head.name); - RandomNumberGenerator rng{(*(uint32_t *)&start_time) ^ seed}; + RandomNumberGenerator rng{*reinterpret_cast<const uint32_t *>(&start_time) ^ seed}; compute_birth_times(settings.rate, context.emit_interval, state, r_birth_times); const int particle_amount = r_birth_times.size(); @@ -346,6 +346,16 @@ void ParticleMeshEmitter::emit(ParticleEmitterContext &context) const attributes.get<float3>("Position").copy_from(new_positions); attributes.get<float3>("Velocity").copy_from(new_velocities); attributes.get<float>("Birth Time").copy_from(new_birth_times); + + if (action_ != nullptr) { + ParticleChunkContext particles{ + *context.solve_context.state_map.lookup<ParticleSimulationState>(name), + IndexRange(amount), + attributes, + nullptr}; + ParticleActionContext action_context{context.solve_context, particles}; + action_->execute(action_context); + } } } diff --git a/source/blender/simulation/intern/particle_mesh_emitter.hh b/source/blender/simulation/intern/particle_mesh_emitter.hh index 601697c9986..cdcf2a34e16 100644 --- a/source/blender/simulation/intern/particle_mesh_emitter.hh +++ b/source/blender/simulation/intern/particle_mesh_emitter.hh @@ -14,8 +14,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#ifndef __SIM_PARTICLE_MESH_EMITTER_HH__ -#define __SIM_PARTICLE_MESH_EMITTER_HH__ +#pragma once #include "simulation_solver_influences.hh" @@ -28,14 +27,17 @@ class ParticleMeshEmitter final : public ParticleEmitter { std::string own_state_name_; Array<std::string> particle_names_; const fn::MultiFunction &inputs_fn_; + const ParticleAction *action_; public: ParticleMeshEmitter(std::string own_state_name, Array<std::string> particle_names, - const fn::MultiFunction &inputs_fn) + const fn::MultiFunction &inputs_fn, + const ParticleAction *action) : own_state_name_(std::move(own_state_name)), particle_names_(particle_names), - inputs_fn_(inputs_fn) + inputs_fn_(inputs_fn), + action_(action) { } @@ -45,5 +47,3 @@ class ParticleMeshEmitter final : public ParticleEmitter { }; } // namespace blender::sim - -#endif /* __SIM_PARTICLE_MESH_EMITTER_HH__ */ diff --git a/source/blender/simulation/intern/simulation_collect_influences.cc b/source/blender/simulation/intern/simulation_collect_influences.cc index 4d339f9e323..818415e5d88 100644 --- a/source/blender/simulation/intern/simulation_collect_influences.cc +++ b/source/blender/simulation/intern/simulation_collect_influences.cc @@ -367,6 +367,17 @@ static const ParticleFunction *create_particle_function_for_inputs( return &particle_fn; } +static const ParticleFunction *create_particle_function_for_inputs( + CollectContext &context, Span<const DInputSocket *> dsockets_to_compute) +{ + Vector<const MFInputSocket *> sockets_to_compute; + for (const DInputSocket *dsocket : dsockets_to_compute) { + const MFInputSocket &socket = context.network_map.lookup_dummy(*dsocket); + sockets_to_compute.append(&socket); + } + return create_particle_function_for_inputs(context, sockets_to_compute); +} + class ParticleFunctionForce : public ParticleForce { private: const ParticleFunction &particle_fn_; @@ -401,11 +412,8 @@ static void create_forces_for_particle_simulation(CollectContext &context, continue; } - const MFInputSocket &force_socket = context.network_map.lookup_dummy( - origin_node.input(0, "Force")); - - const ParticleFunction *particle_fn = create_particle_function_for_inputs(context, - {&force_socket}); + const ParticleFunction *particle_fn = create_particle_function_for_inputs( + context, {&origin_node.input(0, "Force")}); if (particle_fn == nullptr) { continue; @@ -434,7 +442,7 @@ static ParticleEmitter *create_particle_emitter(CollectContext &context, const D return nullptr; } - Array<const MFInputSocket *> input_sockets{dnode.inputs().size()}; + Array<const MFInputSocket *> input_sockets{2}; for (int i : input_sockets.index_range()) { input_sockets[i] = &context.network_map.lookup_dummy(dnode.input(i)); } @@ -446,10 +454,13 @@ static ParticleEmitter *create_particle_emitter(CollectContext &context, const D MultiFunction &inputs_fn = context.resources.construct<MFNetworkEvaluator>( AT, Span<const MFOutputSocket *>(), input_sockets.as_span()); + const ParticleAction *birth_action = create_particle_action( + context, dnode.input(2, "Execute"), names); + StringRefNull own_state_name = get_identifier(context, dnode); context.required_states.add(own_state_name, SIM_TYPE_NAME_PARTICLE_MESH_EMITTER); ParticleEmitter &emitter = context.resources.construct<ParticleMeshEmitter>( - AT, own_state_name, names.as_span(), inputs_fn); + AT, own_state_name, names.as_span(), inputs_fn, birth_action); return &emitter; } @@ -490,15 +501,10 @@ static void collect_time_step_events(CollectContext &context) { for (const DNode *event_dnode : nodes_by_type(context, "SimulationNodeParticleTimeStepEvent")) { const DInputSocket &execute_input = event_dnode->input(0); - if (execute_input.linked_sockets().size() != 1) { - continue; - } - Array<StringRefNull> particle_names = find_linked_particle_simulations(context, event_dnode->output(0)); - const DOutputSocket &execute_source = *execute_input.linked_sockets()[0]; - const ParticleAction *action = create_particle_action(context, execute_source, particle_names); + const ParticleAction *action = create_particle_action(context, execute_input, particle_names); if (action == nullptr) { continue; } @@ -570,6 +576,10 @@ class SetParticleAttributeAction : public ParticleAction { cpp_type_.copy_to_initialized_indices( value_array.data(), attribute_array->data(), context.particles.index_mask); } + + if (attribute_name_ == "Velocity") { + context.particles.update_diffs_after_velocity_change(); + } } }; @@ -595,21 +605,28 @@ static const ParticleAction *create_set_particle_attribute_action( CollectContext &context, const DOutputSocket &dsocket, Span<StringRefNull> particle_names) { const DNode &dnode = dsocket.node(); + + const ParticleAction *previous_action = create_particle_action( + context, dnode.input(0), particle_names); + MFInputSocket &name_socket = context.network_map.lookup_dummy(dnode.input(1)); MFInputSocket &value_socket = name_socket.node().input(1); std::optional<Array<std::string>> names = compute_global_string_inputs(context.network_map, {&name_socket}); if (!names.has_value()) { - return nullptr; + return previous_action; } std::string attribute_name = (*names)[0]; + if (attribute_name.empty()) { + return previous_action; + } const CPPType &attribute_type = value_socket.data_type().single_type(); const ParticleFunction *inputs_fn = create_particle_function_for_inputs(context, {&value_socket}); if (inputs_fn == nullptr) { - return nullptr; + return previous_action; } for (StringRef particle_name : particle_names) { @@ -620,9 +637,6 @@ static const ParticleAction *create_set_particle_attribute_action( ParticleAction &this_action = context.resources.construct<SetParticleAttributeAction>( AT, attribute_name, attribute_type, *inputs_fn); - const ParticleAction *previous_action = create_particle_action( - context, dnode.input(0), particle_names); - return concatenate_actions(context, {previous_action, &this_action}); } @@ -674,12 +688,18 @@ class ParticleConditionAction : public ParticleAction { } if (action_true_ != nullptr) { - ParticleChunkContext chunk_context{true_indices.as_span(), context.particles.attributes}; + ParticleChunkContext chunk_context{context.particles.state, + true_indices.as_span(), + context.particles.attributes, + context.particles.integration}; ParticleActionContext action_context{context.solve_context, chunk_context}; action_true_->execute(action_context); } if (action_false_ != nullptr) { - ParticleChunkContext chunk_context{false_indices.as_span(), context.particles.attributes}; + ParticleChunkContext chunk_context{context.particles.state, + false_indices.as_span(), + context.particles.attributes, + context.particles.integration}; ParticleActionContext action_context{context.solve_context, chunk_context}; action_false_->execute(action_context); } @@ -692,10 +712,9 @@ static const ParticleAction *create_particle_condition_action(CollectContext &co Span<StringRefNull> particle_names) { const DNode &dnode = dsocket.node(); - MFInputSocket &condition_socket = context.network_map.lookup_dummy(dnode.input(0)); - const ParticleFunction *inputs_fn = create_particle_function_for_inputs(context, - {&condition_socket}); + const ParticleFunction *inputs_fn = create_particle_function_for_inputs( + context, {&dnode.input(0, "Condition")}); if (inputs_fn == nullptr) { return nullptr; } @@ -712,17 +731,32 @@ static const ParticleAction *create_particle_condition_action(CollectContext &co AT, *inputs_fn, true_action, false_action); } +class KillParticleAction : public ParticleAction { + public: + void execute(ParticleActionContext &context) const override + { + MutableSpan<int> dead_states = context.particles.attributes.get<int>("Dead"); + for (int i : context.particles.index_mask) { + dead_states[i] = true; + } + } +}; + static const ParticleAction *create_particle_action(CollectContext &context, const DOutputSocket &dsocket, Span<StringRefNull> particle_names) { const DNode &dnode = dsocket.node(); - if (dnode.idname() == "SimulationNodeSetParticleAttribute") { + StringRef idname = dnode.idname(); + if (idname == "SimulationNodeSetParticleAttribute") { return create_set_particle_attribute_action(context, dsocket, particle_names); } - if (dnode.idname() == "SimulationNodeExecuteCondition") { + if (idname == "SimulationNodeExecuteCondition") { return create_particle_condition_action(context, dsocket, particle_names); } + if (idname == "SimulationNodeKillParticle") { + return &context.resources.construct<KillParticleAction>(AT); + } return nullptr; } @@ -740,6 +774,7 @@ static void initialize_particle_attribute_builders(CollectContext &context) /* TODO: Use uint32_t, but we don't have a corresponding custom property type. */ attributes_builder.add<int>("Hash", 0); attributes_builder.add<float>("Birth Time", 0.0f); + attributes_builder.add<float>("Radius", 0.02f); context.influences.particle_attributes_builder.add_new(name, &attributes_builder); } } @@ -752,6 +787,93 @@ static void optimize_function_network(CollectContext &context) // WM_clipboard_text_set(network.to_dot().c_str(), false); } +class AgeReachedEvent : public ParticleEvent { + private: + std::string attribute_name_; + const ParticleFunction &inputs_fn_; + const ParticleAction &action_; + + public: + AgeReachedEvent(std::string attribute_name, + const ParticleFunction &inputs_fn, + const ParticleAction &action) + : attribute_name_(std::move(attribute_name)), inputs_fn_(inputs_fn), action_(action) + { + } + + void filter(ParticleEventFilterContext &context) const override + { + Span<float> birth_times = context.particles.attributes.get<float>("Birth Time"); + std::optional<Span<int>> has_been_triggered = context.particles.attributes.try_get<int>( + attribute_name_); + if (!has_been_triggered.has_value()) { + return; + } + + ParticleFunctionEvaluator evaluator{inputs_fn_, context.solve_context, context.particles}; + evaluator.compute(); + VSpan<float> trigger_ages = evaluator.get<float>(0, "Age"); + + const float end_time = context.particles.integration->end_time; + for (int i : context.particles.index_mask) { + if ((*has_been_triggered)[i]) { + continue; + } + const float trigger_age = trigger_ages[i]; + const float birth_time = birth_times[i]; + const float trigger_time = birth_time + trigger_age; + if (trigger_time > end_time) { + continue; + } + + const float duration = context.particles.integration->durations[i]; + TimeInterval interval(end_time - duration, duration); + const float time_factor = interval.safe_factor_at_time(trigger_time); + + context.factor_dst[i] = std::max<float>(0.0f, time_factor); + } + } + + void execute(ParticleActionContext &context) const override + { + MutableSpan<int> has_been_triggered = context.particles.attributes.get<int>(attribute_name_); + for (int i : context.particles.index_mask) { + has_been_triggered[i] = 1; + } + action_.execute(context); + } +}; + +static void collect_age_reached_events(CollectContext &context) +{ + for (const DNode *dnode : nodes_by_type(context, "SimulationNodeAgeReachedEvent")) { + const DInputSocket &age_input = dnode->input(0, "Age"); + const DInputSocket &execute_input = dnode->input(1, "Execute"); + Array<StringRefNull> particle_names = find_linked_particle_simulations(context, + dnode->output(0)); + const ParticleAction *action = create_particle_action(context, execute_input, particle_names); + if (action == nullptr) { + continue; + } + const ParticleFunction *inputs_fn = create_particle_function_for_inputs(context, {&age_input}); + if (inputs_fn == nullptr) { + continue; + } + + std::string attribute_name = get_identifier(context, *dnode); + const ParticleEvent &event = context.resources.construct<AgeReachedEvent>( + AT, attribute_name, *inputs_fn, *action); + for (StringRefNull particle_name : particle_names) { + const bool added_attribute = context.influences.particle_attributes_builder + .lookup_as(particle_name) + ->add<int>(attribute_name, 0); + if (added_attribute) { + context.influences.particle_events.add_as(particle_name, &event); + } + } + } +} + void collect_simulation_influences(Simulation &simulation, ResourceCollector &resources, SimulationInfluences &r_influences, @@ -773,6 +895,7 @@ void collect_simulation_influences(Simulation &simulation, collect_emitters(context); collect_birth_events(context); collect_time_step_events(context); + collect_age_reached_events(context); optimize_function_network(context); diff --git a/source/blender/simulation/intern/simulation_collect_influences.hh b/source/blender/simulation/intern/simulation_collect_influences.hh index caf5a8c4ffa..8673a308b04 100644 --- a/source/blender/simulation/intern/simulation_collect_influences.hh +++ b/source/blender/simulation/intern/simulation_collect_influences.hh @@ -14,8 +14,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#ifndef __SIM_SIMULATION_COLLECT_INFLUENCES_HH__ -#define __SIM_SIMULATION_COLLECT_INFLUENCES_HH__ +#pragma once #include "NOD_derived_node_tree.hh" @@ -64,5 +63,3 @@ void collect_simulation_influences(Simulation &simulation, RequiredStates &r_required_states); } // namespace blender::sim - -#endif /* __SIM_SIMULATION_COLLECT_INFLUENCES_HH__ */ diff --git a/source/blender/simulation/intern/simulation_solver.cc b/source/blender/simulation/intern/simulation_solver.cc index 3c159eb1c58..d53ccd2bd49 100644 --- a/source/blender/simulation/intern/simulation_solver.cc +++ b/source/blender/simulation/intern/simulation_solver.cc @@ -121,6 +121,171 @@ static void ensure_attributes_exist(ParticleSimulationState *state, const Attrib } } +BLI_NOINLINE static void apply_remaining_diffs(ParticleChunkContext &context) +{ + BLI_assert(context.integration != nullptr); + MutableSpan<float3> positions = context.attributes.get<float3>("Position"); + MutableSpan<float3> velocities = context.attributes.get<float3>("Velocity"); + + for (int i : context.index_mask) { + positions[i] += context.integration->position_diffs[i]; + velocities[i] += context.integration->velocity_diffs[i]; + } +} + +BLI_NOINLINE static void find_next_event_per_particle( + SimulationSolveContext &solve_context, + ParticleChunkContext &particles, + Span<const ParticleEvent *> events, + MutableSpan<int> r_next_event_indices, + MutableSpan<float> r_time_factors_to_next_event) +{ + r_next_event_indices.fill_indices(particles.index_mask, -1); + r_time_factors_to_next_event.fill_indices(particles.index_mask, 1.0f); + + Array<float> time_factors(particles.index_mask.min_array_size()); + for (int event_index : events.index_range()) { + time_factors.fill(-1.0f); + ParticleEventFilterContext event_context{solve_context, particles, time_factors}; + const ParticleEvent &event = *events[event_index]; + event.filter(event_context); + + for (int i : particles.index_mask) { + const float time_factor = time_factors[i]; + const float previously_smallest_time_factor = r_time_factors_to_next_event[i]; + if (time_factor >= 0.0f && time_factor <= previously_smallest_time_factor) { + r_time_factors_to_next_event[i] = time_factor; + r_next_event_indices[i] = event_index; + } + } + } +} + +BLI_NOINLINE static void forward_particles_to_next_event_or_end( + ParticleChunkContext &particles, Span<float> time_factors_to_next_event) +{ + MutableSpan<float3> positions = particles.attributes.get<float3>("Position"); + MutableSpan<float3> velocities = particles.attributes.get<float3>("Velocity"); + + MutableSpan<float3> position_diffs = particles.integration->position_diffs; + MutableSpan<float3> velocity_diffs = particles.integration->velocity_diffs; + MutableSpan<float> durations = particles.integration->durations; + + for (int i : particles.index_mask) { + const float time_factor = time_factors_to_next_event[i]; + positions[i] += position_diffs[i] * time_factor; + velocities[i] += velocity_diffs[i] * time_factor; + + const float remaining_time_factor = 1.0f - time_factor; + position_diffs[i] *= remaining_time_factor; + velocity_diffs[i] *= remaining_time_factor; + durations[i] *= remaining_time_factor; + } +} + +BLI_NOINLINE static void group_particles_by_event( + IndexMask mask, + Span<int> next_event_indices, + MutableSpan<Vector<int64_t>> r_particles_per_event) +{ + for (int i : mask) { + int event_index = next_event_indices[i]; + if (event_index >= 0) { + r_particles_per_event[event_index].append(i); + } + } +} + +BLI_NOINLINE static void execute_events(SimulationSolveContext &solve_context, + ParticleChunkContext &all_particles, + Span<const ParticleEvent *> events, + Span<Vector<int64_t>> particles_per_event) +{ + for (int event_index : events.index_range()) { + Span<int64_t> pindices = particles_per_event[event_index]; + if (pindices.is_empty()) { + continue; + } + + const ParticleEvent &event = *events[event_index]; + ParticleChunkContext particles{ + all_particles.state, pindices, all_particles.attributes, all_particles.integration}; + ParticleActionContext action_context{solve_context, particles}; + event.execute(action_context); + } +} + +BLI_NOINLINE static void find_unfinished_particles(IndexMask index_mask, + Span<float> time_factors_to_next_event, + Vector<int64_t> &r_unfinished_pindices) +{ + for (int i : index_mask) { + float time_factor = time_factors_to_next_event[i]; + if (time_factor < 1.0f) { + r_unfinished_pindices.append(i); + } + } +} + +BLI_NOINLINE static void simulate_to_next_event(SimulationSolveContext &solve_context, + ParticleChunkContext &particles, + Span<const ParticleEvent *> events, + Vector<int64_t> &r_unfinished_pindices) +{ + int array_size = particles.index_mask.min_array_size(); + Array<int> next_event_indices(array_size); + Array<float> time_factors_to_next_event(array_size); + + find_next_event_per_particle( + solve_context, particles, events, next_event_indices, time_factors_to_next_event); + + forward_particles_to_next_event_or_end(particles, time_factors_to_next_event); + + Array<Vector<int64_t>> particles_per_event(events.size()); + group_particles_by_event(particles.index_mask, next_event_indices, particles_per_event); + + execute_events(solve_context, particles, events, particles_per_event); + find_unfinished_particles( + particles.index_mask, time_factors_to_next_event, r_unfinished_pindices); +} + +BLI_NOINLINE static void simulate_with_max_n_events(SimulationSolveContext &solve_context, + ParticleSimulationState &state, + ParticleChunkContext &particles, + int max_events) +{ + Span<const ParticleEvent *> events = solve_context.influences.particle_events.lookup_as( + state.head.name); + if (events.size() == 0) { + apply_remaining_diffs(particles); + return; + } + + Vector<int64_t> unfininished_pindices = particles.index_mask.indices(); + for (int iteration : IndexRange(max_events)) { + UNUSED_VARS(iteration); + if (unfininished_pindices.is_empty()) { + break; + } + + Vector<int64_t> new_unfinished_pindices; + ParticleChunkContext remaining_particles{particles.state, + unfininished_pindices.as_span(), + particles.attributes, + particles.integration}; + simulate_to_next_event(solve_context, remaining_particles, events, new_unfinished_pindices); + unfininished_pindices = std::move(new_unfinished_pindices); + } + + if (!unfininished_pindices.is_empty()) { + ParticleChunkContext remaining_particles{particles.state, + unfininished_pindices.as_span(), + particles.attributes, + particles.integration}; + apply_remaining_diffs(remaining_particles); + } +} + BLI_NOINLINE static void simulate_particle_chunk(SimulationSolveContext &solve_context, ParticleSimulationState &state, MutableAttributesRef attributes, @@ -132,7 +297,7 @@ BLI_NOINLINE static void simulate_particle_chunk(SimulationSolveContext &solve_c Span<const ParticleAction *> begin_actions = solve_context.influences.particle_time_step_begin_actions.lookup_as(state.head.name); for (const ParticleAction *action : begin_actions) { - ParticleChunkContext particles{IndexMask(particle_amount), attributes}; + ParticleChunkContext particles{state, IndexMask(particle_amount), attributes}; ParticleActionContext action_context{solve_context, particles}; action->execute(action_context); } @@ -141,30 +306,32 @@ BLI_NOINLINE static void simulate_particle_chunk(SimulationSolveContext &solve_c Span<const ParticleForce *> forces = solve_context.influences.particle_forces.lookup_as( state.head.name); for (const ParticleForce *force : forces) { - ParticleChunkContext particles{IndexMask(particle_amount), attributes}; + ParticleChunkContext particles{state, IndexMask(particle_amount), attributes}; ParticleForceContext particle_force_context{solve_context, particles, force_vectors}; force->add_force(particle_force_context); } - MutableSpan<float3> positions = attributes.get<float3>("Position"); MutableSpan<float3> velocities = attributes.get<float3>("Velocity"); - MutableSpan<float> birth_times = attributes.get<float>("Birth Time"); - MutableSpan<int> dead_states = attributes.get<int>("Dead"); + Array<float3> position_diffs(particle_amount); + Array<float3> velocity_diffs(particle_amount); for (int i : IndexRange(particle_amount)) { const float time_step = remaining_durations[i]; - velocities[i] += force_vectors[i] * time_step; - positions[i] += velocities[i] * time_step; - - if (end_time - birth_times[i] > 2) { - dead_states[i] = true; - } + velocity_diffs[i] = force_vectors[i] * time_step; + position_diffs[i] = (velocities[i] + velocity_diffs[i] / 2.0f) * time_step; } + ParticleChunkIntegrationContext integration_context = { + position_diffs, velocity_diffs, remaining_durations, end_time}; + ParticleChunkContext particle_chunk_context{ + state, IndexMask(particle_amount), attributes, &integration_context}; + + simulate_with_max_n_events(solve_context, state, particle_chunk_context, 10); + Span<const ParticleAction *> end_actions = solve_context.influences.particle_time_step_end_actions.lookup_as(state.head.name); for (const ParticleAction *action : end_actions) { - ParticleChunkContext particles{IndexMask(particle_amount), attributes}; + ParticleChunkContext particles{state, IndexMask(particle_amount), attributes}; ParticleActionContext action_context{solve_context, particles}; action->execute(action_context); } @@ -326,7 +493,7 @@ void solve_simulation_time_step(Simulation &simulation, Span<const ParticleAction *> actions = influences.particle_birth_actions.lookup_as( state->head.name); for (const ParticleAction *action : actions) { - ParticleChunkContext chunk_context{IndexRange(attributes.size()), attributes}; + ParticleChunkContext chunk_context{*state, IndexRange(attributes.size()), attributes}; ParticleActionContext action_context{solve_context, chunk_context}; action->execute(action_context); } diff --git a/source/blender/simulation/intern/simulation_solver.hh b/source/blender/simulation/intern/simulation_solver.hh index 9d30ea87731..2cf8eb2aa27 100644 --- a/source/blender/simulation/intern/simulation_solver.hh +++ b/source/blender/simulation/intern/simulation_solver.hh @@ -14,8 +14,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#ifndef __SIM_SIMULATION_SOLVER_HH__ -#define __SIM_SIMULATION_SOLVER_HH__ +#pragma once #include "simulation_collect_influences.hh" @@ -36,5 +35,3 @@ void solve_simulation_time_step(Simulation &simulation, float time_step); } // namespace blender::sim - -#endif /* __SIM_SIMULATION_SOLVER_HH__ */ diff --git a/source/blender/simulation/intern/simulation_solver_influences.cc b/source/blender/simulation/intern/simulation_solver_influences.cc index 75c2c820651..3485d7c7bfb 100644 --- a/source/blender/simulation/intern/simulation_solver_influences.cc +++ b/source/blender/simulation/intern/simulation_solver_influences.cc @@ -32,6 +32,10 @@ ParticleAction::~ParticleAction() { } +ParticleEvent::~ParticleEvent() +{ +} + DependencyAnimations::~DependencyAnimations() { } diff --git a/source/blender/simulation/intern/simulation_solver_influences.hh b/source/blender/simulation/intern/simulation_solver_influences.hh index d3c515bb6a0..7dc0b3b8c8d 100644 --- a/source/blender/simulation/intern/simulation_solver_influences.hh +++ b/source/blender/simulation/intern/simulation_solver_influences.hh @@ -14,8 +14,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#ifndef __SIM_SIMULATION_SOLVER_INFLUENCES_HH__ -#define __SIM_SIMULATION_SOLVER_INFLUENCES_HH__ +#pragma once #include "BLI_float3.hh" #include "BLI_float4x4.hh" @@ -45,6 +44,7 @@ using fn::MutableAttributesRef; struct ParticleEmitterContext; struct ParticleForceContext; struct ParticleActionContext; +struct ParticleEventFilterContext; class ParticleEmitter { public: @@ -64,11 +64,19 @@ class ParticleAction { virtual void execute(ParticleActionContext &context) const = 0; }; +class ParticleEvent { + public: + virtual ~ParticleEvent(); + virtual void filter(ParticleEventFilterContext &context) const = 0; + virtual void execute(ParticleActionContext &context) const = 0; +}; + struct SimulationInfluences { MultiValueMap<std::string, const ParticleForce *> particle_forces; MultiValueMap<std::string, const ParticleAction *> particle_birth_actions; MultiValueMap<std::string, const ParticleAction *> particle_time_step_begin_actions; MultiValueMap<std::string, const ParticleAction *> particle_time_step_end_actions; + MultiValueMap<std::string, const ParticleEvent *> particle_events; Map<std::string, AttributesInfoBuilder *> particle_attributes_builder; Vector<const ParticleEmitter *> particle_emitters; }; @@ -88,7 +96,7 @@ class SimulationStateMap { template<typename StateType> StateType *lookup(StringRef name) const { const char *type = BKE_simulation_get_state_type_name<StateType>(); - return (StateType *)this->lookup_name_type(name, type); + return reinterpret_cast<StateType *>(this->lookup_name_type(name, type)); } template<typename StateType> Span<StateType *> lookup() const @@ -157,9 +165,37 @@ class ParticleAllocators { } }; +struct ParticleChunkIntegrationContext { + MutableSpan<float3> position_diffs; + MutableSpan<float3> velocity_diffs; + MutableSpan<float> durations; + float end_time; +}; + struct ParticleChunkContext { + ParticleSimulationState &state; IndexMask index_mask; MutableAttributesRef attributes; + ParticleChunkIntegrationContext *integration = nullptr; + + void update_diffs_after_velocity_change() + { + if (integration == nullptr) { + return; + } + + Span<float> remaining_durations = integration->durations; + MutableSpan<float3> position_diffs = integration->position_diffs; + Span<float3> velocities = attributes.get<float3>("Velocity"); + + for (int i : index_mask) { + const float duration = remaining_durations[i]; + /* This is certainly not a perfect way to "re-integrate" the velocity, but it should be good + * enough for most use cases. Changing the velocity in an instant is not physically correct + * anyway. */ + position_diffs[i] = velocities[i] * duration; + } + } }; struct ParticleEmitterContext { @@ -189,6 +225,10 @@ struct ParticleActionContext { ParticleChunkContext &particles; }; -} // namespace blender::sim +struct ParticleEventFilterContext { + SimulationSolveContext &solve_context; + ParticleChunkContext &particles; + MutableSpan<float> factor_dst; +}; -#endif /* __SIM_SIMULATION_SOLVER_INFLUENCES_HH__ */ +} // namespace blender::sim diff --git a/source/blender/simulation/intern/simulation_update.cc b/source/blender/simulation/intern/simulation_update.cc index 32b582977d0..452b222bb08 100644 --- a/source/blender/simulation/intern/simulation_update.cc +++ b/source/blender/simulation/intern/simulation_update.cc @@ -143,7 +143,7 @@ class SampledDependencyAnimations : public DependencyAnimations { const float factor = simulation_time_interval_.factor_at_time(simulation_time); BLI_assert(factor > 0.0f && factor < 1.0f); const float scaled_factor = factor * (cached_transforms.size() - 1); - const int lower_sample = (int)scaled_factor; + const int lower_sample = static_cast<int>(scaled_factor); const int upper_sample = lower_sample + 1; const float mix_factor = scaled_factor - lower_sample; r_transforms[i] = float4x4::interpolate( @@ -205,7 +205,7 @@ static void prepare_dependency_animations(Depsgraph &depsgraph, if (GS(id_cow->name) != ID_OB) { continue; } - Object &object_cow = *(Object *)id_cow; + Object &object_cow = *reinterpret_cast<Object *>(id_cow); constexpr int sample_count = 10; Array<float4x4, sample_count> transforms(sample_count); sample_object_transforms(object_cow, depsgraph, scene, scene_frame_interval, transforms); @@ -233,7 +233,8 @@ void update_simulation_in_depsgraph(Depsgraph *depsgraph, return; } - Simulation *simulation_orig = (Simulation *)DEG_get_original_id(&simulation_cow->id); + Simulation *simulation_orig = reinterpret_cast<Simulation *>( + DEG_get_original_id(&simulation_cow->id)); ResourceCollector resources; SimulationInfluences influences; @@ -317,8 +318,8 @@ bool update_simulation_dependencies(Simulation *simulation) } used_handles.add_new(next_handle); - SimulationDependency *dependency = (SimulationDependency *)MEM_callocN(sizeof(*dependency), - AT); + SimulationDependency *dependency = static_cast<SimulationDependency *>( + MEM_callocN(sizeof(*dependency), AT)); id_us_plus(id); dependency->id = id; dependency->handle = next_handle; diff --git a/source/blender/simulation/intern/time_interval.hh b/source/blender/simulation/intern/time_interval.hh index 5996dc5d25b..034628fa9be 100644 --- a/source/blender/simulation/intern/time_interval.hh +++ b/source/blender/simulation/intern/time_interval.hh @@ -14,8 +14,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#ifndef __SIM_TIME_INTERVAL_HH__ -#define __SIM_TIME_INTERVAL_HH__ +#pragma once #include "BLI_utildefines.h" @@ -89,5 +88,3 @@ class TimeInterval { }; } // namespace blender::sim - -#endif /* __SIM_TIME_INTERVAL_HH__ */ |