Fixed collision object init, New: Apply collision impulses so minimum distance is...
authorDaniel Genrich <daniel.genrich@gmx.net>
Wed, 19 Sep 2007 12:13:16 +0000 (12:13 +0000)
committerDaniel Genrich <daniel.genrich@gmx.net>
Wed, 19 Sep 2007 12:13:16 +0000 (12:13 +0000)
source/blender/blenkernel/intern/cloth.c
source/blender/blenkernel/intern/collision.c
source/blender/blenkernel/intern/implicit.c
source/blender/src/buttons_object.c

index 194aa06fc3b55411d624bc5e43446a4ad1b5f232..635da0515cba236366664c074a2a3dbe75aa6bc4 100644 (file)
@@ -657,24 +657,28 @@ void clothModifier_do(ClothModifierData *clmd, Object *ob, DerivedMesh *dm,
        Frame *frame = NULL;
        LinkNode *search = NULL;
        float deltaTime = current_time - clmd->sim_parms.sim_time;      
+               
        
        // only be active during a specific period
-       if(current_time < clmd->sim_parms.firstframe)
-               return;
-       else if(current_time > clmd->sim_parms.lastframe)
+       if (!(clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ))
        {
-               int frametime = cloth_cache_last_frame(clmd);
-               if(cloth_cache_search_frame(clmd, frametime))
+               if(current_time < clmd->sim_parms.firstframe)
+                       return;
+               else if(current_time > clmd->sim_parms.lastframe)
                {
-                       cloth_cache_get_frame(clmd, frametime);
-                       cloth_to_object (ob, clmd, vertexCos, numverts);
-               }
-               return;
-       }
-       else if(ABS(deltaTime) >= 2.0f ) // no timewarps allowed
-       {
-               if(!cloth_cache_search_frame(clmd, framenr))
+                       int frametime = cloth_cache_last_frame(clmd);
+                       if(cloth_cache_search_frame(clmd, frametime))
+                       {
+                               cloth_cache_get_frame(clmd, frametime);
+                               cloth_to_object (ob, clmd, vertexCos, numverts);
+                       }
                        return;
+               }
+               else if(ABS(deltaTime) >= 2.0f ) // no timewarps allowed
+               {
+                       if(!cloth_cache_search_frame(clmd, framenr))
+                               return;
+               }
        }
        
        // unused in the moment
