[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [22190] branches/blender2.5/blender/source /blender: Smoke: fix crash with collisions + flows

Daniel Genrich daniel.genrich at gmx.net
Mon Aug 3 18:39:12 CEST 2009


Revision: 22190
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=22190
Author:   genscher
Date:     2009-08-03 18:39:12 +0200 (Mon, 03 Aug 2009)

Log Message:
-----------
Smoke: fix crash with collisions + flows

Modified Paths:
--------------
    branches/blender2.5/blender/source/blender/blenkernel/BKE_smoke.h
    branches/blender2.5/blender/source/blender/blenkernel/intern/modifier.c
    branches/blender2.5/blender/source/blender/blenkernel/intern/smoke.c
    branches/blender2.5/blender/source/blender/makesdna/DNA_smoke_types.h

Modified: branches/blender2.5/blender/source/blender/blenkernel/BKE_smoke.h
===================================================================
--- branches/blender2.5/blender/source/blender/blenkernel/BKE_smoke.h	2009-08-03 15:45:43 UTC (rev 22189)
+++ branches/blender2.5/blender/source/blender/blenkernel/BKE_smoke.h	2009-08-03 16:39:12 UTC (rev 22190)
@@ -32,7 +32,7 @@
 #ifndef BKE_SMOKE_H_
 #define BKE_SMOKE_H_
 
-void smokeModifier_do(struct SmokeModifierData *smd, struct Scene *scene, struct Object *ob, struct DerivedMesh *dm);
+void smokeModifier_do(struct SmokeModifierData *smd, struct Scene *scene, struct Object *ob, struct DerivedMesh *dm, int useRenderParams, int isFinalCalc);
 
 void smokeModifier_free (struct SmokeModifierData *smd);
 void smokeModifier_reset(struct SmokeModifierData *smd);

Modified: branches/blender2.5/blender/source/blender/blenkernel/intern/modifier.c
===================================================================
--- branches/blender2.5/blender/source/blender/blenkernel/intern/modifier.c	2009-08-03 15:45:43 UTC (rev 22189)
+++ branches/blender2.5/blender/source/blender/blenkernel/intern/modifier.c	2009-08-03 16:39:12 UTC (rev 22190)
@@ -5844,7 +5844,7 @@
 	CDDM_apply_vert_coords(dm, vertexCos);
 	CDDM_calc_normals(dm);
 
-	smokeModifier_do(smd, md->scene, ob, dm);
+	smokeModifier_do(smd, md->scene, ob, dm, useRenderParams, isFinalCalc);
 
 	if(dm != derivedData) dm->release(dm);
 }

Modified: branches/blender2.5/blender/source/blender/blenkernel/intern/smoke.c
===================================================================
--- branches/blender2.5/blender/source/blender/blenkernel/intern/smoke.c	2009-08-03 15:45:43 UTC (rev 22189)
+++ branches/blender2.5/blender/source/blender/blenkernel/intern/smoke.c	2009-08-03 16:39:12 UTC (rev 22190)
@@ -48,6 +48,7 @@
 #include "BLI_kdtree.h"
 #include "BLI_kdopbvh.h"
 
+#include "BKE_bvhutils.h"
 #include "BKE_cdderivedmesh.h"
 #include "BKE_customdata.h"
 #include "BKE_DerivedMesh.h"
@@ -125,6 +126,82 @@
 
 #define TRI_UVOFFSET (1./4.)
 
