Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/particle.c
| Show First 20 Lines • Show All 1,883 Lines • ▼ Show 20 Lines | void psys_particle_on_emitter(ParticleSystemModifierData *psmd, | ||||
| float fuv[4], | float fuv[4], | ||||
| float foffset, | float foffset, | ||||
| float vec[3], | float vec[3], | ||||
| float nor[3], | float nor[3], | ||||
| float utan[3], | float utan[3], | ||||
| float vtan[3], | float vtan[3], | ||||
| float orco[3]) | float orco[3]) | ||||
| { | { | ||||
| if (psmd && psmd->mesh_final) { | Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); | ||||
| if (psmd && mesh_final) { | |||||
| if (psmd->psys->part->distr == PART_DISTR_GRID && psmd->psys->part->from != PART_FROM_VERT) { | if (psmd->psys->part->distr == PART_DISTR_GRID && psmd->psys->part->from != PART_FROM_VERT) { | ||||
| if (vec) { | if (vec) { | ||||
| copy_v3_v3(vec, fuv); | copy_v3_v3(vec, fuv); | ||||
| } | } | ||||
| if (orco) { | if (orco) { | ||||
| copy_v3_v3(orco, fuv); | copy_v3_v3(orco, fuv); | ||||
| } | } | ||||
| return; | return; | ||||
| } | } | ||||
| /* we cant use the num_dmcache */ | /* we cant use the num_dmcache */ | ||||
| psys_particle_on_dm( | psys_particle_on_dm( | ||||
| psmd->mesh_final, from, index, index_dmcache, fuv, foffset, vec, nor, utan, vtan, orco); | mesh_final, from, index, index_dmcache, fuv, foffset, vec, nor, utan, vtan, orco); | ||||
| } | } | ||||
| else { | else { | ||||
| psys_particle_on_shape(from, index, fuv, vec, nor, utan, vtan, orco); | psys_particle_on_shape(from, index, fuv, vec, nor, utan, vtan, orco); | ||||
| } | } | ||||
| } | } | ||||
| /************************************************/ | /************************************************/ | ||||
| /* Path Cache */ | /* Path Cache */ | ||||
| /************************************************/ | /************************************************/ | ||||
| ▲ Show 20 Lines • Show All 334 Lines • ▼ Show 20 Lines | void psys_find_parents(ParticleSimulationData *sim, const bool use_render_params) | ||||
| /* hard limit, workaround for it being ignored above */ | /* hard limit, workaround for it being ignored above */ | ||||
| if (sim->psys->totpart < totparent) { | if (sim->psys->totpart < totparent) { | ||||
| totparent = sim->psys->totpart; | totparent = sim->psys->totpart; | ||||
| } | } | ||||
| tree = BLI_kdtree_3d_new(totparent); | tree = BLI_kdtree_3d_new(totparent); | ||||
| Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(sim->psmd); | |||||
| for (p = 0, cpa = sim->psys->child; p < totparent; p++, cpa++) { | for (p = 0, cpa = sim->psys->child; p < totparent; p++, cpa++) { | ||||
| psys_particle_on_emitter( | psys_particle_on_emitter( | ||||
| sim->psmd, from, cpa->num, DMCACHE_ISCHILD, cpa->fuv, cpa->foffset, co, 0, 0, 0, orco); | sim->psmd, from, cpa->num, DMCACHE_ISCHILD, cpa->fuv, cpa->foffset, co, 0, 0, 0, orco); | ||||
| /* Check if particle doesn't exist because of texture influence. | /* Check if particle doesn't exist because of texture influence. | ||||
| * Insert only existing particles into kdtree. */ | * Insert only existing particles into kdtree. */ | ||||
| get_cpa_texture(sim->psmd->mesh_final, | get_cpa_texture(mesh_final, | ||||
| psys, | psys, | ||||
| part, | part, | ||||
| psys->particles + cpa->pa[0], | psys->particles + cpa->pa[0], | ||||
| p, | p, | ||||
| cpa->num, | cpa->num, | ||||
| cpa->fuv, | cpa->fuv, | ||||
| orco, | orco, | ||||
| &ptex, | &ptex, | ||||
| ▲ Show 20 Lines • Show All 151 Lines • ▼ Show 20 Lines | static void psys_thread_create_path(ParticleTask *task, | ||||
| float eff_length, eff_vec[3], weight[4]; | float eff_length, eff_vec[3], weight[4]; | ||||
| int k, cpa_num; | int k, cpa_num; | ||||
| short cpa_from; | short cpa_from; | ||||
| if (!pcache) { | if (!pcache) { | ||||
| return; | return; | ||||
| } | } | ||||
| Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(ctx->sim.psmd); | |||||
| if (ctx->between) { | if (ctx->between) { | ||||
| ParticleData *pa = psys->particles + cpa->pa[0]; | ParticleData *pa = psys->particles + cpa->pa[0]; | ||||
| int w, needupdate; | int w, needupdate; | ||||
| float foffset, wsum = 0.f; | float foffset, wsum = 0.f; | ||||
| float co[3]; | float co[3]; | ||||
| float p_min = part->parting_min; | float p_min = part->parting_min; | ||||
| float p_max = part->parting_max; | float p_max = part->parting_max; | ||||
| /* Virtual parents don't work nicely with parting. */ | /* Virtual parents don't work nicely with parting. */ | ||||
| ▲ Show 20 Lines • Show All 88 Lines • ▼ Show 20 Lines | psys_particle_on_emitter( | ||||
| ctx->sim.psmd, cpa_from, cpa_num, DMCACHE_ISCHILD, cpa->fuv, foffset, co, 0, 0, 0, orco); | ctx->sim.psmd, cpa_from, cpa_num, DMCACHE_ISCHILD, cpa->fuv, foffset, co, 0, 0, 0, orco); | ||||
| mul_m4_v3(ob->obmat, co); | mul_m4_v3(ob->obmat, co); | ||||
| for (w = 0; w < 4; w++) { | for (w = 0; w < 4; w++) { | ||||
| sub_v3_v3v3(off1[w], co, key[w]->co); | sub_v3_v3v3(off1[w], co, key[w]->co); | ||||
| } | } | ||||
| psys_mat_hair_to_global(ob, ctx->sim.psmd->mesh_final, psys->part->from, pa, hairmat); | psys_mat_hair_to_global(ob, mesh_final, psys->part->from, pa, hairmat); | ||||
| } | } | ||||
| else { | else { | ||||
| ParticleData *pa = psys->particles + cpa->parent; | ParticleData *pa = psys->particles + cpa->parent; | ||||
| float co[3]; | float co[3]; | ||||
| if (ctx->editupdate) { | if (ctx->editupdate) { | ||||
| if (!(edit->points[cpa->parent].flag & PEP_EDIT_RECALC)) { | if (!(edit->points[cpa->parent].flag & PEP_EDIT_RECALC)) { | ||||
| return; | return; | ||||
| } | } | ||||
| Show All 14 Lines | else { | ||||
| * ctx->sim.psmd->dm_deformed, | * ctx->sim.psmd->dm_deformed, | ||||
| * pa->num, pa->fuv, | * pa->num, pa->fuv, | ||||
| * NULL); | * NULL); | ||||
| */ | */ | ||||
| cpa_num = (ELEM(pa->num_dmcache, DMCACHE_ISCHILD, DMCACHE_NOTFOUND)) ? pa->num : | cpa_num = (ELEM(pa->num_dmcache, DMCACHE_ISCHILD, DMCACHE_NOTFOUND)) ? pa->num : | ||||
| pa->num_dmcache; | pa->num_dmcache; | ||||
| /* XXX hack to avoid messed up particle num and subsequent crash (#40733) */ | /* XXX hack to avoid messed up particle num and subsequent crash (#40733) */ | ||||
| if (cpa_num > ctx->sim.psmd->mesh_final->totface) { | if (cpa_num > mesh_final->totface) { | ||||
| cpa_num = 0; | cpa_num = 0; | ||||
| } | } | ||||
| cpa_fuv = pa->fuv; | cpa_fuv = pa->fuv; | ||||
| psys_particle_on_emitter(ctx->sim.psmd, | psys_particle_on_emitter(ctx->sim.psmd, | ||||
| cpa_from, | cpa_from, | ||||
| cpa_num, | cpa_num, | ||||
| DMCACHE_ISCHILD, | DMCACHE_ISCHILD, | ||||
| cpa_fuv, | cpa_fuv, | ||||
| pa->foffset, | pa->foffset, | ||||
| co, | co, | ||||
| 0, | 0, | ||||
| 0, | 0, | ||||
| 0, | 0, | ||||
| orco); | orco); | ||||
| psys_mat_hair_to_global(ob, ctx->sim.psmd->mesh_final, psys->part->from, pa, hairmat); | psys_mat_hair_to_global(ob, mesh_final, psys->part->from, pa, hairmat); | ||||
| } | } | ||||
| child_keys->segments = ctx->segments; | child_keys->segments = ctx->segments; | ||||
| /* get different child parameters from textures & vgroups */ | /* get different child parameters from textures & vgroups */ | ||||
| get_child_modifier_parameters(part, ctx, cpa, cpa_from, cpa_num, cpa_fuv, orco, &ptex); | get_child_modifier_parameters(part, ctx, cpa, cpa_from, cpa_num, cpa_fuv, orco, &ptex); | ||||
| if (ptex.exist < psys_frand(psys, i + 24)) { | if (ptex.exist < psys_frand(psys, i + 24)) { | ||||
| ▲ Show 20 Lines • Show All 329 Lines • ▼ Show 20 Lines | cache = psys->pathcache = psys_alloc_path_cache_buffers( | ||||
| &psys->pathcachebufs, totpart, segments + 1); | &psys->pathcachebufs, totpart, segments + 1); | ||||
| psys->lattice_deform_data = psys_create_lattice_deform_data(sim); | psys->lattice_deform_data = psys_create_lattice_deform_data(sim); | ||||
| ma = give_current_material(sim->ob, psys->part->omat); | ma = give_current_material(sim->ob, psys->part->omat); | ||||
| if (ma && (psys->part->draw_col == PART_DRAW_COL_MAT)) { | if (ma && (psys->part->draw_col == PART_DRAW_COL_MAT)) { | ||||
| copy_v3_v3(col, &ma->r); | copy_v3_v3(col, &ma->r); | ||||
| } | } | ||||
| Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); | |||||
| if ((psys->flag & PSYS_GLOBAL_HAIR) == 0) { | if ((psys->flag & PSYS_GLOBAL_HAIR) == 0) { | ||||
| if ((psys->part->flag & PART_CHILD_EFFECT) == 0) { | if ((psys->part->flag & PART_CHILD_EFFECT) == 0) { | ||||
| vg_effector = psys_cache_vgroup(psmd->mesh_final, psys, PSYS_VG_EFFECTOR); | vg_effector = psys_cache_vgroup(mesh_final, psys, PSYS_VG_EFFECTOR); | ||||
| } | } | ||||
| if (!psys->totchild) { | if (!psys->totchild) { | ||||
| vg_length = psys_cache_vgroup(psmd->mesh_final, psys, PSYS_VG_LENGTH); | vg_length = psys_cache_vgroup(mesh_final, psys, PSYS_VG_LENGTH); | ||||
| } | } | ||||
| } | } | ||||
| /* ensure we have tessfaces to be used for mapping */ | /* ensure we have tessfaces to be used for mapping */ | ||||
| if (part->from != PART_FROM_VERT) { | if (part->from != PART_FROM_VERT) { | ||||
| BKE_mesh_tessface_ensure(psmd->mesh_final); | BKE_mesh_tessface_ensure(mesh_final); | ||||
| } | } | ||||
| /*---first main loop: create all actual particles' paths---*/ | /*---first main loop: create all actual particles' paths---*/ | ||||
| LOOP_PARTICLES | LOOP_PARTICLES | ||||
| { | { | ||||
| if (!psys->totchild) { | if (!psys->totchild) { | ||||
| psys_get_texture(sim, pa, &ptex, PAMAP_LENGTH, 0.f); | psys_get_texture(sim, pa, &ptex, PAMAP_LENGTH, 0.f); | ||||
| pa_length = ptex.length * (1.0f - part->randlength * psys_frand(psys, psys->seed + p)); | pa_length = ptex.length * (1.0f - part->randlength * psys_frand(psys, psys->seed + p)); | ||||
| if (vg_length) { | if (vg_length) { | ||||
| pa_length *= psys_particle_value_from_verts(psmd->mesh_final, part->from, pa, vg_length); | pa_length *= psys_particle_value_from_verts(mesh_final, part->from, pa, vg_length); | ||||
| } | } | ||||
| } | } | ||||
| pind.keyed = keyed; | pind.keyed = keyed; | ||||
| pind.cache = baked ? psys->pointcache : NULL; | pind.cache = baked ? psys->pointcache : NULL; | ||||
| pind.epoint = NULL; | pind.epoint = NULL; | ||||
| pind.bspline = (psys->part->flag & PART_HAIR_BSPLINE); | pind.bspline = (psys->part->flag & PART_HAIR_BSPLINE); | ||||
| pind.mesh = hair_mesh; | pind.mesh = hair_mesh; | ||||
| memset(cache[p], 0, sizeof(*cache[p]) * (segments + 1)); | memset(cache[p], 0, sizeof(*cache[p]) * (segments + 1)); | ||||
| cache[p]->segments = segments; | cache[p]->segments = segments; | ||||
| /*--get the first data points--*/ | /*--get the first data points--*/ | ||||
| init_particle_interpolation(sim->ob, sim->psys, pa, &pind); | init_particle_interpolation(sim->ob, sim->psys, pa, &pind); | ||||
| /* hairmat is needed for for non-hair particle too so we get proper rotations */ | /* hairmat is needed for for non-hair particle too so we get proper rotations */ | ||||
| psys_mat_hair_to_global(sim->ob, psmd->mesh_final, psys->part->from, pa, hairmat); | psys_mat_hair_to_global(sim->ob, mesh_final, psys->part->from, pa, hairmat); | ||||
| copy_v3_v3(rotmat[0], hairmat[2]); | copy_v3_v3(rotmat[0], hairmat[2]); | ||||
| copy_v3_v3(rotmat[1], hairmat[1]); | copy_v3_v3(rotmat[1], hairmat[1]); | ||||
| copy_v3_v3(rotmat[2], hairmat[0]); | copy_v3_v3(rotmat[2], hairmat[0]); | ||||
| if (part->draw & PART_ABS_PATH_TIME) { | if (part->draw & PART_ABS_PATH_TIME) { | ||||
| birthtime = MAX2(pind.birthtime, part->path_start); | birthtime = MAX2(pind.birthtime, part->path_start); | ||||
| dietime = MIN2(pind.dietime, part->path_end); | dietime = MIN2(pind.dietime, part->path_end); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | LOOP_PARTICLES | ||||
| /*--modify paths and calculate rotation & velocity--*/ | /*--modify paths and calculate rotation & velocity--*/ | ||||
| if (!(psys->flag & PSYS_GLOBAL_HAIR)) { | if (!(psys->flag & PSYS_GLOBAL_HAIR)) { | ||||
| /* apply effectors */ | /* apply effectors */ | ||||
| if ((psys->part->flag & PART_CHILD_EFFECT) == 0) { | if ((psys->part->flag & PART_CHILD_EFFECT) == 0) { | ||||
| float effector = 1.0f; | float effector = 1.0f; | ||||
| if (vg_effector) { | if (vg_effector) { | ||||
| effector *= psys_particle_value_from_verts( | effector *= psys_particle_value_from_verts( | ||||
| psmd->mesh_final, psys->part->from, pa, vg_effector); | mesh_final, psys->part->from, pa, vg_effector); | ||||
| } | } | ||||
| sub_v3_v3v3(vec, (cache[p] + 1)->co, cache[p]->co); | sub_v3_v3v3(vec, (cache[p] + 1)->co, cache[p]->co); | ||||
| length = len_v3(vec); | length = len_v3(vec); | ||||
| for (k = 1, ca = cache[p] + 1; k <= segments; k++, ca++) { | for (k = 1, ca = cache[p] + 1; k <= segments; k++, ca++) { | ||||
| do_path_effectors( | do_path_effectors( | ||||
| sim, p, ca, k, segments, cache[p]->co, effector, dfra, cfra, &length, vec); | sim, p, ca, k, segments, cache[p]->co, effector, dfra, cfra, &length, vec); | ||||
| ▲ Show 20 Lines • Show All 118 Lines • ▼ Show 20 Lines | static void psys_cache_edit_paths_iter(void *__restrict iter_data_v, | ||||
| memset(cache[iter], 0, sizeof(*cache[iter]) * (segments + 1)); | memset(cache[iter], 0, sizeof(*cache[iter]) * (segments + 1)); | ||||
| cache[iter]->segments = segments; | cache[iter]->segments = segments; | ||||
| /*--get the first data points--*/ | /*--get the first data points--*/ | ||||
| init_particle_interpolation(ob, psys, pa, &pind); | init_particle_interpolation(ob, psys, pa, &pind); | ||||
| if (psys) { | if (psys) { | ||||
| psys_mat_hair_to_global(ob, psmd->mesh_final, psys->part->from, pa, hairmat); | Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); | ||||
| psys_mat_hair_to_global(ob, mesh_final, psys->part->from, pa, hairmat); | |||||
| copy_v3_v3(rotmat[0], hairmat[2]); | copy_v3_v3(rotmat[0], hairmat[2]); | ||||
| copy_v3_v3(rotmat[1], hairmat[1]); | copy_v3_v3(rotmat[1], hairmat[1]); | ||||
| copy_v3_v3(rotmat[2], hairmat[0]); | copy_v3_v3(rotmat[2], hairmat[0]); | ||||
| } | } | ||||
| birthtime = pind.birthtime; | birthtime = pind.birthtime; | ||||
| dietime = pind.dietime; | dietime = pind.dietime; | ||||
| ▲ Show 20 Lines • Show All 863 Lines • ▼ Show 20 Lines | if (mtex && mtex->tex && mtex->mapto) { | ||||
| copy_v3_v3(texvec, pa->state.co); | copy_v3_v3(texvec, pa->state.co); | ||||
| break; | break; | ||||
| case TEXCO_OBJECT: | case TEXCO_OBJECT: | ||||
| copy_v3_v3(texvec, pa->state.co); | copy_v3_v3(texvec, pa->state.co); | ||||
| if (mtex->object) { | if (mtex->object) { | ||||
| mul_m4_v3(mtex->object->imat, texvec); | mul_m4_v3(mtex->object->imat, texvec); | ||||
| } | } | ||||
| break; | break; | ||||
| case TEXCO_UV: | case TEXCO_UV: { | ||||
| if (get_particle_uv(sim->psmd->mesh_final, | Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(sim->psmd); | ||||
| if (get_particle_uv(mesh_final, | |||||
| pa, | pa, | ||||
| 0, | 0, | ||||
| pa->fuv, | pa->fuv, | ||||
| mtex->uvname, | mtex->uvname, | ||||
| texvec, | texvec, | ||||
| (part->from == PART_FROM_VERT))) { | (part->from == PART_FROM_VERT))) { | ||||
| break; | break; | ||||
| } | } | ||||
| /* no break, failed to get uv's, so let's try orco's */ | /* no break, failed to get uv's, so let's try orco's */ | ||||
| ATTR_FALLTHROUGH; | ATTR_FALLTHROUGH; | ||||
| } | |||||
| case TEXCO_ORCO: | case TEXCO_ORCO: | ||||
| psys_particle_on_emitter(sim->psmd, | psys_particle_on_emitter(sim->psmd, | ||||
| sim->psys->part->from, | sim->psys->part->from, | ||||
| pa->num, | pa->num, | ||||
| pa->num_dmcache, | pa->num_dmcache, | ||||
| pa->fuv, | pa->fuv, | ||||
| pa->foffset, | pa->foffset, | ||||
| co, | co, | ||||
| ▲ Show 20 Lines • Show All 257 Lines • ▼ Show 20 Lines | else { | ||||
| do_particle_interpolation(psys, p, pa, t, &pind, state); | do_particle_interpolation(psys, p, pa, t, &pind, state); | ||||
| if (pind.mesh) { | if (pind.mesh) { | ||||
| mul_m4_v3(sim->ob->obmat, state->co); | mul_m4_v3(sim->ob->obmat, state->co); | ||||
| mul_mat3_m4_v3(sim->ob->obmat, state->vel); | mul_mat3_m4_v3(sim->ob->obmat, state->vel); | ||||
| } | } | ||||
| else if (!keyed && !cached && !(psys->flag & PSYS_GLOBAL_HAIR)) { | else if (!keyed && !cached && !(psys->flag & PSYS_GLOBAL_HAIR)) { | ||||
| if ((pa->flag & PARS_REKEY) == 0) { | if ((pa->flag & PARS_REKEY) == 0) { | ||||
| psys_mat_hair_to_global(sim->ob, sim->psmd->mesh_final, part->from, pa, hairmat); | Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(sim->psmd); | ||||
| psys_mat_hair_to_global(sim->ob, mesh_final, part->from, pa, hairmat); | |||||
| mul_m4_v3(hairmat, state->co); | mul_m4_v3(hairmat, state->co); | ||||
| mul_mat3_m4_v3(hairmat, state->vel); | mul_mat3_m4_v3(hairmat, state->vel); | ||||
| if (sim->psys->effectors && (part->flag & PART_CHILD_GUIDE) == 0) { | if (sim->psys->effectors && (part->flag & PART_CHILD_GUIDE) == 0) { | ||||
| do_guides( | do_guides( | ||||
| sim->depsgraph, sim->psys->part, sim->psys->effectors, state, p, state->time); | sim->depsgraph, sim->psys->part, sim->psys->effectors, state, p, state->time); | ||||
| /* TODO: proper velocity handling */ | /* TODO: proper velocity handling */ | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 65 Lines • ▼ Show 20 Lines | else { | ||||
| pa->fuv, | pa->fuv, | ||||
| pa->foffset, | pa->foffset, | ||||
| par_co, | par_co, | ||||
| 0, | 0, | ||||
| 0, | 0, | ||||
| 0, | 0, | ||||
| par_orco); | par_orco); | ||||
| if (part->type == PART_HAIR) { | if (part->type == PART_HAIR) { | ||||
| psys_mat_hair_to_global(sim->ob, sim->psmd->mesh_final, psys->part->from, pa, hairmat); | Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); | ||||
| psys_mat_hair_to_global(sim->ob, mesh_final, psys->part->from, pa, hairmat); | |||||
| } | } | ||||
| else { | else { | ||||
| unit_m4(hairmat); | unit_m4(hairmat); | ||||
| } | } | ||||
| pa = 0; | pa = 0; | ||||
| } | } | ||||
| else { | else { | ||||
| Show All 15 Lines | else { | ||||
| pa->fuv, | pa->fuv, | ||||
| pa->foffset, | pa->foffset, | ||||
| par_co, | par_co, | ||||
| 0, | 0, | ||||
| 0, | 0, | ||||
| 0, | 0, | ||||
| par_orco); | par_orco); | ||||
| if (part->type == PART_HAIR) { | if (part->type == PART_HAIR) { | ||||
| Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); | |||||
| psys_particle_on_emitter( | psys_particle_on_emitter( | ||||
| psmd, cpa_from, cpa_num, DMCACHE_ISCHILD, cpa_fuv, pa->foffset, co, 0, 0, 0, orco); | psmd, cpa_from, cpa_num, DMCACHE_ISCHILD, cpa_fuv, pa->foffset, co, 0, 0, 0, orco); | ||||
| psys_mat_hair_to_global(sim->ob, sim->psmd->mesh_final, psys->part->from, pa, hairmat); | psys_mat_hair_to_global(sim->ob, mesh_final, psys->part->from, pa, hairmat); | ||||
| } | } | ||||
| else { | else { | ||||
| copy_v3_v3(orco, cpa->fuv); | copy_v3_v3(orco, cpa->fuv); | ||||
| unit_m4(hairmat); | unit_m4(hairmat); | ||||
| } | } | ||||
| } | } | ||||
| /* get different child parameters from textures & vgroups */ | /* get different child parameters from textures & vgroups */ | ||||
| memset(&ctx, 0, sizeof(ParticleThreadContext)); | memset(&ctx, 0, sizeof(ParticleThreadContext)); | ||||
| ctx.sim = *sim; | ctx.sim = *sim; | ||||
| ctx.mesh = psmd->mesh_final; | ctx.mesh = BKE_particle_modifier_mesh_final_get(psmd); | ||||
| ctx.ma = ma; | ctx.ma = ma; | ||||
| /* TODO: assign vertex groups */ | /* TODO: assign vertex groups */ | ||||
| get_child_modifier_parameters(part, &ctx, cpa, cpa_from, cpa_num, cpa_fuv, orco, &ptex); | get_child_modifier_parameters(part, &ctx, cpa, cpa_from, cpa_num, cpa_fuv, orco, &ptex); | ||||
| if (between) { | if (between) { | ||||
| int w = 0; | int w = 0; | ||||
| state->co[0] = state->co[1] = state->co[2] = 0.0f; | state->co[0] = state->co[1] = state->co[2] = 0.0f; | ||||
| ▲ Show 20 Lines • Show All 248 Lines • ▼ Show 20 Lines | void psys_get_dupli_texture(ParticleSystem *psys, | ||||
| * For now just include this workaround as an alternative to crashing, | * For now just include this workaround as an alternative to crashing, | ||||
| * but longer term metaballs should behave in a more manageable way, see: T46622. */ | * but longer term metaballs should behave in a more manageable way, see: T46622. */ | ||||
| uv[0] = uv[1] = 0.f; | uv[0] = uv[1] = 0.f; | ||||
| /* Grid distribution doesn't support UV or emit from vertex mode */ | /* Grid distribution doesn't support UV or emit from vertex mode */ | ||||
| bool is_grid = (part->distr == PART_DISTR_GRID && part->from != PART_FROM_VERT); | bool is_grid = (part->distr == PART_DISTR_GRID && part->from != PART_FROM_VERT); | ||||
| Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); | |||||
| if (cpa) { | if (cpa) { | ||||
| if ((part->childtype == PART_CHILD_FACES) && (psmd->mesh_final != NULL)) { | if ((part->childtype == PART_CHILD_FACES) && (mesh_final != NULL)) { | ||||
| CustomData *mtf_data = &psmd->mesh_final->fdata; | CustomData *mtf_data = &mesh_final->fdata; | ||||
| const int uv_idx = CustomData_get_render_layer(mtf_data, CD_MTFACE); | const int uv_idx = CustomData_get_render_layer(mtf_data, CD_MTFACE); | ||||
| mtface = CustomData_get_layer_n(mtf_data, CD_MTFACE, uv_idx); | mtface = CustomData_get_layer_n(mtf_data, CD_MTFACE, uv_idx); | ||||
| if (mtface && !is_grid) { | if (mtface && !is_grid) { | ||||
| mface = CustomData_get(&psmd->mesh_final->fdata, cpa->num, CD_MFACE); | mface = CustomData_get(&mesh_final->fdata, cpa->num, CD_MFACE); | ||||
| mtface += cpa->num; | mtface += cpa->num; | ||||
| psys_interpolate_uvs(mtface, mface->v4, cpa->fuv, uv); | psys_interpolate_uvs(mtface, mface->v4, cpa->fuv, uv); | ||||
| } | } | ||||
| psys_particle_on_emitter(psmd, | psys_particle_on_emitter(psmd, | ||||
| PART_FROM_FACE, | PART_FROM_FACE, | ||||
| cpa->num, | cpa->num, | ||||
| DMCACHE_ISCHILD, | DMCACHE_ISCHILD, | ||||
| cpa->fuv, | cpa->fuv, | ||||
| cpa->foffset, | cpa->foffset, | ||||
| loc, | loc, | ||||
| 0, | 0, | ||||
| 0, | 0, | ||||
| 0, | 0, | ||||
| orco); | orco); | ||||
| return; | return; | ||||
| } | } | ||||
| else { | else { | ||||
| pa = psys->particles + cpa->pa[0]; | pa = psys->particles + cpa->pa[0]; | ||||
| } | } | ||||
| } | } | ||||
| if ((part->from == PART_FROM_FACE) && (psmd->mesh_final != NULL) && !is_grid) { | if ((part->from == PART_FROM_FACE) && (mesh_final != NULL) && !is_grid) { | ||||
| CustomData *mtf_data = &psmd->mesh_final->fdata; | CustomData *mtf_data = &mesh_final->fdata; | ||||
| const int uv_idx = CustomData_get_render_layer(mtf_data, CD_MTFACE); | const int uv_idx = CustomData_get_render_layer(mtf_data, CD_MTFACE); | ||||
| mtface = CustomData_get_layer_n(mtf_data, CD_MTFACE, uv_idx); | mtface = CustomData_get_layer_n(mtf_data, CD_MTFACE, uv_idx); | ||||
| num = pa->num_dmcache; | num = pa->num_dmcache; | ||||
| if (num == DMCACHE_NOTFOUND) { | if (num == DMCACHE_NOTFOUND) { | ||||
| num = pa->num; | num = pa->num; | ||||
| } | } | ||||
| if (num >= psmd->mesh_final->totface) { | if (num >= mesh_final->totface) { | ||||
| /* happens when simplify is enabled | /* happens when simplify is enabled | ||||
| * gives invalid coords but would crash otherwise */ | * gives invalid coords but would crash otherwise */ | ||||
| num = DMCACHE_NOTFOUND; | num = DMCACHE_NOTFOUND; | ||||
| } | } | ||||
| if (mtface && !ELEM(num, DMCACHE_NOTFOUND, DMCACHE_ISCHILD)) { | if (mtface && !ELEM(num, DMCACHE_NOTFOUND, DMCACHE_ISCHILD)) { | ||||
| mface = CustomData_get(&psmd->mesh_final->fdata, num, CD_MFACE); | mface = CustomData_get(&mesh_final->fdata, num, CD_MFACE); | ||||
| mtface += num; | mtface += num; | ||||
| psys_interpolate_uvs(mtface, mface->v4, pa->fuv, uv); | psys_interpolate_uvs(mtface, mface->v4, pa->fuv, uv); | ||||
| } | } | ||||
| } | } | ||||
| psys_particle_on_emitter( | psys_particle_on_emitter( | ||||
| psmd, part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, loc, 0, 0, 0, orco); | psmd, part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, loc, 0, 0, 0, orco); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 104 Lines • ▼ Show 20 Lines | void psys_apply_hair_lattice(Depsgraph *depsgraph, Scene *scene, Object *ob, ParticleSystem *psys) | ||||
| psys->lattice_deform_data = psys_create_lattice_deform_data(&sim); | psys->lattice_deform_data = psys_create_lattice_deform_data(&sim); | ||||
| if (psys->lattice_deform_data) { | if (psys->lattice_deform_data) { | ||||
| ParticleData *pa = psys->particles; | ParticleData *pa = psys->particles; | ||||
| HairKey *hkey; | HairKey *hkey; | ||||
| int p, h; | int p, h; | ||||
| float hairmat[4][4], imat[4][4]; | float hairmat[4][4], imat[4][4]; | ||||
| Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(sim.psmd); | |||||
| for (p = 0; p < psys->totpart; p++, pa++) { | for (p = 0; p < psys->totpart; p++, pa++) { | ||||
| psys_mat_hair_to_global(sim.ob, sim.psmd->mesh_final, psys->part->from, pa, hairmat); | psys_mat_hair_to_global(sim.ob, mesh_final, psys->part->from, pa, hairmat); | ||||
| invert_m4_m4(imat, hairmat); | invert_m4_m4(imat, hairmat); | ||||
| hkey = pa->hair; | hkey = pa->hair; | ||||
| for (h = 0; h < pa->totkey; h++, hkey++) { | for (h = 0; h < pa->totkey; h++, hkey++) { | ||||
| mul_m4_v3(hairmat, hkey->co); | mul_m4_v3(hairmat, hkey->co); | ||||
| calc_latt_deform(psys->lattice_deform_data, hkey->co, psys->lattice_strength); | calc_latt_deform(psys->lattice_deform_data, hkey->co, psys->lattice_strength); | ||||
| mul_m4_v3(imat, hkey->co); | mul_m4_v3(imat, hkey->co); | ||||
| } | } | ||||
| Show All 18 Lines | void BKE_particle_batch_cache_dirty_tag(ParticleSystem *psys, int mode) | ||||
| } | } | ||||
| } | } | ||||
| void BKE_particle_batch_cache_free(ParticleSystem *psys) | void BKE_particle_batch_cache_free(ParticleSystem *psys) | ||||
| { | { | ||||
| if (psys->batch_cache) { | if (psys->batch_cache) { | ||||
| BKE_particle_batch_cache_free_cb(psys); | BKE_particle_batch_cache_free_cb(psys); | ||||
| } | } | ||||
| } | } | ||||
| /* **** Particle system modifier helpers. **** */ | |||||
| Mesh *BKE_particle_modifier_mesh_final_get(ParticleSystemModifierData *psmd) | |||||
| { | |||||
| if (psmd == NULL) { | |||||
| return NULL; | |||||
| } | |||||
| ParticleSystemModifierDataRuntime *runtime = psmd->modifier.runtime; | |||||
| if (runtime == NULL) { | |||||
| return NULL; | |||||
| } | |||||
| return runtime->mesh_final; | |||||
| } | |||||
| Mesh *BKE_particle_modifier_mesh_original_get(ParticleSystemModifierData *psmd) | |||||
| { | |||||
| if (psmd == NULL) { | |||||
| return NULL; | |||||
| } | |||||
| ParticleSystemModifierDataRuntime *runtime = psmd->modifier.runtime; | |||||
| if (runtime == NULL) { | |||||
| return NULL; | |||||
| } | |||||
| return runtime->mesh_original; | |||||
| } | |||||
| ParticleSystemModifierDataRuntime *BKE_particle_modifier_runtime_ensure( | |||||
| ParticleSystemModifierData *psmd) | |||||
| { | |||||
| BLI_assert(psmd != NULL); | |||||
| if (psmd->modifier.runtime == NULL) { | |||||
| psmd->modifier.runtime = MEM_callocN(sizeof(ParticleSystemModifierDataRuntime), | |||||
| "psmd runtime"); | |||||
| } | |||||
| return psmd->modifier.runtime; | |||||
| } | |||||