diff options
author | Janne Karhu <jhkarh@gmail.com> | 2011-03-09 17:18:33 +0300 |
---|---|---|
committer | Janne Karhu <jhkarh@gmail.com> | 2011-03-09 17:18:33 +0300 |
commit | f89fc824aae4212391e26a8b9db62bfe69ae05d6 (patch) | |
tree | 70de7a0fc6271a3bc97e1b8244730099a735d675 | |
parent | 3e8c838a99830012d447d218975653858d6c6ccf (diff) |
Fix for [#26372] Objects as PS Hair displays and renders differently
* Grid distribution isn't really suited for hair, so this is now disabled.
* Setting a jittered distribution with particles/face = 1 now creates particles on the center of faces.
* Quite a bit of cleanup of the whole particle distribution code.
-rw-r--r-- | source/blender/blenkernel/BKE_particle.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/anim.c | 6 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/particle.c | 92 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/particle_system.c | 528 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_particle_types.h | 2 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_particle.c | 35 | ||||
-rw-r--r-- | source/blender/render/intern/source/convertblender.c | 23 |
7 files changed, 297 insertions, 391 deletions
diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h index 507adcc5f2d..e4fbd5603f2 100644 --- a/source/blender/blenkernel/BKE_particle.h +++ b/source/blender/blenkernel/BKE_particle.h @@ -242,7 +242,7 @@ void psys_get_particle_on_path(struct ParticleSimulationData *sim, int pa_num, s int psys_get_particle_state(struct ParticleSimulationData *sim, int p, struct ParticleKey *state, int always); /* for anim.c */ -void psys_get_dupli_texture(struct Object *ob, struct ParticleSettings *part, struct ParticleSystemModifierData *psmd, struct ParticleData *pa, struct ChildParticle *cpa, float *uv, float *orco); +void psys_get_dupli_texture(struct ParticleSystem *psys, struct ParticleSettings *part, struct ParticleSystemModifierData *psmd, struct ParticleData *pa, struct ChildParticle *cpa, float *uv, float *orco); void psys_get_dupli_path_transform(struct ParticleSimulationData *sim, struct ParticleData *pa, struct ChildParticle *cpa, struct ParticleCacheKey *cache, float mat[][4], float *scale); ParticleThread *psys_threads_create(struct ParticleSimulationData *sim); diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index 39fea333cbc..2e1fbf2917a 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -1346,8 +1346,6 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p /* for groups, pick the object based on settings */ if(part->draw&PART_DRAW_RAND_GR) b= BLI_rand() % totgroup; - else if(part->from==PART_FROM_PARTICLE) - b= pa_num % totgroup; else b= a % totgroup; @@ -1402,7 +1400,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p dob= new_dupli_object(lb, go->ob, mat, par->lay, counter, OB_DUPLIPARTS, animated); copy_m4_m4(dob->omat, obcopylist[b].obmat); if(G.rendering) - psys_get_dupli_texture(par, part, sim.psmd, pa, cpa, dob->uv, dob->orco); + psys_get_dupli_texture(psys, part, sim.psmd, pa, cpa, dob->uv, dob->orco); } } else { @@ -1434,7 +1432,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p dob= new_dupli_object(lb, ob, mat, ob->lay, counter, GS(id->name) == ID_GR ? OB_DUPLIGROUP : OB_DUPLIPARTS, animated); copy_m4_m4(dob->omat, oldobmat); if(G.rendering) - psys_get_dupli_texture(par, part, sim.psmd, pa, cpa, dob->uv, dob->orco); + psys_get_dupli_texture(psys, part, sim.psmd, pa, cpa, dob->uv, dob->orco); } } diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index ebbdb7a8788..e2a23f5bc6c 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -2407,7 +2407,7 @@ static int psys_threads_init_path(ParticleThread *threads, Scene *scene, float c steps = (int)pow(2.0, (double)pset->draw_step); } - if(totchild && part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES){ + if(totchild && part->childtype==PART_CHILD_FACES){ totparent=(int)(totchild*part->parents*0.3); if(G.rendering && part->child_nbr && part->ren_child_nbr) @@ -2449,16 +2449,14 @@ static int psys_threads_init_path(ParticleThread *threads, Scene *scene, float c psys->lattice = psys_get_lattice(&ctx->sim); /* cache all relevant vertex groups if they exist */ - if(part->from!=PART_FROM_PARTICLE){ - ctx->vg_length = psys_cache_vgroup(ctx->dm,psys,PSYS_VG_LENGTH); - ctx->vg_clump = psys_cache_vgroup(ctx->dm,psys,PSYS_VG_CLUMP); - ctx->vg_kink = psys_cache_vgroup(ctx->dm,psys,PSYS_VG_KINK); - ctx->vg_rough1 = psys_cache_vgroup(ctx->dm,psys,PSYS_VG_ROUGH1); - ctx->vg_rough2 = psys_cache_vgroup(ctx->dm,psys,PSYS_VG_ROUGH2); - ctx->vg_roughe = psys_cache_vgroup(ctx->dm,psys,PSYS_VG_ROUGHE); - if(psys->part->flag & PART_CHILD_EFFECT) - ctx->vg_effector = psys_cache_vgroup(ctx->dm,psys,PSYS_VG_EFFECTOR); - } + ctx->vg_length = psys_cache_vgroup(ctx->dm,psys,PSYS_VG_LENGTH); + ctx->vg_clump = psys_cache_vgroup(ctx->dm,psys,PSYS_VG_CLUMP); + ctx->vg_kink = psys_cache_vgroup(ctx->dm,psys,PSYS_VG_KINK); + ctx->vg_rough1 = psys_cache_vgroup(ctx->dm,psys,PSYS_VG_ROUGH1); + ctx->vg_rough2 = psys_cache_vgroup(ctx->dm,psys,PSYS_VG_ROUGH2); + ctx->vg_roughe = psys_cache_vgroup(ctx->dm,psys,PSYS_VG_ROUGHE); + if(psys->part->flag & PART_CHILD_EFFECT) + ctx->vg_effector = psys_cache_vgroup(ctx->dm,psys,PSYS_VG_EFFECTOR); /* set correct ipo timing */ #if 0 // XXX old animation system @@ -2912,8 +2910,8 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra) if(ma && (psys->part->draw & PART_DRAW_MAT_COL)) VECCOPY(col, &ma->r) - if(psys->part->from!=PART_FROM_PARTICLE && !(psys->flag & PSYS_GLOBAL_HAIR)) { - if(!(psys->part->flag & PART_CHILD_EFFECT)) + if((psys->flag & PSYS_GLOBAL_HAIR)==0) { + if((psys->part->flag & PART_CHILD_EFFECT)==0) vg_effector = psys_cache_vgroup(psmd->dm, psys, PSYS_VG_EFFECTOR); if(!psys->totchild) @@ -4042,7 +4040,7 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey * if(state->time < 0.0f) t = psys_get_child_time(psys, cpa, -state->time, NULL, NULL); - if(totchild && part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES){ + if(totchild && part->childtype==PART_CHILD_FACES){ /* part->parents could still be 0 so we can't test with totparent */ between=1; } @@ -4192,7 +4190,7 @@ int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *sta if(!psys->totchild) return 0; - if(part->from != PART_FROM_PARTICLE && part->childtype == PART_CHILD_FACES){ + if(part->childtype == PART_CHILD_FACES){ if(!(psys->flag & PSYS_KEYED)) return 0; @@ -4314,13 +4312,15 @@ int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *sta } } -void psys_get_dupli_texture(Object *UNUSED(ob), ParticleSettings *part, ParticleSystemModifierData *psmd, ParticleData *pa, ChildParticle *cpa, float *uv, float *orco) +void psys_get_dupli_texture(ParticleSystem *psys, ParticleSettings *part, ParticleSystemModifierData *psmd, ParticleData *pa, ChildParticle *cpa, float *uv, float *orco) { MFace *mface; MTFace *mtface; float loc[3]; int num; + uv[0] = uv[1] = 0.f; + if(cpa) { if(part->childtype == PART_CHILD_FACES) { mtface= CustomData_get_layer(&psmd->dm->faceData, CD_MTFACE); @@ -4329,43 +4329,36 @@ void psys_get_dupli_texture(Object *UNUSED(ob), ParticleSettings *part, Particle mtface += cpa->num; psys_interpolate_uvs(mtface, mface->v4, cpa->fuv, uv); } - else - uv[0]= uv[1]= 0.0f; + + psys_particle_on_emitter(psmd,PART_FROM_FACE,cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,loc,0,0,0,orco,0); + return; + } + else { + pa = psys->particles + cpa->pa[0]; } - else - uv[0]= uv[1]= 0.0f; - - psys_particle_on_emitter(psmd, - (part->childtype == PART_CHILD_FACES)? PART_FROM_FACE: PART_FROM_PARTICLE, - cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,loc,0,0,0,orco,0); } - else { - if(part->from == PART_FROM_FACE) { - mtface= CustomData_get_layer(&psmd->dm->faceData, CD_MTFACE); - num= pa->num_dmcache; - if(num == DMCACHE_NOTFOUND) - num= pa->num; + if(part->from == PART_FROM_FACE) { + mtface= CustomData_get_layer(&psmd->dm->faceData, CD_MTFACE); + num= pa->num_dmcache; - if (num >= psmd->dm->getNumFaces(psmd->dm)) { - /* happens when simplify is enabled - * gives invalid coords but would crash otherwise */ - num= DMCACHE_NOTFOUND; - } + if(num == DMCACHE_NOTFOUND) + num= pa->num; - if(mtface && num != DMCACHE_NOTFOUND) { - mface= psmd->dm->getFaceData(psmd->dm, num, CD_MFACE); - mtface += num; - psys_interpolate_uvs(mtface, mface->v4, pa->fuv, uv); - } - else - uv[0]= uv[1]= 0.0f; + if (num >= psmd->dm->getNumFaces(psmd->dm)) { + /* happens when simplify is enabled + * gives invalid coords but would crash otherwise */ + num= DMCACHE_NOTFOUND; } - else - uv[0]= uv[1]= 0.0f; - psys_particle_on_emitter(psmd,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,loc,0,0,0,orco,0); + if(mtface && num != DMCACHE_NOTFOUND) { + mface= psmd->dm->getFaceData(psmd->dm, num, CD_MFACE); + mtface += num; + psys_interpolate_uvs(mtface, mface->v4, pa->fuv, uv); + } } + + psys_particle_on_emitter(psmd,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,loc,0,0,0,orco,0); } void psys_get_dupli_path_transform(ParticleSimulationData *sim, ParticleData *pa, ChildParticle *cpa, ParticleCacheKey *cache, float mat[][4], float *scale) @@ -4380,7 +4373,7 @@ void psys_get_dupli_path_transform(ParticleSimulationData *sim, ParticleData *pa len= normalize_v3(vec); if(psys->part->rotmode) { - if(!pa) + if(pa == NULL) pa= psys->particles+cpa->pa[0]; vec_to_quat( q,xvec, ob->trackflag, ob->upflag); @@ -4391,12 +4384,13 @@ void psys_get_dupli_path_transform(ParticleSimulationData *sim, ParticleData *pa mul_m4_m4m4(mat, obrotmat, qmat); } else { + if(pa == NULL && psys->part->childflat != PART_CHILD_FACES) + pa = psys->particles + cpa->pa[0]; + if(pa) psys_particle_on_emitter(psmd,sim->psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,loc,nor,0,0,0,0); else - psys_particle_on_emitter(psmd, - (psys->part->childtype == PART_CHILD_FACES)? PART_FROM_FACE: PART_FROM_PARTICLE, - cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,loc,nor,0,0,0,0); + psys_particle_on_emitter(psmd,PART_FROM_FACE,cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,loc,nor,0,0,0,0); copy_m3_m4(nmat, ob->imat); transpose_m3(nmat); diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 336b683e26b..15c6b30d4e5 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -329,6 +329,10 @@ static void alloc_child_particles(ParticleSystem *psys, int tot) } } +/************************************************/ +/* Distribution */ +/************************************************/ + void psys_calc_dmcache(Object *ob, DerivedMesh *dm, ParticleSystem *psys) { /* use for building derived mesh mapping info: @@ -405,7 +409,35 @@ void psys_calc_dmcache(Object *ob, DerivedMesh *dm, ParticleSystem *psys) } } -static void distribute_particles_in_grid(DerivedMesh *dm, ParticleSystem *psys) +static void distribute_simple_children(Scene *scene, Object *ob, DerivedMesh *finaldm, ParticleSystem *psys) +{ + ChildParticle *cpa = psys->child; + int i, p; + int child_nbr= get_psys_child_number(scene, psys); + int totpart= get_psys_tot_child(scene, psys); + + alloc_child_particles(psys, totpart); + + for(i=0; i<child_nbr; i++){ + for(p=0; p<psys->totpart; p++,cpa++){ + float length=2.0; + cpa->parent=p; + + /* create even spherical distribution inside unit sphere */ + while(length>=1.0f){ + cpa->fuv[0]=2.0f*BLI_frand()-1.0f; + cpa->fuv[1]=2.0f*BLI_frand()-1.0f; + cpa->fuv[2]=2.0f*BLI_frand()-1.0f; + length=len_v3(cpa->fuv); + } + + cpa->num=-1; + } + } + /* dmcache must be updated for parent particles if children from faces is used */ + psys_calc_dmcache(ob, finaldm, psys); +} +static void distribute_grid(DerivedMesh *dm, ParticleSystem *psys) { ParticleData *pa=NULL; float min[3], max[3], delta[3], d; @@ -686,7 +718,7 @@ static void psys_uv_to_w(float u, float v, int quad, float *w) } /* Find the index in "sum" array before "value" is crossed. */ -static int binary_search_distribution(float *sum, int n, float value) +static int distribute_binary_search(float *sum, int n, float value) { int mid, low=0, high=n; @@ -716,13 +748,11 @@ static int binary_search_distribution(float *sum, int n, float value) /* note: this function must be thread safe, for from == PART_FROM_CHILD */ #define ONLY_WORKING_WITH_PA_VERTS 0 -static void psys_thread_distribute_particle(ParticleThread *thread, ParticleData *pa, ChildParticle *cpa, int p) +static void distribute_threads_exec(ParticleThread *thread, ParticleData *pa, ChildParticle *cpa, int p) { ParticleThreadContext *ctx= thread->ctx; Object *ob= ctx->sim.ob; DerivedMesh *dm= ctx->dm; - ParticleData *tpa; -/* ParticleSettings *part= ctx->sim.psys->part; */ float *v1, *v2, *v3, *v4, nor[3], orco1[3], co1[3], co2[3], nor1[3]; float cur_d, min_d, randu, randv; int from= ctx->from; @@ -760,9 +790,17 @@ static void psys_thread_distribute_particle(ParticleThread *thread, ParticleData switch(distr){ case PART_DISTR_JIT: - ctx->jitoff[i] = fmod(ctx->jitoff[i],(float)ctx->jitlevel); - psys_uv_to_w(ctx->jit[2*(int)ctx->jitoff[i]], ctx->jit[2*(int)ctx->jitoff[i]+1], mface->v4, pa->fuv); - ctx->jitoff[i]++; + if(ctx->jitlevel == 1) { + if(mface->v4) + psys_uv_to_w(0.5f, 0.5f, mface->v4, pa->fuv); + else + psys_uv_to_w(0.33333f, 0.33333f, mface->v4, pa->fuv); + } + else { + ctx->jitoff[i] = fmod(ctx->jitoff[i],(float)ctx->jitlevel); + psys_uv_to_w(ctx->jit[2*(int)ctx->jitoff[i]], ctx->jit[2*(int)ctx->jitoff[i]+1], mface->v4, pa->fuv); + ctx->jitoff[i]++; + } break; case PART_DISTR_RAND: randu= rng_getFloat(thread->rng); @@ -828,15 +866,6 @@ static void psys_thread_distribute_particle(ParticleThread *thread, ParticleData } } } - else if(from == PART_FROM_PARTICLE) { - tpa=ctx->tpars+ctx->index[p]; - pa->num=ctx->index[p]; - pa->fuv[0]=tpa->fuv[0]; - pa->fuv[1]=tpa->fuv[1]; - /* abusing foffset a little for timing in near reaction */ - pa->foffset=ctx->weight[ctx->index[p]]; - ctx->weight[ctx->index[p]]+=ctx->maxweight; - } else if(from == PART_FROM_CHILD) { MFace *mf; @@ -870,7 +899,6 @@ static void psys_thread_distribute_particle(ParticleThread *thread, ParticleData maxd=ptn[maxw-1].dist; mind=ptn[0].dist; - /*dd=maxd-mind;*/ /*UNUSED*/ /* the weights here could be done better */ for(w=0; w<maxw; w++){ @@ -906,7 +934,7 @@ static void psys_thread_distribute_particle(ParticleThread *thread, ParticleData rng_skip(thread->rng, rng_skip_tot); } -static void *exec_distribution(void *data) +static void *distribute_threads_exec_cb(void *data) { ParticleThread *thread= (ParticleThread*)data; ParticleSystem *psys= thread->ctx->sim.psys; @@ -923,7 +951,7 @@ static void *exec_distribution(void *data) rng_skip(thread->rng, PSYS_RND_DIST_SKIP * thread->ctx->skip[p]); if((p+thread->num) % thread->tot == 0) - psys_thread_distribute_particle(thread, NULL, cpa, p); + distribute_threads_exec(thread, NULL, cpa, p); else /* thread skip */ rng_skip(thread->rng, PSYS_RND_DIST_SKIP); } @@ -932,7 +960,7 @@ static void *exec_distribution(void *data) totpart= psys->totpart; pa= psys->particles + thread->num; for(p=thread->num; p<totpart; p+=thread->tot, pa+=thread->tot) - psys_thread_distribute_particle(thread, pa, NULL, p); + distribute_threads_exec(thread, pa, NULL, p); } return 0; @@ -940,7 +968,7 @@ static void *exec_distribution(void *data) /* not thread safe, but qsort doesn't take userdata argument */ static int *COMPARE_ORIG_INDEX = NULL; -static int compare_orig_index(const void *p1, const void *p2) +static int distribute_compare_orig_index(const void *p1, const void *p2) { int index1 = COMPARE_ORIG_INDEX[*(const int*)p1]; int index2 = COMPARE_ORIG_INDEX[*(const int*)p2]; @@ -961,44 +989,54 @@ static int compare_orig_index(const void *p1, const void *p2) return 1; } -/* creates a distribution of coordinates on a DerivedMesh */ -/* */ -/* 1. lets check from what we are emitting */ -/* 2. now we know that we have something to emit from so */ -/* let's calculate some weights */ -/* 2.1 from even distribution */ -/* 2.2 and from vertex groups */ -/* 3. next we determine the indexes of emitting thing that */ -/* the particles will have */ -/* 4. let's do jitter if we need it */ -/* 5. now we're ready to set the indexes & distributions to */ -/* the particles */ -/* 6. and we're done! */ +static void distribute_invalid(Scene *scene, ParticleSystem *psys, int from) +{ + if(from == PART_FROM_CHILD) { + ChildParticle *cpa; + int p, totchild = get_psys_tot_child(scene, psys); + + if(psys->child && totchild) { + for(p=0,cpa=psys->child; p<totchild; p++,cpa++){ + cpa->fuv[0]=cpa->fuv[1]=cpa->fuv[2]=cpa->fuv[3]= 0.0; + cpa->foffset= 0.0f; + cpa->parent=0; + cpa->pa[0]=cpa->pa[1]=cpa->pa[2]=cpa->pa[3]=0; + cpa->num= -1; + } + } + } + else { + PARTICLE_P; + LOOP_PARTICLES { + pa->fuv[0]=pa->fuv[1]=pa->fuv[2]= pa->fuv[3]= 0.0; + pa->foffset= 0.0f; + pa->num= -1; + } + } +} +/* Creates a distribution of coordinates on a DerivedMesh */ /* This is to denote functionality that does not yet work with mesh - only derived mesh */ -static int psys_threads_init_distribution(ParticleThread *threads, Scene *scene, DerivedMesh *finaldm, int from) +static int distribute_threads_init_data(ParticleThread *threads, Scene *scene, DerivedMesh *finaldm, int from) { ParticleThreadContext *ctx= threads[0].ctx; Object *ob= ctx->sim.ob; ParticleSystem *psys= ctx->sim.psys; - Object *tob; ParticleData *pa=0, *tpars= 0; ParticleSettings *part; - ParticleSystem *tpsys; ParticleSeam *seams= 0; ChildParticle *cpa=0; KDTree *tree=0; DerivedMesh *dm= NULL; float *jit= NULL; int i, seed, p=0, totthread= threads[0].tot; - int /*no_distr=0,*/ cfrom=0; - int tot=0, totpart, *index=0, children=0, totseam=0; - //int *vertpart=0; + int cfrom=0; + int totelem=0, totpart, *particle_element=0, children=0, totseam=0; int jitlevel= 1, distr; - float *weight=0,*sum=0,*jitoff=0; - float cur, maxweight=0.0, tweight, totweight, co[3], nor[3], orco[3], ornor[3]; + float *element_weight=NULL,*element_sum=NULL,*jitter_offset=NULL, *vweight=NULL; + float cur, maxweight=0.0, tweight, totweight, inv_totweight, co[3], nor[3], orco[3], ornor[3]; - if(ob==0 || psys==0 || psys->part==0) + if(ELEM3(NULL, ob, psys, psys->part)) return 0; part=psys->part; @@ -1012,81 +1050,63 @@ static int psys_threads_init_distribution(ParticleThread *threads, Scene *scene, return 0; } - BLI_srandom(31415926 + psys->seed); + /* First handle special cases */ + if(from == PART_FROM_CHILD) { + /* Simple children */ + if(part->childtype != PART_CHILD_FACES) { + BLI_srandom(31415926 + psys->seed + psys->child_seed); + distribute_simple_children(scene, ob, finaldm, psys); + return 0; + } + } + else { + /* Grid distribution */ + if(part->distr==PART_DISTR_GRID && from != PART_FROM_VERT){ + BLI_srandom(31415926 + psys->seed); + dm= CDDM_from_mesh((Mesh*)ob->data, ob); + distribute_grid(dm,psys); + dm->release(dm); + return 0; + } + } - if(from==PART_FROM_CHILD){ + /* Create trees and original coordinates if needed */ + if(from == PART_FROM_CHILD) { distr=PART_DISTR_RAND; BLI_srandom(31415926 + psys->seed + psys->child_seed); + dm= finaldm; + children=1; - if(part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES){ - dm= finaldm; - children=1; - - tree=BLI_kdtree_new(totpart); - - for(p=0,pa=psys->particles; p<totpart; p++,pa++){ - psys_particle_on_dm(dm,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,nor,0,0,orco,ornor); - transform_mesh_orco_verts((Mesh*)ob->data, &orco, 1, 1); - BLI_kdtree_insert(tree, p, orco, ornor); - } + totpart = get_psys_tot_child(scene, psys); + cfrom = from = PART_FROM_FACE; - BLI_kdtree_balance(tree); + tree=BLI_kdtree_new(totpart); - totpart=get_psys_tot_child(scene, psys); - cfrom=from=PART_FROM_FACE; + for(p=0,pa=psys->particles; p<totpart; p++,pa++){ + psys_particle_on_dm(dm,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,nor,0,0,orco,ornor); + transform_mesh_orco_verts((Mesh*)ob->data, &orco, 1, 1); + BLI_kdtree_insert(tree, p, orco, ornor); } - else{ - /* no need to figure out distribution */ - int child_nbr= get_psys_child_number(scene, psys); - - totpart= get_psys_tot_child(scene, psys); - alloc_child_particles(psys, totpart); - cpa=psys->child; - for(i=0; i<child_nbr; i++){ - for(p=0; p<psys->totpart; p++,cpa++){ - float length=2.0; - cpa->parent=p; - - /* create even spherical distribution inside unit sphere */ - while(length>=1.0f){ - cpa->fuv[0]=2.0f*BLI_frand()-1.0f; - cpa->fuv[1]=2.0f*BLI_frand()-1.0f; - cpa->fuv[2]=2.0f*BLI_frand()-1.0f; - length=len_v3(cpa->fuv); - } - cpa->num=-1; - } - } - /* dmcache must be updated for parent particles if children from faces is used */ - psys_calc_dmcache(ob, finaldm, psys); - - return 0; - } + BLI_kdtree_balance(tree); } - else{ + else { + distr = part->distr; + BLI_srandom(31415926 + psys->seed); + dm= CDDM_from_mesh((Mesh*)ob->data, ob); - /* special handling of grid distribution */ - if(part->distr==PART_DISTR_GRID && from != PART_FROM_VERT){ - distribute_particles_in_grid(dm,psys); - dm->release(dm); - return 0; - } - /* we need orco for consistent distributions */ DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, get_mesh_orco_verts(ob)); - distr=part->distr; - - if(from==PART_FROM_VERT){ + if(from == PART_FROM_VERT) { MVert *mv= dm->getVertDataArray(dm, CD_MVERT); float (*orcodata)[3]= dm->getVertDataArray(dm, CD_ORCO); int totvert = dm->getNumVerts(dm); tree=BLI_kdtree_new(totvert); - for(p=0; p<totvert; p++){ + for(p=0; p<totvert; p++) { if(orcodata) { VECCOPY(co,orcodata[p]) transform_mesh_orco_verts((Mesh*)ob->data, &co, 1, 1); @@ -1100,73 +1120,33 @@ static int psys_threads_init_distribution(ParticleThread *threads, Scene *scene, } } - /* 1. */ - switch(from){ - case PART_FROM_VERT: - tot = dm->getNumVerts(dm); - break; - case PART_FROM_VOLUME: - case PART_FROM_FACE: - tot = dm->getNumFaces(dm); - break; - case PART_FROM_PARTICLE: - if(psys->target_ob) - tob=psys->target_ob; - else - tob=ob; + /* Get total number of emission elements and allocate needed arrays */ + totelem = (from == PART_FROM_VERT) ? dm->getNumVerts(dm) : dm->getNumFaces(dm); - if((tpsys=BLI_findlink(&tob->particlesystem,psys->target_psys-1))){ - tpars=tpsys->particles; - tot=tpsys->totpart; - } - break; - } + if(totelem == 0){ + distribute_invalid(scene, psys, children ? PART_FROM_CHILD : 0); - if(tot==0){ - /*no_distr=1;*/ /*UNUSED*/ - if(children){ - if(G.f & G_DEBUG) - fprintf(stderr,"Particle child distribution error: Nothing to emit from!\n"); - if(psys->child) { - for(p=0,cpa=psys->child; p<totpart; p++,cpa++){ - cpa->fuv[0]=cpa->fuv[1]=cpa->fuv[2]=cpa->fuv[3]= 0.0; - cpa->foffset= 0.0f; - cpa->parent=0; - cpa->pa[0]=cpa->pa[1]=cpa->pa[2]=cpa->pa[3]=0; - cpa->num= -1; - } - } - } - else { - if(G.f & G_DEBUG) - fprintf(stderr,"Particle distribution error: Nothing to emit from!\n"); - for(p=0,pa=psys->particles; p<totpart; p++,pa++){ - pa->fuv[0]=pa->fuv[1]=pa->fuv[2]= pa->fuv[3]= 0.0; - pa->foffset= 0.0f; - pa->num= -1; - } - } + if(G.f & G_DEBUG) + fprintf(stderr,"Particle distribution error: Nothing to emit from!\n"); if(dm != finaldm) dm->release(dm); return 0; } - /* 2. */ - - weight=MEM_callocN(sizeof(float)*tot, "particle_distribution_weights"); - index=MEM_callocN(sizeof(int)*totpart, "particle_distribution_indexes"); - sum=MEM_callocN(sizeof(float)*(tot+1), "particle_distribution_sum"); - jitoff=MEM_callocN(sizeof(float)*tot, "particle_distribution_jitoff"); + element_weight = MEM_callocN(sizeof(float)*totelem, "particle_distribution_weights"); + particle_element= MEM_callocN(sizeof(int)*totpart, "particle_distribution_indexes"); + element_sum = MEM_callocN(sizeof(float)*(totelem+1), "particle_distribution_sum"); + jitter_offset = MEM_callocN(sizeof(float)*totelem, "particle_distribution_jitoff"); - /* 2.1 */ - if((part->flag&PART_EDISTR || children) && ELEM(from,PART_FROM_PARTICLE,PART_FROM_VERT)==0){ + /* Calculate weights from face areas */ + if((part->flag&PART_EDISTR || children) && from != PART_FROM_VERT){ MVert *v1, *v2, *v3, *v4; - float totarea=0.0, co1[3], co2[3], co3[3], co4[3]; + float totarea=0.f, co1[3], co2[3], co3[3], co4[3]; float (*orcodata)[3]; orcodata= dm->getVertDataArray(dm, CD_ORCO); - for(i=0; i<tot; i++){ + for(i=0; i<totelem; i++){ MFace *mf=dm->getFaceData(dm,i,CD_MFACE); if(orcodata) { @@ -1176,6 +1156,10 @@ static int psys_threads_init_distribution(ParticleThread *threads, Scene *scene, transform_mesh_orco_verts((Mesh*)ob->data, &co1, 1, 1); transform_mesh_orco_verts((Mesh*)ob->data, &co2, 1, 1); transform_mesh_orco_verts((Mesh*)ob->data, &co3, 1, 1); + if(mf->v4) { + VECCOPY(co4, orcodata[mf->v4]); + transform_mesh_orco_verts((Mesh*)ob->data, &co4, 1, 1); + } } else { v1= (MVert*)dm->getVertData(dm,mf->v1,CD_MVERT); @@ -1184,156 +1168,133 @@ static int psys_threads_init_distribution(ParticleThread *threads, Scene *scene, VECCOPY(co1, v1->co); VECCOPY(co2, v2->co); VECCOPY(co3, v3->co); - } - - if (mf->v4){ - if(orcodata) { - VECCOPY(co4, orcodata[mf->v4]); - transform_mesh_orco_verts((Mesh*)ob->data, &co4, 1, 1); - } - else { + if(mf->v4) { v4= (MVert*)dm->getVertData(dm,mf->v4,CD_MVERT); VECCOPY(co4, v4->co); } - cur= area_quad_v3(co1, co2, co3, co4); } - else - cur= area_tri_v3(co1, co2, co3); + + cur = mf->v4 ? area_quad_v3(co1, co2, co3, co4) : area_tri_v3(co1, co2, co3); - if(cur>maxweight) - maxweight=cur; + if(cur > maxweight) + maxweight = cur; - weight[i]= cur; - totarea+=cur; + element_weight[i] = cur; + totarea += cur; } - for(i=0; i<tot; i++) - weight[i] /= totarea; + for(i=0; i<totelem; i++) + element_weight[i] /= totarea; maxweight /= totarea; } - else if(from==PART_FROM_PARTICLE){ - float val=(float)tot/(float)totpart; - for(i=0; i<tot; i++) - weight[i]=val; - maxweight=val; - } else{ - float min=1.0f/(float)(MIN2(tot,totpart)); - for(i=0; i<tot; i++) - weight[i]=min; + float min=1.0f/(float)(MIN2(totelem,totpart)); + for(i=0; i<totelem; i++) + element_weight[i]=min; maxweight=min; } - /* 2.2 */ - if(ELEM3(from,PART_FROM_VERT,PART_FROM_FACE,PART_FROM_VOLUME)){ - float *vweight= psys_cache_vgroup(dm,psys,PSYS_VG_DENSITY); + /* Calculate weights from vgroup */ + vweight = psys_cache_vgroup(dm,psys,PSYS_VG_DENSITY); - if(vweight){ - if(from==PART_FROM_VERT) { - for(i=0;i<tot; i++) - weight[i]*=vweight[i]; - } - else { /* PART_FROM_FACE / PART_FROM_VOLUME */ - for(i=0;i<tot; i++){ - MFace *mf=dm->getFaceData(dm,i,CD_MFACE); - tweight = vweight[mf->v1] + vweight[mf->v2] + vweight[mf->v3]; + if(vweight){ + if(from==PART_FROM_VERT) { + for(i=0;i<totelem; i++) + element_weight[i]*=vweight[i]; + } + else { /* PART_FROM_FACE / PART_FROM_VOLUME */ + for(i=0;i<totelem; i++){ + MFace *mf=dm->getFaceData(dm,i,CD_MFACE); + tweight = vweight[mf->v1] + vweight[mf->v2] + vweight[mf->v3]; - if(mf->v4) { - tweight += vweight[mf->v4]; - tweight /= 4.0; - } - else { - tweight /= 3.0; - } - - weight[i]*=tweight; + if(mf->v4) { + tweight += vweight[mf->v4]; + tweight /= 4.0; + } + else { + tweight /= 3.0; } + + element_weight[i]*=tweight; } - MEM_freeN(vweight); } + MEM_freeN(vweight); } - /* 3. */ + /* Calculate total weight of all elements */ totweight= 0.0f; - for(i=0;i<tot; i++) - totweight += weight[i]; + for(i=0;i<totelem; i++) + totweight += element_weight[i]; - if(totweight > 0.0f) - totweight= 1.0f/totweight; + inv_totweight = (totweight > 0.f ? 1.f/totweight : 0.f); - sum[0]= 0.0f; - for(i=0;i<tot; i++) - sum[i+1]= sum[i]+weight[i]*totweight; + /* Calculate cumulative weights */ + element_sum[0]= 0.0f; + for(i=0; i<totelem; i++) + element_sum[i+1]= element_sum[i] + element_weight[i] * inv_totweight; + /* Finally assign elements to particles */ if((part->flag&PART_TRAND) || (part->simplify_flag&PART_SIMPLIFY_ENABLE)) { float pos; for(p=0; p<totpart; p++) { - /* In theory sys[tot] should be 1.0, but due to float errors this is not necessarily always true, so scale pos accordingly. */ - pos= BLI_frand() * sum[tot]; - index[p]= binary_search_distribution(sum, tot, pos); - index[p]= MIN2(tot-1, index[p]); - jitoff[index[p]]= pos; + /* In theory element_sum[totelem] should be 1.0, but due to float errors this is not necessarily always true, so scale pos accordingly. */ + pos= BLI_frand() * element_sum[totelem]; + particle_element[p]= distribute_binary_search(element_sum, totelem, pos); + particle_element[p]= MIN2(totelem-1, particle_element[p]); + jitter_offset[particle_element[p]]= pos; } } else { double step, pos; - step= (totpart <= 1)? 0.5: 1.0/(totpart-1); - pos= 1e-16f; /* tiny offset to avoid zero weight face */ + step= (totpart < 2) ? 0.5 : 1.0/(double)totpart; + pos= 1e-16; /* tiny offset to avoid zero weight face */ i= 0; for(p=0; p<totpart; p++, pos+=step) { - while((i < tot) && (pos > sum[i+1])) + while((i < totelem) && (pos > element_sum[i+1])) i++; - index[p]= MIN2(tot-1, i); + particle_element[p]= MIN2(totelem-1, i); /* avoid zero weight face */ - if(p == totpart-1 && weight[index[p]] == 0.0f) - index[p]= index[p-1]; + if(p == totpart-1 && element_weight[particle_element[p]] == 0.0f) + particle_element[p]= particle_element[p-1]; - jitoff[index[p]]= pos; + jitter_offset[particle_element[p]]= pos; } } - MEM_freeN(sum); + MEM_freeN(element_sum); - /* for hair, sort by origindex, allows optimizations in rendering */ - /* however with virtual parents the children need to be in random order */ + /* For hair, sort by origindex (allows optimizations in rendering), */ + /* however with virtual parents the children need to be in random order. */ if(part->type == PART_HAIR && !(part->childtype==PART_CHILD_FACES && part->parents!=0.0)) { - if(from != PART_FROM_PARTICLE) { - COMPARE_ORIG_INDEX = NULL; + COMPARE_ORIG_INDEX = NULL; - if(from == PART_FROM_VERT) { - if(dm->numVertData) - COMPARE_ORIG_INDEX= dm->getVertDataArray(dm, CD_ORIGINDEX); - } - else { - if(dm->numFaceData) - COMPARE_ORIG_INDEX= dm->getFaceDataArray(dm, CD_ORIGINDEX); - } - - if(COMPARE_ORIG_INDEX) { - qsort(index, totpart, sizeof(int), compare_orig_index); - COMPARE_ORIG_INDEX = NULL; - } + if(from == PART_FROM_VERT) { + if(dm->numVertData) + COMPARE_ORIG_INDEX= dm->getVertDataArray(dm, CD_ORIGINDEX); + } + else { + if(dm->numFaceData) + COMPARE_ORIG_INDEX= dm->getFaceDataArray(dm, CD_ORIGINDEX); } - } - /* weights are no longer used except for FROM_PARTICLE, which needs them zeroed for indexing */ - if(from==PART_FROM_PARTICLE){ - for(i=0; i<tot; i++) - weight[i]=0.0f; + if(COMPARE_ORIG_INDEX) { + qsort(particle_element, totpart, sizeof(int), distribute_compare_orig_index); + COMPARE_ORIG_INDEX = NULL; + } } - /* 4. */ + /* Create jittering if needed */ if(distr==PART_DISTR_JIT && ELEM(from,PART_FROM_FACE,PART_FROM_VOLUME)) { jitlevel= part->userjit; if(jitlevel == 0) { - jitlevel= totpart/tot; + jitlevel= totpart/totelem; if(part->flag & PART_EDISTR) jitlevel*= 2; /* looks better in general, not very scietific */ if(jitlevel<3) jitlevel= 3; } @@ -1350,16 +1311,16 @@ static int psys_threads_init_distribution(ParticleThread *threads, Scene *scene, BLI_array_randomize(jit, 2*sizeof(float), jitlevel, psys->seed); /* for custom jit or even distribution */ } - /* 5. */ + /* Setup things for threaded distribution */ ctx->tree= tree; ctx->seams= seams; ctx->totseam= totseam; ctx->sim.psys= psys; - ctx->index= index; + ctx->index= particle_element; ctx->jit= jit; ctx->jitlevel= jitlevel; - ctx->jitoff= jitoff; - ctx->weight= weight; + ctx->jitoff= jitter_offset; + ctx->weight= element_weight; ctx->maxweight= maxweight; ctx->from= (children)? PART_FROM_CHILD: from; ctx->cfrom= cfrom; @@ -1394,14 +1355,14 @@ static void distribute_particles_on_dm(ParticleSimulationData *sim, int from) pthreads= psys_threads_create(sim); - if(!psys_threads_init_distribution(pthreads, sim->scene, finaldm, from)) { + if(!distribute_threads_init_data(pthreads, sim->scene, finaldm, from)) { psys_threads_free(pthreads); return; } totthread= pthreads[0].tot; if(totthread > 1) { - BLI_init_threads(&threads, exec_distribution, totthread); + BLI_init_threads(&threads, distribute_threads_exec_cb, totthread); for(i=0; i<totthread; i++) BLI_insert_thread(&threads, &pthreads[i]); @@ -1409,7 +1370,7 @@ static void distribute_particles_on_dm(ParticleSimulationData *sim, int from) BLI_end_threads(&threads); } else - exec_distribution(&pthreads[0]); + distribute_threads_exec_cb(&pthreads[0]); psys_calc_dmcache(sim->ob, finaldm, sim->psys); @@ -1423,17 +1384,11 @@ static void distribute_particles_on_dm(ParticleSimulationData *sim, int from) /* ready for future use, to emit particles without geometry */ static void distribute_particles_on_shape(ParticleSimulationData *sim, int UNUSED(from)) { - ParticleSystem *psys = sim->psys; - PARTICLE_P; + distribute_invalid(sim->scene, sim->psys, 0); fprintf(stderr,"Shape emission not yet possible!\n"); - - LOOP_PARTICLES { - pa->fuv[0]=pa->fuv[1]=pa->fuv[2]=pa->fuv[3]= 0.0; - pa->foffset= 0.0f; - pa->num= -1; - } } + static void distribute_particles(ParticleSimulationData *sim, int from) { PARTICLE_PSMD; @@ -1449,16 +1404,9 @@ static void distribute_particles(ParticleSimulationData *sim, int from) distribute_particles_on_shape(sim, from); if(distr_error){ - ParticleSystem *psys = sim->psys; - PARTICLE_P; + distribute_invalid(sim->scene, sim->psys, from); fprintf(stderr,"Particle distribution error!\n"); - - LOOP_PARTICLES { - pa->fuv[0]=pa->fuv[1]=pa->fuv[2]=pa->fuv[3]= 0.0; - pa->foffset= 0.0f; - pa->num= -1; - } } } @@ -1547,7 +1495,7 @@ void initialize_particle(ParticleSimulationData *sim, ParticleData *pa, int p) pa->flag &= ~PARS_UNEXIST; - if(part->from != PART_FROM_PARTICLE && part->type != PART_FLUID) { + if(part->type != PART_FLUID) { psys_get_texture(sim, pa, &ptex, PAMAP_INIT, 0.f); if(ptex.exist < PSYS_FRAND(p+125)) @@ -1628,34 +1576,6 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime, int p = pa - psys->particles; part=psys->part; -#if 0 /* deprecated code */ - if(part->from==PART_FROM_PARTICLE){ - float speed; - ParticleSimulationData tsim= {0}; - tsim.scene= sim->scene; - tsim.ob= psys->target_ob ? psys->target_ob : ob; - tsim.psys = BLI_findlink(&tsim.ob->particlesystem, sim->psys->target_psys-1); - - state.time = pa->time; - if(pa->num == -1) - memset(&state, 0, sizeof(state)); - else - psys_get_particle_state(&tsim, pa->num, &state, 1); - psys_get_from_key(&state, loc, nor, rot, 0); - - mul_qt_v3(rot, vtan); - mul_qt_v3(rot, utan); - - speed= normalize_v3_v3(p_vel, state.vel); - mul_v3_fl(p_vel, dot_v3v3(r_vel, p_vel)); - VECSUB(p_vel, r_vel, p_vel); - normalize_v3(p_vel); - mul_v3_fl(p_vel, speed); - - VECCOPY(pa->fuv, loc); /* abusing pa->fuv (not used for "from particle") for storing emit location */ - } - else{ -#endif /* get precise emitter matrix if particle is born */ if(part->type!=PART_HAIR && pa->time < cfra && pa->time >= sim->psys->cfra) { /* we have to force RECALC_ANIM here since where_is_objec_time only does drivers */ @@ -3156,7 +3076,7 @@ static void psys_update_path_cache(ParticleSimulationData *sim, float cfra) if(!(psys->part->type == PART_HAIR) || (psys->flag & PSYS_HAIR_DONE)) { distribute_particles(sim, PART_FROM_CHILD); - if(part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES && part->parents!=0.0) + if(part->childtype==PART_CHILD_FACES && part->parents!=0.0) psys_find_parents(sim); } } @@ -3923,13 +3843,6 @@ static void psys_changed_type(ParticleSimulationData *sim) BKE_ptcache_id_from_particles(&pid, sim->ob, sim->psys); - if(part->from == PART_FROM_PARTICLE) { - //if(part->type != PART_REACTOR) - part->from = PART_FROM_FACE; - if(part->distr == PART_DISTR_GRID && part->from != PART_FROM_VERT) - part->distr = PART_DISTR_JIT; - } - if(part->phystype != PART_PHYS_KEYED) sim->psys->flag &= ~PSYS_KEYED; @@ -3937,6 +3850,9 @@ static void psys_changed_type(ParticleSimulationData *sim) if(ELEM4(part->ren_as, PART_DRAW_NOT, PART_DRAW_PATH, PART_DRAW_OB, PART_DRAW_GR)==0) part->ren_as = PART_DRAW_PATH; + if(part->distr == PART_DISTR_GRID) + part->distr = PART_DISTR_JIT; + if(ELEM3(part->draw_as, PART_DRAW_NOT, PART_DRAW_REND, PART_DRAW_PATH)==0) part->draw_as = PART_DRAW_REND; diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h index ae97b023e58..b146d49365c 100644 --- a/source/blender/makesdna/DNA_particle_types.h +++ b/source/blender/makesdna/DNA_particle_types.h @@ -339,7 +339,7 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in #define PART_FROM_VERT 0 #define PART_FROM_FACE 1 #define PART_FROM_VOLUME 2 -#define PART_FROM_PARTICLE 3 +/* #define PART_FROM_PARTICLE 3 deprecated! */ #define PART_FROM_CHILD 4 /* part->distr */ diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index f1142e16e8e..57d6e72a102 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -60,7 +60,19 @@ EnumPropertyItem part_reactor_from_items[] = { {PART_FROM_VERT, "VERT", 0, "Verts", ""}, {PART_FROM_FACE, "FACE", 0, "Faces", ""}, {PART_FROM_VOLUME, "VOLUME", 0, "Volume", ""}, - {PART_FROM_PARTICLE, "PARTICLE", 0, "Particle", ""}, + {0, NULL, 0, NULL, NULL} +}; + +EnumPropertyItem part_dist_items[] = { + {PART_DISTR_JIT, "JIT", 0, "Jittered", ""}, + {PART_DISTR_RAND, "RAND", 0, "Random", ""}, + {PART_DISTR_GRID, "GRID", 0, "Grid", ""}, + {0, NULL, 0, NULL, NULL} +}; + +EnumPropertyItem part_hair_dist_items[] = { + {PART_DISTR_JIT, "JIT", 0, "Jittered", ""}, + {PART_DISTR_RAND, "RAND", 0, "Random", ""}, {0, NULL, 0, NULL, NULL} }; @@ -665,6 +677,16 @@ static EnumPropertyItem *rna_Particle_from_itemf(bContext *C, PointerRNA *ptr, i return part_from_items; } +static EnumPropertyItem *rna_Particle_dist_itemf(bContext *C, PointerRNA *ptr, int *free) +{ + ParticleSettings *part = ptr->id.data; + + if(part->type==PART_HAIR) + return part_hair_dist_items; + else + return part_dist_items; +} + static EnumPropertyItem *rna_Particle_draw_as_itemf(bContext *C, PointerRNA *ptr, int *free) { ParticleSettings *part = ptr->id.data; @@ -1361,13 +1383,6 @@ static void rna_def_particle_settings(BlenderRNA *brna) {0, NULL, 0, NULL, NULL} }; - static EnumPropertyItem dist_items[] = { - {PART_DISTR_JIT, "JIT", 0, "Jittered", ""}, - {PART_DISTR_RAND, "RAND", 0, "Random", ""}, - {PART_DISTR_GRID, "GRID", 0, "Grid", ""}, - {0, NULL, 0, NULL, NULL} - }; - static EnumPropertyItem phys_type_items[] = { {PART_PHYS_NO, "NO", 0, "No", ""}, {PART_PHYS_NEWTON, "NEWTON", 0, "Newtonian", ""}, @@ -1609,7 +1624,9 @@ static void rna_def_particle_settings(BlenderRNA *brna) prop= RNA_def_property(srna, "distribution", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "distr"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_enum_items(prop, dist_items); + RNA_def_property_enum_items(prop, part_dist_items); + RNA_def_property_enum_items(prop, part_draw_as_items); + RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_Particle_dist_itemf"); RNA_def_property_ui_text(prop, "Distribution", "How to distribute particles on selected element"); RNA_def_property_update(prop, 0, "rna_Particle_reset"); diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index bbf41f7ac6d..81652f5a290 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -1713,25 +1713,6 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem bb.totnum = totpart+totchild; bb.uv_split = part->bb_uv_split; } - -#if 0 // XXX old animation system -/* 2.3 setup time */ - if(part->flag&PART_ABS_TIME && part->ipo) { - calc_ipo(part->ipo, cfra); - execute_ipo((ID *)part, part->ipo); - } - - if(part->flag & PART_GLOB_TIME) -#endif // XXX old animation system - -///* 2.4 setup reactors */ -// if(part->type == PART_REACTOR){ -// psys_get_reactor_target(ob, psys, &tob, &tpsys); -// if(tpsys && (part->from==PART_FROM_PARTICLE || part->phystype==PART_PHYS_NO)){ -// psmd = psys_get_modifier(tob,tpsys); -// tpart = tpsys->part; -// } -// } /* 2.5 setup matrices */ mul_m4_m4m4(mat, ob->obmat, re->viewmat); @@ -1828,7 +1809,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem hasize = ma->hasize; /* get orco */ - if(tpsys && (part->from==PART_FROM_PARTICLE || part->phystype==PART_PHYS_NO)){ + if(tpsys && part->phystype==PART_PHYS_NO){ tpa=tpsys->particles+pa->num; psys_particle_on_emitter(psmd,tpart->from,tpa->num,pa->num_dmcache,tpa->fuv,tpa->foffset,co,nor,0,0,sd.orco,0); } @@ -1892,7 +1873,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem } /* get uvco & mcol */ - if(part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES) { + if(part->childtype==PART_CHILD_FACES) { get_particle_uvco_mcol(PART_FROM_FACE, psmd->dm, cpa->fuv, cpa->num, &sd); } else { |