Changeset View
Changeset View
Standalone View
Standalone View
source/blender/makesrna/intern/rna_particle.c
| Show First 20 Lines • Show All 167 Lines • ▼ Show 20 Lines | static void rna_ParticleHairKey_location_object_info(PointerRNA *ptr, | ||||
| * IDEAS: include additional information in pointerRNA beforehand, | * IDEAS: include additional information in pointerRNA beforehand, | ||||
| * for example a pointer to the ParticleStstemModifierData to which the | * for example a pointer to the ParticleStstemModifierData to which the | ||||
| * hairkey belongs. | * hairkey belongs. | ||||
| */ | */ | ||||
| for (md = ob->modifiers.first; md; md = md->next) { | for (md = ob->modifiers.first; md; md = md->next) { | ||||
| if (md->type == eModifierType_ParticleSystem) { | if (md->type == eModifierType_ParticleSystem) { | ||||
| psmd = (ParticleSystemModifierData *)md; | psmd = (ParticleSystemModifierData *)md; | ||||
| if (psmd && psmd->mesh_final && psmd->psys) { | Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); | ||||
| if (psmd && mesh_final && psmd->psys) { | |||||
| psys = psmd->psys; | psys = psmd->psys; | ||||
| for (i = 0, pa = psys->particles; i < psys->totpart; i++, pa++) { | for (i = 0, pa = psys->particles; i < psys->totpart; i++, pa++) { | ||||
| /* hairkeys are stored sequentially in memory, so we can | /* hairkeys are stored sequentially in memory, so we can | ||||
| * find if it's the same particle by comparing pointers, | * find if it's the same particle by comparing pointers, | ||||
| * without having to iterate over them all */ | * without having to iterate over them all */ | ||||
| if ((hkey >= pa->hair) && (hkey < pa->hair + pa->totkey)) { | if ((hkey >= pa->hair) && (hkey < pa->hair + pa->totkey)) { | ||||
| *psmd_pt = psmd; | *psmd_pt = psmd; | ||||
| *pa_pt = pa; | *pa_pt = pa; | ||||
| Show All 18 Lines | if (pa) { | ||||
| Mesh *hair_mesh = (psmd->psys->flag & PSYS_HAIR_DYNAMICS) ? psmd->psys->hair_out_mesh : NULL; | Mesh *hair_mesh = (psmd->psys->flag & PSYS_HAIR_DYNAMICS) ? psmd->psys->hair_out_mesh : NULL; | ||||
| if (hair_mesh) { | if (hair_mesh) { | ||||
| MVert *mvert = &hair_mesh->mvert[pa->hair_index + (hkey - pa->hair)]; | MVert *mvert = &hair_mesh->mvert[pa->hair_index + (hkey - pa->hair)]; | ||||
| copy_v3_v3(values, mvert->co); | copy_v3_v3(values, mvert->co); | ||||
| } | } | ||||
| else { | else { | ||||
| float hairmat[4][4]; | float hairmat[4][4]; | ||||
| psys_mat_hair_to_object(ob, psmd->mesh_final, psmd->psys->part->from, pa, hairmat); | Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); | ||||
| psys_mat_hair_to_object(ob, mesh_final, psmd->psys->part->from, pa, hairmat); | |||||
| copy_v3_v3(values, hkey->co); | copy_v3_v3(values, hkey->co); | ||||
| mul_m4_v3(hairmat, values); | mul_m4_v3(hairmat, values); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| zero_v3(values); | zero_v3(values); | ||||
| } | } | ||||
| } | } | ||||
| Show All 13 Lines | if (pa) { | ||||
| if (hair_mesh) { | if (hair_mesh) { | ||||
| MVert *mvert = &hair_mesh->mvert[pa->hair_index + (hkey - pa->hair)]; | MVert *mvert = &hair_mesh->mvert[pa->hair_index + (hkey - pa->hair)]; | ||||
| copy_v3_v3(mvert->co, values); | copy_v3_v3(mvert->co, values); | ||||
| } | } | ||||
| else { | else { | ||||
| float hairmat[4][4]; | float hairmat[4][4]; | ||||
| float imat[4][4]; | float imat[4][4]; | ||||
| psys_mat_hair_to_object(ob, psmd->mesh_final, psmd->psys->part->from, pa, hairmat); | Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); | ||||
| psys_mat_hair_to_object(ob, mesh_final, psmd->psys->part->from, pa, hairmat); | |||||
| invert_m4_m4(imat, hairmat); | invert_m4_m4(imat, hairmat); | ||||
| copy_v3_v3(hkey->co, values); | copy_v3_v3(hkey->co, values); | ||||
| mul_m4_v3(imat, hkey->co); | mul_m4_v3(imat, hkey->co); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| zero_v3(hkey->co); | zero_v3(hkey->co); | ||||
| } | } | ||||
| Show All 10 Lines | Mesh *hair_mesh = (modifier->psys->flag & PSYS_HAIR_DYNAMICS) ? modifier->psys->hair_out_mesh : | ||||
| NULL; | NULL; | ||||
| if (particle) { | if (particle) { | ||||
| if (hair_mesh) { | if (hair_mesh) { | ||||
| MVert *mvert = &hair_mesh->mvert[particle->hair_index + (hairkey - particle->hair)]; | MVert *mvert = &hair_mesh->mvert[particle->hair_index + (hairkey - particle->hair)]; | ||||
| copy_v3_v3(n_co, mvert->co); | copy_v3_v3(n_co, mvert->co); | ||||
| } | } | ||||
| else { | else { | ||||
| float hairmat[4][4]; | float hairmat[4][4]; | ||||
| psys_mat_hair_to_object( | Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(modifier); | ||||
| object, modifier->mesh_final, modifier->psys->part->from, particle, hairmat); | psys_mat_hair_to_object(object, mesh_final, modifier->psys->part->from, particle, hairmat); | ||||
| copy_v3_v3(n_co, hairkey->co); | copy_v3_v3(n_co, hairkey->co); | ||||
| mul_m4_v3(hairmat, n_co); | mul_m4_v3(hairmat, n_co); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| zero_v3(n_co); | zero_v3(n_co); | ||||
| } | } | ||||
| } | } | ||||
| static void rna_Particle_uv_on_emitter(ParticleData *particle, | static void rna_Particle_uv_on_emitter(ParticleData *particle, | ||||
| ReportList *reports, | ReportList *reports, | ||||
| ParticleSystemModifierData *modifier, | ParticleSystemModifierData *modifier, | ||||
| float r_uv[2]) | float r_uv[2]) | ||||
| { | { | ||||
| # if 0 | # if 0 | ||||
| psys_particle_on_emitter( | psys_particle_on_emitter( | ||||
| psmd, part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, co, nor, 0, 0, sd.orco, 0); | psmd, part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, co, nor, 0, 0, sd.orco, 0); | ||||
| # endif | # endif | ||||
| /* get uvco & mcol */ | /* get uvco & mcol */ | ||||
| int num = particle->num_dmcache; | int num = particle->num_dmcache; | ||||
| int from = modifier->psys->part->from; | int from = modifier->psys->part->from; | ||||
| if (!CustomData_has_layer(&modifier->mesh_final->ldata, CD_MLOOPUV)) { | Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(modifier); | ||||
| if (!CustomData_has_layer(&mesh_final->ldata, CD_MLOOPUV)) { | |||||
| BKE_report(reports, RPT_ERROR, "Mesh has no UV data"); | BKE_report(reports, RPT_ERROR, "Mesh has no UV data"); | ||||
| return; | return; | ||||
| } | } | ||||
| BKE_mesh_tessface_ensure(modifier->mesh_final); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */ | BKE_mesh_tessface_ensure(mesh_final); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */ | ||||
| if (num == DMCACHE_NOTFOUND) { | if (num == DMCACHE_NOTFOUND) { | ||||
| if (particle->num < modifier->mesh_final->totface) { | if (particle->num < mesh_final->totface) { | ||||
| num = particle->num; | num = particle->num; | ||||
| } | } | ||||
| } | } | ||||
| /* get uvco */ | /* get uvco */ | ||||
| if (r_uv && ELEM(from, PART_FROM_FACE, PART_FROM_VOLUME)) { | if (r_uv && ELEM(from, PART_FROM_FACE, PART_FROM_VOLUME)) { | ||||
| if (num != DMCACHE_NOTFOUND) { | if (num != DMCACHE_NOTFOUND) { | ||||
| MFace *mface; | MFace *mface; | ||||
| MTFace *mtface; | MTFace *mtface; | ||||
| mface = modifier->mesh_final->mface; | mface = mesh_final->mface; | ||||
| mtface = modifier->mesh_final->mtface; | mtface = mesh_final->mtface; | ||||
| if (mface && mtface) { | if (mface && mtface) { | ||||
| mtface += num; | mtface += num; | ||||
| psys_interpolate_uvs(mtface, mface->v4, particle->fuv, r_uv); | psys_interpolate_uvs(mtface, mface->v4, particle->fuv, r_uv); | ||||
| return; | return; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 112 Lines • ▼ Show 20 Lines | |||||
| { | { | ||||
| ParticleSettings *part = NULL; | ParticleSettings *part = NULL; | ||||
| int totpart; | int totpart; | ||||
| int totchild = 0; | int totchild = 0; | ||||
| int totface; | int totface; | ||||
| int totvert; | int totvert; | ||||
| int num = -1; | int num = -1; | ||||
| BKE_mesh_tessface_ensure(modifier->mesh_final); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */ | Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(modifier); | ||||
| totface = modifier->mesh_final->totface; | BKE_mesh_tessface_ensure(mesh_final); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */ | ||||
| totvert = modifier->mesh_final->totvert; | totface = mesh_final->totface; | ||||
| totvert = mesh_final->totvert; | |||||
| /* 1. check that everything is ok & updated */ | /* 1. check that everything is ok & updated */ | ||||
| if (!particlesystem || !totface) { | if (!particlesystem || !totface) { | ||||
| return num; | return num; | ||||
| } | } | ||||
| part = particlesystem->part; | part = particlesystem->part; | ||||
| totpart = particlesystem->totcached; | totpart = particlesystem->totcached; | ||||
| Show All 16 Lines | if (particle_no < totpart) { | ||||
| if (ELEM(part->from, PART_FROM_FACE, PART_FROM_VOLUME)) { | if (ELEM(part->from, PART_FROM_FACE, PART_FROM_VOLUME)) { | ||||
| if (num != DMCACHE_NOTFOUND && num < totface) { | if (num != DMCACHE_NOTFOUND && num < totface) { | ||||
| *r_fuv = &particle->fuv; | *r_fuv = &particle->fuv; | ||||
| return num; | return num; | ||||
| } | } | ||||
| } | } | ||||
| else if (part->from == PART_FROM_VERT) { | else if (part->from == PART_FROM_VERT) { | ||||
| if (num != DMCACHE_NOTFOUND && num < totvert) { | if (num != DMCACHE_NOTFOUND && num < totvert) { | ||||
| MFace *mface = modifier->mesh_final->mface; | MFace *mface = mesh_final->mface; | ||||
| *r_fuv = &particle->fuv; | *r_fuv = &particle->fuv; | ||||
| /* This finds the first face to contain the emitting vertex, | /* This finds the first face to contain the emitting vertex, | ||||
| * this is not ideal, but is mostly fine as UV seams generally | * this is not ideal, but is mostly fine as UV seams generally | ||||
| * map to equal-colored parts of a texture */ | * map to equal-colored parts of a texture */ | ||||
| for (int i = 0; i < totface; i++, mface++) { | for (int i = 0; i < totface; i++, mface++) { | ||||
| if (ELEM(num, mface->v1, mface->v2, mface->v3, mface->v4)) { | if (ELEM(num, mface->v1, mface->v2, mface->v3, mface->v4)) { | ||||
| Show All 26 Lines | else { | ||||
| if (ELEM(part->from, PART_FROM_FACE, PART_FROM_VOLUME)) { | if (ELEM(part->from, PART_FROM_FACE, PART_FROM_VOLUME)) { | ||||
| if (num != DMCACHE_NOTFOUND && num < totface) { | if (num != DMCACHE_NOTFOUND && num < totface) { | ||||
| *r_fuv = &parent->fuv; | *r_fuv = &parent->fuv; | ||||
| return num; | return num; | ||||
| } | } | ||||
| } | } | ||||
| else if (part->from == PART_FROM_VERT) { | else if (part->from == PART_FROM_VERT) { | ||||
| if (num != DMCACHE_NOTFOUND && num < totvert) { | if (num != DMCACHE_NOTFOUND && num < totvert) { | ||||
| MFace *mface = modifier->mesh_final->mface; | MFace *mface = mesh_final->mface; | ||||
| *r_fuv = &parent->fuv; | *r_fuv = &parent->fuv; | ||||
| /* This finds the first face to contain the emitting vertex, | /* This finds the first face to contain the emitting vertex, | ||||
| * this is not ideal, but is mostly fine as UV seams generally | * this is not ideal, but is mostly fine as UV seams generally | ||||
| * map to equal-colored parts of a texture */ | * map to equal-colored parts of a texture */ | ||||
| for (int i = 0; i < totface; i++, mface++) { | for (int i = 0; i < totface; i++, mface++) { | ||||
| if (ELEM(num, mface->v1, mface->v2, mface->v3, mface->v4)) { | if (ELEM(num, mface->v1, mface->v2, mface->v3, mface->v4)) { | ||||
| Show All 11 Lines | |||||
| static void rna_ParticleSystem_uv_on_emitter(ParticleSystem *particlesystem, | static void rna_ParticleSystem_uv_on_emitter(ParticleSystem *particlesystem, | ||||
| ReportList *reports, | ReportList *reports, | ||||
| ParticleSystemModifierData *modifier, | ParticleSystemModifierData *modifier, | ||||
| ParticleData *particle, | ParticleData *particle, | ||||
| int particle_no, | int particle_no, | ||||
| int uv_no, | int uv_no, | ||||
| float r_uv[2]) | float r_uv[2]) | ||||
| { | { | ||||
| if (modifier->mesh_final == NULL) { | Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(modifier); | ||||
| if (mesh_final == NULL) { | |||||
| BKE_report(reports, RPT_ERROR, "Object was not yet evaluated"); | BKE_report(reports, RPT_ERROR, "Object was not yet evaluated"); | ||||
| zero_v2(r_uv); | zero_v2(r_uv); | ||||
| return; | return; | ||||
| } | } | ||||
| if (!CustomData_has_layer(&modifier->mesh_final->ldata, CD_MLOOPUV)) { | if (!CustomData_has_layer(&mesh_final->ldata, CD_MLOOPUV)) { | ||||
| BKE_report(reports, RPT_ERROR, "Mesh has no UV data"); | BKE_report(reports, RPT_ERROR, "Mesh has no UV data"); | ||||
| zero_v2(r_uv); | zero_v2(r_uv); | ||||
| return; | return; | ||||
| } | } | ||||
| { | { | ||||
| float(*fuv)[4]; | float(*fuv)[4]; | ||||
| /* Note all sanity checks are done in this helper func. */ | /* Note all sanity checks are done in this helper func. */ | ||||
| const int num = rna_ParticleSystem_tessfaceidx_on_emitter( | const int num = rna_ParticleSystem_tessfaceidx_on_emitter( | ||||
| particlesystem, modifier, particle, particle_no, &fuv); | particlesystem, modifier, particle, particle_no, &fuv); | ||||
| if (num < 0) { | if (num < 0) { | ||||
| /* No matching face found. */ | /* No matching face found. */ | ||||
| zero_v2(r_uv); | zero_v2(r_uv); | ||||
| } | } | ||||
| else { | else { | ||||
| MFace *mface = &modifier->mesh_final->mface[num]; | MFace *mface = &mesh_final->mface[num]; | ||||
| MTFace *mtface = (MTFace *)CustomData_get_layer_n( | MTFace *mtface = (MTFace *)CustomData_get_layer_n(&mesh_final->fdata, CD_MTFACE, uv_no); | ||||
| &modifier->mesh_final->fdata, CD_MTFACE, uv_no); | |||||
| psys_interpolate_uvs(&mtface[num], mface->v4, *fuv, r_uv); | psys_interpolate_uvs(&mtface[num], mface->v4, *fuv, r_uv); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| static void rna_ParticleSystem_mcol_on_emitter(ParticleSystem *particlesystem, | static void rna_ParticleSystem_mcol_on_emitter(ParticleSystem *particlesystem, | ||||
| ReportList *reports, | ReportList *reports, | ||||
| ParticleSystemModifierData *modifier, | ParticleSystemModifierData *modifier, | ||||
| ParticleData *particle, | ParticleData *particle, | ||||
| int particle_no, | int particle_no, | ||||
| int vcol_no, | int vcol_no, | ||||
| float r_mcol[3]) | float r_mcol[3]) | ||||
| { | { | ||||
| if (!CustomData_has_layer(&modifier->mesh_final->ldata, CD_MLOOPCOL)) { | Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(modifier); | ||||
| if (!CustomData_has_layer(&mesh_final->ldata, CD_MLOOPCOL)) { | |||||
| BKE_report(reports, RPT_ERROR, "Mesh has no VCol data"); | BKE_report(reports, RPT_ERROR, "Mesh has no VCol data"); | ||||
| zero_v3(r_mcol); | zero_v3(r_mcol); | ||||
| return; | return; | ||||
| } | } | ||||
| { | { | ||||
| float(*fuv)[4]; | float(*fuv)[4]; | ||||
| /* Note all sanity checks are done in this helper func. */ | /* Note all sanity checks are done in this helper func. */ | ||||
| const int num = rna_ParticleSystem_tessfaceidx_on_emitter( | const int num = rna_ParticleSystem_tessfaceidx_on_emitter( | ||||
| particlesystem, modifier, particle, particle_no, &fuv); | particlesystem, modifier, particle, particle_no, &fuv); | ||||
| if (num < 0) { | if (num < 0) { | ||||
| /* No matching face found. */ | /* No matching face found. */ | ||||
| zero_v3(r_mcol); | zero_v3(r_mcol); | ||||
| } | } | ||||
| else { | else { | ||||
| MFace *mface = &modifier->mesh_final->mface[num]; | MFace *mface = &mesh_final->mface[num]; | ||||
| MCol *mc = (MCol *)CustomData_get_layer_n(&modifier->mesh_final->fdata, CD_MCOL, vcol_no); | MCol *mc = (MCol *)CustomData_get_layer_n(&mesh_final->fdata, CD_MCOL, vcol_no); | ||||
| MCol mcol; | MCol mcol; | ||||
| psys_interpolate_mcol(&mc[num * 4], mface->v4, *fuv, &mcol); | psys_interpolate_mcol(&mc[num * 4], mface->v4, *fuv, &mcol); | ||||
| r_mcol[0] = (float)mcol.b / 255.0f; | r_mcol[0] = (float)mcol.b / 255.0f; | ||||
| r_mcol[1] = (float)mcol.g / 255.0f; | r_mcol[1] = (float)mcol.g / 255.0f; | ||||
| r_mcol[2] = (float)mcol.r / 255.0f; | r_mcol[2] = (float)mcol.r / 255.0f; | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 3,297 Lines • Show Last 20 Lines | |||||