@@ -693,8 +697,7 @@ void clothModifier_do(ClothModifierData *clmd, Object *ob, DerivedMesh *dm,
 
        // This is for collisions objects: check special case CSIMSETT_FLAG_COLLOBJ
        if (clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ)
-       {                               
-               
+       {
                // save next position + time            
                if ((clmd->clothObject == NULL) || (numverts != clmd->clothObject->numverts) )
                {
@@ -723,7 +726,8 @@ void clothModifier_do(ClothModifierData *clmd, Object *ob, DerivedMesh *dm,
                        VECCOPY (verts->x, vertexCos[i]);
                        Mat4MulVecfl(ob->obmat, verts->x);
 
-                       // Compute the vertices velocity. 
+                       // Compute the vertices "velocity".
+                       // (no dt correction here because of float error)
                        VECSUB (verts->v, verts->x, verts->xold);
                }
                
@@ -762,9 +766,6 @@ void clothModifier_do(ClothModifierData *clmd, Object *ob, DerivedMesh *dm,
                                        /* Get the current position. */
                                        VECCOPY (verts->xconst, vertexCos[i]);
                                        Mat4MulVecfl(ob->obmat, verts->xconst);
-
-                                       /* Compute the vertices velocity. */
-                                       VECSUB (verts->v, verts->xconst, verts->xold);
                                }
 
                                tstart();
index c70bf461920d16c772bd94c112dff4bfcace978c..32a2f820894169ea32d22759f79dc899e9e3f95f 100644 (file)
@@ -216,18 +216,18 @@ DO_INLINE void interpolateOnTriangle(float to[3], float v1[3], float v2[3], floa
        VECADDMUL(to, v3, w3);
 }
 
+
 DO_INLINE void calculateFrictionImpulse(float to[3], float vrel[3], float normal[3], double normalVelocity,
        double frictionConstant, double delta_V_n) 
 {
        float vrel_t_pre[3];
        float vrel_t[3];
        VECSUBS(vrel_t_pre, vrel, normal, normalVelocity);
-       VECCOPY(vrel_t, vrel_t_pre);
-       VecMulf(vrel_t, MAX2(1.0f - frictionConstant * delta_V_n / INPR(vrel_t_pre,vrel_t_pre), 0.0f));
-       VECSUB(to, vrel_t_pre, vrel_t);
-       VecMulf(to, 1.0f / 2.0f);
+       VECCOPY(to, vrel_t_pre);
+       VecMulf(to, MAX2(1.0f - frictionConstant * delta_V_n / INPR(vrel_t_pre,vrel_t_pre), 0.0f));
 }
 
+               
 int collision_static(ClothModifierData *clmd, ClothModifierData *coll_clmd, LinkNode **collision_list)
 {
        unsigned int i = 0, numverts=0;
@@ -271,6 +271,7 @@ int collision_static(ClothModifierData *clmd, ClothModifierData *coll_clmd, Link
                        face2 = &(cloth2->mfaces[collpair->face2]);
                        
                        // compute barycentric coordinates for both collision points
+                       
                        if(!collpair->quadA)
                                bvh_compute_barycentric(collpair->p1,
                                                        cloth1->verts[face1->v1].txold,
@@ -297,16 +298,17 @@ int collision_static(ClothModifierData *clmd, ClothModifierData *coll_clmd, Link
                                                        cloth2->verts[face2->v3].txold, 
                                                        &u1, &u2, &u3);
                        
-                       // Calculate relative velocity.
+                       // Calculate relative "velocity".
+                       
                        if(!collpair->quadA)
-                               interpolateOnTriangle(v1, cloth1->verts[face1->v1].v, cloth1->verts[face1->v2].v, cloth1->verts[face1->v3].v, w1, w2, w3);
+                               interpolateOnTriangle(v1, cloth1->verts[face1->v1].tv, cloth1->verts[face1->v2].tv, cloth1->verts[face1->v3].tv, w1, w2, w3);
                        else
-                               interpolateOnTriangle(v1, cloth1->verts[face1->v4].v, cloth1->verts[face1->v1].v, cloth1->verts[face1->v3].v, w1, w2, w3);
+                               interpolateOnTriangle(v1, cloth1->verts[face1->v4].tv, cloth1->verts[face1->v1].tv, cloth1->verts[face1->v3].tv, w1, w2, w3);
                        
                        if(!collpair->quadB)
-                               interpolateOnTriangle(v2, cloth2->verts[face2->v1].v, cloth2->verts[face2->v2].v, cloth2->verts[face2->v3].v, u1, u2, u3);
+                               interpolateOnTriangle(v2, cloth2->verts[face2->v1].tv, cloth2->verts[face2->v2].tv, cloth2->verts[face2->v3].tv, u1, u2, u3);
                        else
-                               interpolateOnTriangle(v2, cloth2->verts[face2->v4].v, cloth2->verts[face2->v1].v, cloth2->verts[face2->v3].v, u1, u2, u3);
+                               interpolateOnTriangle(v2, cloth2->verts[face2->v4].tv, cloth2->verts[face2->v1].tv, cloth2->verts[face2->v3].tv, u1, u2, u3);
                        
                        VECSUB(relativeVelocity, v1, v2);
                                
@@ -323,18 +325,22 @@ int collision_static(ClothModifierData *clmd, ClothModifierData *coll_clmd, Link
                                // 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;
+                               float tangential[3], magtangent, magnormal, collvel[3];
+                               float vrel_t_pre[3];
+                               float vrel_t[3], impulse;
+                               float epsilon = clmd->coll_parms.epsilon;
                                
-                               calculateFrictionImpulse(tangential, relativeVelocity, collpair->normal, magrelVel, clmd->coll_parms.friction*0.01, magrelVel);
+                               // calculateFrictionImpulse(tangential, relativeVelocity, collpair->normal, magrelVel, clmd->coll_parms.friction*0.01, magrelVel);
                                
-                               magtangent = INPR(tangential, tangential);
+                               // magtangent = INPR(tangential, tangential);
                                
                                // Apply friction impulse.
                                if (magtangent > ALMOST_ZERO) 
                                {
-                                       /*
-                                       printf("friction applied: %f\n", magtangent);
+                                       
+                                       // printf("friction applied: %f\n", magtangent);
                                        // TODO check original code 
+                                       /*
                                        VECSUB(cloth1->verts[face1->v1].tv, cloth1->verts[face1->v1].tv,tangential);
                                        VECSUB(cloth1->verts[face1->v1].tv, cloth1->verts[face1->v2].tv,tangential);
                                        VECSUB(cloth1->verts[face1->v1].tv, cloth1->verts[face1->v3].tv,tangential);
@@ -345,26 +351,52 @@ int collision_static(ClothModifierData *clmd, ClothModifierData *coll_clmd, Link
                                // printf("magnitude_i: %f\n", magnitude_i); // negative before collision in my case
                                
                                // Apply the impulse and increase impulse counters.
-                               /*
-                               VECADDMUL(cloth1->verts[face1->v1].tv,collpair->normal, -magnitude_i);
-                               VECADDMUL(cloth1->verts[face1->v2].tv,collpair->normal, -magnitude_i);
-                               VECADDMUL(cloth1->verts[face1->v3].tv,collpair->normal, -magnitude_i);
-                               VECADDMUL(cloth1->verts[face1->v4].tv,collpair->normal, -magnitude_i);
-                               */
+                               // my try, works better than the papers ones (maybe i did just something wrong)
+                               VECSUB(collvel, cloth1->verts[face1->v1].tv, v2);
+                               magnormal = INPR(collvel, collpair->normal);
+                               if(magnormal<ALMOST_ZERO)
+                                       magnormal = 0.0f;
+                               
+                               impulse = (epsilon + ALMOST_ZERO-collpair->distance) / 4.0f;
+                               VECADDMUL(cloth1->verts[face1->v1].tv, collpair->normal, -magnormal + impulse); 
                                
-                               // my try
-                               magtangent = INPR(cloth1->verts[face1->v1].tv, collpair->normal);
-                               VECADDMUL(cloth1->verts[face1->v1].tv, collpair->normal, -magtangent); 
+                               // calculateFrictionImpulse(tangential, collvel, collpair->normal, magtangent, clmd->coll_parms.friction*0.01, magtangent);
                                
-                               magtangent = INPR(cloth1->verts[face1->v2].tv, collpair->normal);
-                               VECADDMUL(cloth1->verts[face1->v2].tv, collpair->normal, -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));
+                               magtangent = Normalize(vrel_t_pre);
+                               VecMulf(vrel_t_pre, MIN2(clmd->coll_parms.friction*0.01f*magnormal,magtangent));
                                
-                               magtangent = INPR(cloth1->verts[face1->v3].tv, collpair->normal);
-                               VECADDMUL(cloth1->verts[face1->v3].tv, collpair->normal, -magtangent); 
+                               VECSUB(cloth1->verts[face1->v1].tv, cloth1->verts[face1->v1].tv,vrel_t_pre);
+*/                             
                                
-                               magtangent = INPR(cloth1->verts[face1->v4].tv, collpair->normal);
-                               VECADDMUL(cloth1->verts[face1->v4].tv, collpair->normal, -magtangent); 
+                               VECSUB(collvel, cloth1->verts[face1->v2].tv, v2);
+                               magnormal = INPR(collvel, collpair->normal);
+                               if(magnormal<ALMOST_ZERO)
+                                       magnormal = 0.0f;
                                
+                               impulse = (epsilon + ALMOST_ZERO-collpair->distance) / 4.0f;
+                               VECADDMUL(cloth1->verts[face1->v2].tv, collpair->normal, -magnormal+ impulse); 
+                               
+                               
+                               VECSUB(collvel, cloth1->verts[face1->v3].tv, v2);
+                               magnormal = INPR(collvel, collpair->normal);
+                               if(magnormal<ALMOST_ZERO)
+                                       magnormal = 0.0f;
+                               
+                               impulse = (epsilon + ALMOST_ZERO-collpair->distance) / 4.0f;
+                               VECADDMUL(cloth1->verts[face1->v3].tv, collpair->normal, -magnormal+ impulse); 
+                               
+                               
+                               VECSUB(collvel, cloth1->verts[face1->v4].tv, v2);
+                               magnormal = INPR(collvel, collpair->normal);
+                               if(magnormal<ALMOST_ZERO)
+                                       magnormal = 0.0f;
+                               
+                               impulse = (epsilon + ALMOST_ZERO-collpair->distance) / 4.0f;
+                               VECADDMUL(cloth1->verts[face1->v4].tv, collpair->normal, -magnormal+ impulse); 
+                       
                                result = 1;
                                
                        }
@@ -586,7 +618,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, CM_COLLISION_RE
                                        bvh_traverse(clmd, coll_clmd, cloth_bvh->root, coll_bvh->root, step, collision_response);
                                        
                                        result += collision_static(clmd, coll_clmd, collision_list);
-                                       printf("result: %d\n", result);
+                                       
                                        // calculate velocities
                                        
                                        // free temporary list 
index cfe173767974e9d6d118edc6cf9286566f39eebc..c54897cc89c75f9a94f1f5e1fa535f16cde0e701 100644 (file)
@@ -1484,6 +1484,7 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase
                        VECCOPY(verts[i].tx, id->Xnew[i]);
                        
                        VECSUB(verts[i].tv, verts[i].tx, verts[i].txold);
+                       VECSUB(verts[i].v, verts[i].tx, verts[i].txold);
                }
 
                // call collision function
index 2106525e9b20e09026e3f74b9fedcbc4a9839495..1e3439d41b521342ca9c6bad0f1dd83c95625afa 100644 (file)
@@ -3103,7 +3103,6 @@ static void object_panel_cloth(Object *ob)
        if(clmd)
        {
                but = uiDefButBitI(block, TOG, CSIMSETT_FLAG_COLLOBJ, B_EFFECT_DEP, "Collision Object", 170,200,130,20, &clmd->sim_parms.flags, 0, 0, 0, 0, "Sets object to become a cloth collision object");
-               // uiButSetFunc(but, object_cloth__enabletoggle, ob, NULL);
 
                if (!(clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ))
                {