Bugfix for wrong springs (resulted in weird behaviour), Implemented two speedups...
authorDaniel Genrich <daniel.genrich@gmx.net>
Tue, 6 Nov 2007 02:30:53 +0000 (02:30 +0000)
committerDaniel Genrich <daniel.genrich@gmx.net>
Tue, 6 Nov 2007 02:30:53 +0000 (02:30 +0000)
source/blender/blenkernel/BKE_cloth.h
source/blender/blenkernel/intern/cloth.c
source/blender/blenkernel/intern/implicit.c
source/blender/blenkernel/intern/verlet.c [deleted file]
source/blender/makesdna/DNA_cloth_types.h

index 783faf42e18565e5ef371b50addd183f908fa3c1..8be27ace3461e733352aa9ed3f613c4645dfeb54 100644 (file)
@@ -86,7 +86,9 @@ typedef enum
     CLOTH_SIMSETTINGS_FLAG_COLLOBJ = ( 1 << 2 ),       // object is only collision object, no cloth simulation is done
     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_CCACHE_PROTECT = ( 1 << 5 ),
+    CLOTH_SIMSETTINGS_FLAG_BIG_FORCE = ( 1 << 6 ), // true if we have big spring force for bending
+    CLOTH_SIMSETTINGS_FLAG_SLEEP = ( 1 << 7 ), // true if we let the cloth go to sleep
 } CLOTH_SIMSETTINGS_FLAGS;
 
 /* SPRING FLAGS */
index 4be365fdc864c4d44fd76eec2093813846a061c7..eba11bfedda2b33a07e9a84c884f1b6959236821 100644 (file)
@@ -114,7 +114,7 @@ double tval()
 static CM_SOLVER_DEF solvers [] =
 {
        { "Implicit", CM_IMPLICIT, implicit_init, implicit_solver, implicit_free },
-       { "Verlet", CM_VERLET, verlet_init, verlet_solver, verlet_free },
+       // { "Verlet", CM_VERLET, verlet_init, verlet_solver, verlet_free },
 };
 
 /* ********** cloth engine ******* */
@@ -504,8 +504,9 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d
                        // if(!cloth_cache_search_frame(clmd, framenr))
                        {
                                verts = cloth->verts;
-                               /*
+                               
                                // Force any pinned verts to their constrained location.
+                               // has to be commented for verlet
                                for ( i = 0; i < clmd->clothObject->numverts; i++, verts++ )
                                {
                                        // Save the previous position.
@@ -515,7 +516,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d
                                        VECCOPY ( verts->xconst, mvert[i].co );
                                        Mat4MulVecfl ( ob->obmat, verts->xconst );
                                }
-                               */
+                               
                                tstart();
                                
                                /* Call the solver. */
@@ -1031,8 +1032,8 @@ int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm )
                {
                        spring = ( ClothSpring * ) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" );
 
-                       spring->ij = mface[i].v1;
-                       spring->kl = mface[i].v3;
+                       spring->ij = mface[i].v2;
+                       spring->kl = mface[i].v4;
                        VECSUB ( temp, mvert[spring->kl].co, mvert[spring->ij].co );
                                spring->restlen =  sqrt ( INPR ( temp, temp ) );
                                spring->type = CLOTH_SPRING_TYPE_SHEAR;
@@ -1045,7 +1046,7 @@ int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm )
                                node = node2;
                }
        }
-
+       
        // bending springs
        search2 = cloth->springs;
        for ( i = struct_springs; i < struct_springs+shear_springs; i++ )
@@ -1083,9 +1084,10 @@ int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm )
                }
                search2 = search2->next;
        }
-
-       cloth->numsprings = struct_springs + shear_springs + bend_springs;
-
+       
+       cloth->numspringssave = cloth->numsprings = struct_springs + shear_springs + bend_springs;
+       cloth->numothersprings = struct_springs + shear_springs;
+       
        for ( i = 0; i < numverts; i++ )
        {
                BLI_linklist_free ( edgelist[i],NULL );
index 638f73508226b385f596368a7bd998b3e2ba5db1..091a0580232c06887218474ec0f927e557d3f87a 100644 (file)
@@ -812,6 +812,31 @@ int        implicit_free (ClothModifierData *clmd)
        return 1;
 }
 
+void cloth_bending_mode(ClothModifierData *clmd, int enabled)
+{
+       Cloth *cloth = clmd->clothObject;
+       Implicit_Data *id;
+       
+       if(cloth)
+       {
+               id = cloth->implicit;
+               
+               if(id)
+               {
+                       if(enabled)
+                       {
+                               cloth->numsprings = cloth->numspringssave;
+                       }
+                       else
+                       {
+                               cloth->numsprings = cloth->numothersprings;
+                       }
+                       
+                       id->A[0].scount = id->dFdV[0].scount = id->dFdX[0].scount = id->P[0].scount = id->Pinv[0].scount = id->bigI[0].scount = cloth->numsprings;
+               }       
+       }
+}
+
 DO_INLINE float fb(float length, float L)
 {
        float x = length/L;
@@ -1223,37 +1248,48 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s,
        {
                if(length < L)
                {
+                       // clmd->sim_parms.flags |= CLOTH_SIMSETTINGS_FLAG_BIG_FORCE;
+                       
                        s->flags |= CLOTH_SPRING_FLAG_NEEDED;
                        
                        k = clmd->sim_parms.bending;    
 
                        mul_fvector_S(bending_force, dir, fbstar(length, L, k, cb));
                        VECADD(s->f, s->f, bending_force);
-
+                       
+                       if(INPR(bending_force,bending_force) > 0.13*0.13)
+                       {
+                               clmd->sim_parms.flags |= CLOTH_SIMSETTINGS_FLAG_BIG_FORCE;
+                       }
+                       
                        dfdx_spring_type2(s->dfdx, dir,length,L,k, cb);
                }
        }
 }
 
