diff options
Diffstat (limited to 'source/blender/blenkernel/intern/smoke.c')
-rw-r--r-- | source/blender/blenkernel/intern/smoke.c | 257 |
1 files changed, 2 insertions, 255 deletions
diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index d20994a2e39..b8fe669cab0 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -77,7 +77,6 @@ #include "BKE_main.h" #include "BKE_modifier.h" #include "BKE_object.h" -#include "BKE_particle.h" #include "BKE_pointcache.h" #include "BKE_scene.h" #include "BKE_smoke.h" @@ -1127,248 +1126,6 @@ static void em_combineMaps(EmissionMap *output, EmissionMap *em2, int hires_mult em_freeData(&em1); } -typedef struct EmitFromParticlesData { - SmokeFlowSettings *sfs; - KDTree *tree; - int hires_multiplier; - - EmissionMap *em; - float *particle_vel; - float hr; - - int *min, *max, *res; - - float solid; - float smooth; - float hr_smooth; -} EmitFromParticlesData; - -static void emit_from_particles_task_cb(void *userdata, const int z) -{ - EmitFromParticlesData *data = userdata; - SmokeFlowSettings *sfs = data->sfs; - EmissionMap *em = data->em; - const int hires_multiplier = data->hires_multiplier; - - for (int x = data->min[0]; x < data->max[0]; x++) { - for (int y = data->min[1]; y < data->max[1]; y++) { - /* take low res samples where possible */ - if (hires_multiplier <= 1 || !(x % hires_multiplier || y % hires_multiplier || z % hires_multiplier)) { - /* get low res space coordinates */ - const int lx = x / hires_multiplier; - const int ly = y / hires_multiplier; - const int lz = z / hires_multiplier; - - const int index = smoke_get_index(lx - em->min[0], em->res[0], ly - em->min[1], em->res[1], lz - em->min[2]); - const float ray_start[3] = {((float)lx) + 0.5f, ((float)ly) + 0.5f, ((float)lz) + 0.5f}; - - /* find particle distance from the kdtree */ - KDTreeNearest nearest; - const float range = data->solid + data->smooth; - BLI_kdtree_find_nearest(data->tree, ray_start, &nearest); - - if (nearest.dist < range) { - em->influence[index] = (nearest.dist < data->solid) ? - 1.0f : (1.0f - (nearest.dist - data->solid) / data->smooth); - /* Uses particle velocity as initial velocity for smoke */ - if (sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY && (sfs->psys->part->phystype != PART_PHYS_NO)) { - VECADDFAC(&em->velocity[index * 3], &em->velocity[index * 3], - &data->particle_vel[nearest.index * 3], sfs->vel_multi); - } - } - } - - /* take high res samples if required */ - if (hires_multiplier > 1) { - /* get low res space coordinates */ - const float lx = ((float)x) * data->hr; - const float ly = ((float)y) * data->hr; - const float lz = ((float)z) * data->hr; - - const int index = smoke_get_index( - x - data->min[0], data->res[0], y - data->min[1], data->res[1], z - data->min[2]); - const float ray_start[3] = {lx + 0.5f * data->hr, ly + 0.5f * data->hr, lz + 0.5f * data->hr}; - - /* find particle distance from the kdtree */ - KDTreeNearest nearest; - const float range = data->solid + data->hr_smooth; - BLI_kdtree_find_nearest(data->tree, ray_start, &nearest); - - if (nearest.dist < range) { - em->influence_high[index] = (nearest.dist < data->solid) ? - 1.0f : (1.0f - (nearest.dist - data->solid) / data->smooth); - } - } - - } - } -} - -static void emit_from_particles( - Object *flow_ob, SmokeDomainSettings *sds, SmokeFlowSettings *sfs, EmissionMap *em, Scene *scene, float dt) -{ - if (sfs && sfs->psys && sfs->psys->part && ELEM(sfs->psys->part->type, PART_EMITTER, PART_FLUID)) // is particle system selected - { - ParticleSimulationData sim; - ParticleSystem *psys = sfs->psys; - float *particle_pos; - float *particle_vel; - int totpart = psys->totpart, totchild; - int p = 0; - int valid_particles = 0; - int bounds_margin = 1; - - /* radius based flow */ - const float solid = sfs->particle_size * 0.5f; - const float smooth = 0.5f; /* add 0.5 cells of linear falloff to reduce aliasing */ - int hires_multiplier = 1; - KDTree *tree = NULL; - - sim.scene = scene; - sim.ob = flow_ob; - sim.psys = psys; - - /* prepare curvemapping tables */ - if ((psys->part->child_flag & PART_CHILD_USE_CLUMP_CURVE) && psys->part->clumpcurve) - curvemapping_changed_all(psys->part->clumpcurve); - if ((psys->part->child_flag & PART_CHILD_USE_ROUGH_CURVE) && psys->part->roughcurve) - curvemapping_changed_all(psys->part->roughcurve); - - /* initialize particle cache */ - if (psys->part->type == PART_HAIR) { - // TODO: PART_HAIR not supported whatsoever - totchild = 0; - } - else { - totchild = psys->totchild * psys->part->disp / 100; - } - - particle_pos = MEM_callocN(sizeof(float) * (totpart + totchild) * 3, "smoke_flow_particles"); - particle_vel = MEM_callocN(sizeof(float) * (totpart + totchild) * 3, "smoke_flow_particles"); - - /* setup particle radius emission if enabled */ - if (sfs->flags & MOD_SMOKE_FLOW_USE_PART_SIZE) { - tree = BLI_kdtree_new(psys->totpart + psys->totchild); - - /* check need for high resolution map */ - if ((sds->flags & MOD_SMOKE_HIGHRES) && (sds->highres_sampling == SM_HRES_FULLSAMPLE)) { - hires_multiplier = sds->amplify + 1; - } - - bounds_margin = (int)ceil(solid + smooth); - } - - /* calculate local position for each particle */ - for (p = 0; p < totpart + totchild; p++) - { - ParticleKey state; - float *pos; - if (p < totpart) { - if (psys->particles[p].flag & (PARS_NO_DISP | PARS_UNEXIST)) - continue; - } - else { - /* handle child particle */ - ChildParticle *cpa = &psys->child[p - totpart]; - if (psys->particles[cpa->parent].flag & (PARS_NO_DISP | PARS_UNEXIST)) - continue; - } - - state.time = BKE_scene_frame_get(scene); /* use scene time */ - if (psys_get_particle_state(&sim, p, &state, 0) == 0) - continue; - - /* location */ - pos = &particle_pos[valid_particles * 3]; - copy_v3_v3(pos, state.co); - smoke_pos_to_cell(sds, pos); - - /* velocity */ - copy_v3_v3(&particle_vel[valid_particles * 3], state.vel); - mul_mat3_m4_v3(sds->imat, &particle_vel[valid_particles * 3]); - - if (sfs->flags & MOD_SMOKE_FLOW_USE_PART_SIZE) { - BLI_kdtree_insert(tree, valid_particles, pos); - } - - /* calculate emission map bounds */ - em_boundInsert(em, pos); - valid_particles++; - } - - /* set emission map */ - clampBoundsInDomain(sds, em->min, em->max, NULL, NULL, bounds_margin, dt); - em_allocateData(em, sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY, hires_multiplier); - - if (!(sfs->flags & MOD_SMOKE_FLOW_USE_PART_SIZE)) { - for (p = 0; p < valid_particles; p++) - { - int cell[3]; - size_t i = 0; - size_t index = 0; - int badcell = 0; - - /* 1. get corresponding cell */ - cell[0] = floor(particle_pos[p * 3]) - em->min[0]; - cell[1] = floor(particle_pos[p * 3 + 1]) - em->min[1]; - cell[2] = floor(particle_pos[p * 3 + 2]) - em->min[2]; - /* check if cell is valid (in the domain boundary) */ - for (i = 0; i < 3; i++) { - if ((cell[i] > em->res[i] - 1) || (cell[i] < 0)) { - badcell = 1; - break; - } - } - if (badcell) - continue; - /* get cell index */ - index = smoke_get_index(cell[0], em->res[0], cell[1], em->res[1], cell[2]); - /* Add influence to emission map */ - em->influence[index] = 1.0f; - /* Uses particle velocity as initial velocity for smoke */ - if (sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY && (psys->part->phystype != PART_PHYS_NO)) - { - VECADDFAC(&em->velocity[index * 3], &em->velocity[index * 3], &particle_vel[p * 3], sfs->vel_multi); - } - } // particles loop - } - else if (valid_particles > 0) { // MOD_SMOKE_FLOW_USE_PART_SIZE - int min[3], max[3], res[3]; - const float hr = 1.0f / ((float)hires_multiplier); - /* slightly adjust high res antialias smoothness based on number of divisions - * to allow smaller details but yet not differing too much from the low res size */ - const float hr_smooth = smooth * powf(hr, 1.0f / 3.0f); - - /* setup loop bounds */ - for (int i = 0; i < 3; i++) { - min[i] = em->min[i] * hires_multiplier; - max[i] = em->max[i] * hires_multiplier; - res[i] = em->res[i] * hires_multiplier; - } - - BLI_kdtree_balance(tree); - - EmitFromParticlesData data = { - .sfs = sfs, .tree = tree, .hires_multiplier = hires_multiplier, .hr = hr, - .em = em, .particle_vel = particle_vel, .min = min, .max = max, .res = res, - .solid = solid, .smooth = smooth, .hr_smooth = hr_smooth, - }; - - BLI_task_parallel_range(min[2], max[2], &data, emit_from_particles_task_cb, true); - } - - if (sfs->flags & MOD_SMOKE_FLOW_USE_PART_SIZE) { - BLI_kdtree_free(tree); - } - - /* free data */ - if (particle_pos) - MEM_freeN(particle_pos); - if (particle_vel) - MEM_freeN(particle_vel); - } -} - static void sample_derivedmesh( SmokeFlowSettings *sfs, const MVert *mvert, const MLoop *mloop, const MLoopTri *mlooptri, const MLoopUV *mloopuv, @@ -2093,10 +1850,7 @@ static void update_flowsfluids(Scene *scene, Object *ob, SmokeDomainSettings *sd /* just sample flow directly to emission map if no subframes */ if (!subframes) { - if (sfs->source == MOD_SMOKE_FLOW_SOURCE_PARTICLES) { - emit_from_particles(collob, sds, sfs, em, scene, dt); - } - else { + if (sfs->source == MOD_SMOKE_FLOW_SOURCE_MESH) { emit_from_derivedmesh(collob, sds, sfs, em, dt); } } @@ -2127,14 +1881,7 @@ static void update_flowsfluids(Scene *scene, Object *ob, SmokeDomainSettings *sd scene->r.subframe = 0.0f; } - if (sfs->source == MOD_SMOKE_FLOW_SOURCE_PARTICLES) { - /* emit_from_particles() updates timestep internally */ - emit_from_particles(collob, sds, sfs, &em_temp, scene, sdt); - if (!(sfs->flags & MOD_SMOKE_FLOW_USE_PART_SIZE)) { - hires_multiplier = 1; - } - } - else { /* MOD_SMOKE_FLOW_SOURCE_MESH */ + if (sfs->source == MOD_SMOKE_FLOW_SOURCE_MESH) { /* update flow object frame */ BLI_mutex_lock(&object_update_lock); BKE_object_modifier_update_subframe(scene, collob, true, 5, BKE_scene_frame_get(scene), eModifierType_Smoke); |