Particles

=========

- Texture orco coordinates for particles are now actual orcos instead
  of just the vertex positions, which means they are the same under
  deformations and the same as the ones on the mesh.
- Particle distribution now uses these orcos to get consistent
  distributions independent of deformation.
- This required changing the way orco's are computed for meshes. Now
  instead of generating an orco derivedmesh separately, the derivedmesh
  is generated alongside the regular one and stored in an orco custom
  data layer.
This commit is contained in:
Brecht Van Lommel 2007-12-05 12:40:54 +00:00
parent 2422b1e401
commit 29d87d64ca
12 changed files with 283 additions and 139 deletions

View File

@ -62,8 +62,8 @@ void make_local_tface(struct Mesh *me);
void make_local_mesh(struct Mesh *me);
void boundbox_mesh(struct Mesh *me, float *loc, float *size);
void tex_space_mesh(struct Mesh *me);
float *mesh_create_orco_render(struct Object *ob);
float *mesh_create_orco(struct Object *ob);
float *get_mesh_orco_verts(struct Object *ob);
void transform_mesh_orco_verts(struct Mesh *me, float (*orco)[3], int totvert);
void test_index_face(struct MFace *mface, struct CustomData *mfdata, int mfindex, int nr);
struct Mesh *get_mesh(struct Object *ob);
void set_mesh(struct Object *ob, struct Mesh *me);

View File

@ -219,7 +219,7 @@ void psys_interpolate_uvs(struct MTFace *tface, int quad, float *uv, float *uvco
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);
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);
struct ParticleSystemModifierData *psys_get_modifier(struct Object *ob, struct ParticleSystem *psys);
struct ParticleSettings *psys_new_settings(char *name, struct Main *main);
@ -268,12 +268,12 @@ void psys_mat_hair_to_global(struct Object *ob, struct DerivedMesh *dm, short fr
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 *uv, float *vec, float *nor, float *utan, float *vtan);
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_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);
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);
/* particle_system.c */
void initialize_particle(struct ParticleData *pa, int p, struct Object *ob, struct ParticleSystem *psys, struct ParticleSystemModifierData *psmd);

View File