-DO_INLINE void cloth_apply_spring_force(ClothModifierData *clmd, ClothSpring *s, lfVector *lF, lfVector *X, lfVector *V, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX)
+DO_INLINE int 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)
        {
+               VECADD(lF[s->ij], lF[s->ij], s->f);
+               VECSUB(lF[s->kl], lF[s->kl], s->f);     
+                       
                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);
                        add_fmatrix_fmatrix(dFdV[s->matrix_index].m, dFdV[s->matrix_index].m, s->dfdv); 
                }
-
-               VECADD(lF[s->ij], lF[s->ij], s->f);
-               VECSUB(lF[s->kl], lF[s->kl], s->f);
-
+               else if(!(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_BIG_FORCE))
+                       return 0;
+               
                sub_fmatrix_fmatrix(dFdX[s->ij].m, dFdX[s->ij].m, s->dfdx);
                sub_fmatrix_fmatrix(dFdX[s->kl].m, dFdX[s->kl].m, s->dfdx);
 
                add_fmatrix_fmatrix(dFdX[s->matrix_index].m, dFdX[s->matrix_index].m, s->dfdx);
-       }       
+       }
+       
+       return 1;
 }
 
 DO_INLINE void calculateTriangleNormal(float to[3], lfVector *X, MFace mface)
@@ -1386,15 +1422,34 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec
                search = search->next;
        }
        
+       if(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_BIG_FORCE)
+       {       
+               if(cloth->numspringssave != cloth->numsprings)
+               {
+                       cloth_bending_mode(clmd, 1);
+               }
+       }
+       else
+       {
+               if(cloth->numspringssave == cloth->numsprings)
+               {
+                       cloth_bending_mode(clmd, 0);
+               }
+       }
+       
        // apply spring forces
        search = cloth->springs;
        while(search)
        {
                // 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_apply_spring_force(clmd, search->link, lF, lX, lV, dFdV, dFdX);
+               if(!cloth_apply_spring_force(clmd, search->link, lF, lX, lV, dFdV, dFdX))
+                       break;
                search = search->next;
        }
+       
+       clmd->sim_parms.flags &= ~CLOTH_SIMSETTINGS_FLAG_BIG_FORCE;
+       
 }
 
 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)
@@ -1438,6 +1493,8 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase
        float dt = 1.0f / clmd->sim_parms.stepsPerFrame;
        Implicit_Data *id = cloth->implicit;
        int result = 0;
+       float force = 0, lastforce = 0;
+       lfVector *dx;
        
        if(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) /* do goal stuff */
        {
@@ -1457,10 +1514,27 @@ 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 );      
-               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);
+               cloth_calc_force(clmd, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step );
+               
+               // check for sleeping
+               if(!(clmd->coll_parms.flags & CLOTH_SIMSETTINGS_FLAG_SLEEP))
+               {
+                       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);
+               }
+               
+               dx = create_lfvector(numverts);
+               sub_lfvector_lfvector(dx, id->Xnew, id->X, numverts);
+               force = dot_lfvector(dx, dx, numverts);
+               del_lfvector(dx);
+               
+               if((force < 0.00001) && (lastforce >= force))
+                       clmd->coll_parms.flags |= CLOTH_SIMSETTINGS_FLAG_SLEEP;
+               else if((lastforce*2 < force))
+                       clmd->coll_parms.flags &= ~CLOTH_SIMSETTINGS_FLAG_SLEEP;
                
