diff options
Diffstat (limited to 'source/blender/makesrna/intern/rna_particle.c')
-rw-r--r-- | source/blender/makesrna/intern/rna_particle.c | 388 |
1 files changed, 386 insertions, 2 deletions
diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index 93f940b1aa3..be3cbfaece3 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -238,7 +238,329 @@ static void rna_ParticleHairKey_location_object_set(PointerRNA *ptr, const float } } -/* property update functions */ +static void rna_ParticleHairKey_co_object(HairKey *hairkey, Object *object, ParticleSystemModifierData *modifier, ParticleData *particle, + float n_co[3]) +{ + + DerivedMesh *hairdm = (modifier->psys->flag & PSYS_HAIR_DYNAMICS) ? modifier->psys->hair_out_dm : NULL; + if (particle) { + if (hairdm) { + MVert *mvert = CDDM_get_vert(hairdm, particle->hair_index + (hairkey - particle->hair)); + copy_v3_v3(n_co, mvert->co); + } + else { + float hairmat[4][4]; + psys_mat_hair_to_object(object, modifier->dm, modifier->psys->part->from, particle, hairmat); + copy_v3_v3(n_co, hairkey->co); + mul_m4_v3(hairmat, n_co); + } + } + else { + zero_v3(n_co); + } +} + +static void rna_Particle_uv_on_emitter(ParticleData *particle, ParticleSystemModifierData *modifier, float n_uv[2]) +{ + /*psys_particle_on_emitter(psmd, part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, co, nor, 0, 0, sd.orco, 0);*/ + + /* get uvco & mcol */ + int num = particle->num_dmcache; + int from = modifier->psys->part->from; + + if (num == DMCACHE_NOTFOUND) + if (particle->num < modifier->dm->getNumTessFaces(modifier->dm)) + num = particle->num; + + /* get uvco */ + if (n_uv && ELEM(from, PART_FROM_FACE, PART_FROM_VOLUME)) { + + if (num != DMCACHE_NOTFOUND) { + MFace *mface = modifier->dm->getTessFaceData(modifier->dm, num, CD_MFACE); + MTFace *mtface = (MTFace *)CustomData_get_layer_n(&modifier->dm->faceData, CD_MTFACE, 0); + mtface += num; + + psys_interpolate_uvs(mtface, mface->v4, particle->fuv, n_uv); + } + else { + n_uv[0] = 0.0f; + n_uv[1] = 0.0f; + } + } +} + +static void rna_ParticleSystem_co_hair(ParticleSystem *particlesystem, Object *object, ParticleSystemModifierData *modifier, int particle_no, int step, + float n_co[3]) +{ + ParticleSettings *part = 0; + ParticleData *pars = 0; + ParticleCacheKey *cache = 0; + int totchild = 0; + int path_nbr = 0; + int totpart; + int max_k = 0; + + if (particlesystem == NULL) + return; + + part = particlesystem->part; + pars = particlesystem->particles; + + if (part == NULL || pars == NULL || !psys_check_enabled(object, particlesystem)) + return; + + if (part->ren_as == PART_DRAW_OB || part->ren_as == PART_DRAW_GR || part->ren_as == PART_DRAW_NOT) + return; + + totchild = particlesystem->totchild * part->disp / 100; + + /* can happen for disconnected/global hair */ + if (part->type == PART_HAIR && !particlesystem->childcache) + totchild = 0; + + totpart = particlesystem->totpart; + + if (particle_no >= totpart + totchild) + return; + + if (part->ren_as == PART_DRAW_PATH && particlesystem->pathcache) + path_nbr = (int)pow(2.0, part->draw_step); + + if (particle_no < totpart) { + + if (path_nbr) { + cache = particlesystem->pathcache[particle_no]; + max_k = (int)cache->steps; + } + + } + else { + + if (path_nbr) { + cache = particlesystem->childcache[particle_no - totpart]; + + if (cache->steps < 0) + max_k = 0; + else + max_k = (int)cache->steps; + } + } + + /*strands key loop data stored in cache + step->co*/ + if (path_nbr) { + if (step >= 0 && step <= path_nbr) { + if (step <= max_k) + copy_v3_v3(n_co, (cache + step)->co); + } + } + +} + +static void rna_ParticleSystem_uv_on_emitter(ParticleSystem *particlesystem, ParticleSystemModifierData *modifier, ParticleData *particle, int particle_no, + float n_uv[2]) +{ + ParticleSettings *part = 0; + int totpart; + int totchild = 0; + int num; + + /* 1. check that everything is ok & updated */ + if (particlesystem == NULL) + return; + + part = particlesystem->part; + + totchild = particlesystem->totchild; + + /* can happen for disconnected/global hair */ + if (part->type == PART_HAIR && !particlesystem->childcache) + totchild = 0; + + totpart = particlesystem->totpart; + + if (particle_no >= totpart + totchild) + return; + +/* 3. start creating renderable things */ + /* setup per particle individual stuff */ + if (particle_no < totpart) { + + /* get uvco & mcol */ + num = particle->num_dmcache; + + if (num == DMCACHE_NOTFOUND) + if (particle->num < modifier->dm->getNumTessFaces(modifier->dm)) + num = particle->num; + + if (n_uv && ELEM(part->from, PART_FROM_FACE, PART_FROM_VOLUME)) { + if (num != DMCACHE_NOTFOUND) { + MFace *mface = modifier->dm->getTessFaceData(modifier->dm, num, CD_MFACE); + MTFace *mtface = (MTFace *)CustomData_get_layer_n(&modifier->dm->faceData, CD_MTFACE, 0); + mtface += num; + + psys_interpolate_uvs(mtface, mface->v4, particle->fuv, n_uv); + } + else { + n_uv[0] = 0.0f; + n_uv[1] = 0.0f; + } + } + } + else { + ChildParticle *cpa = particlesystem->child + particle_no - totpart; + + num = cpa->num; + + /* get uvco & mcol */ + if (part->childtype == PART_CHILD_FACES) { + if (n_uv && ELEM(PART_FROM_FACE, PART_FROM_FACE, PART_FROM_VOLUME)) { + if (cpa->num != DMCACHE_NOTFOUND) { + MFace *mface = modifier->dm->getTessFaceData(modifier->dm, cpa->num, CD_MFACE); + MTFace *mtface = (MTFace *)CustomData_get_layer_n(&modifier->dm->faceData, CD_MTFACE, 0); + mtface += cpa->num; + + psys_interpolate_uvs(mtface, mface->v4, cpa->fuv, n_uv); + } + else { + n_uv[0] = 0.0f; + n_uv[1] = 0.0f; + } + } + } + else { + ParticleData *parent = particlesystem->particles + cpa->parent; + num = parent->num_dmcache; + + if (num == DMCACHE_NOTFOUND) + if (parent->num < modifier->dm->getNumTessFaces(modifier->dm)) + num = parent->num; + + if (n_uv && ELEM(part->from, PART_FROM_FACE, PART_FROM_VOLUME)) { + if (num != DMCACHE_NOTFOUND) { + MFace *mface = modifier->dm->getTessFaceData(modifier->dm, num, CD_MFACE); + MTFace *mtface = (MTFace *)CustomData_get_layer_n(&modifier->dm->faceData, CD_MTFACE, 0); + mtface += num; + + psys_interpolate_uvs(mtface, mface->v4, parent->fuv, n_uv); + } + else { + n_uv[0] = 0.0f; + n_uv[1] = 0.0f; + } + } + } + } +} + +static void rna_ParticleSystem_mcol_on_emitter(ParticleSystem *particlesystem, ParticleSystemModifierData *modifier, ParticleData *particle, int particle_no, int vcol_no, + float n_mcol[3]) +{ + ParticleSettings *part = 0; + int totpart; + int totchild = 0; + int num; + MCol mcol = {255, 255, 255, 255}; + + /* 1. check that everything is ok & updated */ + if (particlesystem == NULL) + return; + + part = particlesystem->part; + + totchild = particlesystem->totchild; + + /* can happen for disconnected/global hair */ + if (part->type == PART_HAIR && !particlesystem->childcache) + totchild = 0; + + totpart = particlesystem->totpart; + + if (particle_no >= totpart + totchild) + return; + +/* 3. start creating renderable things */ + /* setup per particle individual stuff */ + if (particle_no < totpart) { + + /* get uvco & mcol */ + num = particle->num_dmcache; + + if (num == DMCACHE_NOTFOUND) + if (particle->num < modifier->dm->getNumTessFaces(modifier->dm)) + num = particle->num; + + if (n_mcol && ELEM(part->from, PART_FROM_FACE, PART_FROM_VOLUME)) { + if (num != DMCACHE_NOTFOUND) { + MFace *mface = modifier->dm->getTessFaceData(modifier->dm, num, CD_MFACE); + MCol *mc = (MCol*)CustomData_get_layer_n(&modifier->dm->faceData, CD_MCOL, vcol_no); + mc += num * 4; + + psys_interpolate_mcol(mc, mface->v4, particle->fuv, &mcol); + n_mcol[0] = (float)mcol.b / 255.0f; + n_mcol[1] = (float)mcol.g / 255.0f; + n_mcol[2] = (float)mcol.r / 255.0f; + } + else { + n_mcol[0] = 0.0f; + n_mcol[1] = 0.0f; + n_mcol[2] = 0.0f; + } + } + } + else { + ChildParticle *cpa = particlesystem->child + particle_no - totpart; + + num = cpa->num; + + /* get uvco & mcol */ + if (part->childtype == PART_CHILD_FACES) { + if (n_mcol && ELEM(PART_FROM_FACE, PART_FROM_FACE, PART_FROM_VOLUME)) { + if (cpa->num != DMCACHE_NOTFOUND) { + MFace *mface = modifier->dm->getTessFaceData(modifier->dm, cpa->num, CD_MFACE); + MCol *mc = (MCol*)CustomData_get_layer_n(&modifier->dm->faceData, CD_MCOL, 0); + mc += cpa->num * 4; + + psys_interpolate_mcol(mc, mface->v4, cpa->fuv, &mcol); + n_mcol[0] = (float)mcol.b / 255.0f; + n_mcol[1] = (float)mcol.g / 255.0f; + n_mcol[2] = (float)mcol.r / 255.0f; + } + else { + n_mcol[0] = 0.0f; + n_mcol[1] = 0.0f; + n_mcol[2] = 0.0f; + } + } + } + else { + ParticleData *parent = particlesystem->particles + cpa->parent; + num = parent->num_dmcache; + + if (num == DMCACHE_NOTFOUND) + if (parent->num < modifier->dm->getNumTessFaces(modifier->dm)) + num = parent->num; + + if (n_mcol && ELEM(part->from, PART_FROM_FACE, PART_FROM_VOLUME)) { + if (num != DMCACHE_NOTFOUND) { + MFace *mface = modifier->dm->getTessFaceData(modifier->dm, num, CD_MFACE); + MCol *mc = (MCol*)CustomData_get_layer_n(&modifier->dm->faceData, CD_MCOL, 0); + mc += num * 4; + + psys_interpolate_mcol(mc, mface->v4, parent->fuv, &mcol); + n_mcol[0] = (float)mcol.b / 255.0f; + n_mcol[1] = (float)mcol.g / 255.0f; + n_mcol[2] = (float)mcol.r / 255.0f; + } + else { + n_mcol[0] = 0.0f; + n_mcol[1] = 0.0f; + n_mcol[2] = 0.0f; + } + } + } + } +} + static void particle_recalc(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr, short flag) { if (ptr->type == &RNA_ParticleSystem) { @@ -905,6 +1227,7 @@ static void rna_def_particle_hair_key(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; + FunctionRNA *func; srna = RNA_def_struct(brna, "ParticleHairKey", NULL); RNA_def_struct_sdna(srna, "HairKey"); @@ -928,6 +1251,19 @@ static void rna_def_particle_hair_key(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Location", "Location of the hair key in its internal coordinate system, " "relative to the emitting face"); + + /* Aided co func */ + func = RNA_def_function(srna, "co_object", "rna_ParticleHairKey_co_object"); + RNA_def_function_ui_description(func, "Obtain hairkey location with particle and modifier data"); + + prop = RNA_def_pointer(func, "object", "Object", "", "Object"); + prop = RNA_def_pointer(func, "modifier", "ParticleSystemModifier", "", "Particle modifier"); + prop = RNA_def_pointer(func, "particle", "Particle", "", "hair particle"); + + prop = RNA_def_float_vector(func, "co", 3, NULL, -FLT_MAX, FLT_MAX, "Co", + "Exported hairkey location", -1e4, 1e4); + RNA_def_property_flag(prop, PROP_THICK_WRAP); + RNA_def_function_output(func, prop); } static void rna_def_particle_key(BlenderRNA *brna) @@ -979,6 +1315,7 @@ static void rna_def_particle(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; + FunctionRNA *func; static EnumPropertyItem alive_items[] = { /*{PARS_KILLED, "KILLED", 0, "Killed", ""}, */ @@ -1083,6 +1420,15 @@ static void rna_def_particle(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Alive State", ""); /* short rt2; */ + +/* UVs */ + func = RNA_def_function(srna, "uv_on_emitter", "rna_Particle_uv_on_emitter"); + RNA_def_function_ui_description(func, "Obtain uv for particle on derived mesh"); + prop = RNA_def_pointer(func, "modifier", "ParticleSystemModifier", "", "Particle modifier"); + prop = RNA_def_property(func, "uv", PROP_FLOAT, PROP_COORDS); + RNA_def_property_array(prop, 2); + RNA_def_property_flag(prop, PROP_THICK_WRAP); + RNA_def_function_output(func, prop); } static void rna_def_particle_dupliweight(BlenderRNA *brna) @@ -2696,6 +3042,7 @@ static void rna_def_particle_system(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; + FunctionRNA *func; srna = RNA_def_struct(brna, "ParticleSystem", NULL); RNA_def_struct_ui_text(srna, "Particle System", "Particle system in an object"); @@ -2793,7 +3140,6 @@ static void rna_def_particle_system(BlenderRNA *brna) "rna_ParticleSystem_active_particle_target_index_range"); RNA_def_property_ui_text(prop, "Active Particle Target Index", ""); - /* billboard */ prop = RNA_def_property(srna, "billboard_normal_uv", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "bb_uvname[0]"); @@ -2995,6 +3341,44 @@ static void rna_def_particle_system(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_struct_path_func(srna, "rna_ParticleSystem_path"); + + /* extract cached hair location data */ + func = RNA_def_function(srna, "co_hair", "rna_ParticleSystem_co_hair"); + RNA_def_function_ui_description(func, "Obtain cache hair data"); + + prop = RNA_def_pointer(func, "object", "Object", "", "Object"); + prop = RNA_def_pointer(func, "modifier", "ParticleSystemModifier", "", "Particle modifier"); + prop = RNA_def_int(func, "particle_no", 0, INT_MIN, INT_MAX, "Particle no", "", INT_MIN, INT_MAX); + prop = RNA_def_int(func, "step", 0, INT_MIN, INT_MAX, "step no", "", INT_MIN, INT_MAX); + + prop = RNA_def_float_vector(func, "co", 3, NULL, -FLT_MAX, FLT_MAX, "Co", + "Exported hairkey location", -1e4, 1e4); + RNA_def_property_flag(prop, PROP_THICK_WRAP); + RNA_def_function_output(func, prop); + + /* extract hair UVs */ + func = RNA_def_function(srna, "uv_on_emitter", "rna_ParticleSystem_uv_on_emitter"); + RNA_def_function_ui_description(func, "Obtain uv for all particles"); + prop = RNA_def_pointer(func, "modifier", "ParticleSystemModifier", "", "Particle modifier"); + prop = RNA_def_pointer(func, "particle", "Particle", "", "Particle"); + prop = RNA_def_int(func, "particle_no", 0, INT_MIN, INT_MAX, "Particle no", "", INT_MIN, INT_MAX); + prop = RNA_def_property(func, "uv", PROP_FLOAT, PROP_COORDS); + RNA_def_property_array(prop, 2); + RNA_def_property_flag(prop, PROP_THICK_WRAP); + RNA_def_function_output(func, prop); + + /* extract hair mcols */ + func = RNA_def_function(srna, "mcol_on_emitter", "rna_ParticleSystem_mcol_on_emitter"); + RNA_def_function_ui_description(func, "Obtain mcol for all particles"); + prop = RNA_def_pointer(func, "modifier", "ParticleSystemModifier", "", "Particle modifier"); + prop = RNA_def_pointer(func, "particle", "Particle", "", "Particle"); + prop = RNA_def_int(func, "particle_no", 0, INT_MIN, INT_MAX, "Particle no", "", INT_MIN, INT_MAX); + prop = RNA_def_int(func, "vcol_no", 0, INT_MIN, INT_MAX, "vcol no", "", INT_MIN, INT_MAX); + prop = RNA_def_property(func, "mcol", PROP_FLOAT, PROP_COLOR); + RNA_def_property_array(prop, 3); + RNA_def_property_flag(prop, PROP_THICK_WRAP); + RNA_def_function_output(func, prop); + } void RNA_def_particle(BlenderRNA *brna) |