[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [12459] branches/particles/source/blender: work in progress commit, no more particles refering to verts, subsurf level change updates hair
Campbell Barton
cbarton at metavr.com
Sat Nov 3 19:17:22 CET 2007
Revision: 12459
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=12459
Author: campbellbarton
Date: 2007-11-03 19:17:22 +0100 (Sat, 03 Nov 2007)
Log Message:
-----------
work in progress commit, no more particles refering to verts, subsurf level change updates hair
Modified Paths:
--------------
branches/particles/source/blender/blenkernel/BKE_particle.h
branches/particles/source/blender/blenkernel/intern/DerivedMesh.c
branches/particles/source/blender/blenkernel/intern/modifier.c
branches/particles/source/blender/blenkernel/intern/particle.c
branches/particles/source/blender/blenkernel/intern/particle_system.c
branches/particles/source/blender/makesdna/DNA_particle_types.h
branches/particles/source/blender/src/editparticle.c
Modified: branches/particles/source/blender/blenkernel/BKE_particle.h
===================================================================
--- branches/particles/source/blender/blenkernel/BKE_particle.h 2007-11-02 16:12:11 UTC (rev 12458)
+++ branches/particles/source/blender/blenkernel/BKE_particle.h 2007-11-03 18:17:22 UTC (rev 12459)
@@ -247,7 +247,7 @@
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 DerivedMesh *dm, int deform_only, int from, int index, float *fuv, float *vec, float *nor, float *utan, float *vtan);
+void psys_particle_on_dm(struct DerivedMesh *dm, int deform_only, int from, int index, int index_dmcache, float *fuv, float *vec, float *nor, float *utan, float *vtan);
/* particle_system.c */
void initialize_particle(struct ParticleData *pa, int p, Object *ob, struct ParticleSystem *psys, struct ParticleSystemModifierData *psmd);
Modified: branches/particles/source/blender/blenkernel/intern/DerivedMesh.c
===================================================================
--- branches/particles/source/blender/blenkernel/intern/DerivedMesh.c 2007-11-02 16:12:11 UTC (rev 12458)
+++ branches/particles/source/blender/blenkernel/intern/DerivedMesh.c 2007-11-03 18:17:22 UTC (rev 12459)
@@ -2184,6 +2184,11 @@
/* set the DerivedMesh to only copy needed data */
DM_set_only_copy(dm, (CustomDataMask)curr->link);
+ /* TODO PARTICLE - this is probably a bad place to add the layer, find a new place to do this */
+ if (modifiers_isParticleEnabled(ob) && (CustomData_has_layer(&dm->faceData, CD_ORIGSPACE))==0) {
+ CustomData_add_layer(&dm->faceData, CD_ORIGSPACE, CD_DEFAULT, NULL, dm->getNumFaces(dm));
+ }
+
ndm = mti->applyModifierEM(md, ob, em, dm);
if (ndm) {
Modified: branches/particles/source/blender/blenkernel/intern/modifier.c
===================================================================
--- branches/particles/source/blender/blenkernel/intern/modifier.c 2007-11-02 16:12:11 UTC (rev 12458)
+++ branches/particles/source/blender/blenkernel/intern/modifier.c 2007-11-03 18:17:22 UTC (rev 12459)
@@ -4984,7 +4984,7 @@
/* TODO - Particles only need this if they are after a non deform modifier, for now do it always
These should be calculated on the fly */
- dataMask |= (1 << CD_MASK_ORIGSPACE);
+ dataMask |= CD_MASK_ORIGSPACE;
return dataMask;
}
@@ -5095,6 +5095,9 @@
if(psmd->flag & eParticleSystemFlag_Loaded)
psmd->flag &= ~eParticleSystemFlag_Loaded;
else{
+ /* TODO PARTICLE - Added this so changing subsurf under hair updates it
+ should it be done elsewhere? - Campbell */
+ psys->recalc |= PSYS_RECALC_HAIR;
psys->recalc |= PSYS_DISTR;
psmd->flag |= eParticleSystemFlag_DM_changed;
}
@@ -5105,8 +5108,8 @@
psmd->flag |= eParticleSystemFlag_psys_updated;
psmd->flag &= ~eParticleSystemFlag_DM_changed;
}
+}
-}
static void particleSystemModifier_deformVertsEM(
ModifierData *md, Object *ob, EditMesh *editData,
DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
@@ -5430,7 +5433,7 @@
/* make tree of emitter locations */
tree=alloc_kdtree(totpart);
for(p=0,pa=psys->particles,cur=tree; p<totpart; p++,pa++,cur++){
- psys_particle_on_dm(dm,deform_only,psys->part->from,pa->num,pa->fuv,cur->co,0,0,0);
+ psys_particle_on_dm(dm,deform_only,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,cur->co,0,0,0);
cur->nbr=p;
if(p) insert_into_kdtree(tree,cur);
}
Modified: branches/particles/source/blender/blenkernel/intern/particle.c
===================================================================
--- branches/particles/source/blender/blenkernel/intern/particle.c 2007-11-02 16:12:11 UTC (rev 12458)
+++ branches/particles/source/blender/blenkernel/intern/particle.c 2007-11-03 18:17:22 UTC (rev 12459)
@@ -55,6 +55,7 @@
#include "BLI_arithb.h"
#include "BLI_blenlib.h"
#include "BLI_dynstr.h"
+#include "BLI_linklist.h"
#include "BKE_anim.h"
@@ -594,6 +595,9 @@
//}
}
}
+
+
+
/************************************************/
/* Particles on a dm */
/************************************************/
@@ -773,9 +777,64 @@
}
return 0.0;
}
+
+/* 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*/
+int psys_particle_dm_face_lookup(DerivedMesh *dm, int index, float *fuv, struct LinkNode *node)
+{
+ MFace *mface=dm->getFaceData(dm,index,CD_MFACE);
+ int *origindex, *oi, totface, i;
+ OrigSpaceFace *osface=dm->getFaceDataArray(dm, CD_ORIGSPACE);
+ origindex = oi = dm->getFaceDataArray(dm, CD_ORIGINDEX);
+ totface = dm->getNumFaces(dm);
+
+ if (osface==NULL) {
+ /* Assume we dont need osface data */
+ if (index < totface) {
+ printf("\tNO CD_ORIGSPACE, assuming not needed\n");
+ return index;
+ } else {
+ printf("\tNO CD_ORIGSPACE, error out of range\n");
+ return -1;
+ }
+ }
+
+ if (node) { /* we have a linked list of faces that we use, faster! */
+ int node_index;
+ OrigSpaceFace *osface_node;
+ for(;node;node=node->next) {
+ node_index = (int *)node->link;
+ osface_node = osface+node_index;
+ if (*(oi+node_index) == index) {
+ if ( mface->v4 ) { /* check that this intersects - Its possible this misses :/ - could also check its not between */
+ if (IsectPQ2Df(fuv, osface_node->uv[0], osface_node->uv[1], osface_node->uv[2], osface_node->uv[3])) {
+ return i;
+ }
+ } else if (IsectPT2Df(fuv, osface_node->uv[0], osface_node->uv[1], osface_node->uv[2])) {
+ return i;
+ }
+ }
+ }
+ } else { /* if we have no node, try every face */
+ for (i=0; i<totface; i++, oi++, mface++, osface++) {
+ //printf("\tTesting dm_index:%i orig_index:%i looking for %i fuv(%f, %f)\n", i, *oi, index, fuv[0], fuv[1]);
+ if (*oi == index) {
+ if ( mface->v4 ) { /* check that this intersects - Its possible this misses :/ - could also check its not between */
+ if (IsectPQ2Df(fuv, osface->uv[0], osface->uv[1], osface->uv[2], osface->uv[3])) {
+ return i;
+ }
+ } else if (IsectPT2Df(fuv, osface->uv[0], osface->uv[1], osface->uv[2])) {
+ return i;
+ }
+ }
+ }
+ }
+ return -1;
+}
+
/* 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(DerivedMesh *dm, int deform_only, int from, int index, float *fuv, float *vec, float *nor, float *utan, float *vtan)
+void psys_particle_on_dm(DerivedMesh *dm, int deform_only, int from, int index, int index_dmcache, float *fuv, float *vec, float *nor, float *utan, float *vtan)
{
if(index < 0){ /* 'no dm' error has happened! */
PARTICLE_ERROR(nor, vec);
@@ -784,7 +843,7 @@
if (deform_only) {
/* this works for meshes with deform verts only - constructive modifiers wont work properly*/
- float temp1[3], temp2[3];
+ float temp1[3];
if(from == PART_FROM_VERT) {
dm->getVertCo(dm,index,vec);
if(nor){
@@ -821,15 +880,15 @@
/* Only face supported at the moment */
if (from==PART_FROM_FACE) {
/* find a face on the derived mesh that uses this face */
- MFace *mface=dm->getFaceDataArray(dm,CD_MFACE);
MVert *mvert=dm->getVertDataArray(dm,CD_MVERT);
+ MFace *mface;
int *origindex, *oi, totface, i;
MTFace *mtface=0;
OrigSpaceFace *osface=0;
int uv_index=CustomData_get_active_layer_index(&dm->faceData,CD_MTFACE);
int osf_index=CustomData_get_layer_index(&dm->faceData,CD_ORIGSPACE);
- int foundface=0; /* its possibe we dont fine the face we came from - it could have even been removed by a modifier */
+
CustomDataLayer *layer_uv, *layer_osf;
/* we need to modify the original fuv for its uv in relation to the derived mesh face)
@@ -849,7 +908,6 @@
origindex = oi = dm->getFaceDataArray(dm, CD_ORIGINDEX);
totface = dm->getNumFaces(dm);
-
/* For this to work we need origindex and OrigSpace coords */
if (origindex==NULL || osf_index<0) {
PARTICLE_ERROR(nor, vec);
@@ -860,53 +918,45 @@
if (uv_index>=0)
layer_uv=&dm->faceData.layers[uv_index];
- //printf("Lookup on particle %i\n", index);
- for (i=0; i<totface; i++, oi++, mface++) {
- // printf("\tTesting dm_index:%i orig_index:%i looking for %i fuv(%f, %f)\n", i, *oi, index, fuv[0], fuv[1]);
- if (*oi == index) {
- /* check that this intersects - Its possible this misses :/ - could also check its not between */
-
- /* uv's are optional */
- if (uv_index>=0)
- mtface= &((MTFace*)layer_uv->data)[i];
-
- osface= &((OrigSpaceFace*)layer_osf->data)[i];
-
- if ( mface->v4 ) {
- if (IsectPQ2Df(fuv, osface->uv[0], osface->uv[1], osface->uv[2], osface->uv[3])) {
- /* quads use a totaly different way of calculating the fuv_mod */
- PointInQuad2DUV(osface->uv[0], osface->uv[1], osface->uv[2], osface->uv[3], fuv, fuv_mod);
- psys_interpolate_face(mvert,mface,mtface,fuv_mod,vec,nor,utan,vtan);
- foundface = 1;
- break;
- }
- } else if (IsectPT2Df(fuv, osface->uv[0], osface->uv[1], osface->uv[2])) {
- /* generate a new fuv, (this is possibly a non optimal solution,
- * since we only need 2d calculation but use 3d func's)
- *
- * this method makes an imaginary triangle in 2d space using the UV's from the derived mesh face
- * Then find new uv coords using the fuv and this face with LineIntersectsTriangleUV.
- * .This means the new values will be correct in relation to the derived meshes face.
- */
- Vec2Copyf(v0, osface->uv[0]);
- Vec2Copyf(v1, osface->uv[1]);
- Vec2Copyf(v2, osface->uv[2]);
-
- /* Doing this in 3D is not nice */
- LineIntersectsTriangleUV(p1, p2, v0, v1, v2, &lambda, fuv_mod);
- //fuv_mod[1] = 1.0f-fuv_mod[1];
- psys_interpolate_face(mvert,mface,mtface,fuv_mod,vec,nor,utan,vtan);
- foundface = 1;
- break;
- }
- }
+ if (index_dmcache == -1) {
+ i = psys_particle_dm_face_lookup(dm, index, fuv, (LinkNode*)NULL);
+ } else {
+ i = index_dmcache;
}
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list