Fix: GUI cache reset should work again, same goes for collision modifier (enabled...
authorDaniel Genrich <daniel.genrich@gmx.net>
Thu, 29 Nov 2007 12:29:32 +0000 (12:29 +0000)
committerDaniel Genrich <daniel.genrich@gmx.net>
Thu, 29 Nov 2007 12:29:32 +0000 (12:29 +0000)
source/blender/blenkernel/BKE_cloth.h
source/blender/blenkernel/BKE_collisions.h
source/blender/blenkernel/intern/cloth.c
source/blender/blenkernel/intern/collision.c
source/blender/blenkernel/intern/implicit.c
source/blender/blenkernel/intern/modifier.c
source/blender/makesdna/DNA_modifier_types.h
source/blender/src/buttons_editing.c
source/blender/src/buttons_object.c

index 2bb3e32d6b688861dbed4c357b958ffc60bc294e..c8ec1698b86d899547e992dd17090fe0cd86cec5 100644 (file)
@@ -72,10 +72,10 @@ typedef struct ClothVertex {
 } ClothVertex;
 
 typedef struct ClothSpring {
-       int     ij;             /* Pij from the paper, one end of the spring.   */
-       int     kl;             /* Pkl from the paper, one end of the spring.   */
+       unsigned int    ij;             /* Pij from the paper, one end of the spring.   */
+       unsigned int    kl;             /* Pkl from the paper, one end of the spring.   */
        float   restlen;        /* The original length of the spring.   */
-       int     matrix_index;   /* needed for implicit solver (fast lookup) */
+       unsigned int    matrix_index;   /* needed for implicit solver (fast lookup) */
        int     type;           /* types defined in BKE_cloth.h ("springType") */
        int     flags;          /* defined in BKE_cloth.h, e.g. deactivated due to tearing */
        float dfdx[3][3];
@@ -152,6 +152,7 @@ typedef enum
     CLOTH_SPRING_TYPE_STRUCTURAL = 0,
     CLOTH_SPRING_TYPE_SHEAR,
     CLOTH_SPRING_TYPE_BENDING,
+    CLOTH_SPRING_TYPE_COLLISION,
 } CLOTH_SPRING_TYPES;
 
 /* SPRING FLAGS */
index f358bd629e65a432bb981e4a70a885070dd516a7..e38662fdf95d332358c21974a8b454ae3f9942ad 100644 (file)
 #include <math.h>
 #include <stdlib.h>
 #include <string.h>
+
 /* types */
 #include "BLI_linklist.h"
 #include "BKE_DerivedMesh.h"
 #include "BKE_object.h"
-#include "BKE_DerivedMesh.h"
+
+#include "DNA_modifier_types.h"
 
 // used in kdop.c and collision.c
 typedef struct CollisionTree
@@ -82,6 +84,8 @@ typedef struct CollisionPair
 {
        int point_indexA[4], point_indexB[4];
        float vector[3];
+       float normal[3]; // has to be calculated from vector
+       float distance;
        float pa[3], pb[3];
 }
 CollisionPair;
@@ -115,6 +119,10 @@ LinkNode *BLI_linklist_append_fast (LinkNode **listp, void *ptr);
 // defined in collisions.c
 void collision_move_object(CollisionModifierData *collmd, float step, float prevstep);
 
+// interface for collision functions
+void collisions_compute_barycentric (float pv[3], float p1[3], float p2[3], float p3[3], float *w1, float *w2, float *w3);
+void interpolateOnTriangle(float to[3], float v1[3], float v2[3], float v3[3], double w1, double w2, double w3);
+
 /////////////////////////////////////////////////
 
 #endif
index 6eacb26c315dd4c5c0049b08cc7c31bdf25462ba..2dd4f1a0f0f3075d0f0ed2cfb6f9837dd131f6d2 100644 (file)
@@ -1009,6 +1009,7 @@ static void cloth_from_mesh (Object *ob, ClothModifierData *clmd, DerivedMesh *d
 ***************************************************************************************/
 
 // be carefull: implicit solver has to be resettet when using this one!
+// --> only for implicit handling of this spring!
 int cloth_add_spring ( ClothModifierData *clmd, unsigned int indexA, unsigned int indexB, float restlength, int spring_type)
 {
        Cloth *cloth = clmd->clothObject;
index 6f0ac5f8c6d74ec75a286bd6851b8b1b9fbe129c..4bc1efc1e70cb1ae96196f036eaa1662d7c75260 100644 (file)
@@ -71,7 +71,6 @@
 
 #include "Bullet-C-Api.h"
 
-
 // step is limited from 0 (frame start position) to 1 (frame end position)
 void collision_move_object(CollisionModifierData *collmd, float step, float prevstep)
 {
@@ -83,6 +82,7 @@ void collision_move_object(CollisionModifierData *collmd, float step, float prev
                VECSUB(tv, collmd->xnew[i].co, collmd->x[i].co);
                VECADDS(collmd->current_x[i].co, collmd->x[i].co, tv, prevstep);
                VECADDS(collmd->current_xnew[i].co, collmd->x[i].co, tv, step);
+               VECSUB(collmd->current_v[i].co, collmd->current_xnew[i].co, collmd->current_x[i].co);
        }
 }
 
index 12c5c1906911c262ae9d5f8029a65280fd413057..3b8f6ddd7d843fb430a37c4f25fe7b2605201850 100644 (file)
@@ -63,6 +63,8 @@
 #include "BKE_global.h"
 #include  "BIF_editdeform.h"
 
+#include "Bullet-C-Api.h"
+
 #ifdef _WIN32
 #include <windows.h>
 static LARGE_INTEGER _itstart, _itend;
@@ -1123,6 +1125,17 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s,
        }
        
        
+       if(s->type == CLOTH_SPRING_TYPE_COLLISION)
+       {
+               if(length < L)
+               {
+                       mul_fvector_S(stretch_force, dir, (100.0*(length-L))); 
+       
+                       VECADD(s->f, s->f, stretch_force);
+               }
+               return;
+       }
+       
        // calculate force of structural + shear springs
        if(s->type != CLOTH_SPRING_TYPE_BENDING)
        {
@@ -1415,6 +1428,19 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase
        {               
                effectors= pdInitEffectors(ob,NULL);
                
+               // clear constraint matrix from collisions
+               if(clmd->coll_parms->flags & CLOTH_COLLISIONSETTINGS_FLAG_ENABLED)
+               {
+                       for(i = 0; i < id->S[0].vcount; i++)
+                       {
+                               if(!(verts [id->S[i].r].goal >= SOFTGOALSNAP))
+                               {
+                                       id->S[0].vcount = i-1;
+                                       break;
+                               }
+                       }
+               }
+               
                // calculate 
                cloth_calc_force(clmd, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step );
                
@@ -1553,122 +1579,148 @@ void implicit_set_positions (ClothModifierData *clmd)
        memcpy(id->V, cloth->v, sizeof(lfVector) * numverts);   
 }
 
+unsigned int implicit_getcreate_S_index(ClothModifierData *clmd, unsigned int index)
+{
+       Cloth *cloth = clmd->clothObject;
+       Implicit_Data *id = cloth->implicit;
+       unsigned int i = 0, pinned = 0;
+       
+       pinned = id->S[0].vcount;
+       
+       for(i = 0; i < pinned; i++)
+       {
+               if(id->S[i].r == index)
+               {
+                       return index;
+               }
+       }
+       
+       // create new PINNED entry in constraint matrix
+       id->S[0].vcount++;
+       id->S[pinned].c = id->S[pinned].r = index;
+       return pinned;
+}
 
-int collisions_collision_response_static(ClothModifierData *clmd, ClothModifierData *coll_clmd)
+int collisions_collision_response_static ( ClothModifierData *clmd, CollisionModifierData *collmd, CollisionPair *collpair )
 {
-       /*
+
        unsigned int i = 0;
        int result = 0;
        LinkNode *search = NULL;
-       CollPair *collpair = NULL;
-       Cloth *cloth1, *cloth2;
+       Cloth *cloth1 = NULL;
        float w1, w2, w3, u1, u2, u3;
        float v1[3], v2[3], relativeVelocity[3];
-       float magrelVel;
-       
-       cloth1 = clmd->clothObject;
-       cloth2 = coll_clmd->clothObject;
+       float magrelVel = 0.0;
+       float epsilon = clmd->coll_parms->epsilon;
 
-       // search = clmd->coll_parms.collision_list;
+       cloth1 = clmd->clothObject;
        
-       while(search)
-       {
-       collpair = search->link;
-               
-               // compute barycentric coordinates for both collision points
-       collisions_compute_barycentric(collpair->pa,
-       cloth1->verts[collpair->ap1].txold,
-       cloth1->verts[collpair->ap2].txold,
-       cloth1->verts[collpair->ap3].txold, 
-       &w1, &w2, &w3);
-       
-       collisions_compute_barycentric(collpair->pb,
-       cloth2->verts[collpair->bp1].txold,
-       cloth2->verts[collpair->bp2].txold,
-       cloth2->verts[collpair->bp3].txold,
-       &u1, &u2, &u3);
-       
-               // Calculate relative "velocity".
-       interpolateOnTriangle(v1, cloth1->verts[collpair->ap1].tv, cloth1->verts[collpair->ap2].tv, cloth1->verts[collpair->ap3].tv, w1, w2, w3);
-               
-       interpolateOnTriangle(v2, cloth2->verts[collpair->bp1].tv, cloth2->verts[collpair->bp2].tv, cloth2->verts[collpair->bp3].tv, u1, u2, u3);
-               
-       VECSUB(relativeVelocity, v1, v2);
-                       
-               // Calculate the normal component of the relative velocity (actually only the magnitude - the direction is stored in 'normal').
-       magrelVel = INPR(relativeVelocity, collpair->normal);
-               
-               // printf("magrelVel: %f\n", magrelVel);
-                               
-               // Calculate masses of points.
-               
-               // If v_n_mag < 0 the edges are approaching each other.
-       if(magrelVel < -ALMOST_ZERO) 
-       {
-                       // Calculate Impulse magnitude to stop all motion in normal direction.
-                       // const double I_mag = v_n_mag / (1/m1 + 1/m2);
-       float magnitude_i = magrelVel / 2.0f; // TODO implement masses
-       float tangential[3], magtangent, magnormal, collvel[3];
-       float vrel_t_pre[3];
-       float vrel_t[3];
-       double impulse;
-       float epsilon = clmd->coll_parms.epsilon;
-       float overlap = (epsilon + ALMOST_ZERO-collpair->distance);
-                       
-                       // calculateFrictionImpulse(tangential, relativeVelocity, collpair->normal, magrelVel, clmd->coll_parms.friction*0.01, magrelVel);
-                       
-                       // magtangent = INPR(tangential, tangential);
+       if(!collpair)
+               return 0;
+       
+       // TODO: check distance & calc normal
+                       // calc distance + normal       
+       collpair->distance = plNearestPoints(
+               cloth1->current_xold[collpair->point_indexA[0]],
+               cloth1->current_xold[collpair->point_indexA[1]],
+               cloth1->current_xold[collpair->point_indexA[2]], 
+               collmd->current_x[collpair->point_indexB[0]].co,
+               collmd->current_x[collpair->point_indexB[1]].co,
+               collmd->current_x[collpair->point_indexB[2]].co, 
+               collpair->pa,collpair->pb,collpair->vector);
                        
-                       // Apply friction impulse.
-       if (magtangent < -ALMOST_ZERO) 
+       if (collpair->distance > (epsilon + ALMOST_ZERO))
        {
-                               
-                               // printf("friction applied: %f\n", magtangent);
-                               // TODO check original code 
-}
-                       
+               return 0;
+       }
 
-       impulse = -2.0f * magrelVel / ( 1.0 + w1*w1 + w2*w2 + w3*w3);
-                       
-                       // printf("impulse: %f\n", impulse);
-                       
-                       // face A
-       VECADDMUL(cloth1->verts[collpair->ap1].impulse, collpair->normal, w1 * impulse); 
-       cloth1->verts[collpair->ap1].impulse_count++;
-                       
-       VECADDMUL(cloth1->verts[collpair->ap2].impulse, collpair->normal, w2 * impulse); 
-       cloth1->verts[collpair->ap2].impulse_count++;
-                       
-       VECADDMUL(cloth1->verts[collpair->ap3].impulse, collpair->normal, w3 * impulse); 
-       cloth1->verts[collpair->ap3].impulse_count++;
-                       
-                       // face B
-       VECADDMUL(cloth2->verts[collpair->bp1].impulse, collpair->normal, u1 * impulse); 
-       cloth2->verts[collpair->bp1].impulse_count++;
-                       
-       VECADDMUL(cloth2->verts[collpair->bp2].impulse, collpair->normal, u2 * impulse); 
-       cloth2->verts[collpair->bp2].impulse_count++;
-                       
-       VECADDMUL(cloth2->verts[collpair->bp3].impulse, collpair->normal, u3 * impulse); 
-       cloth2->verts[collpair->bp3].impulse_count++;
-                       
-                       
-       result = 1;     
-               
-                       // printf("magnitude_i: %f\n", magnitude_i); // negative before collision in my case
-                       
-                       // Apply the impulse and increase impulse counters.
-       
-                       
-}
+       // compute barycentric coordinates for both collision points
+       collisions_compute_barycentric (collpair->pa,
+                                       cloth1->current_xold[collpair->point_indexA[0]],
+                                       cloth1->current_xold[collpair->point_indexA[1]],
+                                       cloth1->current_xold[collpair->point_indexA[2]],
+                                       &w1, &w2, &w3 );
+
+       collisions_compute_barycentric (collpair->pb,
+                                       collmd->current_x[collpair->point_indexB[0]].co,
+                                       collmd->current_x[collpair->point_indexB[1]].co,
+                                       collmd->current_x[collpair->point_indexB[2]].co,
+                                       &u1, &u2, &u3 );
+
+       // Calculate relative "velocity".
+       interpolateOnTriangle ( v1, cloth1->current_v[collpair->point_indexA[0]], cloth1->current_v[collpair->point_indexA[1]], cloth1->current_v[collpair->point_indexA[2]], w1, w2, w3 );
+
+       interpolateOnTriangle ( v2, collmd->current_v[collpair->point_indexB[0]].co, collmd->current_v[collpair->point_indexB[1]].co, collmd->current_v[collpair->point_indexB[2]].co, u1, u2, u3 );
+
+       VECSUB ( relativeVelocity, v1, v2 );
+
+       // Calculate the normal component of the relative velocity (actually only the magnitude - the direction is stored in 'normal').
+       magrelVel = INPR ( relativeVelocity, collpair->normal );
+
+       // printf("magrelVel: %f\n", magrelVel);
+
+       // Calculate masses of points.
+
+       // If v_n_mag < 0 the edges are approaching each other.
+       if ( magrelVel < -ALMOST_ZERO )
+       {
+               // Calculate Impulse magnitude to stop all motion in normal direction.
+               // const double I_mag = v_n_mag / (1/m1 + 1/m2);
+               float magnitude_i = magrelVel / 2.0f; // TODO implement masses
+               float tangential[3], magtangent, magnormal, collvel[3];
+               float vrel_t_pre[3];
+               float vrel_t[3];
+               double impulse;
+               float overlap = ( epsilon + ALMOST_ZERO-collpair->distance );
+
+               // calculateFrictionImpulse(tangential, relativeVelocity, collpair->normal, magrelVel, clmd->coll_parms.friction*0.01, magrelVel);
+
+               // magtangent = INPR(tangential, tangential);
+
+               // Apply friction impulse.
+               if ( magtangent < -ALMOST_ZERO )
+               {
+
+                       // printf("friction applied: %f\n", magtangent);
+                       // TODO check original code
+               }
+
+
+               impulse = -2.0f * magrelVel / ( 1.0 + w1*w1 + w2*w2 + w3*w3 );
+
+               // printf("impulse: %f\n", impulse);
+
+               // face A
+               VECADDMUL ( cloth1->verts[collpair->point_indexA[0]].impulse, collpair->normal, w1 * impulse );
+               cloth1->verts[collpair->point_indexA[0]].impulse_count++;
+
+               VECADDMUL ( cloth1->verts[collpair->point_indexA[1]].impulse, collpair->normal, w2 * impulse );
+               cloth1->verts[collpair->point_indexA[1]].impulse_count++;
+
+               VECADDMUL ( cloth1->verts[collpair->point_indexA[2]].impulse, collpair->normal, w3 * impulse );
+               cloth1->verts[collpair->point_indexA[2]].impulse_count++;
+
+               // face B
+               /*
+               VECADDMUL ( collmd->verts[collpair->point_indexB[0]].impulse, collpair->normal, u1 * impulse );
+               collmd->verts[collpair->point_indexB[0]].impulse_count++;
+
+               VECADDMUL ( collmd->verts[collpair->point_indexB[1]].impulse, collpair->normal, u2 * impulse );
+               collmd->verts[collpair->point_indexB[1]].impulse_count++;
+
+               VECADDMUL ( collmd->verts[collpair->point_indexB[2]].impulse, collpair->normal, u3 * impulse );
+               collmd->verts[collpair->point_indexB[2]].impulse_count++;
+               */
                
-       search = search->next;
-}
-       
+               result = 1;
+
+               // printf("magnitude_i: %f\n", magnitude_i); // negative before collision in my case
+
+               // Apply the impulse and increase impulse counters.
+
+       }
        
        return result;
-       */
-       return 0;
 }
 
 
@@ -2087,10 +2139,11 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep,
        Object *ob2 = NULL;
        BVH *bvh1 = NULL, *bvh2 = NULL, *self_bvh;
        LinkNode *collision_list = NULL; 
-       unsigned int i = 0, j = 0;
+       unsigned int i = 0, j = 0, index;
        int collisions = 0, count = 0;
        float (*current_x)[3];
-
+       Implicit_Data *id = NULL;
+       /*
        if (!(((Cloth *)clmd->clothObject)->tree))
        {
                printf("No BVH found\n");
@@ -2100,65 +2153,77 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep,
        cloth = clmd->clothObject;
        bvh1 = cloth->tree;
        self_bvh = cloth->selftree;
+       id = cloth->implicit;
        
        ////////////////////////////////////////////////////////////
        // static collisions
        ////////////////////////////////////////////////////////////
        
        // update cloth bvh
-       bvh_update_from_float3(bvh1, cloth->current_xold, cloth->numverts, cloth->current_x, 0); // 0 means STATIC, 1 means MOVING (see later in this function)
-/*
+       bvh_update_from_float3 ( bvh1, cloth->current_xold, cloth->numverts, cloth->current_x, 0 ); // 0 means STATIC, 1 means MOVING (see later in this function)
+       
        // check all collision objects
-       for (base = G.scene->base.first; base; base = base->next)
+       for ( base = G.scene->base.first; base; base = base->next )
        {
-       ob2 = base->object;
-       collmd = (CollisionModifierData *) modifiers_findByType (ob2, eModifierType_Collision);
-               
-       if (!collmd)
-       continue;
-               
+               ob2 = base->object;
+               collmd = ( CollisionModifierData * ) modifiers_findByType ( ob2, eModifierType_Collision );
+       
+               if ( !collmd )
+                       continue;
+       
                // check if there is a bounding volume hierarchy
-       if (collmd->tree) 
-       {                       
-       bvh2 = collmd->tree;
-                       
+               if ( collmd->tree )
+               {
+                       bvh2 = collmd->tree;
+       
                        // update position + bvh of collision object
-       collision_move_object(collmd, step, prevstep);
-       bvh_update_from_mvert(collmd->tree, collmd->current_x, collmd->numverts, NULL, 0);
-                       
-                       // fill collision list 
-       collisions += bvh_traverse(bvh1->root, bvh2->root, &collision_list);
-                       
+                       collision_move_object ( collmd, step, prevstep );
+                       bvh_update_from_mvert ( collmd->tree, collmd->current_x, collmd->numverts, NULL, 0 );
+       
+                       // fill collision list
+                       collisions += bvh_traverse ( bvh1->root, bvh2->root, &collision_list );
+       
                        // call static collision response
+                       if ( collision_list )
+                       {
+                               LinkNode *search = collision_list;
+       
+                               while ( search )
+                               {
+                                       collisions_collision_response_static(clmd, collmd, (CollisionPair *)search->link);
+                                       
+                                       search = search->next;
+                               }
+                       }
                        
                        // free collision list
-       if(collision_list)
-       {
-       LinkNode *search = collision_list;
-                               
-       while(search)
-       {
-       CollisionPair *coll_pair = search->link;
-                                       
-       MEM_freeN(coll_pair);
-       search = search->next;
-}
-       BLI_linklist_free(collision_list,NULL);
+                       if ( collision_list )
+                       {
+                               LinkNode *search = collision_list;
        
-       collision_list = NULL;
-}
-}
-}
+                               while ( search )
+                               {
+                                       CollisionPair *coll_pair = search->link;
+       
+                                       MEM_freeN ( coll_pair );
+                                       search = search->next;
+                               }
+                               BLI_linklist_free ( collision_list,NULL );
+       
+                               collision_list = NULL;
+                       }
+               }
+       }
        
        //////////////////////////////////////////////
        // update velocities + positions
        //////////////////////////////////////////////
        for(i = 0; i < cloth->numverts; i++)
        {
-       VECADD(cloth->current_x[i], cloth->current_xold[i], cloth->current_v[i]);
-}
+               VECADD(cloth->current_x[i], cloth->current_xold[i], cloth->current_v[i]);
+       }
        //////////////////////////////////////////////
-*/     
+       */
        /*
        // fill collision list 
        collisions += bvh_traverse(self_bvh->root, self_bvh->root, &collision_list);
@@ -2235,7 +2300,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep,
        collisions = 1;
        count = 0;
        current_x = cloth->current_x; // needed for openMP
-       
+       /*
        // #pragma omp parallel for private(i,j, collisions) shared(current_x)
        // for ( count = 0; count < 6; count++ )
        {
@@ -2275,8 +2340,6 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep,
                                {
                                        float correction = ((mindistance1 + mindistance2)) - length;
                                        
-                                       printf("correction: %f\n", correction);
-       
                                        if ( ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) && ( cloth->verts [i].goal >= SOFTGOALSNAP ) )
                                        {
                                                VecMulf ( temp, -correction );
@@ -2289,10 +2352,24 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep,
                                        }
                                        else
                                        {
+                                               unsigned int pinned = id->S[0].vcount;
+                                               
+                                               printf("correction: %f\n", correction);
+                                               
                                                VecMulf ( temp, -correction*0.5 );
                                                VECADD ( current_x[j], current_x[j], temp );
-       
+                                               VECSUB ( cloth->current_v[j], cloth->current_x[j], cloth->current_xold[j] );
+                                               
+                                               index = implicit_getcreate_S_index(clmd, j);
+                                               id->S[index].pinned = 1;
+                                               
                                                VECSUB ( current_x[i], current_x[i], temp );
+                                               VECSUB ( cloth->current_v[i], cloth->current_x[i], cloth->current_xold[i] );
+                                               
+                                               index = implicit_getcreate_S_index(clmd, i);
+                                               id->S[index].pinned = 1;
+                                               
+                                               cloth_add_spring (clmd, i, j, mindistance1 + mindistance2, CLOTH_SPRING_TYPE_COLLISION);
                                        }
        
                                        collisions = 1;
@@ -2300,16 +2377,18 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep,
                        }
                }
        }
-       
+       */
        
        //////////////////////////////////////////////
        // SELFCOLLISIONS: update velocities
        //////////////////////////////////////////////
+       /*
        for ( i = 0; i < cloth->numverts; i++ )
        {
                VECSUB ( cloth->current_v[i], cloth->current_x[i], cloth->current_xold[i] );
        }
+       */
        //////////////////////////////////////////////
 
-       return 1;
+       return 0;
 }
