Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/simulation')
-rw-r--r--source/blender/simulation/SIM_mass_spring.h5
-rw-r--r--source/blender/simulation/SIM_simulation_update.hh5
-rw-r--r--source/blender/simulation/intern/ConstrainedConjugateGradient.h5
-rw-r--r--source/blender/simulation/intern/eigen_utils.h5
-rw-r--r--source/blender/simulation/intern/hair_volume.cpp16
-rw-r--r--source/blender/simulation/intern/implicit.h5
-rw-r--r--source/blender/simulation/intern/implicit_blender.c74
-rw-r--r--source/blender/simulation/intern/particle_allocator.cc4
-rw-r--r--source/blender/simulation/intern/particle_allocator.hh5
-rw-r--r--source/blender/simulation/intern/particle_function.cc5
-rw-r--r--source/blender/simulation/intern/particle_function.hh5
-rw-r--r--source/blender/simulation/intern/particle_mesh_emitter.cc14
-rw-r--r--source/blender/simulation/intern/particle_mesh_emitter.hh12
-rw-r--r--source/blender/simulation/intern/simulation_collect_influences.cc173
-rw-r--r--source/blender/simulation/intern/simulation_collect_influences.hh5
-rw-r--r--source/blender/simulation/intern/simulation_solver.cc193
-rw-r--r--source/blender/simulation/intern/simulation_solver.hh5
-rw-r--r--source/blender/simulation/intern/simulation_solver_influences.cc4
-rw-r--r--source/blender/simulation/intern/simulation_solver_influences.hh50
-rw-r--r--source/blender/simulation/intern/simulation_update.cc11
-rw-r--r--source/blender/simulation/intern/time_interval.hh5
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__ */