Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/simulation.cc
| Show All 25 Lines | |||||
| #include "DNA_defaults.h" | #include "DNA_defaults.h" | ||||
| #include "DNA_scene_types.h" | #include "DNA_scene_types.h" | ||||
| #include "DNA_simulation_types.h" | #include "DNA_simulation_types.h" | ||||
| #include "BLI_compiler_compat.h" | #include "BLI_compiler_compat.h" | ||||
| #include "BLI_float3.hh" | #include "BLI_float3.hh" | ||||
| #include "BLI_listbase.h" | #include "BLI_listbase.h" | ||||
| #include "BLI_math.h" | #include "BLI_math.h" | ||||
| #include "BLI_rand.h" | |||||
| #include "BLI_span.hh" | #include "BLI_span.hh" | ||||
| #include "BLI_string.h" | #include "BLI_string.h" | ||||
| #include "BLI_utildefines.h" | #include "BLI_utildefines.h" | ||||
| #include "BKE_anim_data.h" | #include "BKE_anim_data.h" | ||||
| #include "BKE_animsys.h" | #include "BKE_animsys.h" | ||||
| #include "BKE_customdata.h" | #include "BKE_customdata.h" | ||||
| #include "BKE_idtype.h" | #include "BKE_idtype.h" | ||||
| ▲ Show 20 Lines • Show All 50 Lines • ▼ Show 20 Lines | BKE_id_copy_ex(bmain, | ||||
| flag_private_id_data); | flag_private_id_data); | ||||
| } | } | ||||
| BLI_listbase_clear(&simulation_dst->states); | BLI_listbase_clear(&simulation_dst->states); | ||||
| LISTBASE_FOREACH (const SimulationState *, state_src, &simulation_src->states) { | LISTBASE_FOREACH (const SimulationState *, state_src, &simulation_src->states) { | ||||
| switch ((eSimulationStateType)state_src->type) { | switch ((eSimulationStateType)state_src->type) { | ||||
| case SIM_STATE_TYPE_PARTICLES: { | case SIM_STATE_TYPE_PARTICLES: { | ||||
| ParticleSimulationState *particle_state_src = (ParticleSimulationState *)state_src; | |||||
| ParticleSimulationState *particle_state_dst = (ParticleSimulationState *)MEM_callocN( | ParticleSimulationState *particle_state_dst = (ParticleSimulationState *)MEM_callocN( | ||||
| sizeof(ParticleSimulationState), __func__); | sizeof(ParticleSimulationState), __func__); | ||||
| CustomData_reset(&particle_state_dst->attributes); | CustomData_copy(&particle_state_src->attributes, | ||||
| &particle_state_dst->attributes, | |||||
| CD_MASK_ALL, | |||||
| CD_DUPLICATE, | |||||
| particle_state_src->tot_particles); | |||||
| particle_state_dst->tot_particles = particle_state_src->tot_particles; | |||||
| particle_state_dst->current_frame = particle_state_src->current_frame; | |||||
| BLI_addtail(&simulation_dst->states, particle_state_dst); | BLI_addtail(&simulation_dst->states, particle_state_dst); | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 59 Lines • ▼ Show 20 Lines | |||||
| static MutableSpan<float3> get_particle_positions(ParticleSimulationState *state) | static MutableSpan<float3> get_particle_positions(ParticleSimulationState *state) | ||||
| { | { | ||||
| return MutableSpan<float3>( | return MutableSpan<float3>( | ||||
| (float3 *)CustomData_get_layer_named(&state->attributes, CD_LOCATION, "Position"), | (float3 *)CustomData_get_layer_named(&state->attributes, CD_LOCATION, "Position"), | ||||
| state->tot_particles); | state->tot_particles); | ||||
| } | } | ||||
| static MutableSpan<float> get_particle_speeds(ParticleSimulationState *state) | |||||
| { | |||||
| return MutableSpan<float>( | |||||
| (float *)CustomData_get_layer_named(&state->attributes, CD_PROP_FLOAT, "Speed"), | |||||
| state->tot_particles); | |||||
| } | |||||
| static void ensure_attributes_exist(ParticleSimulationState *state) | static void ensure_attributes_exist(ParticleSimulationState *state) | ||||
| { | { | ||||
| if (CustomData_get_layer_named(&state->attributes, CD_LOCATION, "Position") == nullptr) { | if (CustomData_get_layer_named(&state->attributes, CD_LOCATION, "Position") == nullptr) { | ||||
| CustomData_add_layer_named( | CustomData_add_layer_named( | ||||
| &state->attributes, CD_LOCATION, CD_CALLOC, nullptr, state->tot_particles, "Position"); | &state->attributes, CD_LOCATION, CD_CALLOC, nullptr, state->tot_particles, "Position"); | ||||
| } | } | ||||
| if (CustomData_get_layer_named(&state->attributes, CD_PROP_FLOAT, "Speed") == nullptr) { | |||||
| CustomData_add_layer_named( | |||||
| &state->attributes, CD_PROP_FLOAT, CD_CALLOC, nullptr, state->tot_particles, "Speed"); | |||||
| } | |||||
| } | } | ||||
| static void copy_particle_state_to_cow(ParticleSimulationState *state_orig, | static void copy_particle_state_to_cow(ParticleSimulationState *state_orig, | ||||
| ParticleSimulationState *state_cow) | ParticleSimulationState *state_cow) | ||||
| { | { | ||||
| ensure_attributes_exist(state_cow); | ensure_attributes_exist(state_cow); | ||||
| CustomData_free(&state_cow->attributes, state_cow->tot_particles); | CustomData_free(&state_cow->attributes, state_cow->tot_particles); | ||||
| CustomData_copy(&state_orig->attributes, | CustomData_copy(&state_orig->attributes, | ||||
| Show All 11 Lines | void BKE_simulation_data_update(Depsgraph *depsgraph, Scene *scene, Simulation *simulation) | ||||
| ParticleSimulationState *state_cow = (ParticleSimulationState *)simulation->states.first; | ParticleSimulationState *state_cow = (ParticleSimulationState *)simulation->states.first; | ||||
| ParticleSimulationState *state_orig = (ParticleSimulationState *)state_cow->head.orig_state; | ParticleSimulationState *state_orig = (ParticleSimulationState *)state_cow->head.orig_state; | ||||
| if (current_frame == state_cow->current_frame) { | if (current_frame == state_cow->current_frame) { | ||||
| return; | return; | ||||
| } | } | ||||
| /* Number of particles should be stored in the cache, but for now assume it is constant. */ | |||||
| state_cow->tot_particles = state_orig->tot_particles; | |||||
| CustomData_realloc(&state_cow->attributes, state_orig->tot_particles); | |||||
| ensure_attributes_exist(state_cow); | |||||
| PTCacheID pid_cow; | PTCacheID pid_cow; | ||||
| BKE_ptcache_id_from_sim_particles(&pid_cow, state_cow); | BKE_ptcache_id_from_sim_particles(&pid_cow, state_cow); | ||||
| BKE_ptcache_id_time(&pid_cow, scene, current_frame, nullptr, nullptr, nullptr); | BKE_ptcache_id_time(&pid_cow, scene, current_frame, nullptr, nullptr, nullptr); | ||||
| /* If successfull, this will read the state directly into the cow state. */ | /* If successfull, this will read the state directly into the cow state. */ | ||||
| int cache_result = BKE_ptcache_read(&pid_cow, current_frame, true); | int cache_result = BKE_ptcache_read(&pid_cow, current_frame, true); | ||||
| if (cache_result == PTCACHE_READ_EXACT) { | if (cache_result == PTCACHE_READ_EXACT) { | ||||
| state_cow->current_frame = current_frame; | state_cow->current_frame = current_frame; | ||||
| Show All 11 Lines | void BKE_simulation_data_update(Depsgraph *depsgraph, Scene *scene, Simulation *simulation) | ||||
| if (current_frame == 1) { | if (current_frame == 1) { | ||||
| state_orig->tot_particles = 100; | state_orig->tot_particles = 100; | ||||
| state_orig->current_frame = 1; | state_orig->current_frame = 1; | ||||
| CustomData_realloc(&state_orig->attributes, state_orig->tot_particles); | CustomData_realloc(&state_orig->attributes, state_orig->tot_particles); | ||||
| ensure_attributes_exist(state_orig); | ensure_attributes_exist(state_orig); | ||||
| MutableSpan<float3> positions = get_particle_positions(state_orig); | MutableSpan<float3> positions = get_particle_positions(state_orig); | ||||
| MutableSpan<float> speeds = get_particle_speeds(state_orig); | |||||
| for (uint i : positions.index_range()) { | for (uint i : positions.index_range()) { | ||||
| positions[i] = {i / 10.0f, 0, 0}; | positions[i] = {i / 10.0f, 0, 0}; | ||||
| speeds[i] = 1; | |||||
| } | } | ||||
| BKE_ptcache_write(&pid_orig, current_frame); | BKE_ptcache_write(&pid_orig, current_frame); | ||||
| copy_particle_state_to_cow(state_orig, state_cow); | copy_particle_state_to_cow(state_orig, state_cow); | ||||
| } | } | ||||
| else if (current_frame == state_orig->current_frame + 1) { | else if (current_frame == state_orig->current_frame + 1) { | ||||
| state_orig->current_frame = current_frame; | state_orig->current_frame = current_frame; | ||||
| ensure_attributes_exist(state_orig); | ensure_attributes_exist(state_orig); | ||||
| CustomData_realloc(&state_orig->attributes, ++state_orig->tot_particles); | |||||
| MutableSpan<float3> positions = get_particle_positions(state_orig); | MutableSpan<float3> positions = get_particle_positions(state_orig); | ||||
| for (float3 &position : positions) { | MutableSpan<float> speeds = get_particle_speeds(state_orig); | ||||
| position.z += 0.1f; | positions.last() = {2, 2, 0}; | ||||
| speeds.last() = 1; | |||||
| RNG *rng = BLI_rng_new(0); | |||||
| for (uint i : positions.index_range()) { | |||||
| float3 direction; | |||||
| BLI_rng_get_float_unit_v3(rng, direction); | |||||
| positions[i] += direction * speeds[i] * 0.1; | |||||
| speeds[i] *= 0.9f; | |||||
| } | } | ||||
| BLI_rng_free(rng); | |||||
| BKE_ptcache_write(&pid_orig, current_frame); | BKE_ptcache_write(&pid_orig, current_frame); | ||||
| copy_particle_state_to_cow(state_orig, state_cow); | copy_particle_state_to_cow(state_orig, state_cow); | ||||
| } | } | ||||
| } | } | ||||