+
+BVHTree *bvhtree_build_from_smoke ( float mat[4][4], MFace *mfaces, unsigned int numfaces, MVert *x, unsigned int numverts, float epsilon )
+{
+	BVHTree *tree;
+	float co[12];
+	int i;
+	MFace *tface = mfaces;
+
+	// calc quads 
+	// todo
+
+	tree = BLI_bvhtree_new ( numfaces, epsilon, 2, 6 );
+
+	// fill tree
+	for ( i = 0; i < numfaces; i++, tface++ )
+	{
+		VECCOPY ( &co[0*3], x[tface->v1].co );
+		Mat4MulVecfl (mat, &co[0*3]);
+		VECCOPY ( &co[1*3], x[tface->v2].co );
+		Mat4MulVecfl (mat, &co[1*3]);
+		VECCOPY ( &co[2*3], x[tface->v3].co );
+		Mat4MulVecfl (mat, &co[2*3]);
+
+		if ( tface->v4 )
+		{
+			VECCOPY ( &co[3*3], x[tface->v4].co );
+			Mat4MulVecfl (mat, &co[3*3]);
+		}
+
+		BLI_bvhtree_insert ( tree, i, co, ( mfaces->v4 ? 4 : 3 ) );
+	}
+
+	// balance tree
+	BLI_bvhtree_balance ( tree );
+
+	return tree;
+}
+
+void bvhtree_update_from_smoke ( float mat[4][4], BVHTree * bvhtree, MFace *faces, int numfaces, MVert *x, int numverts)
+{
+	int i;
+	MFace *mfaces = faces;
+	float co[12];
+	int ret = 0;
+
+	if ( !bvhtree )
+		return;
+
+	if ( x )
+	{
+		for ( i = 0; i < numfaces; i++, mfaces++ )
+		{
+			VECCOPY ( &co[0*3], x[mfaces->v1].co );
+			Mat4MulVecfl (mat, &co[0*3]);
+			VECCOPY ( &co[1*3], x[mfaces->v2].co );
+			Mat4MulVecfl (mat, &co[1*3]);
+			VECCOPY ( &co[2*3], x[mfaces->v3].co );
+			Mat4MulVecfl (mat, &co[2*3]);
+
+			if ( mfaces->v4 )
+			{
+				VECCOPY ( &co[3*3], x[mfaces->v4].co );
+				Mat4MulVecfl (mat, &co[3*3]);
+			}
+
+			ret = BLI_bvhtree_update_node ( bvhtree, i, co, NULL, ( mfaces->v4 ? 4 : 3 ) );
+
+			// check if tree is already full
+			if ( !ret )
+				break;
+		}
+
+		BLI_bvhtree_update_tree ( bvhtree );
+	}
+}
+
 int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, DerivedMesh *dm)
 {
 	if((smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain && !smd->domain->fluid)
@@ -134,8 +211,10 @@
 		float size[3];
 		MVert *verts = dm->getVertArray(dm);
 		float scale = 0.0;
-		int res = smd->domain->maxres;
+		int res;		
 
+		res = smd->domain->maxres;
+
 		// get BB of domain
 		for(i = 0; i < dm->getNumVerts(dm); i++)
 		{
@@ -370,6 +449,11 @@
 			MEM_freeN(tridivs);
 		}
 
+		if(!smd->coll->bvhtree)
+		{
+			smd->coll->bvhtree = bvhtree_build_from_smoke ( ob->obmat, dm->getFaceArray(dm), dm->getNumFaces(dm), dm->getVertArray(dm), dm->getNumVerts(dm), 0.0 );
+		}
+
 	}
 
 	return 0;
@@ -522,6 +606,12 @@
 			smd->coll->points = NULL;
 		}
 
+		if(smd->coll->bvhtree)
+		{
+			BLI_bvhtree_free(smd->coll->bvhtree);
+			smd->coll->bvhtree = NULL;
+		}
+
 		MEM_freeN(smd->coll);
 		smd->coll = NULL;
 	}
@@ -574,6 +664,12 @@
 				MEM_freeN(smd->coll->points);
 				smd->coll->points = NULL;
 			}
+
+			if(smd->coll->bvhtree)
+			{
+				BLI_bvhtree_free(smd->coll->bvhtree);
+				smd->coll->bvhtree = NULL;
+			}
 		}
 	}
 }
@@ -608,7 +704,7 @@
 			smd->domain->coll_group = NULL;
 			smd->domain->maxres = 32;
 			smd->domain->amplify = 2;
-			smd->domain->omega = 0.5;
+			smd->domain->omega = 1.0;
 			smd->domain->alpha = -0.001;
 			smd->domain->beta = 0.1;
 			smd->domain->flags = 0;
@@ -650,6 +746,7 @@
 			smd->coll->smd = smd;
 			smd->coll->points = NULL;
 			smd->coll->numpoints = 0;
+			smd->coll->bvhtree = NULL;
 		}
 	}
 }
@@ -657,7 +754,7 @@
 // forward declaration
 void smoke_calc_transparency(struct SmokeModifierData *smd, float *light, int big);
 
-void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedMesh *dm)
+void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc)
 {	
 	if(scene->r.cfra >= smd->time)
 		smokeModifier_init(smd, ob, scene, dm);
@@ -667,6 +764,7 @@
 		if(scene->r.cfra > smd->time)
 		{
 			// XXX TODO
+			smd->time = scene->r.cfra;
 		}
 		else if(scene->r.cfra < smd->time)
 		{
@@ -674,8 +772,26 @@
 			smokeModifier_reset(smd);
 		}
 	}
