From ee92957b363950f49a562632d42494cb35f0e8ed Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Mon, 3 Aug 2009 16:39:12 +0000 Subject: Smoke: fix crash with collisions + flows --- source/blender/blenkernel/BKE_smoke.h | 2 +- source/blender/blenkernel/intern/modifier.c | 2 +- source/blender/blenkernel/intern/smoke.c | 154 ++++++++++++++++++++++++++-- source/blender/makesdna/DNA_smoke_types.h | 7 +- 4 files changed, 150 insertions(+), 15 deletions(-) (limited to 'source') 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; -- cgit v1.2.3