index af8b4aa80790748683305f01716a455fc44518e4..e433fb6ed88cf4e345596f694ec385bac22d53ec 100644 (file)
@@ -5068,6 +5068,7 @@ static void collisionModifier_initData(ModifierData *md)
        collmd->xnew = NULL;
        collmd->current_x = NULL;
        collmd->current_xnew = NULL;
+       collmd->current_v = NULL;
        collmd->time = -1;
        collmd->numverts = 0;
        collmd->tree = NULL;
@@ -5089,11 +5090,14 @@ static void collisionModifier_freeData(ModifierData *md)
                        MEM_freeN(collmd->current_x);
                if(collmd->current_xnew)
                        MEM_freeN(collmd->current_xnew);
+               if(collmd->current_v)
+                       MEM_freeN(collmd->current_v);
                
                collmd->x = NULL;
                collmd->xnew = NULL;
                collmd->current_x = NULL;
                collmd->current_xnew = NULL;
+               collmd->current_v = NULL;
                collmd->time = -1;
                collmd->numverts = 0;
                collmd->tree = NULL;
@@ -5155,6 +5159,8 @@ static void collisionModifier_deformVerts(
                                collmd->xnew = MEM_dupallocN(collmd->x); // frame end position
                                collmd->current_x = MEM_dupallocN(collmd->x); // inter-frame
                                collmd->current_xnew = MEM_dupallocN(collmd->x); // inter-frame
+                               collmd->current_v = MEM_dupallocN(collmd->x); // inter-frame
+
                                collmd->numverts = numverts;
                                
                                // TODO: epsilon
index 65eec871404030d5af4875476b91701e4e84705a..1bb8ce99c88b732a021c92bbf8b7e1c2ef21bc81 100644 (file)
@@ -358,6 +358,7 @@ typedef struct CollisionModifierData {
        struct MVert *xnew; /* position at the end of the frame */
        struct MVert *current_xnew; /* new position at the actual inter-frame step */
        struct MVert *current_x; /* position at the actual inter-frame step */
+       struct MVert *current_v; /* position at the actual inter-frame step */
        
        unsigned int numverts;
        float time;
index 959fd77095961c9f1ff10706b986ca7000098d3c..83f04110974033e22e732f512776933cb36a8d58 100644 (file)
@@ -1494,14 +1494,6 @@ static void modifiers_convertToReal(void *ob_v, void *md_v)
        BIF_undo_push("Modifier convert to real");
 }
 
-static void modifiers_pointCacheClearModifier(void *ob_v, void *md_v)
-{
-       Object *ob = ob_v;
-       ModifierData *md = md_v;        
-       int stack_index = modifiers_indexInObject(ob_v, md_v);
-       PTCache_id_clear((ID *)ob, CFRA, stack_index);
-}
-
 static void build_uvlayer_menu_vars(CustomData *data, char **menu_string,
                                     int *uvlayer_tmp, char *uvlayer_name)
 {
index 2ce543eec443b17a534b00ff8cca0ff09241197a..1808618d7b73925a7cee307e71ebe92b6a5919cb 100644 (file)
@@ -48,6 +48,7 @@
 
 #include "BKE_action.h"
 #include "BKE_cloth.h"
+#include "BKE_collisions.h"
 #include "BKE_global.h"
 #include "BKE_main.h"
 #include "BKE_library.h"
@@ -2966,6 +2967,30 @@ void do_effects_panels(unsigned short event)
                }
                allqueue(REDRAWVIEW3D, 0);
                break;
+       case B_CLOTH_CLEARCACHEALL:
+               {
+                       ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
+                       if(clmd)
+                       {
+                               CFRA= 1;
+                               update_for_newframe_muted();
+                               DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); 
+                               cloth_clear_cache(ob, clmd, 2); 
+                               allqueue(REDRAWBUTSOBJECT, 0);
+                               allqueue(REDRAWVIEW3D, 0);
+                       }       
+               }
+               break;  
+       case B_CLOTH_RENEW:
+               {
+                       ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
+                       if(clmd)
+                       {
+                               do_object_panels(B_CLOTH_CLEARCACHEALL);
+                               cloth_free_modifier (clmd);
+                       }
+               }
+               break;
        default:
                if(event>=B_SELEFFECT && event<B_SELEFFECT+MAX_EFFECT) {
                        ob= OBACT;
@@ -3002,10 +3027,31 @@ static void field_testTexture(char *name, ID **idpp)
        }
        *idpp = 0;
 }
