Fix for bug #17302: subsurf + particle size vertex groups did not

work correct, also refactored some code here to make it more clear.
This commit is contained in:
Brecht Van Lommel 2008-09-30 06:12:47 +00:00
parent 13c8e189f6
commit 8c4744c4d6
6 changed files with 158 additions and 261 deletions

@ -226,7 +226,7 @@ void psys_interpolate_mcol(struct MCol *mcol, int quad, float *uv, struct MCol *
void copy_particle_key(struct ParticleKey *to, struct ParticleKey *from, int time);
void psys_particle_on_emitter(struct Object *ob, struct ParticleSystemModifierData *psmd, int distr, int index, int index_dmcache, float *fuv, float foffset, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor);
void psys_particle_on_emitter(struct ParticleSystemModifierData *psmd, int distr, int index, int index_dmcache, float *fuv, float foffset, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor);
struct ParticleSystemModifierData *psys_get_modifier(struct Object *ob, struct ParticleSystem *psys);
struct ParticleSettings *psys_new_settings(char *name, struct Main *main);
@ -284,11 +284,12 @@ void psys_mat_hair_to_orco(struct Object *ob, struct DerivedMesh *dm, short from
float *psys_cache_vgroup(struct DerivedMesh *dm, struct ParticleSystem *psys, int vgroup);
void psys_get_texture(struct Object *ob, struct Material *ma, struct ParticleSystemModifierData *psmd, struct ParticleSystem *psys, struct ParticleData *pa, struct ParticleTexture *ptex, int event);
void psys_interpolate_face(struct MVert *mvert, struct MFace *mface, struct MTFace *tface, float (*orcodata)[3], float *uv, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor);
float psys_particle_value_from_verts(struct DerivedMesh *dm, short from, struct ParticleData *pa, float *values);
float psys_interpolate_value_from_verts(struct DerivedMesh *dm, short from, int index, float *fw, float *values);
void psys_get_from_key(struct ParticleKey *key, float *loc, float *vel, float *rot, float *time);
int psys_intersect_dm(struct Object *ob, struct DerivedMesh *dm, float *vert_cos, float *co1, float* co2, float *min_d, int *min_face, float *min_uv, float *face_minmax, float *pa_minmax, float radius, float *ipoint);
void psys_particle_on_dm(struct Object *ob, struct DerivedMesh *dm, int from, int index, int index_dmcache, float *fw, float foffset, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor);
void psys_particle_on_dm(struct DerivedMesh *dm, int from, int index, int index_dmcache, float *fw, float foffset, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor);
/* particle_system.c */
void initialize_particle(struct ParticleData *pa, int p, struct Object *ob, struct ParticleSystem *psys, struct ParticleSystemModifierData *psmd);

@ -6543,7 +6543,7 @@ static void explodeModifier_createFacepa(ExplodeModifierData *emd,
/* make tree of emitter locations */
tree=BLI_kdtree_new(totpart);
for(p=0,pa=psys->particles; p<totpart; p++,pa++){
psys_particle_on_dm(ob,psmd->dm,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,0,0,0,0,0);
psys_particle_on_dm(psmd->dm,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,0,0,0,0,0);
BLI_kdtree_insert(tree, p, co, NULL);
}
BLI_kdtree_balance(tree);
@ -7146,7 +7146,7 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd,
pa= pars+i;
/* get particle state */
psys_particle_on_emitter(ob, psmd,part->from,pa->num,-1,pa->fuv,pa->foffset,loc0,nor,0,0,0,0);
psys_particle_on_emitter(psmd,part->from,pa->num,-1,pa->fuv,pa->foffset,loc0,nor,0,0,0,0);
Mat4MulVecfl(ob->obmat,loc0);
state.time=cfra;

@ -1117,8 +1117,8 @@ static void psys_origspace_to_w(OrigSpaceFace *osface, int quad, float *w, float
}
}
/* find the derived mesh face for a particle, set the mf passed.
This is slow, can be optimized but only for many lookups, return the face lookup index*/
/* find the derived mesh face for a particle, set the mf passed. this is slow
* and can be optimized but only for many lookups. returns the face index. */
int psys_particle_dm_face_lookup(Object *ob, DerivedMesh *dm, int index, float *fw, struct LinkNode *node)
{
Mesh *me= (Mesh*)ob->data;
@ -1186,168 +1186,142 @@ int psys_particle_dm_face_lookup(Object *ob, DerivedMesh *dm, int index, float *
return DMCACHE_NOTFOUND;
}
/* interprets particle data to get a point on a mesh in object space */
#define PARTICLE_ON_DM_ERROR \
{ if(vec) { vec[0]=vec[1]=vec[2]=0.0; } \
if(nor) { nor[0]=nor[1]=0.0; nor[2]=1.0; } \
if(orco) { orco[0]=orco[1]=orco[2]=0.0; } \
if(ornor) { ornor[0]=ornor[1]=0.0; ornor[2]=1.0; } \
if(utan) { utan[0]=utan[1]=utan[2]=0.0; } \
if(vtan) { vtan[0]=vtan[1]=vtan[2]=0.0; } }
void psys_particle_on_dm(Object *ob, DerivedMesh *dm, int from, int index, int index_dmcache, float *fw, float foffset, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor)
static int psys_map_index_on_dm(DerivedMesh *dm, int from, int index, int index_dmcache, float *fw, float foffset, int *mapindex, float *mapfw)
{
float temp1[3];
float (*orcodata)[3];
if(index < 0) { /* 'no dm' error has happened! */
PARTICLE_ON_DM_ERROR;
return;
}
orcodata= dm->getVertDataArray(dm, CD_ORCO);
if(index < 0)
return 0;
if (dm->deformedOnly || index_dmcache == DMCACHE_ISCHILD) {
/* this works for meshes with deform verts only - constructive modifiers wont work properly*/
/* for meshes that are either only defined or for child particles, the
* index and fw do not require any mapping, so we can directly use it */
if(from == PART_FROM_VERT) {
if(index >= dm->getNumVerts(dm)) {
PARTICLE_ON_DM_ERROR;
return;
}
dm->getVertCo(dm,index,vec);
if(nor){
dm->getVertNo(dm,index,nor);
Normalize(nor);
}
if(orco)
VECCOPY(orco, orcodata[index])
if(ornor) {
dm->getVertNo(dm,index,nor);
Normalize(nor);
}
if(index >= dm->getNumVerts(dm))
return 0;
*mapindex = index;
}
else { /* PART_FROM_FACE / PART_FROM_VOLUME */
MFace *mface;
MTFace *mtface=0;
MVert *mvert;
int uv_index;
else { /* FROM_FACE/FROM_VOLUME */
if(index >= dm->getNumFaces(dm))
return 0;
if(index >= dm->getNumFaces(dm)) {
PARTICLE_ON_DM_ERROR;
return;
}
mface=dm->getFaceData(dm,index,CD_MFACE);
mvert=dm->getVertDataArray(dm,CD_MVERT);
uv_index=CustomData_get_active_layer_index(&dm->faceData,CD_MTFACE);
if(uv_index>=0){
CustomDataLayer *layer=&dm->faceData.layers[uv_index];
mtface= &((MTFace*)layer->data)[index];
}
if(from==PART_FROM_VOLUME){
psys_interpolate_face(mvert,mface,mtface,orcodata,fw,vec,temp1,utan,vtan,orco,ornor);
if(nor)
VECCOPY(nor,temp1);
Normalize(temp1);
VecMulf(temp1,-foffset);
VECADD(vec,vec,temp1);
}
else
psys_interpolate_face(mvert,mface,mtface,orcodata,fw,vec,nor,utan,vtan,orco,ornor);
*mapindex = index;
QUATCOPY(mapfw, fw);
}
} else {
/* Need to support constructive modifiers, this is a bit more tricky
we need a customdata layer like UV's so we can position the particle */
/* Only face supported at the moment */
if(ELEM(from, PART_FROM_FACE, PART_FROM_VOLUME)) {
/* for other meshes that have been modified, we try to map the particle
* to their new location, which means a different index, and for faces
* also a new face interpolation weights */
if(from == PART_FROM_VERT) {
if (index_dmcache == DMCACHE_NOTFOUND || index_dmcache > dm->getNumVerts(dm))
return 0;
*mapindex = index_dmcache;
}
else { /* FROM_FACE/FROM_VOLUME */
/* find a face on the derived mesh that uses this face */
Mesh *me= (Mesh*)ob->data;
MVert *mvert;
MFace *mface;
MTFace *mtface;
OrigSpaceFace *osface;
int *origindex;
float fw_mod[4];
int i, totface;
mvert= dm->getVertDataArray(dm,CD_MVERT);
int i;
i = index_dmcache;
if(i== DMCACHE_NOTFOUND || i >= dm->getNumFaces(dm))
return 0;
*mapindex = i;
/* modify the original weights to become
* weights for the derived mesh face */
osface= dm->getFaceDataArray(dm, CD_ORIGSPACE);
origindex= dm->getFaceDataArray(dm, CD_ORIGINDEX);
/* For this to work we need origindex and OrigSpace coords */
if(origindex==NULL || osface==NULL || index>=me->totface) {
PARTICLE_ON_DM_ERROR;
return;
}
if (index_dmcache == DMCACHE_NOTFOUND)
i = psys_particle_dm_face_lookup(ob, dm, index, fw, (LinkNode*)NULL);
else
i = index_dmcache;
totface = dm->getNumFaces(dm);
/* Any time this happens, and the face has not been removed,
* its a BUG watch out for this error! */
if (i==-1) {
printf("Cannot find original face %i\n", index);
PARTICLE_ON_DM_ERROR;
return;
}
else if(i >= totface)
return;
mface= dm->getFaceData(dm, i, CD_MFACE);
mtface= dm->getFaceData(dm, i, CD_MTFACE);
osface += i;
/* we need to modify the original weights to become weights for
* the derived mesh face */
psys_origspace_to_w(osface, mface->v4, fw, fw_mod);
if(from==PART_FROM_VOLUME){
psys_interpolate_face(mvert,mface,mtface,orcodata,fw_mod,vec,temp1,utan,vtan,orco,ornor);
if(nor)
VECCOPY(nor,temp1);
Normalize(temp1);
VecMulf(temp1,-foffset);
VECADD(vec,vec,temp1);
}
if(osface == NULL)
mapfw[0]= mapfw[1]= mapfw[2]= mapfw[3]= 0.0f;
else
psys_interpolate_face(mvert,mface,mtface,orcodata,fw_mod,vec,nor,utan,vtan,orco,ornor);
}
else if(from == PART_FROM_VERT) {
if (index_dmcache == DMCACHE_NOTFOUND || index_dmcache > dm->getNumVerts(dm)) {
PARTICLE_ON_DM_ERROR;
return;
}
dm->getVertCo(dm,index_dmcache,vec);
if(nor) {
dm->getVertNo(dm,index_dmcache,nor);
Normalize(nor);
}
if(orco)
VECCOPY(orco, orcodata[index])
if(ornor) {
dm->getVertNo(dm,index_dmcache,nor);
Normalize(nor);
}
if(utan && vtan) {
utan[0]= utan[1]= utan[2]= 0.0f;
vtan[0]= vtan[1]= vtan[2]= 0.0f;
}
}
else {
PARTICLE_ON_DM_ERROR;
psys_origspace_to_w(&osface[i], mface->v4, fw, mapfw);
}
}
return 1;
}
/* interprets particle data to get a point on a mesh in object space */
void psys_particle_on_dm(DerivedMesh *dm, int from, int index, int index_dmcache, float *fw, float foffset, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor)
{
float tmpnor[3], mapfw[4];
float (*orcodata)[3];
int mapindex;
if(!psys_map_index_on_dm(dm, from, index, index_dmcache, fw, foffset, &mapindex, mapfw)) {
if(vec) { vec[0]=vec[1]=vec[2]=0.0; }
if(nor) { nor[0]=nor[1]=0.0; nor[2]=1.0; }
if(orco) { orco[0]=orco[1]=orco[2]=0.0; }
if(ornor) { ornor[0]=ornor[1]=0.0; ornor[2]=1.0; }
if(utan) { utan[0]=utan[1]=utan[2]=0.0; }
if(vtan) { vtan[0]=vtan[1]=vtan[2]=0.0; }
return;
}
orcodata= dm->getVertDataArray(dm, CD_ORCO);
if(from == PART_FROM_VERT) {
dm->getVertCo(dm,mapindex,vec);
if(nor) {
dm->getVertNo(dm,mapindex,nor);
Normalize(nor);
}
if(orco)
VECCOPY(orco, orcodata[mapindex])
if(ornor) {
dm->getVertNo(dm,mapindex,nor);
Normalize(nor);
}
if(utan && vtan) {
utan[0]= utan[1]= utan[2]= 0.0f;
vtan[0]= vtan[1]= vtan[2]= 0.0f;
}
}
else { /* PART_FROM_FACE / PART_FROM_VOLUME */
MFace *mface;
MTFace *mtface;
MVert *mvert;
mface=dm->getFaceData(dm,mapindex,CD_MFACE);
mvert=dm->getVertDataArray(dm,CD_MVERT);
mtface=CustomData_get_layer(&dm->faceData,CD_MTFACE);
if(mtface)
mtface += mapindex;
if(from==PART_FROM_VOLUME) {
psys_interpolate_face(mvert,mface,mtface,orcodata,mapfw,vec,tmpnor,utan,vtan,orco,ornor);
if(nor)
VECCOPY(nor,tmpnor);
Normalize(tmpnor);
VecMulf(tmpnor,-foffset);
VECADD(vec,vec,tmpnor);
}
else
psys_interpolate_face(mvert,mface,mtface,orcodata,mapfw,vec,nor,utan,vtan,orco,ornor);
}
}
float psys_particle_value_from_verts(DerivedMesh *dm, short from, ParticleData *pa, float *values)
{
float mapfw[4];
int mapindex;
if(!psys_map_index_on_dm(dm, from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, &mapindex, mapfw))
return 0.0f;
return psys_interpolate_value_from_verts(dm, from, mapindex, mapfw, values);
}
#undef PARTICLE_ON_DM_ERROR
ParticleSystemModifierData *psys_get_modifier(Object *ob, ParticleSystem *psys)
{
@ -1394,7 +1368,7 @@ static void psys_particle_on_shape(int distr, int index, float *fuv, float *vec,
/************************************************/
/* Particles on emitter */
/************************************************/
void psys_particle_on_emitter(Object *ob, ParticleSystemModifierData *psmd, int from, int index, int index_dmcache, float *fuv, float foffset, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor){
void psys_particle_on_emitter(ParticleSystemModifierData *psmd, int from, int index, int index_dmcache, float *fuv, float foffset, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor){
if(psmd){
if(psmd->psys->part->distr==PART_DISTR_GRID && psmd->psys->part->from != PART_FROM_VERT){
if(vec){
@ -1403,7 +1377,7 @@ void psys_particle_on_emitter(Object *ob, ParticleSystemModifierData *psmd, int
return;
}
/* we cant use the num_dmcache */
psys_particle_on_dm(ob, psmd->dm,from,index,index_dmcache,fuv,foffset,vec,nor,utan,vtan,orco,ornor);
psys_particle_on_dm(psmd->dm,from,index,index_dmcache,fuv,foffset,vec,nor,utan,vtan,orco,ornor);
}
else
psys_particle_on_shape(from,index,fuv,vec,nor,utan,vtan,orco,ornor);
@ -1834,14 +1808,14 @@ void psys_find_parents(Object *ob, ParticleSystemModifierData *psmd, ParticleSys
tree=BLI_kdtree_new(totparent);
for(p=0,cpa=psys->child; p<totparent; p++,cpa++){
psys_particle_on_emitter(ob,psmd,from,cpa->num,-1,cpa->fuv,cpa->foffset,co,0,0,0,orco,0);
psys_particle_on_emitter(psmd,from,cpa->num,-1,cpa->fuv,cpa->foffset,co,0,0,0,orco,0);
BLI_kdtree_insert(tree, p, orco, NULL);
}
BLI_kdtree_balance(tree);
for(; p<totchild; p++,cpa++){
psys_particle_on_emitter(ob,psmd,from,cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,co,0,0,0,orco,0);
psys_particle_on_emitter(psmd,from,cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,co,0,0,0,orco,0);
cpa->parent=BLI_kdtree_find_nearest(tree, orco, NULL, NULL);
}
@ -2033,7 +2007,7 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa,
cpa_fuv = cpa->fuv;
cpa_from = PART_FROM_FACE;
psys_particle_on_emitter(ob,ctx->psmd,cpa_from,cpa_num,DMCACHE_ISCHILD,cpa->fuv,foffset,co,ornor,0,0,orco,0);
psys_particle_on_emitter(ctx->psmd,cpa_from,cpa_num,DMCACHE_ISCHILD,cpa->fuv,foffset,co,ornor,0,0,orco,0);
/* we need to save the actual root position of the child for positioning it accurately to the surface of the emitter */
VECCOPY(cpa_1st,co);
@ -2059,7 +2033,7 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa,
cpa_num=pa->num;
cpa_fuv=pa->fuv;
psys_particle_on_emitter(ob,ctx->psmd,cpa_from,cpa_num,DMCACHE_ISCHILD,cpa_fuv,pa->foffset,co,ornor,0,0,orco,0);
psys_particle_on_emitter(ctx->psmd,cpa_from,cpa_num,DMCACHE_ISCHILD,cpa_fuv,pa->foffset,co,ornor,0,0,orco,0);
}
keys->steps = ctx->steps;
@ -2437,7 +2411,7 @@ void psys_cache_paths(Object *ob, ParticleSystem *psys, float cfra, int editupda
if(!edit && !psys->totchild) {
pa_length = part->length * (1.0f - part->randlength*pa->r_ave[0]);
if(vg_length)
pa_length *= psys_interpolate_value_from_verts(psmd->dm,part->from,pa->num,pa->fuv,vg_length);
pa_length *= psys_particle_value_from_verts(psmd->dm,part->from,pa,vg_length);
}
cache[i]->steps = steps;
@ -2598,7 +2572,7 @@ void psys_cache_paths(Object *ob, ParticleSystem *psys, float cfra, int editupda
effector= 1.0f;
if(vg_effector)
effector*= psys_interpolate_value_from_verts(psmd->dm,psys->part->from,pa->num,pa->fuv,vg_effector);
effector*= psys_particle_value_from_verts(psmd->dm,psys->part->from,pa,vg_effector);
for(k=0, ca=cache[i]; k<=steps; k++, ca++) {
/* apply effectors */
@ -2839,7 +2813,7 @@ void psys_mat_hair_to_object(Object *ob, DerivedMesh *dm, short from, ParticleDa
float vec[3];
psys_face_mat(0, dm, pa, hairmat, 0);
psys_particle_on_dm(ob, dm, from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, vec, 0, 0, 0, 0, 0);
psys_particle_on_dm(dm, from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, vec, 0, 0, 0, 0, 0);
VECCOPY(hairmat[3],vec);
}
@ -2848,62 +2822,14 @@ void psys_mat_hair_to_orco(Object *ob, DerivedMesh *dm, short from, ParticleData
float vec[3], orco[3];
psys_face_mat(ob, dm, pa, hairmat, 1);
psys_particle_on_dm(ob, dm, from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, vec, 0, 0, 0, orco, 0);
psys_particle_on_dm(dm, from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, vec, 0, 0, 0, orco, 0);
/* see psys_face_mat for why this function is called */
transform_mesh_orco_verts(ob->data, &orco, 1, 1);
VECCOPY(hairmat[3],orco);
}
/*
void psys_key_to_geometry(DerivedMesh *dm, ParticleData *pa, ParticleKey *key)
{
float q[4], v1[3], v2[3], v3[3];
dm->getVertCo(dm,pa->verts[0],v1);
dm->getVertCo(dm,pa->verts[1],v2);
dm->getVertCo(dm,pa->verts[2],v3);
triatoquat(v1, v2, v3, q);
QuatInv(q);
VECSUB(key->co,key->co,v1);
VECADD(key->vel,key->vel,key->co);
QuatMulVecf(q, key->co);
QuatMulVecf(q, key->vel);
VECSUB(key->vel,key->vel,key->co);
QuatMul(key->rot,q,key->rot);
}
void psys_key_from_geometry(DerivedMesh *dm, ParticleData *pa, ParticleKey *key)
{
float q[4], v1[3], v2[3], v3[3];
dm->getVertCo(dm,pa->verts[0],v1);
dm->getVertCo(dm,pa->verts[1],v2);
dm->getVertCo(dm,pa->verts[2],v3);
triatoquat(v1, v2, v3, q);
VECADD(key->vel,key->vel,key->co);
QuatMulVecf(q, key->co);
QuatMulVecf(q, key->vel);
VECSUB(key->vel,key->vel,key->co);
VECADD(key->co,key->co,v1);
QuatMul(key->rot,q,key->rot);
}
*/
void psys_vec_rot_to_face(DerivedMesh *dm, ParticleData *pa, float *vec)//to_geometry(DerivedMesh *dm, ParticleData *pa, float *vec)
void psys_vec_rot_to_face(DerivedMesh *dm, ParticleData *pa, float *vec)
{
float mat[4][4];
@ -2912,36 +2838,6 @@ void psys_vec_rot_to_face(DerivedMesh *dm, ParticleData *pa, float *vec)//to_geo
Mat4Mul3Vecfl(mat, vec);
}
/* unused */
#if 0
static void psys_vec_rot_from_face(DerivedMesh *dm, ParticleData *pa, float *vec)//from_geometry(DerivedMesh *dm, ParticleData *pa, float *vec)
{
float q[4], v1[3], v2[3], v3[3];
/*
dm->getVertCo(dm,pa->verts[0],v1);
dm->getVertCo(dm,pa->verts[1],v2);
dm->getVertCo(dm,pa->verts[2],v3);
*/
/* replace with this */
MFace *mface;
int i; // = psys_particle_dm_face_lookup(dm, pa->num, pa->fuv, pa->foffset, (LinkNode*)NULL);
i = pa->num_dmcache==DMCACHE_NOTFOUND ? pa->num : pa->num_dmcache;
if (i==-1 || i >= dm->getNumFaces(dm)) { vec[0] = vec[1] = 0; vec[2] = 1; return; }
mface=dm->getFaceData(dm,i,CD_MFACE);
dm->getVertCo(dm,mface->v1,v1);
dm->getVertCo(dm,mface->v2,v2);
dm->getVertCo(dm,mface->v3,v3);
/* done */
triatoquat(v1, v2, v3, q);
QuatMulVecf(q, vec);
//VECADD(vec,vec,v1);
}
#endif
void psys_mat_hair_to_global(Object *ob, DerivedMesh *dm, short from, ParticleData *pa, float hairmat[][4])
{
float facemat[4][4];
@ -3295,11 +3191,11 @@ void psys_get_texture(Object *ob, Material *ma, ParticleSystemModifierData *psmd
if((mtex->texco & TEXCO_UV) && ELEM(psys->part->from, PART_FROM_FACE, PART_FROM_VOLUME)) {
if(!get_particle_uv(psmd->dm, pa, 0, pa->fuv, mtex->uvname, texco)) {
/* failed to get uv's, let's try orco's */
psys_particle_on_emitter(ob,psmd,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,0,0,0,texco, 0);
psys_particle_on_emitter(psmd,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,0,0,0,texco, 0);
}
}
else {
psys_particle_on_emitter(ob,psmd,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,0,0,0,texco, 0);
psys_particle_on_emitter(psmd,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,0,0,0,texco, 0);
}
externtex(mtex, texco, &value, rgba, rgba+1, rgba+2, rgba+3);
@ -3366,7 +3262,7 @@ float psys_get_size(Object *ob, Material *ma, ParticleSystemModifierData *psmd,
}
if(vg_size)
size*=psys_interpolate_value_from_verts(psmd->dm,part->from,pa->num,pa->fuv,vg_size);
size*=psys_particle_value_from_verts(psmd->dm,part->from,pa,vg_size);
if(part->randsize!=0.0)
size*= 1.0f - part->randsize*pa->sizemul;
@ -3613,7 +3509,7 @@ void psys_get_particle_on_path(Object *ob, ParticleSystem *psys, int p, Particle
cpa_fuv = cpa->fuv;
cpa_from = PART_FROM_FACE;
psys_particle_on_emitter(ob,psmd,cpa_from,cpa_num,DMCACHE_ISCHILD,cpa->fuv,foffset,co,0,0,0,orco,0);
psys_particle_on_emitter(psmd,cpa_from,cpa_num,DMCACHE_ISCHILD,cpa->fuv,foffset,co,0,0,0,orco,0);
/* we need to save the actual root position of the child for positioning it accurately to the surface of the emitter */
//VECCOPY(cpa_1st,co);
@ -3635,7 +3531,7 @@ void psys_get_particle_on_path(Object *ob, ParticleSystem *psys, int p, Particle
cpa_num=pa->num;
cpa_fuv=pa->fuv;
psys_particle_on_emitter(ob,psmd,cpa_from,cpa_num,DMCACHE_ISCHILD,cpa_fuv,pa->foffset,co,0,0,0,orco,0);
psys_particle_on_emitter(psmd,cpa_from,cpa_num,DMCACHE_ISCHILD,cpa_fuv,pa->foffset,co,0,0,0,orco,0);
}
/* correct child ipo timing */
@ -3883,7 +3779,7 @@ void psys_get_dupli_texture(Object *ob, ParticleSettings *part, ParticleSystemMo
else
uv[0]= uv[1]= 0.0f;
psys_particle_on_emitter(ob, psmd,
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);
}
@ -3907,7 +3803,7 @@ void psys_get_dupli_texture(Object *ob, ParticleSettings *part, ParticleSystemMo
else
uv[0]= uv[1]= 0.0f;
psys_particle_on_emitter(ob,psmd,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,loc,0,0,0,orco,0);
psys_particle_on_emitter(psmd,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,loc,0,0,0,orco,0);
}
}
@ -3920,9 +3816,9 @@ void psys_get_dupli_path_transform(Object *ob, ParticleSystem *psys, ParticleSys
len= Normalize(vec);
if(pa)
psys_particle_on_emitter(ob,psmd,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,loc,nor,0,0,0,0);
psys_particle_on_emitter(psmd,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,loc,nor,0,0,0,0);
else
psys_particle_on_emitter(ob, psmd,
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);

@ -622,7 +622,7 @@ void psys_thread_distribute_particle(ParticleThread *thread, ParticleData *pa, C
KDTreeNearest ptn[3];
int w, maxw;
psys_particle_on_dm(ctx->ob,ctx->dm,from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co1,0,0,0,orco1,0);
psys_particle_on_dm(ctx->dm,from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co1,0,0,0,orco1,0);
transform_mesh_orco_verts((Mesh*)ob->data, &orco1, 1, 1);
maxw = BLI_kdtree_find_n_nearest(ctx->tree,3,orco1,NULL,ptn);
@ -766,7 +766,7 @@ void psys_thread_distribute_particle(ParticleThread *thread, ParticleData *pa, C
do_seams= (part->flag&PART_CHILD_SEAMS && ctx->seams);
psys_particle_on_dm(ob,dm,cfrom,cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,co1,nor1,0,0,orco1,ornor1);
psys_particle_on_dm(dm,cfrom,cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,co1,nor1,0,0,orco1,ornor1);
transform_mesh_orco_verts((Mesh*)ob->data, &orco1, 1, 1);
maxw = BLI_kdtree_find_n_nearest(ctx->tree,(do_seams)?10:4,orco1,ornor1,ptn);
@ -980,7 +980,7 @@ int psys_threads_init_distribution(ParticleThread *threads, DerivedMesh *finaldm
tree=BLI_kdtree_new(totpart);
for(p=0,pa=psys->particles; p<totpart; p++,pa++){
psys_particle_on_dm(ob,dm,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,nor,0,0,orco,ornor);
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);
}
@ -1741,7 +1741,7 @@ void reset_particle(ParticleData *pa, ParticleSystem *psys, ParticleSystemModifi
where_is_object_time(ob,pa->time);
/* get birth location from object */
psys_particle_on_emitter(ob,psmd,part->from,pa->num, pa->num_dmcache, pa->fuv,pa->foffset,loc,nor,utan,vtan,0,0);
psys_particle_on_emitter(psmd,part->from,pa->num, pa->num_dmcache, pa->fuv,pa->foffset,loc,nor,utan,vtan,0,0);
/* save local coordinates for later */
VECCOPY(tloc,loc);
@ -1750,7 +1750,7 @@ void reset_particle(ParticleData *pa, ParticleSystem *psys, ParticleSystemModifi
psys_get_texture(ob,give_current_material(ob,part->omat),psmd,psys,pa,&ptex,MAP_PA_IVEL);
if(vg_vel && pa->num != -1)
ptex.ivel*=psys_interpolate_value_from_verts(psmd->dm,part->from,pa->num,pa->fuv,vg_vel);
ptex.ivel*=psys_particle_value_from_verts(psmd->dm,part->from,pa,vg_vel);
/* particles live in global space so */
/* let's convert: */
@ -1765,7 +1765,7 @@ void reset_particle(ParticleData *pa, ParticleSystem *psys, ParticleSystemModifi
/* -tangent */
if(part->tanfac!=0.0){
float phase=vg_rot?2.0f*(psys_interpolate_value_from_verts(psmd->dm,part->from,pa->num,pa->fuv,vg_rot)-0.5f):0.0f;
float phase=vg_rot?2.0f*(psys_particle_value_from_verts(psmd->dm,part->from,pa,vg_rot)-0.5f):0.0f;
VecMulf(vtan,-(float)cos(M_PI*(part->tanphase+phase)));
fac=-(float)sin(M_PI*(part->tanphase+phase));
VECADDFAC(vtan,vtan,utan,fac);
@ -1825,7 +1825,7 @@ void reset_particle(ParticleData *pa, ParticleSystem *psys, ParticleSystemModifi
/* *emitter tangent */
if(part->tanfac!=0.0)
VECADDFAC(vel,vel,vtan,part->tanfac*(vg_tan?psys_interpolate_value_from_verts(psmd->dm,part->from,pa->num,pa->fuv,vg_tan):1.0f));
VECADDFAC(vel,vel,vtan,part->tanfac*(vg_tan?psys_particle_value_from_verts(psmd->dm,part->from,pa,vg_tan):1.0f));
/* *texture */
/* TODO */
@ -2483,7 +2483,7 @@ static void precalc_effectors(Object *ob, ParticleSystem *psys, ParticleSystemMo
ec->locations=MEM_callocN(totpart*3*sizeof(float),"particle locations");
for(p=0,pa=psys->particles; p<totpart; p++, pa++){
psys_particle_on_emitter(ob,psmd,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,loc,0,0,0,0,0);
psys_particle_on_emitter(psmd,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,loc,0,0,0,0,0);
Mat4MulVecfl(ob->obmat,loc);
ec->distances[p]=VecLenf(loc,vec);
VECSUB(loc,loc,vec);

@ -1703,10 +1703,10 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
/* get orco */
if(tpsys && (part->from==PART_FROM_PARTICLE || part->phystype==PART_PHYS_NO)){
tpa=tpsys->particles+pa->num;
psys_particle_on_emitter(ob, psmd,tpart->from,tpa->num,pa->num_dmcache,tpa->fuv,tpa->foffset,co,nor,0,0,orco,0);
psys_particle_on_emitter(psmd,tpart->from,tpa->num,pa->num_dmcache,tpa->fuv,tpa->foffset,co,nor,0,0,orco,0);
}
else
psys_particle_on_emitter(ob, psmd,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,nor,0,0,orco,0);
psys_particle_on_emitter(psmd,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,nor,0,0,orco,0);
num= pa->num_dmcache;
@ -1780,13 +1780,13 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
/* get orco */
if(part->childtype == PART_CHILD_FACES) {
psys_particle_on_emitter(ob, psmd,
psys_particle_on_emitter(psmd,
PART_FROM_FACE, cpa->num,DMCACHE_ISCHILD,
cpa->fuv,cpa->foffset,co,nor,0,0,orco,0);
}
else {
ParticleData *par = psys->particles + cpa->parent;
psys_particle_on_emitter(ob, psmd, part->from,
psys_particle_on_emitter(psmd, part->from,
par->num,DMCACHE_ISCHILD,par->fuv,
par->foffset,co,nor,0,0,orco,0);
}

@ -2408,7 +2408,7 @@ static void brush_add(Object *ob, ParticleSystem *psys, short *mval, short numbe
tree=BLI_kdtree_new(psys->totpart);
for(i=0, pa=psys->particles; i<totpart; i++, pa++) {
psys_particle_on_dm(ob,psmd->dm,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,cur_co,0,0,0,0,0);
psys_particle_on_dm(psmd->dm,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,cur_co,0,0,0,0,0);
BLI_kdtree_insert(tree, i, cur_co, NULL);
}
@ -2448,7 +2448,7 @@ static void brush_add(Object *ob, ParticleSystem *psys, short *mval, short numbe
int w, maxw;
float maxd, mind, dd, totw=0.0, weight[3];
psys_particle_on_dm(ob,psmd->dm,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co1,0,0,0,0,0);
psys_particle_on_dm(psmd->dm,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co1,0,0,0,0,0);
maxw = BLI_kdtree_find_n_nearest(tree,3,co1,NULL,ptn);
maxd = ptn[maxw-1].dist;