diff options
author | Daniel Genrich <daniel.genrich@gmx.net> | 2008-02-08 03:55:48 +0300 |
---|---|---|
committer | Daniel Genrich <daniel.genrich@gmx.net> | 2008-02-08 03:55:48 +0300 |
commit | 1efba5bdb15ab4782d41b418a4927f1bb696bfb7 (patch) | |
tree | f3c2103c0b7d986cb55adf81425d212c7c09696f | |
parent | cd0262b6359bb9bcbdaf6f04616765a285272d91 (diff) |
Cloth: Hopefully fixed bug reported from bjornmose (2nd try)
-rw-r--r-- | source/blender/blenkernel/BKE_cloth.h | 67 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/cloth.c | 17 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/implicit.c | 247 | ||||
-rw-r--r-- | source/blender/src/buttons_object.c | 26 |
4 files changed, 234 insertions, 123 deletions
diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index bf0ecd21397..e4d64b2affa 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -65,6 +65,18 @@ struct CollisionTree; #define CLOTH_MAX_THREAD 2 +/* goal defines */ +#define SOFTGOALSNAP 0.999f + +/* This is approximately the smallest number that can be +* represented by a float, given its precision. */ +#define ALMOST_ZERO FLT_EPSILON + +/* Bits to or into the ClothVertex.flags. */ +#define CLOTH_VERT_FLAG_PINNED 1 +#define CLOTH_VERT_FLAG_COLLISION 2 +#define CLOTH_VERT_FLAG_PINNED_EM 3 + /** * The definition of a cloth vertex. */ @@ -108,13 +120,6 @@ typedef struct ClothSpring } ClothSpring; -/* goal defines */ -#define SOFTGOALSNAP 0.999f - -/* This is approximately the smallest number that can be -* represented by a float, given its precision. */ -#define ALMOST_ZERO FLT_EPSILON - // some macro enhancements for vector treatment #define VECADDADD(v1,v2,v3) {*(v1)+= *(v2) + *(v3); *(v1+1)+= *(v2+1) + *(v3+1); *(v1+2)+= *(v2+2) + *(v3+2);} #define VECSUBADD(v1,v2,v3) {*(v1)-= *(v2) + *(v3); *(v1+1)-= *(v2+1) + *(v3+1); *(v1+2)-= *(v2+2) + *(v3+2);} @@ -139,24 +144,25 @@ typedef enum 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_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_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 */ typedef enum { CLOTH_COLLSETTINGS_FLAG_ENABLED = ( 1 << 1 ), /* enables cloth - object collisions */ - CLOTH_COLLSETTINGS_FLAG_SELF = ( 1 << 2 ), /* unused */ + CLOTH_COLLSETTINGS_FLAG_SELF = ( 1 << 2 ), /* unused */ } CLOTH_COLLISIONSETTINGS_FLAGS; /* Spring types as defined in the paper.*/ typedef enum { - CLOTH_SPRING_TYPE_STRUCTURAL = 0, - CLOTH_SPRING_TYPE_SHEAR, - CLOTH_SPRING_TYPE_BENDING, + CLOTH_SPRING_TYPE_STRUCTURAL = 1, + CLOTH_SPRING_TYPE_SHEAR, + CLOTH_SPRING_TYPE_BENDING, + CLOTH_SPRING_TYPE_GOAL, } CLOTH_SPRING_TYPES; /* SPRING FLAGS */ @@ -166,11 +172,6 @@ typedef enum CLOTH_SPRING_FLAG_NEEDED = ( 1 << 2 ), // springs has values to be applied } CLOTH_SPRINGS_FLAGS; -/* Bits to or into the ClothVertex.flags. */ -#define CLOTH_VERT_FLAG_PINNED 1 -#define CLOTH_VERT_FLAG_COLLISION 2 -#define CLOTH_VERT_FLAG_PINNED_EM 3 - typedef void ( *CM_COLLISION_RESPONSE ) ( ClothModifierData *clmd, CollisionModifierData *collmd, CollisionTree *tree1, CollisionTree *tree2 ); @@ -189,7 +190,7 @@ int bvh_traverse ( ClothModifierData * clmd, CollisionModifierData * collmd, Col //////////////////////////////////////////////// // implicit.c //////////////////////////////////////////////// - + // needed for cloth.c int implicit_init ( Object *ob, ClothModifierData *clmd ); int implicit_free ( ClothModifierData *clmd ); @@ -197,7 +198,7 @@ int implicit_solver ( Object *ob, float frame, ClothModifierData *clmd, ListBase void implicit_set_positions ( ClothModifierData *clmd ); // globally needed -void clmdSetInterruptCallBack(int (*f)(void)); +void clmdSetInterruptCallBack ( int ( *f ) ( void ) ); //////////////////////////////////////////////// @@ -206,22 +207,25 @@ void clmdSetInterruptCallBack(int (*f)(void)); //////////////////////////////////////////////// // needed for modifier.c -void cloth_free_modifier_extern (ClothModifierData *clmd); -void cloth_free_modifier (Object *ob, ClothModifierData *clmd); -void cloth_init (ClothModifierData *clmd); -DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc); +void cloth_free_modifier_extern ( ClothModifierData *clmd ); +void cloth_free_modifier ( Object *ob, ClothModifierData *clmd ); +void cloth_init ( ClothModifierData *clmd ); +DerivedMesh *clothModifier_do ( ClothModifierData *clmd,Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc ); -void cloth_update_normals (ClothVertex *verts, int nVerts, MFace *face, int totface); +void cloth_update_normals ( ClothVertex *verts, int nVerts, MFace *face, int totface ); // needed for collision.c -void bvh_update_from_cloth(ClothModifierData *clmd, int moving); +void bvh_update_from_cloth ( ClothModifierData *clmd, int moving ); // needed for editmesh.c -void cloth_write_cache(Object *ob, ClothModifierData *clmd, float framenr); -int cloth_read_cache(Object *ob, ClothModifierData *clmd, float framenr); +void cloth_write_cache ( Object *ob, ClothModifierData *clmd, float framenr ); +int cloth_read_cache ( Object *ob, ClothModifierData *clmd, float framenr ); // needed for button_object.c -void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr); +void cloth_clear_cache ( Object *ob, ClothModifierData *clmd, float framenr ); + +// needed for cloth.c +int cloth_add_spring ( ClothModifierData *clmd, unsigned int indexA, unsigned int indexB, float restlength, int spring_type); //////////////////////////////////////////////// @@ -233,7 +237,8 @@ typedef void ( *CM_COLLISION_OBJ ) ( ClothModifierData *clmd, int step, CM_COLLI /* This enum provides the IDs for our solvers. */ // only one available in the moment -typedef enum { +typedef enum +{ CM_IMPLICIT = 0, } CM_SOLVER_ID; diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 07a32771fef..d75c4ecbfac 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -182,8 +182,8 @@ void cloth_init ( ClothModifierData *clmd ) clmd->sim_parms->maxgoal = 1.0f; clmd->sim_parms->mingoal = 0.0f; clmd->sim_parms->defgoal = 0.0f; - clmd->sim_parms->goalspring = 100.0f; - clmd->sim_parms->goalfrict = 0.0f; + clmd->sim_parms->goalspring = 10.0f; + clmd->sim_parms->goalfrict = 5.0f; } @@ -1035,7 +1035,6 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm ) unsigned int numverts = dm->getNumVerts ( dm ); float goalfac = 0; ClothVertex *verts = NULL; - // clmd->sim_parms->vgroup_mass clothObj = clmd->clothObject; @@ -1111,6 +1110,7 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d ClothVertex *verts = NULL; float tnull[3] = {0,0,0}; int cache_there = 0; + Cloth *cloth = NULL; // If we have a clothObject, free it. if ( clmd->clothObject != NULL ) @@ -1126,6 +1126,7 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d { clmd->clothObject->old_solver_type = 255; // clmd->clothObject->old_collision_type = 255; + cloth = clmd->clothObject; } else if ( !clmd->clothObject ) { @@ -1200,6 +1201,13 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d return 0; } + for ( i = 0; i < dm->getNumVerts(dm); i++) + { + if((!(cloth->verts[i].flags & CLOTH_VERT_FLAG_PINNED)) && (cloth->verts[i].goal > ALMOST_ZERO)) + { + cloth_add_spring (clmd, i, i, 0.0, CLOTH_SPRING_TYPE_GOAL); + } + } // init our solver if ( solvers [clmd->sim_parms->solver_type].init ) @@ -1273,10 +1281,11 @@ int cloth_add_spring ( ClothModifierData *clmd, unsigned int indexA, unsigned in spring->restlen = restlength; spring->type = spring_type; spring->flags = 0; + spring->stiffness = 0; cloth->numsprings++; - BLI_linklist_append ( &cloth->springs, spring ); + BLI_linklist_prepend ( &cloth->springs, spring ); return 1; } diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index 8c3aa514cf0..a42953e5ce7 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -169,8 +169,9 @@ DO_INLINE void mul_fvectorT_fvector(float to[3][3], float vectorA[3], float vect /* simple v^T * v product with scalar ("outer product") */ /* STATUS: HAS TO BE verified (*should* work) */ DO_INLINE void mul_fvectorT_fvectorS(float to[3][3], float vectorA[3], float vectorB[3], float aS) -{ +{ mul_fvectorT_fvector(to, vectorA, vectorB); + mul_fvector_S(to[0], to[0], aS); mul_fvector_S(to[1], to[1], aS); mul_fvector_S(to[2], to[2], aS); @@ -811,6 +812,8 @@ int implicit_init (Object *ob, ClothModifierData *clmd) search = search->next; } + + initdiag_bfmatrix(id->bigI, I); for(i = 0; i < cloth->numverts; i++) { @@ -989,7 +992,7 @@ DO_INLINE void BuildPPinv(fmatrix3x3 *lA, fmatrix3x3 *P, fmatrix3x3 *Pinv) } } - +/* // version 1.3 int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix3x3 *S, fmatrix3x3 *P, fmatrix3x3 *Pinv) { @@ -1053,6 +1056,110 @@ int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fma del_lfvector(p); del_lfvector(r); + printf("iterations: %d\n", iterations); + + return iterations<conjgrad_looplimit; +} +*/ +// version 1.4 +int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix3x3 *S, fmatrix3x3 *P, fmatrix3x3 *Pinv, fmatrix3x3 *bigI) +{ + unsigned int numverts = lA[0].vcount, iterations = 0, conjgrad_looplimit=100; + float delta0 = 0, deltaNew = 0, deltaOld = 0, alpha = 0, tol = 0; + float conjgrad_epsilon=0.0001; // 0.2 is dt for steps=5 + lfVector *r = create_lfvector(numverts); + lfVector *p = create_lfvector(numverts); + lfVector *s = create_lfvector(numverts); + lfVector *h = create_lfvector(numverts); + lfVector *bhat = create_lfvector(numverts); + lfVector *btemp = create_lfvector(numverts); + + BuildPPinv(lA, P, Pinv); + + initdiag_bfmatrix(bigI, I); + sub_bfmatrix_Smatrix(bigI, bigI, S); + + // x = Sx_0+(I-S)z + filter(dv, S); + add_lfvector_lfvector(dv, dv, z, numverts); + + // b_hat = S(b-A(I-S)z) + mul_bfmatrix_lfvector(r, lA, z); + mul_bfmatrix_lfvector(bhat, bigI, r); + sub_lfvector_lfvector(bhat, lB, bhat, numverts); + + // r = S(b-Ax) + mul_bfmatrix_lfvector(r, lA, dv); + sub_lfvector_lfvector(r, lB, r, numverts); + filter(r, S); + + // p = SP^-1r + mul_prevfmatrix_lfvector(p, Pinv, r); + filter(p, S); + + // delta0 = bhat^TP^-1bhat + mul_prevfmatrix_lfvector(btemp, Pinv, bhat); + delta0 = dot_lfvector(bhat, btemp, numverts); + + // deltaNew = r^TP + deltaNew = dot_lfvector(r, p, numverts); + + /* + filter(dv, S); + add_lfvector_lfvector(dv, dv, z, numverts); + + mul_bfmatrix_lfvector(r, lA, dv); + sub_lfvector_lfvector(r, lB, r, numverts); + filter(r, S); + + mul_prevfmatrix_lfvector(p, Pinv, r); + filter(p, S); + + deltaNew = dot_lfvector(r, p, numverts); + + delta0 = deltaNew * sqrt(conjgrad_epsilon); + */ + + // itstart(); + + tol = (0.01*0.2); + + while ((deltaNew > delta0*tol*tol) && (iterations < conjgrad_looplimit)) + { + iterations++; + + mul_bfmatrix_lfvector(s, lA, p); + filter(s, S); + + alpha = deltaNew / dot_lfvector(p, s, numverts); + + add_lfvector_lfvectorS(dv, dv, p, alpha, numverts); + + add_lfvector_lfvectorS(r, r, s, -alpha, numverts); + + mul_prevfmatrix_lfvector(h, Pinv, r); + filter(h, S); + + deltaOld = deltaNew; + + deltaNew = dot_lfvector(r, h, numverts); + + add_lfvector_lfvectorS(p, h, p, deltaNew / deltaOld, numverts); + + filter(p, S); + + } + + // itend(); + // printf("cg_filtered_pre time: %f\n", (float)itval()); + + del_lfvector(btemp); + del_lfvector(bhat); + del_lfvector(h); + del_lfvector(s); + del_lfvector(p); + del_lfvector(r); + // printf("iterations: %d\n", iterations); return iterations<conjgrad_looplimit; @@ -1065,11 +1172,15 @@ DO_INLINE void dfdx_spring_type1(float to[3][3], float extent[3], float length, // return (outerprod(dir,dir)*k + (I - outerprod(dir,dir))*(k - ((k*L)/length))); float temp[3][3]; float temp1 = k*(1.0 - (L/length)); + float t[3][3]; + mul_fvectorT_fvectorS(temp, extent, extent, 1.0 / dot); sub_fmatrix_fmatrix(to, I, temp); mul_fmatrix_S(to, temp1); + mul_fvectorT_fvectorS(temp, extent, extent, k/ dot); add_fmatrix_fmatrix(to, to, temp); + /* mul_fvectorT_fvector(temp, dir, dir); sub_fmatrix_fmatrix(to, I, temp); @@ -1085,10 +1196,10 @@ DO_INLINE void dfdx_spring_type2(float to[3][3], float dir[3], float length, flo mul_fvectorT_fvectorS(to, dir, dir, fbstar_jacobi(length, L, k, cb)); } -DO_INLINE void dfdv_damp(float to[3][3], float ext[3], float damping, float dot) +DO_INLINE void dfdv_damp(float to[3][3], float dir[3], float damping) { // derivative of force wrt velocity. - mul_fvectorT_fvectorS(to, ext, ext, damping / dot); + mul_fvectorT_fvectorS(to, dir, dir, damping); } @@ -1114,8 +1225,10 @@ DO_INLINE void dfdx_damp(float to[3][3], float dir[3],float length,const float } -DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, lfVector *lF, lfVector *X, lfVector *V, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX) +DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, lfVector *lF, lfVector *X, lfVector *V, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, float time) { + Cloth *cloth = clmd->clothObject; + ClothVertex *verts = cloth->verts; float extent[3]; float length = 0, dot = 0; float dir[3] = {0,0,0}; @@ -1128,6 +1241,7 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, float stretch_force[3] = {0,0,0}; float bending_force[3] = {0,0,0}; float damping_force[3] = {0,0,0}; + float goal_force[3] = {0,0,0}; float nulldfdx[3][3]={ {0,0,0}, {0,0,0}, {0,0,0}}; float scaling = 0.0; @@ -1144,7 +1258,7 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, s->flags &= ~CLOTH_SPRING_FLAG_NEEDED; - if(length > ABS(ALMOST_ZERO)) + if(length > ALMOST_ZERO) { /* if(length>L) @@ -1165,7 +1279,7 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, } // calculate force of structural + shear springs - if(s->type != CLOTH_SPRING_TYPE_BENDING) + if((s->type & CLOTH_SPRING_TYPE_STRUCTURAL) || (s->type & CLOTH_SPRING_TYPE_SHEAR)) { if(length > L) // only on elonglation { @@ -1179,33 +1293,57 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, if(G.rt>3) printf("struct scaling: %f\n", k); - /* - if((s->ij == 4) || (s->kl == 4)) - { - 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]); - } - */ - // TODO: verify, half verified (couldn't see error) mul_fvector_S(stretch_force, dir, k*(length-L)); VECADD(s->f, s->f, stretch_force); // Ascher & Boxman, p.21: Damping only during elonglation - /* VERIFIED */ - mul_fvector_S(damping_force, extent, clmd->sim_parms->Cdis * (INPR(vel,extent)/dot)); + // something wrong with it... + mul_fvector_S(damping_force, dir, MIN2(1.0, clmd->sim_parms->Cdis) * INPR(vel,dir)); VECADD(s->f, s->f, damping_force); - // TODO: verify, half verified (couldn't see error) - dfdx_spring_type1(s->dfdx, extent, length, L, dot, k); - + /* VERIFIED */ + dfdx_spring(s->dfdx, dir, length, L, k); /* VERIFIED */ - dfdv_damp(s->dfdv, extent, clmd->sim_parms->Cdis, dot); + dfdv_damp(s->dfdv, dir, clmd->sim_parms->Cdis); + } } + else if(s->type & CLOTH_SPRING_TYPE_GOAL) + { + float tvect[3]; + + s->flags |= CLOTH_SPRING_FLAG_NEEDED; + + // current_position = xold + t * (newposition - xold) + VECSUB(tvect, verts[s->ij].xconst, verts[s->ij].xold); + mul_fvector_S(tvect, tvect, time); + VECADD(tvect, tvect, verts[s->ij].xold); + + VECSUB(extent, tvect, X[s->ij]); + + dot = INPR(extent, extent); + length = sqrt(dot); + + if(length > ALMOST_ZERO) + mul_fvector_S(dir, extent, 1.0f/length); + else + mul_fvector_S(dir, extent, 0.0f); + + k = clmd->sim_parms->goalspring; + k /= (clmd->coll_parms->avg_spring_len + FLT_EPSILON); + k *= verts [s->ij].goal; + VECADDS(s->f, s->f, extent, k); + + mul_fvector_S(damping_force, dir, MIN2(1.0, (clmd->sim_parms->goalfrict/100.0)) * INPR(vel,dir)); + VECADD(s->f, s->f, damping_force); + + // HERE IS THE PROBLEM!!!! + // dfdx_spring(s->dfdx, dir, length, 0.0, k); + // dfdv_damp(s->dfdv, dir, MIN2(1.0, (clmd->sim_parms->goalfrict/100.0))); + } else // calculate force of bending springs { if(length < L) @@ -1226,19 +1364,13 @@ 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) { if(s->flags & CLOTH_SPRING_FLAG_NEEDED) { - if(s->type != CLOTH_SPRING_TYPE_BENDING) + if(!(s->type & CLOTH_SPRING_TYPE_BENDING)) { sub_fmatrix_fmatrix(dFdV[s->ij].m, dFdV[s->ij].m, s->dfdv); sub_fmatrix_fmatrix(dFdV[s->kl].m, dFdV[s->kl].m, s->dfdv); @@ -1246,11 +1378,12 @@ DO_INLINE void cloth_apply_spring_force(ClothModifierData *clmd, ClothSpring *s, } VECADD(lF[s->ij], lF[s->ij], s->f); - VECSUB(lF[s->kl], lF[s->kl], s->f); - - sub_fmatrix_fmatrix(dFdX[s->ij].m, dFdX[s->ij].m, s->dfdx); + + if(!(s->type & CLOTH_SPRING_TYPE_GOAL)) + VECSUB(lF[s->kl], lF[s->kl], s->f); + sub_fmatrix_fmatrix(dFdX[s->kl].m, dFdX[s->kl].m, s->dfdx); - + sub_fmatrix_fmatrix(dFdX[s->ij].m, dFdX[s->ij].m, s->dfdx); add_fmatrix_fmatrix(dFdX[s->matrix_index].m, dFdX[s->matrix_index].m, s->dfdx); } } @@ -1332,32 +1465,6 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec } submul_lfvectorS(lF, lV, spring_air, numverts); - - /* do goal stuff */ - /* - if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) - { - for(i = 0; i < numverts; i++) - { - if(verts [i].goal < SOFTGOALSNAP) - { - // current_position = xold + t * (newposition - xold) - VECSUB(tvect, verts[i].xconst, verts[i].xold); - mul_fvector_S(tvect, tvect, time); - VECADD(tvect, tvect, verts[i].xold); - - VECSUB(auxvect, tvect, lX[i]); - 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 - 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) @@ -1390,7 +1497,7 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec { // only handle active springs // if(((clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED) && !(springs[i].flags & CSPRING_FLAG_DEACTIVATE))|| !(clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED)){} - cloth_calc_spring_force(clmd, search->link, lF, lX, lV, dFdV, dFdX); + cloth_calc_spring_force(clmd, search->link, lF, lX, lV, dFdV, dFdX, time); search = search->next; } @@ -1407,7 +1514,7 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec // 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, fmatrix3x3 *M) +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, fmatrix3x3 *M, fmatrix3x3 *bigI) { unsigned int numverts = dFdV[0].vcount; @@ -1425,7 +1532,7 @@ void simulate_implicit_euler(lfVector *Vnew, lfVector *lX, lfVector *lV, lfVecto itstart(); cg_filtered(dV, A, B, z, S); /* conjugate gradient algorithm to solve Ax=b */ - // cg_filtered_pre(dV, A, B, z, S, P, Pinv); + // cg_filtered_pre(dV, A, B, z, S, P, Pinv, bigI); itend(); // printf("cg_filtered calc time: %f\n", (float)itval()); @@ -1469,19 +1576,9 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase // calculate cloth_calc_force(clmd, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step, id->M); - - // 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, id->M); + 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, id->M, id->bigI); 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[4][0], id->Xnew[4][1], id->Xnew[4][2]); - printf("X -> x: %f, y: %f; z: %f\n", id->X[4][0], id->X[4][1], id->X[4][2]); - printf("Vnew -> x: %f, y: %f; z: %f\n", id->Vnew[4][0], id->Vnew[3][1], id->Vnew[4][2]); - printf("V -> x: %f, y: %f; z: %f\n\n", id->V[4][0], id->V[4][1], id->V[4][2]); - */ // clmd->coll_parms->flags &= ~CLOTH_COLLSETTINGS_FLAG_ENABLED; @@ -1557,7 +1654,7 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase // calculate cloth_calc_force(clmd, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step, id->M); - simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt / 2.0f, id->A, id->B, id->dV, id->S, id->z, id->olddV, id->P, id->Pinv, id->M); + simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt / 2.0f, id->A, id->B, id->dV, id->S, id->z, id->olddV, id->P, id->Pinv, id->M, id->bigI); } } else @@ -1582,7 +1679,7 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase { if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) { - if(verts [i].goal < SOFTGOALSNAP) + if(!(verts [i].flags & CLOTH_VERT_FLAG_PINNED)) { VECCOPY(verts[i].txold, id->X[i]); VECCOPY(verts[i].x, id->X[i]); diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index af22635ffdc..742b9aafa1b 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -5157,18 +5157,18 @@ static void object_panel_cloth(Object *ob) if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT) uiSetButLock(1, "Cache is protected"); uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_CLOTH_RENEW, "StructStiff:", 10,170,150,20, &clmd->sim_parms->structural, 1.0, 10000.0, 100, 0, "Overall stiffness of structure"); - uiDefButF(block, NUM, B_CLOTH_RENEW, "BendStiff:", 160,170,150,20, &clmd->sim_parms->bending, 0.0, 10000.0, 1000, 0, "Wrinkle coefficient (higher = less smaller but more big wrinkles)"); - uiDefButI(block, NUM, B_CLOTH_RENEW, "Quality:", 10,150,150,20, &clmd->sim_parms->stepsPerFrame, 4.0, 80.0, 5, 0, "Quality of the simulation (higher=better=slower)"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "StructStiff:", 10,170,150,20, &clmd->sim_parms->structural, 1.0, 10000.0, 100, 0, "Overall stiffness of structure"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "BendStiff:", 160,170,150,20, &clmd->sim_parms->bending, 0.0, 10000.0, 1000, 0, "Wrinkle coefficient (higher = less smaller but more big wrinkles)"); + uiDefButI(block, NUM, B_CLOTH_RENEW, "Quality:", 10,150,150,20, &clmd->sim_parms->stepsPerFrame, 4.0, 80.0, 5, 0, "Quality of the simulation (higher=better=slower)"); - uiDefButF(block, NUM, B_CLOTH_RENEW, "Spring Damp:", 160,150,150,20, &clmd->sim_parms->Cdis, 0.0, 10.0, 10, 0, "Spring damping"); - uiDefButF(block, NUM, B_DIFF, "Air Damp:", 10,130,150,20, &clmd->sim_parms->Cvi, 0.0, 10.0, 10, 0, "Air has normaly some thickness which slows falling things down"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "Spring Damp:", 160,150,150,20, &clmd->sim_parms->Cdis, 0.0, 1.0, 10, 0, "Spring damping"); + uiDefButF(block, NUM, B_DIFF, "Air Damp:", 10,130,150,20, &clmd->sim_parms->Cvi, 0.0, 10.0, 10, 0, "Air has normaly some thickness which slows falling things down"); uiDefBut(block, LABEL, 0, "Gravity:", 10,100,60,20, NULL, 0.0, 0, 0, 0, ""); - uiDefButF(block, NUM, B_CLOTH_RENEW, "X:", 70,100,80,20, &clmd->sim_parms->gravity[0], -100.0, 100.0, 10, 0, "Apply gravitation to point movement"); - uiDefButF(block, NUM, B_CLOTH_RENEW, "Y:", 150,100,80,20, &clmd->sim_parms->gravity[1], -100.0, 100.0, 10, 0, "Apply gravitation to point movement"); - uiDefButF(block, NUM, B_CLOTH_RENEW, "Z:", 230,100,80,20, &clmd->sim_parms->gravity[2], -100.0, 100.0, 10, 0, "Apply gravitation to point movement"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "X:", 70,100,80,20, &clmd->sim_parms->gravity[0], -100.0, 100.0, 10, 0, "Apply gravitation to point movement"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "Y:", 150,100,80,20, &clmd->sim_parms->gravity[1], -100.0, 100.0, 10, 0, "Apply gravitation to point movement"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "Z:", 230,100,80,20, &clmd->sim_parms->gravity[2], -100.0, 100.0, 10, 0, "Apply gravitation to point movement"); uiBlockEndAlign(block); /* GOAL STUFF */ @@ -5204,16 +5204,16 @@ static void object_panel_cloth(Object *ob) sprintf (clvg2, "%s%s", clmvg, clvg1); - uiDefButS(block, MENU, B_CLOTH_RENEW, clvg2, 160,70,150,20, &clmd->sim_parms->vgroup_mass, 0, defCount, 0, 0, "Browses available vertex groups"); + uiDefButS(block, MENU, B_CLOTH_RENEW, clvg2, 160,70,150,20, &clmd->sim_parms->vgroup_mass, 0, defCount, 0, 0, "Browses available vertex groups"); MEM_freeN (clvg1); MEM_freeN (clvg2); } - uiDefButF(block, NUM, B_CLOTH_RENEW, "Pin Stiff:", 10,50,150,20, &clmd->sim_parms->goalspring, 0.0, 500.0, 10, 0, "Pin (vertex target position) spring stiffness"); - uiDefBut(block, LABEL, 0, " ", 160,50,150,20, NULL, 0.0, 0, 0, 0, ""); + uiDefButF(block, NUM, B_CLOTH_RENEW, "Pin Stiff:", 10,50,150,20, &clmd->sim_parms->goalspring, 0.0, 500.0, 10, 0, "Pin (vertex target position) spring stiffness"); + uiDefBut(block, LABEL, 0, "",160,50,150,20, NULL, 0.0, 0, 0, 0, ""); + // uiDefButI(block, NUM, B_CLOTH_RENEW, "Pin Damp:", 160,50,150,20, &clmd->sim_parms->goalfrict, 1.0, 100.0, 10, 0, "Pined damping (higher = doesn't oszilate so much)"); /* // nobody is changing these ones anyway - uiDefButF(block, NUM, B_CLOTH_RENEW, "G Damp:", 160,50,150,20, &clmd->sim_parms->goalfrict , 0.0, 50.0, 10, 0, "Goal (vertex target position) friction"); uiDefButF(block, NUM, B_CLOTH_RENEW, "G Min:", 10,30,150,20, &clmd->sim_parms->mingoal, 0.0, 1.0, 10, 0, "Goal minimum, vertex group weights are scaled to match this range"); uiDefButF(block, NUM, B_CLOTH_RENEW, "G Max:", 160,30,150,20, &clmd->sim_parms->maxgoal, 0.0, 1.0, 10, 0, "Goal maximum, vertex group weights are scaled to match this range"); */ @@ -5323,7 +5323,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,150,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"); - uiDefButF(block, NUM, REDRAWBUTSOBJECT, "Friction:", 160,40,150,20, &clmd->coll_parms->friction, 1.0, 100.0, 1.0, 0, "Friction force if a collision happened (high=slower movement when collided)"); + uiDefButF(block, NUM, REDRAWBUTSOBJECT, "Friction:", 160,40,150,20, &clmd->coll_parms->friction, 0.0, 10.0, 1.0, 0, "Friction force if a collision happened (high=slower movement when collided)"); } else uiDefBut(block, LABEL, 0, "",160,60,150,20, NULL, 0.0, 0, 0, 0, ""); |