static void distribute_from_verts_exec(ParticleTask *thread, ParticleData *pa, int p) { ParticleThreadContext *ctx= thread->ctx; int rng_skip_tot= PSYS_RND_DIST_SKIP; /* count how many rng_* calls wont need skipping */ /* TODO_PARTICLE - use original index */ pa->num= ctx->index[p]; pa->fuv[0] = 1.0f; pa->fuv[1] = pa->fuv[2] = pa->fuv[3] = 0.0; #if ONLY_WORKING_WITH_PA_VERTS if (ctx->tree) { KDTreeNearest ptn[3]; int w, maxw; psys_particle_on_dm(ctx->dm,from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co1,0,0,0,orco1,0); BKE_mesh_orco_verts_transform((Mesh*)ob->data, &orco1, 1, 1); maxw = BLI_kdtree_find_nearest_n(ctx->tree,orco1,ptn,3); for (w=0; w<maxw; w++) { pa->verts[w]=ptn->num; } } #endif if (rng_skip_tot > 0) /* should never be below zero */ BLI_rng_skip(thread->rng, rng_skip_tot); }
static void distribute_from_verts_exec(ParticleTask *thread, ParticleData *pa, int p) { ParticleThreadContext *ctx= thread->ctx; MFace *mface; mface = ctx->dm->getTessFaceDataArray(ctx->dm, CD_MFACE); int rng_skip_tot = PSYS_RND_DIST_SKIP; /* count how many rng_* calls wont need skipping */ /* TODO_PARTICLE - use original index */ pa->num = ctx->index[p]; zero_v4(pa->fuv); if (pa->num != DMCACHE_NOTFOUND && pa->num < ctx->dm->getNumVerts(ctx->dm)) { /* This finds the first face to contain the emitting vertex, * this is not ideal, but is mostly fine as UV seams generally * map to equal-colored parts of a texture */ for (int i = 0; i < ctx->dm->getNumTessFaces(ctx->dm); i++, mface++) { if (ELEM(pa->num, mface->v1, mface->v2, mface->v3, mface->v4)) { unsigned int *vert = &mface->v1; for (int j = 0; j < 4; j++, vert++) { if (*vert == pa->num) { pa->fuv[j] = 1.0f; break; } } break; } } } #if ONLY_WORKING_WITH_PA_VERTS if (ctx->tree) { KDTreeNearest ptn[3]; int w, maxw; psys_particle_on_dm(ctx->dm,from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co1,0,0,0,orco1,0); BKE_mesh_orco_verts_transform((Mesh*)ob->data, &orco1, 1, 1); maxw = BLI_kdtree_find_nearest_n(ctx->tree,orco1,ptn,3); for (w=0; w<maxw; w++) { pa->verts[w]=ptn->num; } } #endif if (rng_skip_tot > 0) /* should never be below zero */ BLI_rng_skip(thread->rng, rng_skip_tot); }
static void distribute_children_exec(ParticleTask *thread, ChildParticle *cpa, int p) { ParticleThreadContext *ctx= thread->ctx; Object *ob= ctx->sim.ob; DerivedMesh *dm= ctx->dm; float orco1[3], co1[3], nor1[3]; float randu, randv; int cfrom= ctx->cfrom; int i; int rng_skip_tot= PSYS_RND_DIST_SKIP; /* count how many rng_* calls wont need skipping */ MFace *mf; if (ctx->index[p] < 0) { cpa->num=0; cpa->fuv[0]=cpa->fuv[1]=cpa->fuv[2]=cpa->fuv[3]=0.0f; cpa->pa[0]=cpa->pa[1]=cpa->pa[2]=cpa->pa[3]=0; return; } mf= dm->getTessFaceData(dm, ctx->index[p], CD_MFACE); randu= BLI_rng_get_float(thread->rng); randv= BLI_rng_get_float(thread->rng); rng_skip_tot -= 2; psys_uv_to_w(randu, randv, mf->v4, cpa->fuv); cpa->num = ctx->index[p]; if (ctx->tree) { KDTreeNearest ptn[10]; int w,maxw;//, do_seams; float maxd /*, mind,dd */, totw= 0.0f; int parent[10]; float pweight[10]; psys_particle_on_dm(dm,cfrom,cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,co1,nor1,NULL,NULL,orco1,NULL); BKE_mesh_orco_verts_transform((Mesh*)ob->data, &orco1, 1, 1); maxw = BLI_kdtree_find_nearest_n(ctx->tree,orco1,ptn,3); maxd=ptn[maxw-1].dist; /* mind=ptn[0].dist; */ /* UNUSED */ /* the weights here could be done better */ for (w=0; w<maxw; w++) { parent[w]=ptn[w].index; pweight[w]=(float)pow(2.0,(double)(-6.0f*ptn[w].dist/maxd)); } for (;w<10; w++) { parent[w]=-1; pweight[w]=0.0f; } for (w=0,i=0; w<maxw && i<4; w++) { if (parent[w]>=0) { cpa->pa[i]=parent[w]; cpa->w[i]=pweight[w]; totw+=pweight[w]; i++; } } for (;i<4; i++) { cpa->pa[i]=-1; cpa->w[i]=0.0f; } if (totw > 0.0f) { for (w = 0; w < 4; w++) { cpa->w[w] /= totw; } } cpa->parent=cpa->pa[0]; } if (rng_skip_tot > 0) /* should never be below zero */ BLI_rng_skip(thread->rng, rng_skip_tot); }