diff options
author | Daniel Genrich <daniel.genrich@gmx.net> | 2008-01-29 19:32:42 +0300 |
---|---|---|
committer | Daniel Genrich <daniel.genrich@gmx.net> | 2008-01-29 19:32:42 +0300 |
commit | 5da7f4df472f41997a1f424315f94d0d04b3dd30 (patch) | |
tree | e89ba6ccf1bec0b9d34ee3a62d3f17b295de76c1 /source | |
parent | 9c1fa1ff4d5d5d21170d7a56c00abc6476b85dda (diff) |
-= Cloth cleanup =-
Fixes:
- Cloth event refactor to solve 2 unknown cache bugs
- Cloth vgroup refactor (faster + scalable stinnes now working)
- Cloth + Collision modifier on one object crash
- Editmode + faceextrude on baked cloth crash
- Stiffness groups would get pinned
- Correct scaled stiffness calculation
- Fixes freeing error under some circumstances
- Deactivating reset/cache freeing when in editmode
- Autobaking setting doesn't get screwed up anymore
- More than 1 collision object in a scene could explode
- Pinning + not protected cache didn't reset cloth
- Start simulation on first frame and not on 2nd
- Maximum structstiff now correct (copy-paste error)
- Loading file with baked cloth calculate the spring length correctly
- Loading file behaviour improved with cache
- Collision object is evaluated first (untested)
- Debug output activated with rt>0
Be carefull: Files with some cloth cache or something should be
regenerated.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/BKE_cloth.h | 3 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/cloth.c | 213 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/collision.c | 10 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/implicit.c | 95 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/modifier.c | 13 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 3 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_cloth_types.h | 2 | ||||
-rw-r--r-- | source/blender/src/buttons_object.c | 21 | ||||
-rw-r--r-- | source/blender/src/editmesh.c | 12 |
9 files changed, 244 insertions, 128 deletions
diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index 1a3feed0a0c..80d09cde342 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -133,9 +133,10 @@ typedef enum CLOTH_SIMSETTINGS_FLAG_GOAL = ( 1 << 3 ), // we have goals enabled CLOTH_SIMSETTINGS_FLAG_TEARING = ( 1 << 4 ),// true if tearing is enabled CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT = ( 1 << 5 ), // true if tearing is enabled - CLOTH_SIMSETTINGS_FLAG_NEW = ( 1 << 6 ), // unsued, true if cloth was just enabled + CLOTH_SIMSETTINGS_FLAG_EDITMODE = ( 1 << 6 ), // are we in editmode? -several things disabled CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE = (1 << 7), /* force cache freeing */ CLOTH_SIMSETTINGS_FLAG_SCALING = (1 << 8), /* is advanced scaling active? */ + CLOTH_SIMSETTINGS_FLAG_LOADED = (1 << 9), /* did we just got load? */ } CLOTH_SIMSETTINGS_FLAGS; /* COLLISION FLAGS */ diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 0870bf2efa3..a99ac705c0b 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -153,7 +153,7 @@ void cloth_init ( ClothModifierData *clmd ) clmd->sim_parms->mass = 1.0f; clmd->sim_parms->stepsPerFrame = 5; clmd->sim_parms->sim_time = 1.0; - clmd->sim_parms->flags = CLOTH_SIMSETTINGS_FLAG_NEW; + clmd->sim_parms->flags = 0; clmd->sim_parms->solver_type = 0; clmd->sim_parms->preroll = 0; clmd->sim_parms->maxspringlen = 10; @@ -163,6 +163,7 @@ void cloth_init ( ClothModifierData *clmd ) clmd->sim_parms->lastcachedframe = 0; clmd->sim_parms->editedframe = 0; clmd->sim_parms->autoprotect = 25; + clmd->sim_parms->firstcachedframe = -1.0; clmd->coll_parms->self_friction = 5.0; clmd->coll_parms->friction = 10.0; @@ -520,20 +521,14 @@ int cloth_read_cache(Object *ob, ClothModifierData *clmd, float framenr) fclose(fp); - /* - // belongs to another location ?!? - if((clmd->sim_parms->solver_type == 0) && (ret!=0)) - { - implicit_set_positions(clmd); - } - */ - if(clmd->sim_parms->lastcachedframe < framenr) { + if(G.rt > 0) printf("cloth_read_cache problem: lnex - f#: %f, lastCF: %d\n", framenr, clmd->sim_parms->lastcachedframe); } } + if(G.rt > 0) printf("cloth_read_cache: %f\n", framenr); return ret; @@ -542,15 +537,15 @@ int cloth_read_cache(Object *ob, ClothModifierData *clmd, float framenr) void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr) { int stack_index = -1; - printf("cloth_clear_cache: %f\n", framenr); - /* - // belongs to another location ?!? - if(framenr>0) + // don't do anything as long as we're in editmode! + if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_EDITMODE) { - cloth_read_cache(ob, clmd, framenr); + /* delete cache free request */ + clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE; + + return; } - */ /* clear cache if specific frame cleaning requested or cache is not protected */ if((!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT)) || (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE)) @@ -558,11 +553,18 @@ void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr) stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd); BKE_ptcache_id_clear((ID *)ob, PTCACHE_CLEAR_AFTER, framenr, stack_index); + + /* update last cached frame # */ + clmd->sim_parms->lastcachedframe = framenr; + + /* update first cached frame # */ + if((framenr < clmd->sim_parms->firstcachedframe) && (clmd->sim_parms->firstcachedframe >=0.0)) + clmd->sim_parms->firstcachedframe = -1.0; + + if(G.rt > 0) + printf("cloth_clear_cache: %f\n", framenr); } - /* update last cached frame # */ - clmd->sim_parms->lastcachedframe = framenr; - /* delete cache free request */ clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE; @@ -575,10 +577,12 @@ void cloth_write_cache(Object *ob, ClothModifierData *clmd, float framenr) unsigned int a; Cloth *cloth = clmd->clothObject; + if(G.rt > 0) printf("cloth_write_cache: %f\n", framenr); if(!cloth) { + if(G.rt > 0) printf("cloth_write_cache: no cloth\n"); return; } @@ -588,6 +592,7 @@ void cloth_write_cache(Object *ob, ClothModifierData *clmd, float framenr) fp = BKE_ptcache_id_fopen((ID *)ob, 'w', framenr, stack_index); if(!fp) { + if(G.rt > 0) printf("cloth_write_cache: no fp\n"); return; } @@ -599,8 +604,14 @@ void cloth_write_cache(Object *ob, ClothModifierData *clmd, float framenr) fwrite(&cloth->verts[a].v, sizeof(float),3,fp); } + /* update last cached frame # */ clmd->sim_parms->lastcachedframe = MAX2(clmd->sim_parms->lastcachedframe, framenr); + /* update first cached frame # */ + if((clmd->sim_parms->firstcachedframe < 0.0) || ((framenr < clmd->sim_parms->firstcachedframe) && (clmd->sim_parms->firstcachedframe > 0.0))) + clmd->sim_parms->firstcachedframe = framenr; + + if(G.rt > 0) printf("lcf: %d, framenr: %f\n", clmd->sim_parms->lastcachedframe, framenr); fclose(fp); @@ -629,8 +640,18 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d MFace *mface = NULL; DerivedMesh *result = NULL; + if(G.rt > 0) printf("clothModifier_do start\n"); + /* we're getting called two times during file load, + resulting in a not valid G.relbase on the first time (cache makes problems) + --> just return back */ + if((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_LOADED)&& (!G.relbase_valid)) + { + clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_LOADED; + return dm; + } + result = CDDM_copy(dm); if(!result) @@ -656,6 +677,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_RESET) { cloth_free_modifier (ob, clmd); + if(G.rt > 0) printf("clothModifier_do CLOTH_SIMSETTINGS_FLAG_RESET\n"); } @@ -693,10 +715,12 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d if ( deltaTime == 1.0f ) cloth_write_cache(ob, clmd, framenr-1.0); */ + if(G.rt > 0) printf("cloth_from_object NO cloth_read_cache cloth_write_cache\n"); } else { + if(G.rt > 0) printf("cloth_from_object cloth_read_cache\n"); implicit_set_positions(clmd); @@ -707,33 +731,35 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d // only be active during a specific period: // that's "first frame" and "last frame" on GUI - /* + // TODO: enable later again after refactoring if ( current_time < clmd->sim_parms->firstframe ) { - return result; -} + return result; + } else if ( current_time > clmd->sim_parms->lastframe ) { - int stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd); - - if(BKE_ptcache_id_exist((ID *)ob, clmd->sim_parms->lastcachedframe, stack_index)) - { - if(cloth_read_cache(ob, clmd, framenr)) - { + int stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd); + + if(BKE_ptcache_id_exist((ID *)ob, clmd->sim_parms->lastcachedframe, stack_index)) + { + if(cloth_read_cache(ob, clmd, clmd->sim_parms->lastcachedframe)) + { + implicit_set_positions(clmd); + // Copy the result back to the object. - cloth_to_object (ob, clmd, result); -} -} - return result; -} - */ + cloth_to_object (ob, clmd, result); + } + } + return result; + } /* nice moving one frame forward */ if ( deltaTime == 1.0f ) { clmd->sim_parms->sim_time = current_time; + if(G.rt > 0) printf("clothModifier_do deltaTime=1\n"); if(!cloth_read_cache(ob, clmd, framenr)) @@ -766,14 +792,16 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d // check for autoprotection if(framenr >= clmd->sim_parms->autoprotect) { + if(G.rt > 0) printf("fr#: %f, auto: %d\n", framenr, clmd->sim_parms->autoprotect); clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT; } - + if(G.rt > 0) printf("clothModifier_do deltaTime=1 cachewrite\n"); } else { + if(G.rt > 0) printf("clothModifier_do deltaTime=1 cacheread\n"); implicit_set_positions(clmd); } @@ -783,6 +811,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d } else if(deltaTime == 0.0f) { + if(G.rt > 0) printf("clothModifier_do deltaTime!=1 clmd->clothObject != NULL\n"); if(cloth_read_cache(ob, clmd, framenr)) { @@ -802,6 +831,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d } else { + if(G.rt > 0) printf("clothModifier_do deltaTime!=1 clmd->clothObject != NULL\n"); if(cloth_read_cache(ob, clmd, framenr)) { @@ -885,7 +915,7 @@ void cloth_free_modifier ( Object *ob, ClothModifierData *clmd ) void cloth_free_modifier_extern ( ClothModifierData *clmd ) { Cloth *cloth = NULL; - + if(G.rt > 0) printf("cloth_free_modifier_extern\n"); if ( !clmd ) @@ -895,6 +925,7 @@ void cloth_free_modifier_extern ( ClothModifierData *clmd ) if ( cloth ) { + if(G.rt > 0) printf("cloth_free_modifier_extern in\n"); // If our solver provides a free function, call it @@ -1070,12 +1101,13 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d MVert *mvert = NULL; ClothVertex *verts = NULL; float tnull[3] = {0,0,0}; + int cache_there = 0; // If we have a clothObject, free it. if ( clmd->clothObject != NULL ) { cloth_free_modifier ( ob, clmd ); - + if(G.rt > 0) printf("cloth_free_modifier cloth_from_object\n"); } @@ -1098,66 +1130,73 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d cloth_from_mesh ( ob, clmd, dm ); - if ( clmd->clothObject != NULL ) + if((clmd->sim_parms->firstcachedframe < 0.0) || ((clmd->sim_parms->firstcachedframe >= 0.0) && (!cloth_read_cache(ob, clmd, clmd->sim_parms->firstcachedframe)))) { - // create springs - clmd->clothObject->springs = NULL; - clmd->clothObject->numsprings = -1; - - mvert = dm->getVertArray ( dm ); - verts = clmd->clothObject->verts; + // no cache there + cache_there = 0; + if(G.rt > 0) + printf("cache_there = 0\n"); + } + else + { + // we have a cache + cache_there = 1; + if(G.rt > 0) + printf("cache_there = 1, fcf: %d\n", clmd->sim_parms->firstcachedframe); + } + + // create springs + clmd->clothObject->springs = NULL; + clmd->clothObject->numsprings = -1; + + mvert = dm->getVertArray ( dm ); + verts = clmd->clothObject->verts; - // set initial values - for ( i = 0; i < dm->getNumVerts(dm); i++, verts++ ) + // set initial values + for ( i = 0; i < dm->getNumVerts(dm); i++, verts++ ) + { + if(!cache_there) { VECCOPY ( verts->x, mvert[i].co ); - - if(i<5) - printf("i: %d, verts->x[0]: %f\n", i, verts->x[0]); - Mat4MulVecfl ( ob->obmat, verts->x ); - - if(i<5) - printf("i: %d, verts->x[0]: %f\n\n", i, verts->x[0]); - - verts->mass = clmd->sim_parms->mass; - - if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) - verts->goal= clmd->sim_parms->defgoal; - else - verts->goal= 0.0f; - - verts->flags = 0; - VECCOPY ( verts->xold, verts->x ); - VECCOPY ( verts->xconst, verts->x ); - VECCOPY ( verts->txold, verts->x ); - VecMulf ( verts->v, 0.0f ); - - verts->impulse_count = 0; - VECCOPY ( verts->impulse, tnull ); - } - - // apply / set vertex groups - // has to be happen before springs are build! - cloth_apply_vgroup (clmd, dm); - - if ( !cloth_build_springs ( clmd, dm ) ) - { - cloth_free_modifier ( ob, clmd ); - modifier_setError ( & ( clmd->modifier ), "Can't build springs." ); - printf("cloth_free_modifier cloth_build_springs\n"); - return 0; } - // init our solver - if ( solvers [clmd->sim_parms->solver_type].init ) - solvers [clmd->sim_parms->solver_type].init ( ob, clmd ); + verts->mass = clmd->sim_parms->mass; - clmd->clothObject->tree = bvh_build_from_cloth ( clmd, clmd->coll_parms->epsilon ); - - return 1; + if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) + verts->goal= clmd->sim_parms->defgoal; + else + verts->goal= 0.0f; + + verts->flags = 0; + VECCOPY ( verts->xold, verts->x ); + VECCOPY ( verts->xconst, verts->x ); + VECCOPY ( verts->txold, verts->x ); + VecMulf ( verts->v, 0.0f ); + + verts->impulse_count = 0; + VECCOPY ( verts->impulse, tnull ); } - return 0; + + // apply / set vertex groups + // has to be happen before springs are build! + cloth_apply_vgroup (clmd, dm); + + if ( !cloth_build_springs ( clmd, dm ) ) + { + cloth_free_modifier ( ob, clmd ); + modifier_setError ( & ( clmd->modifier ), "Can't build springs." ); + printf("cloth_free_modifier cloth_build_springs\n"); + return 0; + } + + // init our solver + if ( solvers [clmd->sim_parms->solver_type].init ) + solvers [clmd->sim_parms->solver_type].init ( ob, clmd ); + + clmd->clothObject->tree = bvh_build_from_cloth ( clmd, clmd->coll_parms->epsilon ); + + return 1; } diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index 083ae5a2b46..0689b8b6dd2 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -561,7 +561,7 @@ int cloth_collision_response_static(ClothModifierData *clmd, CollisionModifierDa // Apply the impulse and increase impulse counters. - /* + /* // calculateFrictionImpulse(tangential, collvel, collpair->normal, magtangent, clmd->coll_parms->friction*0.01, magtangent); VECSUBS(vrel_t_pre, collvel, collpair->normal, magnormal); // VecMulf(vrel_t_pre, clmd->coll_parms->friction*0.01f/INPR(vrel_t_pre,vrel_t_pre)); @@ -1097,6 +1097,14 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) // verts come from clmd for(i = 0; i < numverts; i++) { + if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) + { + if(verts [i].goal >= SOFTGOALSNAP) + { + continue; + } + } + VECADD(verts[i].tx, verts[i].txold, verts[i].tv); } //////////////////////////////////////////////////////////// diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index 7ea48d6629b..cda56f5b601 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -82,7 +82,7 @@ void itend(void) double itval() { return ((double)_itend.QuadPart - - (double)_itstart.QuadPart)/((double)ifreq.QuadPart); + (double)_itstart.QuadPart)/((double)ifreq.QuadPart); } #else #include <sys/time.h> @@ -91,9 +91,9 @@ double itval() // #include <pmmintrin.h> // #include <pthread.h> -static struct timeval _itstart, _itend; -static struct timezone itz; -void itstart(void) + static struct timeval _itstart, _itend; + static struct timezone itz; + void itstart(void) { gettimeofday(&_itstart, &itz); } @@ -331,7 +331,7 @@ DO_INLINE void cp_fmatrix(float to[3][3], float from[3][3]) DO_INLINE float det_fmatrix(float m[3][3]) { return m[0][0]*m[1][1]*m[2][2] + m[1][0]*m[2][1]*m[0][2] + m[0][1]*m[1][2]*m[2][0] - -m[0][0]*m[1][2]*m[2][1] - m[0][1]*m[1][0]*m[2][2] - m[2][0]*m[1][1]*m[0][2]; + -m[0][0]*m[1][2]*m[2][1] - m[0][1]*m[1][0]*m[2][2] - m[2][0]*m[1][1]*m[0][2]; } DO_INLINE void inverse_fmatrix(float to[3][3], float from[3][3]) { @@ -719,6 +719,9 @@ int implicit_init (Object *ob, ClothModifierData *clmd) ClothSpring *spring = NULL; Implicit_Data *id = NULL; LinkNode *search = NULL; + + if(G.rt > 0) + printf("implicit_init\n"); // init memory guard // MEMORY_BASE.first = MEMORY_BASE.last = NULL; @@ -776,7 +779,7 @@ int implicit_init (Object *ob, ClothModifierData *clmd) // dFdV_start[i].c = big_I[i].c = big_zero[i].c = id->A[i+cloth->numverts].c = id->dFdV[i+cloth->numverts].c = id->dFdX[i+cloth->numverts].c = - id->P[i+cloth->numverts].c = id->Pinv[i+cloth->numverts].c = id->bigI[i+cloth->numverts].c = spring->kl; + id->P[i+cloth->numverts].c = id->Pinv[i+cloth->numverts].c = id->bigI[i+cloth->numverts].c = spring->kl; spring->matrix_index = i + cloth->numverts; @@ -1023,7 +1026,7 @@ int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fma del_lfvector(p); del_lfvector(r); - // printf("iterations: %d\n", iterations); + printf("iterations: %d\n", iterations); return iterations<conjgrad_looplimit; } @@ -1109,13 +1112,13 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, /* if(length>L) { - if((clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED) - && ((((length-L)*100.0f/L) > clmd->sim_parms->maxspringlen))) // cut spring! - { - s->flags |= CSPRING_FLAG_DEACTIVATE; - return; - } - } + if((clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED) + && ((((length-L)*100.0f/L) > clmd->sim_parms->maxspringlen))) // cut spring! + { + s->flags |= CSPRING_FLAG_DEACTIVATE; + return; + } + } */ mul_fvector_S(dir, extent, 1.0f/length); } @@ -1133,8 +1136,18 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, k = clmd->sim_parms->structural; - scaling = k + s->stiffness * (clmd->sim_parms->max_struct-k); + scaling = k + s->stiffness * ABS(clmd->sim_parms->max_struct-k); k = scaling; + + // printf("scaling: %f, stiffness: %f\n", k, s->stiffness); + /* + if((s->ij == 109) || (s->kl == 109)) + { + printf("length-L: %f, f: %f, len: %f, L: %f\n", length-L, (k*(length-L)), length, L); + printf("kl X-x: %f, f-y: %f, f-z: %f\n", X[s->kl][0], X[s->kl][1], X[s->kl][2]); + printf("ij X-x: %f, f-y: %f, f-z: %f\n\n", X[s->ij][0], X[s->ij][1], X[s->ij][2]); + } + */ mul_fvector_S(stretch_force, dir, (k*(length-L))); @@ -1157,7 +1170,7 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, k = clmd->sim_parms->bending; - scaling = k + s->stiffness * (clmd->sim_parms->max_bend-k); + scaling = k + s->stiffness * ABS(clmd->sim_parms->max_bend-k); cb = k = scaling; mul_fvector_S(bending_force, dir, fbstar(length, L, k, cb)); @@ -1166,6 +1179,12 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, dfdx_spring_type2(s->dfdx, dir,length,L,k, cb); } } + /* + if((s->ij == 109) || (s->kl == 109)) + { + printf("type: %d, f-x: %f, f-y: %f, f-z: %f\n", s->type, s->f[0], s->f[1], s->f[2]); +} + */ } DO_INLINE void cloth_apply_spring_force(ClothModifierData *clmd, ClothSpring *s, lfVector *lF, lfVector *X, lfVector *V, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX) @@ -1258,7 +1277,7 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec init_lfvector(lF, gravity, numverts); submul_lfvectorS(lF, lV, spring_air, numverts); - + /* do goal stuff */ if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) { @@ -1275,22 +1294,24 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec ks = 1.0f/(1.0f- verts [i].goal*clmd->sim_parms->goalspring)-1.0f ; VECADDS(lF[i], lF[i], auxvect, -ks); - // calulate damping forces generated by goals + // calulate damping forces generated by goals + VECSUB(velgoal,verts[i].xold, verts[i].xconst); kd = clmd->sim_parms->goalfrict * 0.01f; // friction force scale taken from SB VECSUBADDSS(lF[i], velgoal, kd, lV[i], kd); + } } } - + /* handle external forces like wind */ if(effectors) { float speed[3] = {0.0f, 0.0f,0.0f}; float force[3]= {0.0f, 0.0f, 0.0f}; - #pragma omp parallel for private (i) shared(lF) +#pragma omp parallel for private (i) shared(lF) for(i = 0; i < cloth->numverts; i++) { float vertexnormal[3]={0,0,0}; @@ -1308,7 +1329,7 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec VECADDS(lF[i], lF[i], wind_normalized, -calculateVertexWindForce(speed, vertexnormal)); } } - + // calculate spring forces search = cloth->springs; while(search) @@ -1329,6 +1350,7 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec cloth_apply_spring_force(clmd, search->link, lF, lX, lV, dFdV, dFdX); search = search->next; } + // printf("\n"); } void simulate_implicit_euler(lfVector *Vnew, lfVector *lX, lfVector *lV, lfVector *lF, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, float dt, fmatrix3x3 *A, lfVector *B, lfVector *dV, fmatrix3x3 *S, lfVector *z, lfVector *olddV, fmatrix3x3 *P, fmatrix3x3 *Pinv) @@ -1391,11 +1413,23 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase effectors= pdInitEffectors(ob,NULL); // calculate - cloth_calc_force(clmd, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step ); + cloth_calc_force(clmd, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step ); + + // printf("F -> x: %f, y: %f; z: %f\n\n", id->F[109][0], id->F[109][1], id->F[109][2]); + simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt, id->A, id->B, id->dV, id->S, id->z, id->olddV, id->P, id->Pinv); add_lfvector_lfvectorS(id->Xnew, id->X, id->Vnew, dt, numverts); + /* + printf("dt: %f\n", dt); + printf("Xnew -> x: %f, y: %f; z: %f\n", id->Xnew[109][0], id->Xnew[109][1], id->Xnew[109][2]); + printf("X -> x: %f, y: %f; z: %f\n", id->X[109][0], id->X[109][1], id->X[109][2]); + printf("Vnew -> x: %f, y: %f; z: %f\n\n", id->Vnew[109][0], id->Vnew[109][1], id->Vnew[109][2]); + */ + + // clmd->coll_parms->flags &= ~CLOTH_COLLSETTINGS_FLAG_ENABLED; + if(clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_ENABLED) { // collisions @@ -1404,7 +1438,8 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase // update verts to current positions for(i = 0; i < numverts; i++) { - if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) /* do goal stuff */ + + if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) { if(verts [i].goal >= SOFTGOALSNAP) { @@ -1431,6 +1466,16 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase { if(result) { + + if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) + { + if(verts [i].goal >= SOFTGOALSNAP) + { + continue; + } + } + + // VECADD(verts[i].tx, verts[i].txold, verts[i].tv); VECCOPY(verts[i].txold, verts[i].tx); @@ -1515,5 +1560,7 @@ void implicit_set_positions (ClothModifierData *clmd) { VECCOPY(id->X[i], verts[i].x); VECCOPY(id->V[i], verts[i].v); - } + } + if(G.rt > 0) + printf("implicit_set_positions\n"); } diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 475009c8fa6..7f378f136b6 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -4987,7 +4987,6 @@ static void clothModifier_updateDepgraph( Base *base; - /* TODO: this belongs to collision modifier */ if(clmd) { for(base = G.scene->base.first; base; base= base->next) @@ -4995,14 +4994,11 @@ static void clothModifier_updateDepgraph( Object *ob1= base->object; if(ob1 != ob) { - ClothModifierData *coll_clmd = (ClothModifierData *)modifiers_findByType(ob1, eModifierType_Cloth); + CollisionModifierData *coll_clmd = (CollisionModifierData *)modifiers_findByType(ob1, eModifierType_Collision); if(coll_clmd) - { - if (coll_clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) - { - DagNode *curNode = dag_get_node(forest, ob1); - dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA|DAG_RL_OB_DATA); - } + { + DagNode *curNode = dag_get_node(forest, ob1); + dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA|DAG_RL_OB_DATA); } } } @@ -5220,6 +5216,7 @@ static void collisionModifier_deformVerts( dm->release(dm); } + /* Boolean */ static void booleanModifier_copyData(ModifierData *md, ModifierData *target) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index a9d2e7d05a1..4feb8c00659 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -3015,6 +3015,9 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb) clmd->sim_parms= newdataadr(fd, clmd->sim_parms); clmd->coll_parms= newdataadr(fd, clmd->coll_parms); + clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_LOADED; + clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_EDITMODE; + } else if (md->type==eModifierType_Collision) { diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h index 93aa09db349..7d2ec9b96b4 100644 --- a/source/blender/makesdna/DNA_cloth_types.h +++ b/source/blender/makesdna/DNA_cloth_types.h @@ -82,6 +82,8 @@ typedef struct SimulationSettings float max_bend; /* max bending scaling value, min is "bending" */ float max_struct; /* max structural scaling value, min is "structural" */ float max_shear; /* max shear scaling value, UNUSED */ + int firstcachedframe; + int pad; } SimulationSettings; diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index 4f23d60cd67..e6046203c4f 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -2352,6 +2352,10 @@ void do_object_panels(unsigned short event) ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); if(clmd) { + // do nothing in editmode + if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_EDITMODE) + break; + /* force freeing because user wants */ clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE; @@ -2372,6 +2376,10 @@ void do_object_panels(unsigned short event) ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); if(clmd) { + // do nothing in editmode + if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_EDITMODE) + break; + /* force freeing because user wants */ clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE; @@ -2386,6 +2394,10 @@ void do_object_panels(unsigned short event) ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); if(clmd) { + // do nothing in editmode + if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_EDITMODE) + break; + CFRA= 1; update_for_newframe_muted(); DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); @@ -5211,8 +5223,8 @@ static void object_panel_cloth_II(Object *ob) if(clmd) { - uiDefButI(block, NUM, B_DIFF, "First Frame:", 10,160,150,20, &clmd->sim_parms->firstframe, 0, MAXFRAME, 1, 0, "Frame on which the simulation starts"); - uiDefButI(block, NUM, B_DIFF, "Last Frame:", 160,160,150,20, &clmd->sim_parms->lastframe, 0, MAXFRAME, 1, 0, "Frame on which the simulation stops"); + uiDefButI(block, NUM, B_CLOTH_RENEW, "First Frame:",10,160,150,20, &clmd->sim_parms->firstframe, 0, MAXFRAME, 1, 0, "Frame on which the simulation starts"); + uiDefButI(block, NUM, B_CLOTH_RENEW, "Last Frame:",160,160,150,20, &clmd->sim_parms->lastframe, 0, MAXFRAME, 1, 0, "Frame on which the simulation stops"); uiDefBut(block, LABEL, 0, "",10,140,300,20, NULL, 0.0, 0, 0, 0, ""); @@ -5244,6 +5256,7 @@ static void object_panel_cloth_II(Object *ob) { uiDefButF(block, NUM, REDRAWBUTSOBJECT, "Min Distance:", 160,60,150,20, &clmd->coll_parms->epsilon, 0.001f, 1.0, 0.01f, 0, "Minimum distance between collision objects before collision response takes in, can be changed for each frame"); uiDefButS(block, NUM, REDRAWBUTSOBJECT, "Collision Quality:", 10,40,300,20, &clmd->coll_parms->loop_count, 1.0, 100.0, 1.0, 0, "How many collision iterations should be done. (higher = better = slower), can be changed for each frame"); + uiDefButS(block, NUM, REDRAWBUTSOBJECT, "Friction:", 10,40,300,20, &clmd->coll_parms->friction, 1.0, 100.0, 1.0, 0, "Friction force if a collision happened"); } else uiDefBut(block, LABEL, 0, "",160,60,150,20, NULL, 0.0, 0, 0, 0, ""); @@ -5330,9 +5343,9 @@ static void object_panel_cloth_III(Object *ob) MEM_freeN (clvg1); MEM_freeN (clvg2); - uiDefButF(block, NUM, B_CLOTH_RENEW, "StructStiff Max:",10,70,150,20, &clmd->sim_parms->max_struct, clmd->sim_parms->structural, 1000.0, 0.01f, 0, "Maximum structural stiffness value"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "StructStiff Max:",10,70,150,20, &clmd->sim_parms->max_struct, clmd->sim_parms->structural, 10000.0, 0.01f, 0, "Maximum structural stiffness value"); - uiDefButF(block, NUM, B_CLOTH_RENEW, "BendStiff Max:",160,70,150,20, &clmd->sim_parms->max_bend, clmd->sim_parms->bending, 1000.0, 0.01f, 0, "Maximum bending stiffness value"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "BendStiff Max:",160,70,150,20, &clmd->sim_parms->max_bend, clmd->sim_parms->bending, 10000.0, 0.01f, 0, "Maximum bending stiffness value"); } else if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SCALING) diff --git a/source/blender/src/editmesh.c b/source/blender/src/editmesh.c index 712c9ddc4a9..94ac17ebd6c 100644 --- a/source/blender/src/editmesh.c +++ b/source/blender/src/editmesh.c @@ -862,10 +862,11 @@ void make_editMesh() cloth_enabled = 1; clmd->sim_parms->editedframe = G.scene->r.cfra; + clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_EDITMODE; /* inverse matrix is not uptodate... */ Mat4Invert ( G.obedit->imat, G.obedit->obmat ); - + if(G.rt > 0) printf("make_editmesh --> cloth_enabled\n"); } } @@ -1017,8 +1018,6 @@ void load_editMesh(void) Cloth *cloth = NULL; float temp[3], dt = 0.0; - printf("loadmesh\n"); - #ifdef WITH_VERSE if(em->vnode) { struct VNode *vnode = (VNode*)em->vnode; @@ -1106,6 +1105,7 @@ void load_editMesh(void) Mat4Invert ( G.obedit->imat, G.obedit->obmat ); dt = 1.0f / clmd->sim_parms->stepsPerFrame; } + if(G.rt > 0) printf("loadmesh --> tot: %d, num: %d\n", G.totvert, cloth->numverts); } } @@ -1115,6 +1115,7 @@ void load_editMesh(void) if(cloth_enabled) { + if(G.rt > 0) printf("loadmesh --> cloth_enabled\n"); VECCOPY(temp, cloth->verts[i].x); @@ -1129,6 +1130,7 @@ void load_editMesh(void) */ if(oldverts) { VECCOPY(mvert->co, oldverts[i].co); + if(G.rt > 0) printf("loadmesh --> cloth_enabled oldverts\n"); } i++; @@ -1166,6 +1168,7 @@ void load_editMesh(void) /* burn changes to cache */ if(cloth_enabled) { + if(G.rt > 0) printf("loadmesh --> cloth_enabled cloth_write_cache\n"); cloth_write_cache(G.obedit, clmd, clmd->sim_parms->editedframe); @@ -1174,14 +1177,17 @@ void load_editMesh(void) { cloth_read_cache(G.obedit, clmd, G.scene->r.cfra); } + clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_EDITMODE; } else { if(modifiers_isClothEnabled(G.obedit)) { ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(G.obedit, eModifierType_Cloth); + if(G.rt > 0) printf("loadmesh --> CLOTH_SIMSETTINGS_FLAG_RESET\n"); /* only reset cloth when no cache was used */ clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET; + clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_EDITMODE; } } |