-	else if((smd->type & MOD_SMOKE_TYPE_DOMAIN))
+	else if(smd->type & MOD_SMOKE_TYPE_COLL)
 	{
+		if(scene->r.cfra > smd->time)
+		{
+			// XXX TODO
+			smd->time = scene->r.cfra;
+			
+			if(smd->coll->bvhtree)
+				bvhtree_update_from_smoke ( ob->obmat, smd->coll->bvhtree, dm->getFaceArray(dm), dm->getNumFaces(dm), dm->getVertArray(dm), dm->getNumVerts(dm));
+			else
+				printf("smoke coll with no bvh\n");
+		}
+		else if(scene->r.cfra < smd->time)
+		{
+			smd->time = scene->r.cfra;
+			smokeModifier_reset(smd);
+		}
+	}
+	else if(smd->type & MOD_SMOKE_TYPE_DOMAIN)
+	{
 		SmokeDomainSettings *sds = smd->domain;
 		
 		if(scene->r.cfra > smd->time)
@@ -777,6 +893,7 @@
 									int cell[3];
 									size_t i = 0;
 									size_t index = 0;
+									int badcell = 0;
 									
 									if(pa->alive == PARS_KILLED) continue;
 									else if(pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN)==0) continue;
@@ -793,8 +910,14 @@
 									for(i = 0; i < 3; i++)
 									{
 										if((cell[i] > sds->res[i] - 1) || (cell[i] < 0))
-											continue;
+										{
+											badcell = 1;
+											break;
+										}
 									}
+										
+									if(badcell)
+										continue;
 									
 									// 2. set cell values (heat, density and velocity)
 									index = smoke_get_index(cell[0], sds->res[0], cell[1], sds->res[1], cell[2]);
@@ -921,18 +1044,31 @@
 							size_t i, j;
 							unsigned char *obstacles = smoke_get_obstacle(smd->domain->fluid);
 
+							// int BLI_bvhtree_find_nearest(BVHTree *tree, const float *co, BVHTreeNearest *nearest, BVHTree_NearestPointCallback callback, void *userdata);
+
 							for(i = 0; i < scs->numpoints; i++)
 							{
+								int badcell = 0;
+
 								// 1. get corresponding cell
 								get_cell(smd, &scs->points[3 * i], cell, 0);
 							
 								// check if cell is valid (in the domain boundary)
 								for(j = 0; j < 3; j++)
 									if((cell[j] > sds->res[j] - 1) || (cell[j] < 0))
-										continue;
-								
+									{
+										badcell = 1;
+										break;
+									}
+										
+								if(badcell)
+									continue;
+
 								// 2. set cell values (heat, density and velocity)
 								index = smoke_get_index(cell[0], sds->res[0], cell[1], sds->res[1], cell[2]);
+								
+								// printf("cell[0]: %d, cell[1]: %d, cell[2]: %d\n", cell[0], cell[1], cell[2]);
+								// printf("res[0]: %d, res[1]: %d, res[2]: %d, index: %d\n\n", sds->res[0], sds->res[1], sds->res[2], index);
 									
 								obstacles[index] = 1;
 
@@ -1015,7 +1151,7 @@
 					// formula taken from "Visual Simulation of Smoke" / Fedkiw et al. pg. 4
 					// T_vox = exp(-C_ext * h)
 					// C_ext/sigma_t = density * C_ext
-					smoke_set_tvox(smd, index, exp(-density[index] * 4.0 * smd->domain->dx));
+					smoke_set_tvox(smd, index, exp(-density[index] * 7.0 * smd->domain->dx));
 	}
 	smoke_calc_transparency(smd, light, 0);
 }
@@ -1047,7 +1183,7 @@
 		// formula taken from "Visual Simulation of Smoke" / Fedkiw et al. pg. 4
 		// T_vox = exp(-C_ext * h)
 		// C_ext/sigma_t = density * C_ext
-		smoke_set_bigtvox(smd, i, exp(-density[i] * 4.0 * smd->domain->dx / smd->domain->amplify) );
+		smoke_set_bigtvox(smd, i, exp(-density[i] * 7.0 * smd->domain->dx / smd->domain->amplify) );
 	}
 	smoke_calc_transparency(smd, light, 1);
 }

Modified: branches/blender2.5/blender/source/blender/makesdna/DNA_smoke_types.h
===================================================================
--- branches/blender2.5/blender/source/blender/makesdna/DNA_smoke_types.h	2009-08-03 15:45:43 UTC (rev 22189)
+++ branches/blender2.5/blender/source/blender/makesdna/DNA_smoke_types.h	2009-08-03 16:39:12 UTC (rev 22190)
@@ -75,10 +75,8 @@
 	int max_textures;
 	short noise; /* noise type: wave, curl, anisotropic */
 	short pad2;
-	int prev_res[3];
-	int prev_maxres;
-	int render_res[3];
-	int render_maxres;
+	int pad;
+	int pad3;
 } SmokeDomainSettings;
 
 
@@ -104,6 +102,7 @@
 /* collision objects (filled with smoke) */
 typedef struct SmokeCollSettings {
 	struct SmokeModifierData *smd; /* for fast RNA access */
+	struct BVHTree *bvhtree; /* bounding volume hierarchy for this cloth object */
 	float *points;
 	float *points_old;
 	float *vel;





More information about the Bf-blender-cvs mailing list