+
+/* Panel for collision */
+static void object_collision__enabletoggle ( void *ob_v, void *arg2 )
+{
+       Object *ob = ob_v;
+       ModifierData *md = modifiers_findByType ( ob, eModifierType_Collision );
+
+       if ( !md )
+       {
+               md = modifier_new ( eModifierType_Collision );
+               BLI_addhead ( &ob->modifiers, md );
+       }
+       else
+       {
+               BLI_remlink ( &ob->modifiers, md );
+               modifier_free ( md );
+               allqueue(REDRAWBUTSEDIT, 0);
+       }
+}
+
 /* Panels for particle interaction settings */
 static void object_panel_deflection(Object *ob)
 {
        uiBlock *block;
+       uiBut *but;
 
        block= uiNewBlock(&curarea->uiblocks, "object_panel_deflection", UI_EMBOSS, UI_HELV, curarea->win);
        if(uiNewPanel(curarea, block, "Deflection", "Physics", 0, 0, 318, 204)==0) return;
@@ -3025,7 +3071,9 @@ static void object_panel_deflection(Object *ob)
        if(ob->pd && ob->type==OB_MESH) {
                PartDeflect *pd= ob->pd;
                
-               uiDefButBitS(block, TOG, 1, B_REDR, "Deflection",160,160,150,20, &pd->deflect, 0, 0, 0, 0, "Deflects particles based on collision");
+               but = uiDefButBitS(block, TOG, 1, B_REDR, "Deflection",160,160,150,20, &pd->deflect, 0, 0, 0, 0, "Deflects particles based on collision");
+               uiButSetFunc(but, object_collision__enabletoggle, ob, NULL);
+               
                if(pd->deflect) {
                        uiDefBut(block, LABEL, 0, "Particles",                  160,140,75,20, NULL, 0.0, 0, 0, 0, "");
                        uiDefButBitS(block, TOG, PDEFLE_KILL_PART, B_DIFF, "Kill",235,140,75,20, &pd->flag, 0, 0, 0, 0, "Kill collided particles");