-               add_lfvector_lfvectorS(id->Xnew, id->X, id->Vnew, dt, numverts);
+               lastforce = force;
                
                if(clmd->coll_parms.flags & CLOTH_COLLISIONSETTINGS_FLAG_ENABLED)
                {
diff --git a/source/blender/blenkernel/intern/verlet.c b/source/blender/blenkernel/intern/verlet.c
deleted file mode 100644 (file)
index 71001fa..0000000
+++ /dev/null
@@ -1,170 +0,0 @@
-/*  implicit.c      
-* 
-*
-* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
-*
-* This program is free software; you can redistribute it and/or
-* modify it under the terms of the GNU General Public License
-* as published by the Free Software Foundation; either version 2
-* of the License, or (at your option) any later version. The Blender
-* Foundation also sells licenses for use in proprietary software under
-* the Blender License.  See http://www.blender.org/BL/ for information
-* about this.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software Foundation,
-* Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-*
-* The Original Code is Copyright (C) Blender Foundation
-* All rights reserved.
-*
-* The Original Code is: all of this file.
-*
-* Contributor(s): none yet.
-*
-* ***** END GPL/BL DUAL LICENSE BLOCK *****
-*/
-#include <math.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include "MEM_guardedalloc.h"
-/* types */
-#include "DNA_curve_types.h"
-#include "DNA_object_types.h"
-#include "DNA_object_force.h"  
-#include "DNA_cloth_types.h"   
-#include "DNA_key_types.h"
-#include "DNA_mesh_types.h"
-#include "DNA_modifier_types.h"
-#include "DNA_meshdata_types.h"
-#include "DNA_lattice_types.h"
-#include "DNA_scene_types.h"
-#include "DNA_modifier_types.h"
-#include "BLI_arithb.h"
-#include "BLI_blenlib.h"
-#include "BLI_edgehash.h"
-#include "BLI_threads.h"
-#include "BKE_collisions.h"
-#include "BKE_curve.h"
-#include "BKE_displist.h"
-#include "BKE_effect.h"
-#include "BKE_global.h"
-#include "BKE_key.h"
-#include "BKE_object.h"
-#include "BKE_cloth.h"
-#include "BKE_modifier.h"
-#include "BKE_utildefines.h"
-#include "BKE_global.h"
-#include  "BIF_editdeform.h"
-
-struct Cloth;
-
-int verlet_init ( Object *ob, ClothModifierData *clmd )
-{
-       return 1;
-}
-
-int verlet_free ( ClothModifierData *clmd )
-{
-       return 1;
-}
-
-void integrate ( ClothModifierData *clmd, float dt )
-{
-       Cloth *cloth = clmd->clothObject;
-       unsigned int i = 0;
-
-       // temporary vectors
-       float temp[3], velocity[3], force[3];
-       
-       mul_fvector_S( force, clmd->sim_parms.gravity, dt*dt );
-       
-       // iterate through all control points
-       for(i = 0; i < cloth->numverts; i++)
-       {
-               if(((clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [i].goal < SOFTGOALSNAP)) || !(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL))
-               {
-                       // save current control point location
-                       VECCOPY ( temp, cloth->x[i] );
-
-                       // update control point by the formula
-                       //  x += (x - old_x)*dampingFactor + force*timeStep^2
-                       VECSUB ( velocity, cloth->x[i], cloth->xold[i] );
-                       VECSUBMUL( force, velocity, -clmd->sim_parms.Cvi * 0.01f* dt * dt);
-                       VecMulf(velocity, 0.99);
-                       VECADD ( cloth->x[i], cloth->x[i], velocity );
-                       VECADD ( cloth->x[i], cloth->x[i], force );
-
-                       // store old control point location
-                       VECCOPY ( cloth->xold[i], temp );
-               }
-       }
-}
-
-void satisfyconstraints(ClothModifierData *clmd)
-{
-       float delta[3];
-       Cloth *cloth = clmd->clothObject;
-       unsigned int i = 0;
-
-       for(i = 0; i < 5; i++)
-       {
-               // calculate spring forces
-               LinkNode *search = cloth->springs;
-               while(search)
-               {
-                       ClothSpring *spring = search->link;
-                       float temp = 0;
-                       float restlen2 = spring->restlen * spring->restlen;
-                       float len2 = 0, len = 0;
-                       
-                       VECSUB(delta, cloth->x[spring->kl], cloth->x[spring->ij]);
-                       len = sqrt(INPR(delta, delta));
-                       
-                       if(spring->type != CLOTH_SPRING_TYPE_BENDING)
-                       {
-                               temp = (len - spring->restlen)/len;
-                               
-                               mul_fvector_S(delta, delta, temp*0.5);
-                               
-                               // check if vertex is pinned
-                               if(((clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [spring->ij].goal < SOFTGOALSNAP)) || !(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL))
-                                       VECADD(cloth->x[spring->ij], cloth->x[spring->ij], delta);
-                               
-                               // check if vertex is pinned
-                               if(((clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [spring->kl].goal < SOFTGOALSNAP)) || !(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL))
-                                       VECSUB(cloth->x[spring->kl], cloth->x[spring->kl], delta);
-                       }
-                       
-                       search = search->next;
-               }
-       }
-}
-
-int verlet_solver ( Object *ob, float frame, ClothModifierData *clmd, ListBase *effectors )
-{
-       float dt = 0.01;
-       float step = 0;
-       
-       while(step < 1.0f)
-       {
-               integrate(clmd, dt);
-               satisfyconstraints(clmd);
-               
-               step+= dt;
-       }
-       
-       return 1;
-}
-
-
-
-
-
-
index 0edfb64e92f0371f86d05d1132351cdd3f100545..4d75f7a3778868c0c7a5074ae141650081d7b391 100644 (file)
@@ -161,6 +161,8 @@ typedef struct Cloth
        float                   (*v)[3]; /* the current velocity of all vertices */
        float                   (*current_v)[3];
        struct EdgeHash         *edgehash; // used for fast checking adjacent points
+       unsigned int            numothersprings;
+       unsigned int            numspringssave;
 }
 Cloth;