@ -1813,7 +1813,7 @@ CustomDataMask get_viewedit_datamask()
View3D *view = sa->spacedata.first;
if(view->drawtype == OB_SHADED) {
/* this includes normals for mesh_create_shadedColors */
mask |= CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_NORMAL;
mask |= CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_NORMAL | CD_MASK_ORCO;
}
if((view->drawtype == OB_TEXTURE) || ((view->drawtype == OB_SOLID) && (view->flag2 & V3D_SOLID_TEX))) {
mask |= CD_MASK_MTFACE | CD_MASK_MCOL;
@ -1829,6 +1829,48 @@ CustomDataMask get_viewedit_datamask()
return mask;
}
static DerivedMesh *create_orco_dm(Object *ob, Mesh *me)
{
DerivedMesh *dm;
float (*orco)[3];
dm= CDDM_from_mesh(me, ob);
orco= (float(*)[3])get_mesh_orco_verts(ob);
CDDM_apply_vert_coords(dm, orco);
CDDM_calc_normals(dm);
MEM_freeN(orco);
return dm;
}
static void add_orco_dm(Object *ob, DerivedMesh *dm, DerivedMesh *orcodm)
{
float (*orco)[3], (*layerorco)[3];
int totvert;
totvert= dm->getNumVerts(dm);
if(orcodm) {
orco= MEM_callocN(sizeof(float)*3*totvert, "dm orco");
if(orcodm->getNumVerts(orcodm) == totvert)
orcodm->getVertCos(orcodm, orco);
else
dm->getVertCos(dm, orco);
}
else
orco= (float(*)[3])get_mesh_orco_verts(ob);
transform_mesh_orco_verts(ob->data, orco, totvert);
if((layerorco = DM_get_vert_data_layer(dm, CD_ORCO))) {
memcpy(layerorco, orco, sizeof(float)*totvert);
MEM_freeN(orco);
}
else
DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, orco);
}
static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3],
DerivedMesh **deform_r, DerivedMesh **final_r,
int useRenderParams, int useDeform,
@ -1837,8 +1879,9 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3],
Mesh *me = ob->data;
ModifierData *md = modifiers_getVirtualModifierList(ob);
LinkNode *datamasks, *curr;
CustomDataMask mask;
float (*deformedVerts)[3] = NULL;
DerivedMesh *dm;
DerivedMesh *dm, *orcodm, *finaldm;
int numVerts = me->totvert;
int fluidsimMeshUsed = 0;
int required_mode;
@ -1936,6 +1979,7 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3],
* OnlyDeform ones.
*/
dm = NULL;
orcodm = NULL;
#ifdef WITH_VERSE
/* hack to make sure modifiers don't try to use mesh data from a verse
@ -1957,6 +2001,13 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3],
if(mti->isDisabled && mti->isDisabled(md)) continue;
if(needMapping && !modifier_supportsMapping(md)) continue;
/* add an orco layer if needed by this modifier */
if(dm && mti->requiredDataMask) {
mask = mti->requiredDataMask(md);
if(mask & CD_MASK_ORCO)
add_orco_dm(ob, dm, orcodm);
}
/* How to apply modifier depends on (a) what we already have as
* a result of previous modifiers (could be a DerivedMesh or just
* deformed vertices) and (b) what type the modifier is.
@ -1980,6 +2031,8 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3],
}
}
if(md->type == eModifierType_ParticleSystem)
mti->deformVerts(md, ob, dm, deformedVerts, numVerts);
} else {
DerivedMesh *ndm;
@ -2003,13 +2056,31 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3],
}
}
/* create an orco derivedmesh in parallel */
mask= (CustomDataMask)curr->link;
if(mask & CD_MASK_ORCO) {
if(!orcodm)
orcodm= create_orco_dm(ob, me);
mask &= ~CD_MASK_ORCO;
DM_set_only_copy(orcodm, mask);
ndm = mti->applyModifier(md, ob, orcodm, useRenderParams, !inputVertexCos);
if(ndm) {
/* if the modifier returned a new dm, release the old one */
if(orcodm && orcodm != ndm) orcodm->release(orcodm);
orcodm = ndm;
}
}
/* set the DerivedMesh to only copy needed data */
DM_set_only_copy(dm, (CustomDataMask)curr->link);
DM_set_only_copy(dm, mask);
/* add an origspace layer if needed */
if(((CustomDataMask)curr->link) & CD_MASK_ORIGSPACE)
if(!CustomData_has_layer(&dm->faceData, CD_ORIGSPACE))
CustomData_add_layer(&dm->faceData, CD_ORIGSPACE, CD_DEFAULT, NULL, dm->getNumFaces(dm));
DM_add_face_layer(dm, CD_ORIGSPACE, CD_DEFAULT, NULL);
ndm = mti->applyModifier(md, ob, dm, useRenderParams, !inputVertexCos);
if(ndm) {
@ -2033,34 +2104,43 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3],
* DerivedMesh then we need to build one.
*/
if(dm && deformedVerts) {
*final_r = CDDM_copy(dm);
finaldm = CDDM_copy(dm);
dm->release(dm);
CDDM_apply_vert_coords(*final_r, deformedVerts);
CDDM_calc_normals(*final_r);
CDDM_apply_vert_coords(finaldm, deformedVerts);
CDDM_calc_normals(finaldm);
} else if(dm) {
*final_r = dm;
finaldm = dm;
} else {
#ifdef WITH_VERSE
if(me->vnode)
*final_r = derivedmesh_from_versemesh(me->vnode, deformedVerts);
finaldm = derivedmesh_from_versemesh(me->vnode, deformedVerts);
else {
*final_r = CDDM_from_mesh(me, ob);
finaldm = CDDM_from_mesh(me, ob);
if(deformedVerts) {
CDDM_apply_vert_coords(*final_r, deformedVerts);
CDDM_calc_normals(*final_r);
CDDM_apply_vert_coords(finaldm, deformedVerts);
CDDM_calc_normals(finaldm);
}
}
#else
*final_r = CDDM_from_mesh(me, ob);
finaldm = CDDM_from_mesh(me, ob);
if(deformedVerts) {
CDDM_apply_vert_coords(*final_r, deformedVerts);
CDDM_calc_normals(*final_r);
CDDM_apply_vert_coords(finaldm, deformedVerts);
CDDM_calc_normals(finaldm);
}
#endif
}
/* add an orco layer if needed */
if(dataMask & CD_MASK_ORCO)
add_orco_dm(ob, finaldm, orcodm);
*final_r = finaldm;
if(orcodm)
orcodm->release(orcodm);
if(deformedVerts && deformedVerts != inputVertexCos)
MEM_freeN(deformedVerts);
@ -2190,7 +2270,7 @@ static void editmesh_calc_modifiers(DerivedMesh **cage_r,
if(((CustomDataMask)curr->link) & CD_MASK_ORIGSPACE)
if(!CustomData_has_layer(&dm->faceData, CD_ORIGSPACE))
CustomData_add_layer(&dm->faceData, CD_ORIGSPACE, CD_DEFAULT, NULL, dm->getNumFaces(dm));
DM_add_face_layer(dm, CD_ORIGSPACE, CD_DEFAULT, NULL);
ndm = mti->applyModifierEM(md, ob, em, dm);

View File

@ -449,11 +449,13 @@ const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
{sizeof(MStringProperty), "MStringProperty",1,"String",NULL,NULL,NULL,NULL},
{sizeof(OrigSpaceFace), "OrigSpaceFace", 1, "UVTex", layerCopy_origspace_face, NULL,
layerInterp_origspace_face, layerSwap_origspace_face, layerDefault_origspace_face},
{sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL}
};
const char *LAYERTYPENAMES[CD_NUMTYPES] = {
"CDMVert", "CDMSticky", "CDMDeformVert", "CDMEdge", "CDMFace", "CDMTFace",
"CDMCol", "CDOrigIndex", "CDNormal", "CDFlags","CDMFloatProperty","CDMIntProperty","CDMStringProperty", "CDOrigSpace"};
"CDMCol", "CDOrigIndex", "CDNormal", "CDFlags","CDMFloatProperty",
"CDMIntProperty","CDMStringProperty", "CDOrigSpace", "CDOrco"};
const CustomDataMask CD_MASK_BAREMESH =
CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE;
@ -466,8 +468,8 @@ const CustomDataMask CD_MASK_EDITMESH =
CD_MASK_MCOL|CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR;
const CustomDataMask CD_MASK_DERIVEDMESH =
CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE |
CD_MASK_MCOL | CD_MASK_ORIGINDEX |
CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR | CD_MASK_ORIGSPACE;
CD_MASK_MCOL | CD_MASK_ORIGINDEX | CD_MASK_PROP_FLT | CD_MASK_PROP_INT |
CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORCO;
static const LayerTypeInfo *layerType_getInfo(int type)
{

View File

@ -485,9 +485,11 @@ static void mesh_create_shadedColors(Render *re, Object *ob, int onlyForMesh, un
CustomDataMask dataMask = CD_MASK_BAREMESH | CD_MASK_MCOL
| CD_MASK_MTFACE | CD_MASK_NORMAL;
init_fastshade_for_ob(re, ob, &need_orco, mat, imat);
orco = (need_orco)? mesh_create_orco(ob): NULL;
if(need_orco)
dataMask |= CD_MASK_ORCO;
if (onlyForMesh)
dm = mesh_get_derived_deform(ob, dataMask);
@ -499,6 +501,7 @@ static void mesh_create_shadedColors(Render *re, Object *ob, int onlyForMesh, un
nors = dm->getFaceDataArray(dm, CD_NORMAL);
totvert = dm->getNumVerts(dm);
totface = dm->getNumFaces(dm);
orco= dm->getVertDataArray(dm, CD_ORCO);
if (onlyForMesh) {
col1 = *col1_r;
@ -577,9 +580,6 @@ static void mesh_create_shadedColors(Render *re, Object *ob, int onlyForMesh, un
}
MEM_freeN(vnors);
if (orco)
MEM_freeN(orco);
dm->release(dm);
end_fastshade_for_ob(ob);

View File

@ -474,17 +474,13 @@ void mesh_get_texspace(Mesh *me, float *loc_r, float *rot_r, float *size_r)
if (size_r) VECCOPY(size_r, me->size);
}
static float *make_orco_mesh_internal(Object *ob, int render)
float *get_mesh_orco_verts(Object *ob)
{
Mesh *me = ob->data;
float (*orcoData)[3];
int a, totvert;
float loc[3], size[3];
DerivedMesh *dm;
float (*vcos)[3] = NULL;
/* Get appropriate vertex coordinates */
/* Get appropriate vertex coordinates */
if(me->key && me->texcomesh==0 && me->key->refkey) {
vcos= mesh_getRefKeyCos(me, &totvert);
}
@ -512,40 +508,22 @@ static float *make_orco_mesh_internal(Object *ob, int render)
}
}
/* Apply orco-changing modifiers */
return (float*)vcos;
}
if (render) {
dm = mesh_create_derived_no_deform_render(ob, vcos, CD_MASK_BAREMESH);
} else {
dm = mesh_create_derived_no_deform(ob, vcos, CD_MASK_BAREMESH);
}
totvert = dm->getNumVerts(dm);
orcoData = MEM_mallocN(sizeof(*orcoData)*totvert, "orcoData");
dm->getVertCos(dm, orcoData);
dm->release(dm);
MEM_freeN(vcos);
void transform_mesh_orco_verts(Mesh *me, float (*orco)[3], int totvert)
{
float loc[3], size[3];
int a;
mesh_get_texspace(me->texcomesh?me->texcomesh:me, loc, NULL, size);
for(a=0; a<totvert; a++) {
float *co = orcoData[a];
float *co = orco[a];
co[0] = (co[0]-loc[0])/size[0];
co[1] = (co[1]-loc[1])/size[1];
co[2] = (co[2]-loc[2])/size[2];
}
return (float*) orcoData;
}
float *mesh_create_orco_render(Object *ob)
{
return make_orco_mesh_internal(ob, 1);
}
float *mesh_create_orco(Object *ob)
{
return make_orco_mesh_internal(ob, 0);
}
/* rotates the vertices of a face in case v[2] or v[3] (vertex index) is = 0.

View File

@ -5010,7 +5010,7 @@ static void particleSystemModifier_initData(ModifierData *md)
ParticleSystemModifierData *psmd= (ParticleSystemModifierData*) md;
psmd->psys= 0;
psmd->dm=0;
psmd->totdmvert= psmd->totdmedge= psmd->totdmface= 0;
}
static void particleSystemModifier_freeData(ModifierData *md)
{
@ -5054,6 +5054,8 @@ CustomDataMask particleSystemModifier_requiredDataMask(ModifierData *md)
/* particles only need this if they are after a non deform modifier, and
* the modifier stack will only create them in that case. */
dataMask |= CD_MASK_ORIGSPACE;
dataMask |= CD_MASK_ORCO;
return dataMask;
}
@ -5104,6 +5106,8 @@ static void particleSystemModifier_deformVerts(
CDDM_apply_vert_coords(dm, vertexCos);
//CDDM_calc_normals(dm);
DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, get_mesh_orco_verts(ob));
needsFree=1;
}
@ -5505,7 +5509,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);
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);
BLI_kdtree_insert(tree, p, co, NULL);
}
BLI_kdtree_balance(tree);
@ -6076,7 +6080,7 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd,
/*duplicate & displace vertices*/
for(i=0, pa=pars; i<=totpart; i++, pa++){
if(i!=totpart){
psys_particle_on_emitter(ob, psmd,part->from,pa->num,-1,pa->fuv,pa->foffset,loc0,nor,0,0);
psys_particle_on_emitter(ob, psmd,part->from,pa->num,-1,pa->fuv,pa->foffset,loc0,nor,0,0,0,0);
Mat4MulVecfl(ob->obmat,loc0);
state.time=cfra;

View File

@ -417,12 +417,13 @@ static void interpolate_particle(short type, ParticleKey keys[4], float dt, Part
/* Particles on a dm */
/************************************************/
/* interpolate a location on a face based on face coordinates */
void psys_interpolate_face(MVert *mvert, MFace *mface, MTFace *tface, float *w, float *vec, float *nor, float *utan, float *vtan){
void psys_interpolate_face(MVert *mvert, MFace *mface, MTFace *tface, float (*orcodata)[3], float *w, float *vec, float *nor, float *utan, float *vtan, float *orco,float *ornor){
float *v1=0, *v2=0, *v3=0, *v4=0;
float e1[3],e2[3],s1,s2,t1,t2;
float *uv1, *uv2, *uv3, *uv4;
float n1[3], n2[3], n3[3], n4[3];
float tuv[4][2];
float *o1, *o2, *o3, *o4;
v1= (mvert+mface->v1)->co;
v2= (mvert+mface->v2)->co;
@ -515,6 +516,37 @@ void psys_interpolate_face(MVert *mvert, MFace *mface, MTFace *tface, float *w,
utan[1] = (t1*e2[1] - t2*e1[1]);
utan[2] = (t1*e2[2] - t2*e1[2]);
}
if(orco) {
if(orcodata) {
o1= orcodata[mface->v1];
o2= orcodata[mface->v2];
o3= orcodata[mface->v3];
if(mface->v4) {
o4= orcodata[mface->v4];
orco[0]= w[0]*o1[0] + w[1]*o2[0] + w[2]*o3[0] + w[3]*o4[0];
orco[1]= w[0]*o1[1] + w[1]*o2[1] + w[2]*o3[1] + w[3]*o4[1];
orco[2]= w[0]*o1[2] + w[1]*o2[2] + w[2]*o3[2] + w[3]*o4[2];
if(ornor)
CalcNormFloat4(o1, o2, o3, o4, ornor);
}
else {
orco[0]= w[0]*o1[0] + w[1]*o2[0] + w[2]*o3[0];
orco[1]= w[0]*o1[1] + w[1]*o2[1] + w[2]*o3[1];
orco[2]= w[0]*o1[2] + w[1]*o2[2] + w[2]*o3[2];
if(ornor)
CalcNormFloat(o1, o2, o3, ornor);
}
}
else {
VECCOPY(orco, vec);
if(ornor)
VECCOPY(ornor, nor);
}
}
}
void psys_interpolate_uvs(MTFace *tface, int quad, float *w, float *uvco){
float v10= tface->uv[0][0];
@ -656,8 +688,10 @@ int psys_particle_dm_face_lookup(Object *ob, DerivedMesh *dm, int index, float *
/* interprets particle data to get a point on a mesh in object space */
#define PARTICLE_ERROR(_nor, _vec) _vec[0]=_vec[1]=_vec[2]=0.0; if(_nor){ _nor[0]=_nor[1]=0.0; _nor[2]=1.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)
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)
{
float (*orcodata)[3] = dm->getVertDataArray(dm, CD_ORCO);
if(index < 0){ /* 'no dm' error has happened! */
PARTICLE_ERROR(nor, vec);
return;
@ -678,6 +712,12 @@ void psys_particle_on_dm(Object *ob, DerivedMesh *dm, int from, int index, int i
dm->getVertNo(dm,index,nor);
Normalize(nor);
}
if(orco)
VECCOPY(orco, orcodata[index])
if(ornor) {
dm->getVertNo(dm,index,nor);
Normalize(nor);
}
}
else { /* PART_FROM_FACE / PART_FROM_VOLUME */
MFace *mface;
@ -700,7 +740,7 @@ void psys_particle_on_dm(Object *ob, DerivedMesh *dm, int from, int index, int i
}
if(from==PART_FROM_VOLUME){
psys_interpolate_face(mvert,mface,mtface,fw,vec,temp1,utan,vtan);
psys_interpolate_face(mvert,mface,mtface,orcodata,fw,vec,temp1,utan,vtan,orco,ornor);
if(nor)
VECCOPY(nor,temp1);
Normalize(temp1);
@ -708,7 +748,7 @@ void psys_particle_on_dm(Object *ob, DerivedMesh *dm, int from, int index, int i
VECADD(vec,vec,temp1);
}
else
psys_interpolate_face(mvert,mface,mtface,fw,vec,nor,utan,vtan);
psys_interpolate_face(mvert,mface,mtface,orcodata,fw,vec,nor,utan,vtan,orco,ornor);
}
} else {
/* Need to support constructive modifiers, this is a bit more tricky
@ -761,7 +801,7 @@ void psys_particle_on_dm(Object *ob, DerivedMesh *dm, int from, int index, int 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);
psys_interpolate_face(mvert,mface,mtface,fw_mod,vec,nor,utan,vtan);
psys_interpolate_face(mvert,mface,mtface,orcodata,fw_mod,vec,nor,utan,vtan,orco,ornor);
}
else {
/* TODO PARTICLE - support verts and volume */
@ -790,7 +830,7 @@ ParticleSystemModifierData *psys_get_modifier(Object *ob, ParticleSystem *psys)
/* Particles on a shape */
/************************************************/
/* ready for future use */
void psys_particle_on_shape(int distr, int index, float *fuv, float *vec, float *nor, float *utan, float *vtan)
void psys_particle_on_shape(int distr, int index, float *fuv, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor)
{
/* TODO */
float zerovec[3]={0.0f,0.0f,0.0f};
@ -806,11 +846,17 @@ void psys_particle_on_shape(int distr, int index, float *fuv, float *vec, float
if(vtan){
VECCOPY(vtan,zerovec);
}
if(orco){
VECCOPY(orco,zerovec);
}
if(ornor){
VECCOPY(ornor,zerovec);
}
}
/************************************************/
/* 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){
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){
if(psmd){
if(psmd->psys->part->distr==PART_DISTR_GRID){
if(vec){
@ -819,10 +865,10 @@ 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);
psys_particle_on_dm(ob, 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);
psys_particle_on_shape(from,index,fuv,vec,nor,utan,vtan,orco,ornor);
}
/************************************************/
@ -1293,27 +1339,25 @@ void psys_find_parents(Object *ob, ParticleSystemModifierData *psmd, ParticleSys
KDTree *tree;
ChildParticle *cpa;
int p, totparent,totchild=psys->totchild;
float co[3], *orcos=0;
float co[3], orco[3];
int from=PART_FROM_FACE;
totparent=(int)(totchild*part->parents*0.3);
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);
BLI_kdtree_insert(tree, p, co, NULL);
psys_particle_on_emitter(ob,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);
cpa->parent=BLI_kdtree_find_nearest(tree, co, NULL, NULL);
psys_particle_on_emitter(ob,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);
}
BLI_kdtree_free(tree);
if(orcos)
MEM_freeN(orcos);
}
static void get_strand_normal(Material *ma, float *surfnor, float surfdist, float *nor)
@ -1434,7 +1478,7 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa,
ParticleData *pa;
ParticleTexture ptex;
float *cpa_fuv=0;
float orco[3], ornor[3], t, rough_t, cpa_1st[3], dvec[3];
float co[3], orco[3], ornor[3], t, rough_t, cpa_1st[3], dvec[3];
float branch_begin, branch_end, branch_prob, branchfac, rough_rand;
float pa_rough1, pa_rough2, pa_roughe, length, pa_length, pa_clump, pa_kink;
float max_length = 1.0f, cur_length = 0.0f;
@ -1497,10 +1541,10 @@ 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,orco,ornor,0,0);
psys_particle_on_emitter(ob,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,orco);
VECCOPY(cpa_1st,co);
Mat4MulVecfl(ob->obmat,cpa_1st);
pa=0;
@ -1523,7 +1567,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,orco,ornor,0,0);
psys_particle_on_emitter(ob,ctx->psmd,cpa_from,cpa_num,DMCACHE_ISCHILD,cpa_fuv,pa->foffset,co,ornor,0,0,orco,0);
}
keys->steps = ctx->steps;
@ -2216,7 +2260,7 @@ void psys_mat_hair_to_object(Object *ob, DerivedMesh *dm, short from, ParticleDa
float vec[3];
psys_face_mat(dm, pa, hairmat);
psys_particle_on_dm(ob, dm, from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, vec, 0, 0, 0);
psys_particle_on_dm(ob, dm, from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, vec, 0, 0, 0, 0, 0);
VECCOPY(hairmat[3],vec);
}
@ -2574,7 +2618,7 @@ void psys_get_texture(Object *ob, Material *ma, ParticleSystemModifierData *psmd
{
MTex *mtex;
int m;
float value, rgba[4], texco[3];
float value, rgba[4], co[3], texco[3];
int setvars=0;
if(ma) for(m=0; m<MAX_MTEX; m++){
@ -2604,12 +2648,12 @@ void psys_get_texture(Object *ob, Material *ma, ParticleSystemModifierData *psmd
/* <jahka> anyways I think it will be too small a difference to notice, so psys_get_texture should only know about the original mesh structure.. no dm needed anywhere */
/* <brecht> the code only does dm based lookup now, so passing num_dmcache anyway to avoid^
* massive slowdown here */
psys_particle_on_emitter(ob,psmd,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,texco,0,0,0);
psys_particle_on_emitter(ob,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->fuv,pa->offset,texco,0,0,0);
/* ditto above */
psys_particle_on_emitter(ob,psmd,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,texco,0,0,0);
psys_particle_on_emitter(ob,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);
@ -2740,7 +2784,7 @@ void psys_get_particle_on_path(Object *ob, ParticleSystem *psys, int p, Particle
ParticleKey *par=0, keys[4];
float t, real_t, dfra, keytime;
float orco[3];
float co[3], orco[3];
float imat[4][4], hairmat[4][4], cpa_1st[3];
float pa_clump = 0.0, pa_kink = 0.0;
int totparent = 0;
@ -2877,10 +2921,10 @@ 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,orco,0,0,0);
psys_particle_on_emitter(ob,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,orco);
VECCOPY(cpa_1st,co);
//w=0;
//while(w<4 && cpa->pa[w]>=0){
@ -2909,7 +2953,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,orco,0,0,0);
psys_particle_on_emitter(ob,psmd,cpa_from,cpa_num,DMCACHE_ISCHILD,cpa_fuv,pa->foffset,co,0,0,0,orco,0);
}
/* correct child ipo timing */

View File

@ -75,6 +75,7 @@
#include "BKE_depsgraph.h"
#include "BKE_lattice.h"
#include "BKE_pointcache.h"
#include "BKE_mesh.h"
#include "BKE_modifier.h"
#include "BSE_headerbuttons.h"
@ -473,7 +474,7 @@ void psys_thread_distribute_particle(ParticleThread *thread, ParticleData *pa, C
DerivedMesh *dm= ctx->dm;
ParticleData *tpars=0, *tpa;
ParticleSettings *part= ctx->psys->part;
float *v1, *v2, *v3, *v4, nor[3], co1[3], co2[3], nor1[3];
float *v1, *v2, *v3, *v4, nor[3], orco1[3], co1[3], co2[3], nor1[3], ornor1[3];
float cur_d, min_d;
int from= ctx->from;
int cfrom= ctx->cfrom;
@ -492,8 +493,8 @@ 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);
maxw = BLI_kdtree_find_n_nearest(ctx->tree,3,co1,NULL,ptn);
psys_particle_on_dm(ctx->ob,ctx->dm,from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co1,0,0,0,orco1,0);
maxw = BLI_kdtree_find_n_nearest(ctx->tree,3,orco1,NULL,ptn);
for(w=0; w<maxw; w++){
pa->verts[w]=ptn->num;
@ -532,7 +533,7 @@ void psys_thread_distribute_particle(ParticleThread *thread, ParticleData *pa, C
tot=dm->getNumFaces(dm);
psys_interpolate_face(mvert,mface,0,pa->fuv,co1,nor,0,0);
psys_interpolate_face(mvert,mface,0,0,pa->fuv,co1,nor,0,0,0,0);
Normalize(nor);
VecMulf(nor,-100.0);
@ -631,8 +632,8 @@ 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);
maxw = BLI_kdtree_find_n_nearest(ctx->tree,(do_seams)?10:4,co1,nor1,ptn);
psys_particle_on_dm(ob,dm,cfrom,cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,co1,nor1,0,0,orco1,ornor1);
maxw = BLI_kdtree_find_n_nearest(ctx->tree,(do_seams)?10:4,orco1,ornor1,ptn);
maxd=ptn[maxw-1].dist;
mind=ptn[0].dist;
@ -642,7 +643,8 @@ void psys_thread_distribute_particle(ParticleThread *thread, ParticleData *pa, C
for(w=0; w<maxw; w++){
parent[w]=ptn[w].index;
pweight[w]=(float)pow(2.0,(double)(-6.0f*ptn[w].dist/maxd));
//totw+=cpa->w[w];
//pweight[w]= (1.0f - ptn[w].dist*ptn[w].dist/(maxd*maxd));
//pweight[w] *= pweight[w];
}
for(;w<10; w++){
parent[w]=-1;
@ -790,7 +792,7 @@ int psys_threads_init_distribution(ParticleThread *threads, DerivedMesh *finaldm
//int *vertpart=0;
int jitlevel= 1, distr;
float *weight=0,*sum=0,*jitoff=0;
float cur, maxweight=0.0, tweight, totweight, co[3], nor[3];
float cur, maxweight=0.0, tweight, totweight, co[3], nor[3], orco[3], ornor[3];
if(ob==0 || psys==0 || psys->part==0)
return 0;
@ -817,8 +819,8 @@ 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);
BLI_kdtree_insert(tree, p, co, nor);
psys_particle_on_dm(ob,dm,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,nor,0,0,orco,ornor);
BLI_kdtree_insert(tree, p, orco, ornor);
}
BLI_kdtree_balance(tree);
@ -908,16 +910,23 @@ int psys_threads_init_distribution(ParticleThread *threads, DerivedMesh *finaldm
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;
pa=psys->particles;
if(from==PART_FROM_VERT){
MVert *mv= dm->getVertDataArray(dm,0);
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++,mv++){
VECCOPY(co,mv->co);
for(p=0; p<totvert; p++){
if(orcodata)
VECCOPY(co,orcodata[p])
else
VECCOPY(co,mv[p].co)
BLI_kdtree_insert(tree,p,co,NULL);
}
@ -981,20 +990,34 @@ int psys_threads_init_distribution(ParticleThread *threads, DerivedMesh *finaldm
/* 2.1 */
if((part->flag&PART_EDISTR || children) && ELEM(from,PART_FROM_PARTICLE,PART_FROM_VERT)==0){
float totarea=0.0;
float totarea=0.0, *co1, *co2, *co3, *co4;
float (*orcodata)[3];
orcodata= dm->getVertDataArray(dm, CD_ORCO);
for(i=0; i<tot; i++){
MFace *mf=dm->getFaceData(dm,i,CD_MFACE);
MVert *mv1=dm->getVertData(dm,mf->v1,CD_MVERT);
MVert *mv2=dm->getVertData(dm,mf->v2,CD_MVERT);
MVert *mv3=dm->getVertData(dm,mf->v3,CD_MVERT);
if(orcodata) {
co1= orcodata[mf->v1];
co2= orcodata[mf->v2];
co3= orcodata[mf->v3];
}
else {
co1= ((MVert*)dm->getVertData(dm,mf->v1,CD_MVERT))->co;
co2= ((MVert*)dm->getVertData(dm,mf->v2,CD_MVERT))->co;
co3= ((MVert*)dm->getVertData(dm,mf->v3,CD_MVERT))->co;
}
if (mf->v4){
MVert *mv4=dm->getVertData(dm,mf->v4,CD_MVERT);
cur= AreaQ3Dfl(mv1->co,mv2->co,mv3->co,mv4->co);
if(orcodata)
co4= orcodata[mf->v4];
else
co4= ((MVert*)dm->getVertData(dm,mf->v4,CD_MVERT))->co;
cur= AreaQ3Dfl(co1, co2, co3, co4);
}
else
cur= AreaT3Dfl(mv1->co,mv2->co,mv3->co);
cur= AreaT3Dfl(co1, co2, co3);
if(cur>maxweight)
maxweight=cur;
@ -1516,7 +1539,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);
psys_particle_on_emitter(ob,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);
@ -2415,7 +2438,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);
psys_particle_on_emitter(ob,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);
@ -3125,7 +3148,7 @@ static void deflect_particle(Object *pob, ParticleSystemModifierData *psmd, Part
}
else{
/* get deflection point & normal */
psys_interpolate_face(mvert,mface,0,min_w,ipoint,unit_nor,0,0);
psys_interpolate_face(mvert,mface,0,0,min_w,ipoint,unit_nor,0,0,0,0);
if(global){
Mat4Mul3Vecfl(ob->obmat,unit_nor);
Mat4MulVecfl(ob->obmat,ipoint);
@ -3338,7 +3361,7 @@ static int boid_see_mesh(ListBase *lb, Object *pob, ParticleSystem *psys, float
mvert=dm->getVertDataArray(dm,CD_MVERT);
/* get deflection point & normal */
psys_interpolate_face(mvert,mface,0,min_w,loc,nor,0,0);
psys_interpolate_face(mvert,mface,0,0,min_w,loc,nor,0,0,0,0);
VECADD(nor,nor,loc);
Mat4MulVecfl(ob->obmat,loc);
@ -3834,7 +3857,7 @@ static void boid_body(BoidVecFunc *bvf, ParticleData *pa, ParticleSystem *psys,
mvert=dm->getVertDataArray(dm,CD_MVERT);
/* get deflection point & normal */
psys_interpolate_face(mvert,mface,0,min_w,loc,nor,0,0);
psys_interpolate_face(mvert,mface,0,0,min_w,loc,nor,0,0,0,0);
Mat4MulVecfl(zob->obmat,loc);
Mat4Mul3Vecfl(zob->obmat,nor);

View File

@ -68,7 +68,8 @@ typedef struct CustomData {
#define CD_PROP_INT 11
#define CD_PROP_STR 12
#define CD_ORIGSPACE 13 /* for modifier stack face location mapping */
#define CD_NUMTYPES 14
#define CD_ORCO 14
#define CD_NUMTYPES 15
/* Bits for CustomDataMask */
#define CD_MASK_MVERT (1 << CD_MVERT)
@ -85,6 +86,7 @@ typedef struct CustomData {
#define CD_MASK_PROP_INT (1 << CD_PROP_INT)
#define CD_MASK_PROP_STR (1 << CD_PROP_STR)
#define CD_MASK_ORIGSPACE (1 << CD_ORIGSPACE)
#define CD_MASK_ORCO (1 << CD_ORCO)
/* CustomData.flag */

View File

@ -966,9 +966,7 @@ static float *get_object_orco(Render *re, Object *ob)
orco = BLI_ghash_lookup(re->orco_hash, ob);
if (!orco) {
if (ob->type==OB_MESH) {
orco = mesh_create_orco_render(ob);
} else if (ELEM(ob->type, OB_CURVE, OB_FONT)) {
if (ELEM(ob->type, OB_CURVE, OB_FONT)) {
orco = make_orco_curve(ob);
} else if (ob->type==OB_SURF) {
orco = make_orco_surf(ob);
@ -981,6 +979,14 @@ static float *get_object_orco(Render *re, Object *ob)
return orco;
}
static void set_object_orco(Render *re, void *ob, float *orco)
{
if (!re->orco_hash)
re->orco_hash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
BLI_ghash_insert(re->orco_hash, ob, orco);
}
static void free_mesh_orco_hash(Render *re)
{
if (re->orco_hash) {
@ -1727,7 +1733,7 @@ static int render_new_particle_system(Render *re, Object *ob, ParticleSystem *ps
StrandVert *svert=0;
StrandRen *strand=0;
RNG *rng= 0;
float loc[3],loc1[3],loc0[3],vel[3],mat[4][4],nmat[3][3],ornor[3],time;
float loc[3],loc1[3],loc0[3],vel[3],mat[4][4],nmat[3][3],co[3],nor[3],time;
float *orco=0,*surfnor=0,*uvco=0;
float hasize, pa_size, pa_time, r_tilt, cfra=bsystem_time(ob,(float)CFRA,0.0);
float loc_tex[3], size_tex[3], adapt_angle=0.0, adapt_pix=0.0, random;
@ -1859,9 +1865,7 @@ static int render_new_particle_system(Render *re, Object *ob, ParticleSystem *ps
if(path_nbr) {
if((ma->mode & (MA_HALO|MA_WIRE))==0) {
orco= MEM_mallocN(3*sizeof(float)*(totpart+totchild), "particle orcos");
if (!re->orco_hash)
re->orco_hash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
BLI_ghash_insert(re->orco_hash, psys, orco);
set_object_orco(re, psys, orco);
}
path=1;
}
@ -1932,10 +1936,10 @@ static int render_new_particle_system(Render *re, Object *ob, ParticleSystem *ps
/* 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, -1,tpa->fuv,tpa->foffset,orco,ornor,0,0);
psys_particle_on_emitter(ob, psmd,tpart->from,tpa->num, -1,tpa->fuv,tpa->foffset,co,nor,0,0,orco,0);
}
else
psys_particle_on_emitter(ob, psmd,part->from,pa->num,-1,pa->fuv,pa->foffset,orco,ornor,0,0);
psys_particle_on_emitter(ob, psmd,part->from,pa->num,-1,pa->fuv,pa->foffset,co,nor,0,0,orco,0);
if(uvco && ELEM(part->from,PART_FROM_FACE,PART_FROM_VOLUME)){
layer=psmd->dm->faceData.layers + CustomData_get_layer_index(&psmd->dm->faceData,CD_MFACE);
@ -1988,7 +1992,7 @@ static int render_new_particle_system(Render *re, Object *ob, ParticleSystem *ps
/* get orco */
psys_particle_on_emitter(ob, psmd,
(part->childtype == PART_CHILD_FACES)? PART_FROM_FACE: PART_FROM_PARTICLE,
cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,orco,ornor,0,0);
cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,co,nor,0,0,orco,0);
if(uvco){
layer=psmd->dm->faceData.layers + CustomData_get_layer_index(&psmd->dm->faceData,CD_MFACE);
@ -2040,8 +2044,8 @@ static int render_new_particle_system(Render *re, Object *ob, ParticleSystem *ps
}
if(ma->mode_l & MA_STR_SURFDIFF) {
Mat3MulVecfl(nmat, ornor);
surfnor= ornor;
Mat3MulVecfl(nmat, nor);
surfnor= nor;
}
else
surfnor= NULL;
@ -2208,9 +2212,7 @@ static void render_static_particle_system(Render *re, Object *ob, PartEff *paf)
/* orcos */
if(!(ma->mode & (MA_HALO|MA_WIRE))) {
orco= MEM_mallocN(3*sizeof(float)*paf->totpart, "static particle orcos");
if (!re->orco_hash)
re->orco_hash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
BLI_ghash_insert(re->orco_hash, paf, orco); /* pointer is particles, otherwise object uses it */
set_object_orco(re, paf, orco);
}
mesh_get_texspace(ob->data, loc_tex, NULL, size_tex);
@ -2653,6 +2655,7 @@ static void init_render_mesh(Render *re, Object *ob, Object *par, int only_verts
MSticky *ms = NULL;
PartEff *paf;
DerivedMesh *dm;
CustomDataMask mask;
float xn, yn, zn, imat[3][3], mat[4][4]; //nor[3],
float *orco=0;
int a, a1, ok, need_orco=0, need_stress=0, need_tangent=0, totvlako, totverto, vertofs;
@ -2716,14 +2719,22 @@ static void init_render_mesh(Render *re, Object *ob, Object *par, int only_verts
if(test_for_displace(re, ob ) )
only_verts= 0;
mask= CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL;
if(!only_verts)
if(need_orco) orco = get_object_orco(re, ob);
if(need_orco)
mask |= CD_MASK_ORCO;
dm = mesh_create_derived_render(ob,
CD_MASK_BAREMESH | CD_MASK_MTFACE | CD_MASK_MCOL);
dm= mesh_create_derived_render(ob, mask);
if(dm==NULL) return; /* in case duplicated object fails? */
if(mask & CD_MASK_ORCO) {
orco= dm->getVertDataArray(dm, CD_ORCO);
if(orco) {
orco= MEM_dupallocN(orco);
set_object_orco(re, ob, orco);
}
}
if((ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) &&
(ob->fluidsimSettings->type & OB_FLUIDSIM_DOMAIN)&&
(ob->fluidsimSettings->meshSurface) ) {
@ -4909,7 +4920,7 @@ void RE_Database_FromScene_Vectors(Render *re, Scene *sce)
/* exported call to recalculate hoco for vertices, when winmat changed */
void RE_DataBase_ApplyWindow(Render *re)
{
project_renderdata(re, projectverto, 0, 0, 1);
project_renderdata(re, projectverto, 0, 0, 0);
}
/* setup for shaded view or bake, so only lamps and materials are initialized */

View File

@ -2272,7 +2272,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);
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);
BLI_kdtree_insert(tree, i, cur_co, NULL);
}
@ -2311,7 +2311,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);
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);
maxw = BLI_kdtree_find_n_nearest(tree,3,co1,NULL,ptn);
maxd = ptn[maxw-1].dist;