Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenkernel/BKE_mesh.h4
-rw-r--r--source/blender/blenkernel/BKE_particle.h6
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c114
-rw-r--r--source/blender/blenkernel/intern/customdata.c8
-rw-r--r--source/blender/blenkernel/intern/displist.c8
-rw-r--r--source/blender/blenkernel/intern/mesh.c40
-rw-r--r--source/blender/blenkernel/intern/modifier.c10
-rw-r--r--source/blender/blenkernel/intern/particle.c100
-rw-r--r--source/blender/blenkernel/intern/particle_system.c73
-rw-r--r--source/blender/makesdna/DNA_customdata_types.h4
-rw-r--r--source/blender/render/intern/source/convertblender.c51
-rw-r--r--source/blender/src/editparticle.c4
12 files changed, 283 insertions, 139 deletions
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index a8e4969ad43..1bba980c47b 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -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);
diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h
index d419eac2fab..c41a54b0ea7 100644
--- a/source/blender/blenkernel/BKE_particle.h
+++ b/source/blender/blenkernel/BKE_particle.h
@@ -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);
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 5e688af14a4..e2e7b9dbd02 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -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);
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index aa0dc10f4e0..d8ce311b5ca 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -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)
{
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index 82a108a20eb..bea0626286e 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -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);
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index 4e551e28885..746cc80d638 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -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 */
-
- 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);
+ return (float*)vcos;
+}
- 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.
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index efad06adcf3..2189fed3448 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -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;
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index f85efd23ad6..32383302485 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -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 */
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index c8a0c2632be..414b64cae6a 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -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);
diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h
index 249a4a5c36c..09af11fa64b 100644
--- a/source/blender/makesdna/DNA_customdata_types.h
+++ b/source/blender/makesdna/DNA_customdata_types.h
@@ -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 */
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index 9bf62e52f31..127f2d427d5 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -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 */
diff --git a/source/blender/src/editparticle.c b/source/blender/src/editparticle.c
index d2ac7bc5761..fc839f7e80b 100644
--- a/source/blender/src/editparticle.c
+++ b/source/blender/src/editparticle.c
@@ -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;