Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/particle_system.c
| Show First 20 Lines • Show All 1,895 Lines • ▼ Show 20 Lines | if (spring_constant > 0.f) { | ||||
| else if (fluid->spring_frames == 0 || | else if (fluid->spring_frames == 0 || | ||||
| (pa->prev_state.time - pa->time) <= fluid->spring_frames) { | (pa->prev_state.time - pa->time) <= fluid->spring_frames) { | ||||
| ParticleSpring temp_spring; | ParticleSpring temp_spring; | ||||
| temp_spring.particle_index[0] = index; | temp_spring.particle_index[0] = index; | ||||
| temp_spring.particle_index[1] = pfn->index; | temp_spring.particle_index[1] = pfn->index; | ||||
| temp_spring.rest_length = (fluid->flag & SPH_CURRENT_REST_LENGTH) ? rij : rest_length; | temp_spring.rest_length = (fluid->flag & SPH_CURRENT_REST_LENGTH) ? rij : rest_length; | ||||
| temp_spring.delete_flag = 0; | temp_spring.delete_flag = 0; | ||||
| /* sph_spring_add is not thread-safe. - z0r */ | BLI_buffer_append(&sphdata->new_springs, ParticleSpring, temp_spring); | ||||
| sph_spring_add(psys[0], &temp_spring); | |||||
| } | } | ||||
| } | } | ||||
| else { /* PART_SPRING_HOOKES - Hooke's spring force */ | else { /* PART_SPRING_HOOKES - Hooke's spring force */ | ||||
| madd_v3_v3fl(force, vec, -10.f * spring_constant * (1.f - rij / h) * (rest_length - rij)); | madd_v3_v3fl(force, vec, -10.f * spring_constant * (1.f - rij / h) * (rest_length - rij)); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 205 Lines • ▼ Show 20 Lines | static void sphclassical_calc_dens(ParticleData *pa, float UNUSED(dfra), SPHData *sphdata) | ||||
| pa->sphdensity = min_ff(max_ff(data[0], fluid->rest_density * 0.9f), fluid->rest_density * 1.1f); | pa->sphdensity = min_ff(max_ff(data[0], fluid->rest_density * 0.9f), fluid->rest_density * 1.1f); | ||||
| } | } | ||||
| void psys_sph_init(ParticleSimulationData *sim, SPHData *sphdata) | void psys_sph_init(ParticleSimulationData *sim, SPHData *sphdata) | ||||
| { | { | ||||
| ParticleTarget *pt; | ParticleTarget *pt; | ||||
| int i; | int i; | ||||
| BLI_buffer_field_init(&sphdata->new_springs, ParticleSpring); | |||||
| // Add other coupled particle systems. | // Add other coupled particle systems. | ||||
| sphdata->psys[0] = sim->psys; | sphdata->psys[0] = sim->psys; | ||||
| for (i = 1, pt = sim->psys->targets.first; i < 10; i++, pt = (pt ? pt->next : NULL)) { | for (i = 1, pt = sim->psys->targets.first; i < 10; i++, pt = (pt ? pt->next : NULL)) { | ||||
| sphdata->psys[i] = pt ? psys_get_target_system(sim->ob, pt) : NULL; | sphdata->psys[i] = pt ? psys_get_target_system(sim->ob, pt) : NULL; | ||||
| } | } | ||||
| if (psys_uses_gravity(sim)) { | if (psys_uses_gravity(sim)) { | ||||
| sphdata->gravity = sim->scene->physics_settings.gravity; | sphdata->gravity = sim->scene->physics_settings.gravity; | ||||
| Show All 16 Lines | void psys_sph_init(ParticleSimulationData *sim, SPHData *sphdata) | ||||
| else { | else { | ||||
| /* SPH_SOLVER_CLASSICAL */ | /* SPH_SOLVER_CLASSICAL */ | ||||
| sphdata->force_cb = sphclassical_force_cb; | sphdata->force_cb = sphclassical_force_cb; | ||||
| sphdata->density_cb = sphclassical_density_accum_cb; | sphdata->density_cb = sphclassical_density_accum_cb; | ||||
| sphdata->hfac = 0.5f; | sphdata->hfac = 0.5f; | ||||
| } | } | ||||
| } | } | ||||
| static void psys_sph_flush_springs(SPHData *sphdata) | |||||
| { | |||||
| for (int i = 0; i < sphdata->new_springs.count; i++) { | |||||
| /* sph_spring_add is not thread-safe. - z0r */ | |||||
| sph_spring_add(sphdata->psys[0], &BLI_buffer_at(&sphdata->new_springs, ParticleSpring, i)); | |||||
| } | |||||
| BLI_buffer_field_free(&sphdata->new_springs); | |||||
| } | |||||
| void psys_sph_finalise(SPHData *sphdata) | void psys_sph_finalise(SPHData *sphdata) | ||||
| { | { | ||||
| psys_sph_flush_springs(sphdata); | |||||
| if (sphdata->eh) { | if (sphdata->eh) { | ||||
| BLI_edgehash_free(sphdata->eh, NULL); | BLI_edgehash_free(sphdata->eh, NULL); | ||||
| sphdata->eh = NULL; | sphdata->eh = NULL; | ||||
| } | } | ||||
| } | } | ||||
| /* Sample the density field at a point in space. */ | /* Sample the density field at a point in space. */ | ||||
| void psys_sph_density(BVHTree *tree, SPHData *sphdata, float co[3], float vars[2]) | void psys_sph_density(BVHTree *tree, SPHData *sphdata, float co[3], float vars[2]) | ||||
| { | { | ||||
| ParticleSystem **psys = sphdata->psys; | ParticleSystem **psys = sphdata->psys; | ||||
| SPHFluidSettings *fluid = psys[0]->part->fluid; | SPHFluidSettings *fluid = psys[0]->part->fluid; | ||||
| /* 4.0 seems to be a pretty good value */ | /* 4.0 seems to be a pretty good value */ | ||||
| float interaction_radius = fluid->radius * | float interaction_radius = fluid->radius * | ||||
| (fluid->flag & SPH_FAC_RADIUS ? 4.0f * psys[0]->part->size : 1.0f); | (fluid->flag & SPH_FAC_RADIUS ? 4.0f * psys[0]->part->size : 1.0f); | ||||
| ▲ Show 20 Lines • Show All 1,504 Lines • ▼ Show 20 Lines | typedef struct DynamicStepSolverTaskData { | ||||
| float cfra; | float cfra; | ||||
| float timestep; | float timestep; | ||||
| float dtime; | float dtime; | ||||
| SpinLock spin; | SpinLock spin; | ||||
| } DynamicStepSolverTaskData; | } DynamicStepSolverTaskData; | ||||
| static void dynamics_step_finalize_sphdata(void *__restrict UNUSED(userdata), | |||||
| void *__restrict userdata_chunk) | |||||
| { | |||||
| SPHData *sphdata = userdata_chunk; | |||||
| psys_sph_flush_springs(sphdata); | |||||
| } | |||||
| static void dynamics_step_sph_ddr_task_cb_ex(void *__restrict userdata, | static void dynamics_step_sph_ddr_task_cb_ex(void *__restrict userdata, | ||||
| const int p, | const int p, | ||||
| const TaskParallelTLS *__restrict tls) | const TaskParallelTLS *__restrict tls) | ||||
| { | { | ||||
| DynamicStepSolverTaskData *data = userdata; | DynamicStepSolverTaskData *data = userdata; | ||||
| ParticleSimulationData *sim = data->sim; | ParticleSimulationData *sim = data->sim; | ||||
| ParticleSystem *psys = sim->psys; | ParticleSystem *psys = sim->psys; | ||||
| ParticleSettings *part = psys->part; | ParticleSettings *part = psys->part; | ||||
| ▲ Show 20 Lines • Show All 270 Lines • ▼ Show 20 Lines | case PART_PHYS_FLUID: { | ||||
| /* Apply SPH forces using double-density relaxation algorithm | /* Apply SPH forces using double-density relaxation algorithm | ||||
| * (Clavat et. al.) */ | * (Clavat et. al.) */ | ||||
| TaskParallelSettings settings; | TaskParallelSettings settings; | ||||
| BLI_parallel_range_settings_defaults(&settings); | BLI_parallel_range_settings_defaults(&settings); | ||||
| settings.use_threading = (psys->totpart > 100); | settings.use_threading = (psys->totpart > 100); | ||||
| settings.userdata_chunk = &sphdata; | settings.userdata_chunk = &sphdata; | ||||
| settings.userdata_chunk_size = sizeof(sphdata); | settings.userdata_chunk_size = sizeof(sphdata); | ||||
| settings.func_finalize = dynamics_step_finalize_sphdata; | |||||
| BLI_task_parallel_range( | BLI_task_parallel_range( | ||||
| 0, psys->totpart, &task_data, dynamics_step_sph_ddr_task_cb_ex, &settings); | 0, psys->totpart, &task_data, dynamics_step_sph_ddr_task_cb_ex, &settings); | ||||
| sph_springs_modify(psys, timestep); | sph_springs_modify(psys, timestep); | ||||
| } | } | ||||
| else { | else { | ||||
| /* SPH_SOLVER_CLASSICAL */ | /* SPH_SOLVER_CLASSICAL */ | ||||
| /* Apply SPH forces using classical algorithm (due to Gingold | /* Apply SPH forces using classical algorithm (due to Gingold | ||||
| Show All 15 Lines | case PART_PHYS_FLUID: { | ||||
| /* Note that we could avoid copying sphdata for each thread here (it's only read here), | /* Note that we could avoid copying sphdata for each thread here (it's only read here), | ||||
| * but doubt this would gain us anything except confusion... */ | * but doubt this would gain us anything except confusion... */ | ||||
| { | { | ||||
| TaskParallelSettings settings; | TaskParallelSettings settings; | ||||
| BLI_parallel_range_settings_defaults(&settings); | BLI_parallel_range_settings_defaults(&settings); | ||||
| settings.use_threading = (psys->totpart > 100); | settings.use_threading = (psys->totpart > 100); | ||||
| settings.userdata_chunk = &sphdata; | settings.userdata_chunk = &sphdata; | ||||
| settings.userdata_chunk_size = sizeof(sphdata); | settings.userdata_chunk_size = sizeof(sphdata); | ||||
| settings.func_finalize = dynamics_step_finalize_sphdata; | |||||
| BLI_task_parallel_range(0, | BLI_task_parallel_range(0, | ||||
| psys->totpart, | psys->totpart, | ||||
| &task_data, | &task_data, | ||||
| dynamics_step_sph_classical_calc_density_task_cb_ex, | dynamics_step_sph_classical_calc_density_task_cb_ex, | ||||
| &settings); | &settings); | ||||
| } | } | ||||
| /* do global forces & effectors */ | /* do global forces & effectors */ | ||||
| { | { | ||||
| TaskParallelSettings settings; | TaskParallelSettings settings; | ||||
| BLI_parallel_range_settings_defaults(&settings); | BLI_parallel_range_settings_defaults(&settings); | ||||
| settings.use_threading = (psys->totpart > 100); | settings.use_threading = (psys->totpart > 100); | ||||
| settings.userdata_chunk = &sphdata; | settings.userdata_chunk = &sphdata; | ||||
| settings.userdata_chunk_size = sizeof(sphdata); | settings.userdata_chunk_size = sizeof(sphdata); | ||||
| settings.func_finalize = dynamics_step_finalize_sphdata; | |||||
| BLI_task_parallel_range(0, | BLI_task_parallel_range(0, | ||||
| psys->totpart, | psys->totpart, | ||||
| &task_data, | &task_data, | ||||
| dynamics_step_sph_classical_integrate_task_cb_ex, | dynamics_step_sph_classical_integrate_task_cb_ex, | ||||
| &settings); | &settings); | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 818 Lines • Show Last 20 Lines | |||||