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:
authorDaniel Genrich <daniel.genrich@gmx.net>2009-08-03 20:39:12 +0400
committerDaniel Genrich <daniel.genrich@gmx.net>2009-08-03 20:39:12 +0400
commitee92957b363950f49a562632d42494cb35f0e8ed (patch)
treefb0cde76df25786b3630feecebc087278e4a73f5
parent7185303219310db45ccdbb521d626edd23b9fd06 (diff)
Smoke: fix crash with collisions + flows
-rw-r--r--source/blender/blenkernel/BKE_smoke.h2
-rw-r--r--source/blender/blenkernel/intern/modifier.c2
-rw-r--r--source/blender/blenkernel/intern/smoke.c154
-rw-r--r--source/blender/makesdna/DNA_smoke_types.h7
4 files changed, 150 insertions, 15 deletions
diff --git a/source/blender/blenkernel/BKE_smoke.h b/source/blender/blenkernel/BKE_smoke.h
index b37e1d08fcc..b1b42286788 100644
--- a/source/blender/blenkernel/BKE_smoke.h
+++ b/source/blender/blenkernel/BKE_smoke.h
@@ -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);
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index d86d563aaa2..f8795edc878 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -5844,7 +5844,7 @@ static void smokeModifier_deformVerts(
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);
}
diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c
index c619c3e25ab..3f23fbda484 100644
--- a/source/blender/blenkernel/intern/smoke.c
+++ b/source/blender/blenkernel/intern/smoke.c
@@ -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 @@ void calcTriangleDivs(Object *ob, MVert *verts, int numverts, MFace *tris, int n
#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,7 +211,9 @@ int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, Derive
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 @@ int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, Derive
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 @@ void smokeModifier_freeCollision(SmokeModifierData *smd)
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 @@ void smokeModifier_reset(struct SmokeModifierData *smd)
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 @@ void smokeModifier_createType(struct SmokeModifierData *smd)
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 @@ void smokeModifier_createType(struct SmokeModifierData *smd)
smd->coll->smd = smd;
smd->coll->points = NULL;
smd->coll->numpoints = 0;
+ smd->coll->bvhtree = NULL;
}
}
}
@@ -657,7 +754,7 @@ void smokeModifier_createType(struct SmokeModifierData *smd)
// 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,25 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM
if(scene->r.cfra > smd->time)
{
// XXX TODO
+ smd->time = scene->r.cfra;
+ }
+ else if(scene->r.cfra < smd->time)
+ {
+ smd->time = scene->r.cfra;
+ smokeModifier_reset(smd);
+ }
+ }
+ 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)
{
@@ -674,7 +790,7 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM
smokeModifier_reset(smd);
}
}
- else if((smd->type & MOD_SMOKE_TYPE_DOMAIN))
+ else if(smd->type & MOD_SMOKE_TYPE_DOMAIN)
{
SmokeDomainSettings *sds = smd->domain;
@@ -777,6 +893,7 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM
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 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM
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 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM
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 @@ void smoke_prepare_View(SmokeModifierData *smd, float *light)
// 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 @@ void smoke_prepare_bigView(SmokeModifierData *smd, float *light)
// 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);
}
diff --git a/source/blender/makesdna/DNA_smoke_types.h b/source/blender/makesdna/DNA_smoke_types.h
index 0c93b5eb56e..c3efc5e04dd 100644
--- a/source/blender/makesdna/DNA_smoke_types.h
+++ b/source/blender/makesdna/DNA_smoke_types.h
@@ -75,10 +75,8 @@ typedef struct SmokeDomainSettings {
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 @@ typedef struct SmokeFlowSettings {
/* 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;