Replace MFace w/ vert-tri's for collision modifier
authorCampbell Barton <ideasman42@gmail.com>
Fri, 31 Jul 2015 04:00:07 +0000 (14:00 +1000)
committerCampbell Barton <ideasman42@gmail.com>
Fri, 31 Jul 2015 04:00:07 +0000 (14:00 +1000)
Note that the collision modifier doesn't have any use for Loop indices,
so to avoid duplicating the loop array too,
MVertTri has been added which simply stores vertex indices (runtime only).

19 files changed:
source/blender/blenkernel/BKE_DerivedMesh.h
source/blender/blenkernel/BKE_cloth.h
source/blender/blenkernel/BKE_collision.h
source/blender/blenkernel/BKE_particle.h
source/blender/blenkernel/intern/DerivedMesh.c
source/blender/blenkernel/intern/cloth.c
source/blender/blenkernel/intern/collision.c
source/blender/blenkernel/intern/particle_system.c
source/blender/blenkernel/intern/pointcache.c
source/blender/blenkernel/intern/softbody.c
source/blender/blenloader/intern/readfile.c
source/blender/makesdna/DNA_meshdata_types.h
source/blender/makesdna/DNA_modifier_types.h
source/blender/modifiers/intern/MOD_collision.c
source/blender/physics/BPH_mass_spring.h
source/blender/physics/intern/BPH_mass_spring.cpp
source/blender/physics/intern/implicit.h
source/blender/physics/intern/implicit_blender.c
source/blender/physics/intern/implicit_eigen.cpp

index f331bcb1ac5e4710aab81434132ec827d669906a..6a6e975bc7281144be435989df6fad38cd7407d9 100644 (file)
@@ -613,6 +613,7 @@ void DM_ensure_tessface(DerivedMesh *dm);
 
 void DM_ensure_looptri_data(DerivedMesh *dm);
 void DM_ensure_looptri(DerivedMesh *dm);
+void DM_verttri_from_looptri(MVertTri *verttri, const MLoop *mloop, const MLoopTri *looptri, int looptri_num);
 
 void DM_update_tessface_data(DerivedMesh *dm);
 void DM_generate_tangent_tessface_data(DerivedMesh *dm, bool generate);
index 81621f9d3e762f25d2f94b410057eff530c51232..b8ac6afda1e52dae11c5660d3b17486a11c1de1f 100644 (file)
@@ -86,15 +86,15 @@ typedef struct ClothSolverResult {
 typedef struct Cloth {
        struct ClothVertex      *verts;                 /* The vertices that represent this cloth. */
        struct  LinkNode        *springs;               /* The springs connecting the mesh. */
-       unsigned int            numverts;               /* The number of verts == m * n. */
        unsigned int            numsprings;             /* The count of springs. */
-       unsigned int            numfaces;
+       unsigned int            mvert_num;              /* The number of verts == m * n. */
+       unsigned int            tri_num;
        unsigned char           old_solver_type;        /* unused, only 1 solver here */
        unsigned char           pad2;
        short                   pad3;
        struct BVHTree          *bvhtree;                       /* collision tree for this cloth object */
        struct BVHTree          *bvhselftree;                   /* collision tree for this cloth object */
-       struct MFace            *mfaces;
+       struct MVertTri         *tri;
        struct Implicit_Data    *implicit;              /* our implicit solver connects to this pointer */
        struct EdgeSet          *edgeset;               /* used for selfcollisions */
        int last_frame, pad4;
@@ -233,8 +233,8 @@ void clothModifier_do (struct ClothModifierData *clmd, struct Scene *scene, stru
 int cloth_uses_vgroup(struct ClothModifierData *clmd);
 
 // needed for collision.c
-void bvhtree_update_from_cloth (struct ClothModifierData *clmd, int moving );
-void bvhselftree_update_from_cloth (struct ClothModifierData *clmd, int moving );
+void bvhtree_update_from_cloth(struct ClothModifierData *clmd, bool moving);
+void bvhselftree_update_from_cloth(struct ClothModifierData *clmd, bool moving);
 
 // needed for button_object.c
 void cloth_clear_cache (struct Object *ob, struct ClothModifierData *clmd, float framenr );
index bdc20324bee033e9e77d3a12caf37f16586f148a..d5b4a584ec674b798cf9efaec3c3c004b28fce81 100644 (file)
@@ -49,6 +49,7 @@ struct MFace;
 struct MVert;
 struct Object;
 struct Scene;
+struct MVertTri;
 
 ////////////////////////////////////////
 // used for collisions in collision.c
@@ -124,8 +125,15 @@ FaceCollPair;
 // used in modifier.c from collision.c
 /////////////////////////////////////////////////
 
-BVHTree *bvhtree_build_from_mvert(struct MFace *mfaces, unsigned int numfaces, struct MVert *x, unsigned int numverts, float epsilon);
-void bvhtree_update_from_mvert(BVHTree *bvhtree, struct MFace *faces, int numfaces, struct MVert *x, struct MVert *xnew, int numverts, int moving);
+BVHTree *bvhtree_build_from_mvert(
+        const struct MVert *mvert,
+        const struct MVertTri *tri, int tri_num,
+        float epsilon);
+void bvhtree_update_from_mvert(
+        BVHTree *bvhtree,
+        const struct MVert *mvert, const struct MVert *mvert_moving,
+        const struct MVertTri *tri, int tri_num,
+        bool moving);
 
 /////////////////////////////////////////////////
 
index e03789f502b619c0cd4347d1eea81feca4ec7af5..32325707c9aff8f1b0fd8dfc7486853e672520ac 100644 (file)
@@ -179,7 +179,7 @@ typedef struct ParticleBillboardData {
 
 typedef struct ParticleCollisionElement {
        /* pointers to original data */
-       float *x[4], *v[4];
+       float *x[3], *v[3];
 
        /* values interpolated from original data*/
        float x0[3], x1[3], x2[3], p[3];
index 3156eb391b8d67b6d17473fd5fba9afa8b5537cb..25f409b037cf9c207e7272ccc1576c382cb9a19e 100644 (file)
@@ -493,6 +493,16 @@ void DM_ensure_looptri(DerivedMesh *dm)
        }
 }
 
+void DM_verttri_from_looptri(MVertTri *verttri, const MLoop *mloop, const MLoopTri *looptri, int looptri_num)
+{
+       int i;
+       for (i = 0; i < looptri_num; i++) {
+               verttri[i].tri[0] = mloop[looptri[i].tri[0]].v;
+               verttri[i].tri[1] = mloop[looptri[i].tri[1]].v;
+               verttri[i].tri[2] = mloop[looptri[i].tri[2]].v;
+       }
+}
+
 /* Update tessface CD data from loop/poly ones. Needed when not retessellating after modstack evaluation. */
 /* NOTE: Assumes dm has valid tessellated data! */
 void DM_update_tessface_data(DerivedMesh *dm)
index e3ff96853b362917c11276ace10b0e77866828ca..1b233772d63efdca5efcad361ec8f10af69d7aa9 100644 (file)
@@ -137,7 +137,6 @@ static BVHTree *bvhselftree_build_from_cloth (ClothModifierData *clmd, float eps
        BVHTree *bvhtree;
        Cloth *cloth;
        ClothVertex *verts;
-       float co[12];
 
        if (!clmd)
                return NULL;
@@ -149,21 +148,22 @@ static BVHTree *bvhselftree_build_from_cloth (ClothModifierData *clmd, float eps
        
        verts = cloth->verts;
        
-       // in the moment, return zero if no faces there
-       if (!cloth->numverts)
+       /* in the moment, return zero if no faces there */
+       if (!cloth->mvert_num)
                return NULL;
        
-       // create quadtree with k=26
-       bvhtree = BLI_bvhtree_new(cloth->numverts, epsilon, 4, 6);
+       /* create quadtree with k=26 */
+       bvhtree = BLI_bvhtree_new(cloth->mvert_num, epsilon, 4, 6);
        
-       // fill tree
-       for (i = 0; i < cloth->numverts; i++, verts++) {
-               copy_v3_v3(&co[0*3], verts->xold);
+       /* fill tree */
+       for (i = 0; i < cloth->mvert_num; i++, verts++) {
+               const float *co;
+               co = verts->xold;
                
                BLI_bvhtree_insert(bvhtree, i, co, 1);
        }
        
-       // balance tree
+       /* balance tree */
        BLI_bvhtree_balance(bvhtree);
        
        return bvhtree;
@@ -175,8 +175,7 @@ static BVHTree *bvhtree_build_from_cloth (ClothModifierData *clmd, float epsilon
        BVHTree *bvhtree;
        Cloth *cloth;
        ClothVertex *verts;
-       MFace *mfaces;
-       float co[12];
+       const MVertTri *vt;
 
        if (!clmd)
                return NULL;
@@ -187,25 +186,24 @@ static BVHTree *bvhtree_build_from_cloth (ClothModifierData *clmd, float epsilon
                return NULL;
        
        verts = cloth->verts;
-       mfaces = cloth->mfaces;
+       vt = cloth->tri;
        
        /* in the moment, return zero if no faces there */
-       if (!cloth->numfaces)
+       if (!cloth->tri_num)
                return NULL;
 
        /* create quadtree with k=26 */
-       bvhtree = BLI_bvhtree_new(cloth->numfaces, epsilon, 4, 26);
+       bvhtree = BLI_bvhtree_new(cloth->tri_num, epsilon, 4, 26);
 
        /* fill tree */
-       for (i = 0; i < cloth->numfaces; i++, mfaces++) {
-               copy_v3_v3(&co[0*3], verts[mfaces->v1].xold);
-               copy_v3_v3(&co[1*3], verts[mfaces->v2].xold);
-               copy_v3_v3(&co[2*3], verts[mfaces->v3].xold);
+       for (i = 0; i < cloth->tri_num; i++, vt++) {
+               float co[3][3];
 
-               if (mfaces->v4)
-                       copy_v3_v3(&co[3*3], verts[mfaces->v4].xold);
+               copy_v3_v3(co[0], verts[vt->tri[0]].xold);
+               copy_v3_v3(co[1], verts[vt->tri[1]].xold);
+               copy_v3_v3(co[2], verts[vt->tri[2]].xold);
 
-               BLI_bvhtree_insert(bvhtree, i, co, (mfaces->v4 ? 4 : 3));
+               BLI_bvhtree_insert(bvhtree, i, co[0], 3);
        }
 
        /* balance tree */
@@ -214,90 +212,87 @@ static BVHTree *bvhtree_build_from_cloth (ClothModifierData *clmd, float epsilon
        return bvhtree;
 }
 
-void bvhtree_update_from_cloth(ClothModifierData *clmd, int moving)
+void bvhtree_update_from_cloth(ClothModifierData *clmd, bool moving)
 {      
        unsigned int i = 0;
        Cloth *cloth = clmd->clothObject;
        BVHTree *bvhtree = cloth->bvhtree;
        ClothVertex *verts = cloth->verts;
-       MFace *mfaces;
-       float co[12], co_moving[12];
-       bool ret = false;
+       const MVertTri *vt;
        
        if (!bvhtree)
                return;
        
-       mfaces = cloth->mfaces;
+       vt = cloth->tri;
        
-       // update vertex position in bvh tree
-       if (verts && mfaces) {
-               for (i = 0; i < cloth->numfaces; i++, mfaces++) {
-                       copy_v3_v3(&co[0*3], verts[mfaces->v1].txold);
-                       copy_v3_v3(&co[1*3], verts[mfaces->v2].txold);
-                       copy_v3_v3(&co[2*3], verts[mfaces->v3].txold);
-                       
-                       if (mfaces->v4)
-                               copy_v3_v3(&co[3*3], verts[mfaces->v4].txold);
-               
-                       // copy new locations into array
+       /* update vertex position in bvh tree */
+       if (verts && vt) {
+               for (i = 0; i < cloth->tri_num; i++, vt++) {
+                       float co[3][3], co_moving[3][3];
+                       bool ret;
+
+                       copy_v3_v3(co[0], verts[vt->tri[0]].txold);
+                       copy_v3_v3(co[1], verts[vt->tri[1]].txold);
+                       copy_v3_v3(co[2], verts[vt->tri[2]].txold);
+
+                       /* copy new locations into array */
                        if (moving) {
-                               // update moving positions
-                               copy_v3_v3(&co_moving[0*3], verts[mfaces->v1].tx);
-                               copy_v3_v3(&co_moving[1*3], verts[mfaces->v2].tx);
-                               copy_v3_v3(&co_moving[2*3], verts[mfaces->v3].tx);
-                               
-                               if (mfaces->v4)
-                                       copy_v3_v3(&co_moving[3*3], verts[mfaces->v4].tx);
-                               
-                               ret = BLI_bvhtree_update_node(bvhtree, i, co, co_moving, (mfaces->v4 ? 4 : 3));
+                               /* update moving positions */
+                               copy_v3_v3(co_moving[0], verts[vt->tri[0]].tx);
+                               copy_v3_v3(co_moving[1], verts[vt->tri[1]].tx);
+                               copy_v3_v3(co_moving[2], verts[vt->tri[2]].tx);
+
+                               ret = BLI_bvhtree_update_node(bvhtree, i, co[0], co_moving[0], 3);
                        }
                        else {
-                               ret = BLI_bvhtree_update_node(bvhtree, i, co, NULL, (mfaces->v4 ? 4 : 3));
+                               ret = BLI_bvhtree_update_node(bvhtree, i, co[0], NULL, 3);
                        }
                        
-                       // check if tree is already full
-                       if (!ret)
+                       /* check if tree is already full */
+                       if (ret == false) {
                                break;
+                       }
                }
                
                BLI_bvhtree_update_tree(bvhtree);
        }
 }
 
-void bvhselftree_update_from_cloth(ClothModifierData *clmd, int moving)
+void bvhselftree_update_from_cloth(ClothModifierData *clmd, bool moving)
 {      
        unsigned int i = 0;
        Cloth *cloth = clmd->clothObject;
        BVHTree *bvhtree = cloth->bvhselftree;
        ClothVertex *verts = cloth->verts;
-       MFace *mfaces;
-       float co[12], co_moving[12];
-       int ret = 0;
+       const MVertTri *vt;
        
        if (!bvhtree)
                return;
-       
-       mfaces = cloth->mfaces;
 
-       // update vertex position in bvh tree
-       if (verts && mfaces) {
-               for (i = 0; i < cloth->numverts; i++, verts++) {
-                       copy_v3_v3(&co[0*3], verts->txold);
+       vt = cloth->tri;
 
-                       // copy new locations into array
-                       if (moving) {
-                               // update moving positions
-                               copy_v3_v3(&co_moving[0*3], verts->tx);
+       /* update vertex position in bvh tree */
+       if (verts && vt) {
+               for (i = 0; i < cloth->mvert_num; i++, verts++) {
+                       const float *co, *co_moving;
+                       bool ret;
+
+                       co = verts->txold;
 
+                       /* copy new locations into array */
+                       if (moving) {
+                               /* update moving positions */
+                               co_moving = verts->tx;
                                ret = BLI_bvhtree_update_node(bvhtree, i, co, co_moving, 1);
                        }
                        else {
                                ret = BLI_bvhtree_update_node(bvhtree, i, co, NULL, 1);
                        }
 
-                       // check if tree is already full
-                       if (!ret)
+                       /* check if tree is already full */
+                       if (ret == false) {
                                break;
+                       }
                }
                
                BLI_bvhtree_update_tree(bvhtree);
@@ -360,7 +355,7 @@ static int do_step_cloth(Object *ob, ClothModifierData *clmd, DerivedMesh *resul
        mvert = result->getVertArray(result);
 
        /* force any pinned verts to their constrained location. */
-       for (i = 0; i < clmd->clothObject->numverts; i++, verts++) {
+       for (i = 0; i < clmd->clothObject->mvert_num; i++, verts++) {
                /* save the previous position. */
                copy_v3_v3(verts->xold, verts->xconst);
                copy_v3_v3(verts->txold, verts->x);
@@ -462,7 +457,7 @@ void clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob, Derived
        BKE_ptcache_id_time(&pid, scene, framenr, &startframe, &endframe, &timescale);
        clmd->sim_parms->timescale= timescale;
 
-       if (clmd->sim_parms->reset || (clmd->clothObject && dm->getNumVerts(dm) != clmd->clothObject->numverts)) {
+       if (clmd->sim_parms->reset || (clmd->clothObject && dm->getNumVerts(dm) != clmd->clothObject->mvert_num)) {
                clmd->sim_parms->reset = 0;
                cache->flag |= PTCACHE_OUTDATED;
                BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
@@ -562,7 +557,7 @@ void cloth_free_modifier(ClothModifierData *clmd )
                        MEM_freeN ( cloth->verts );
 
                cloth->verts = NULL;
-               cloth->numverts = 0;
+               cloth->mvert_num = 0;
 
                // Free the springs.
                if ( cloth->springs != NULL ) {
@@ -589,9 +584,9 @@ void cloth_free_modifier(ClothModifierData *clmd )
                        BLI_bvhtree_free ( cloth->bvhselftree );
 
                // we save our faces for collision objects
-               if ( cloth->mfaces )
-                       MEM_freeN ( cloth->mfaces );
-               
+               if (cloth->tri)
+                       MEM_freeN(cloth->tri);
+
                if (cloth->edgeset)
                        BLI_edgeset_free(cloth->edgeset);
                
@@ -628,7 +623,7 @@ void cloth_free_modifier_extern(ClothModifierData *clmd )
                        MEM_freeN ( cloth->verts );
 
                cloth->verts = NULL;
-               cloth->numverts = 0;
+               cloth->mvert_num = 0;
 
                // Free the springs.
                if ( cloth->springs != NULL ) {
@@ -655,8 +650,8 @@ void cloth_free_modifier_extern(ClothModifierData *clmd )
                        BLI_bvhtree_free ( cloth->bvhselftree );
 
                // we save our faces for collision objects
-               if ( cloth->mfaces )
-                       MEM_freeN ( cloth->mfaces );
+               if (cloth->tri)
+                       MEM_freeN(cloth->tri);
 
                if (cloth->edgeset)
                        BLI_edgeset_free(cloth->edgeset);
@@ -690,7 +685,7 @@ static void cloth_to_object (Object *ob,  ClothModifierData *clmd, float (*verte
                /* inverse matrix is not uptodate... */
                invert_m4_m4(ob->imat, ob->obmat);
 
-               for (i = 0; i < cloth->numverts; i++) {
+               for (i = 0; i < cloth->mvert_num; i++) {
                        copy_v3_v3 (vertexCos[i], cloth->verts[i].x);
                        mul_m4_v3(ob->imat, vertexCos[i]);      /* cloth is in global coords */
                }
@@ -721,7 +716,7 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm )
        int j = 0;
        MDeformVert *dvert = NULL;
        Cloth *clothObj = NULL;
-       int numverts;
+       int mvert_num;
        /* float goalfac = 0; */ /* UNUSED */
        ClothVertex *verts = NULL;
 
@@ -729,12 +724,12 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm )
 
        clothObj = clmd->clothObject;
 
-       numverts = dm->getNumVerts (dm);
+       mvert_num = dm->getNumVerts(dm);
 
        verts = clothObj->verts;
        
        if (cloth_uses_vgroup(clmd)) {
-               for ( i = 0; i < numverts; i++, verts++ ) {
+               for (i = 0; i < mvert_num; i++, verts++) {
 
                        /* Reset Goal values to standard */
                        if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL )
@@ -831,6 +826,7 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d
        if ( !dm )
                return 0;
 
+       DM_ensure_looptri(dm);
        cloth_from_mesh ( clmd, dm );
 
        // create springs
@@ -883,6 +879,9 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d
        // has to be happen before springs are build!
        cloth_apply_vgroup (clmd, dm);
 
+       /* springs yse MFace currently */
+       DM_ensure_tessface(dm);
+
        if ( !cloth_build_springs ( clmd, dm ) ) {
                cloth_free_modifier ( clmd );
                modifier_setError(&(clmd->modifier), "Cannot build springs");
@@ -915,32 +914,31 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d
 
 static void cloth_from_mesh ( ClothModifierData *clmd, DerivedMesh *dm )
 {
-       unsigned int numverts = dm->getNumVerts (dm);
-       unsigned int numfaces = dm->getNumTessFaces (dm);
-       MFace *mface = dm->getTessFaceArray(dm);
-       unsigned int i = 0;
+       const MLoop *mloop = dm->getLoopArray(dm);
+       const MLoopTri *looptri = dm->getLoopTriArray(dm);
+       const unsigned int mvert_num = dm->getNumVerts(dm);
+       const unsigned int looptri_num = dm->getNumLoopTri(dm);
 
        /* Allocate our vertices. */
-       clmd->clothObject->numverts = numverts;
-       clmd->clothObject->verts = MEM_callocN ( sizeof ( ClothVertex ) * clmd->clothObject->numverts, "clothVertex" );
-       if ( clmd->clothObject->verts == NULL ) {
-               cloth_free_modifier ( clmd );
+       clmd->clothObject->mvert_num = mvert_num;
+       clmd->clothObject->verts = MEM_callocN(sizeof(ClothVertex) * clmd->clothObject->mvert_num, "clothVertex");
+       if (clmd->clothObject->verts == NULL) {
+               cloth_free_modifier(clmd);
                modifier_setError(&(clmd->modifier), "Out of memory on allocating clmd->clothObject->verts");
                printf("cloth_free_modifier clmd->clothObject->verts\n");
                return;
        }
 
-       // save face information
-       clmd->clothObject->numfaces = numfaces;
-       clmd->clothObject->mfaces = MEM_callocN ( sizeof ( MFace ) * clmd->clothObject->numfaces, "clothMFaces" );
-       if ( clmd->clothObject->mfaces == NULL ) {
-               cloth_free_modifier ( clmd );
-               modifier_setError(&(clmd->modifier), "Out of memory on allocating clmd->clothObject->mfaces");
-               printf("cloth_free_modifier clmd->clothObject->mfaces\n");
+       /* save face information */
+       clmd->clothObject->tri_num = looptri_num;
+       clmd->clothObject->tri = MEM_mallocN(sizeof(MVertTri) * looptri_num, "clothLoopTris");
+       if (clmd->clothObject->tri == NULL) {
+               cloth_free_modifier(clmd);
+               modifier_setError(&(clmd->modifier), "Out of memory on allocating clmd->clothObject->looptri");
+               printf("cloth_free_modifier clmd->clothObject->looptri\n");
                return;
        }
-       for ( i = 0; i < numfaces; i++ )
-               memcpy ( &clmd->clothObject->mfaces[i], &mface[i], sizeof ( MFace ) );
+       DM_verttri_from_looptri(clmd->clothObject->tri, mloop, looptri, looptri_num);
 
        /* Free the springs since they can't be correct if the vertices
         * changed.
@@ -997,11 +995,11 @@ int cloth_add_spring(ClothModifierData *clmd, unsigned int indexA, unsigned int
        return 0;
 }
 
-static void cloth_free_edgelist(LinkNodePair *edgelist, unsigned int numverts)
+static void cloth_free_edgelist(LinkNodePair *edgelist, unsigned int mvert_num)
 {
        if (edgelist) {
                unsigned int i;
-               for (i = 0; i < numverts; i++) {
+               for (i = 0; i < mvert_num; i++) {
                        BLI_linklist_free(edgelist[i].list, NULL);
                }
 
@@ -1024,7 +1022,7 @@ static void cloth_free_errorsprings(Cloth *cloth, LinkNodePair *edgelist)
                cloth->springs = NULL;
        }
 
-       cloth_free_edgelist(edgelist, cloth->numverts);
+       cloth_free_edgelist(edgelist, cloth->mvert_num);
        
        if (cloth->edgeset) {
                BLI_edgeset_free(cloth->edgeset);
@@ -1253,7 +1251,7 @@ static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
        ClothSpring *spring = NULL, *tspring = NULL, *tspring2 = NULL;
        unsigned int struct_springs = 0, shear_springs=0, bend_springs = 0;
        unsigned int i = 0;
-       unsigned int numverts = (unsigned int)dm->getNumVerts (dm);
+       unsigned int mvert_num = (unsigned int)dm->getNumVerts(dm);
        unsigned int numedges = (unsigned int)dm->getNumEdges (dm);
        unsigned int numfaces = (unsigned int)dm->getNumTessFaces (dm);
        float shrink_factor;
@@ -1276,7 +1274,7 @@ static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
        cloth->springs = NULL;
        cloth->edgeset = NULL;
 
-       edgelist = MEM_callocN(sizeof(*edgelist) * numverts, "cloth_edgelist_alloc" );
+       edgelist = MEM_callocN(sizeof(*edgelist) * mvert_num, "cloth_edgelist_alloc" );
        
        if (!edgelist)
                return 0;
@@ -1321,7 +1319,7 @@ static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
        if (struct_springs > 0)
                clmd->sim_parms->avg_spring_len /= struct_springs;
        
-       for (i = 0; i < numverts; i++) {
+       for (i = 0; i < mvert_num; i++) {
                cloth->verts[i].avg_spring_len = cloth->verts[i].avg_spring_len * 0.49f / ((float)cloth->verts[i].spring_count);
        }
 
@@ -1511,7 +1509,7 @@ static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
        
        cloth->numsprings = struct_springs + shear_springs + bend_springs;
        
-       cloth_free_edgelist(edgelist, numverts);
+       cloth_free_edgelist(edgelist, mvert_num);
 
 #if 0
        if (G.debug_value > 0)
index 763024ec5659ab86a19b6dc6eb58fbdf41874724..db3642ae183125b8b6227f924a6a0f6316347673 100644 (file)
@@ -71,82 +71,92 @@ void collision_move_object(CollisionModifierData *collmd, float step, float prev
        float tv[3] = {0, 0, 0};
        unsigned int i = 0;
 
-       for ( i = 0; i < collmd->numverts; i++ ) {
+       for (i = 0; i < collmd->mvert_num; i++) {
                sub_v3_v3v3(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);
                sub_v3_v3v3(collmd->current_v[i].co, collmd->current_xnew[i].co, collmd->current_x[i].co);
        }
 
-       bvhtree_update_from_mvert ( collmd->bvhtree, collmd->mfaces, collmd->numfaces, collmd->current_x, collmd->current_xnew, collmd->numverts, 1 );
+       bvhtree_update_from_mvert(
+               collmd->bvhtree, collmd->current_x, collmd->current_xnew,
+               collmd->tri, collmd->tri_num, true);
 }
 
-BVHTree *bvhtree_build_from_mvert ( MFace *mfaces, unsigned int numfaces, MVert *x, unsigned int UNUSED(numverts), float epsilon )
+BVHTree *bvhtree_build_from_mvert(
+        const MVert *mvert,
+        const struct MVertTri *tri, int tri_num,
+        float epsilon)
 {
        BVHTree *tree;
-       float co[12];
-       unsigned int i;
-       MFace *tface = mfaces;
+       const MVertTri *vt;
+       int i;
+
+       tree = BLI_bvhtree_new(tri_num, epsilon, 4, 26);
 
-       tree = BLI_bvhtree_new ( numfaces*2, epsilon, 4, 26 );
+       /* fill tree */
+       for (i = 0, vt = tri; i < tri_num; i++, vt++) {
+               float co[3][3];
 
-       // fill tree
-       for ( i = 0; i < numfaces; i++, tface++ ) {
-               copy_v3_v3 ( &co[0*3], x[tface->v1].co );
-               copy_v3_v3 ( &co[1*3], x[tface->v2].co );
-               copy_v3_v3 ( &co[2*3], x[tface->v3].co );
-               if ( tface->v4 )
-                       copy_v3_v3 ( &co[3*3], x[tface->v4].co );
+               copy_v3_v3(co[0], mvert[vt->tri[0]].co);
+               copy_v3_v3(co[1], mvert[vt->tri[1]].co);
+               copy_v3_v3(co[2], mvert[vt->tri[2]].co);
 
-               BLI_bvhtree_insert ( tree, i, co, ( mfaces->v4 ? 4 : 3 ) );
+               BLI_bvhtree_insert(tree, i, co[0], 3);
        }
 
-       // balance tree
-       BLI_bvhtree_balance ( tree );
+       /* balance tree */
+       BLI_bvhtree_balance(tree);
 
        return tree;
 }
 
-void bvhtree_update_from_mvert(BVHTree *bvhtree, MFace *faces, int numfaces, MVert *x, MVert *xnew, int UNUSED(numverts), int moving )
+void bvhtree_update_from_mvert(
+        BVHTree *bvhtree,
+        const MVert *mvert, const MVert *mvert_moving,
+        const MVertTri *tri, int tri_num,
+        bool moving)
 {
+       const MVertTri *vt;
        int i;
-       MFace *mfaces = faces;
-       float co[12], co_moving[12];
-       bool ret = false;
 
-       if ( !bvhtree )
+       if ((bvhtree == NULL) || (mvert == NULL)) {
                return;
+       }
 
-       if ( x ) {
-               for ( i = 0; i < numfaces; i++, mfaces++ ) {
-                       copy_v3_v3 ( &co[0*3], x[mfaces->v1].co );
-                       copy_v3_v3 ( &co[1*3], x[mfaces->v2].co );
-                       copy_v3_v3 ( &co[2*3], x[mfaces->v3].co );
-                       if ( mfaces->v4 )
-                               copy_v3_v3 ( &co[3*3], x[mfaces->v4].co );
-
-                       // copy new locations into array
-                       if ( moving && xnew ) {
-                               // update moving positions
-                               copy_v3_v3 ( &co_moving[0*3], xnew[mfaces->v1].co );
-                               copy_v3_v3 ( &co_moving[1*3], xnew[mfaces->v2].co );
-                               copy_v3_v3 ( &co_moving[2*3], xnew[mfaces->v3].co );
-                               if ( mfaces->v4 )
-                                       copy_v3_v3 ( &co_moving[3*3], xnew[mfaces->v4].co );
-
-                               ret = BLI_bvhtree_update_node ( bvhtree, i, co, co_moving, ( mfaces->v4 ? 4 : 3 ) );
-                       }
-                       else {
-                               ret = BLI_bvhtree_update_node ( bvhtree, i, co, NULL, ( mfaces->v4 ? 4 : 3 ) );
-                       }
+       if (mvert_moving == NULL) {
+               moving = false;
+       }
+
+       for (i = 0, vt = tri; i < tri_num; i++, vt++) {
+               float co[3][3];
+               bool ret;
+
+               copy_v3_v3(co[0], mvert[vt->tri[0]].co);
+               copy_v3_v3(co[1], mvert[vt->tri[1]].co);
+               copy_v3_v3(co[2], mvert[vt->tri[2]].co);
 
-                       // check if tree is already full
-                       if ( !ret )
-                               break;
+               /* copy new locations into array */
+               if (moving) {
+                       float co_moving[3][3];
+                       /* update moving positions */
+                       copy_v3_v3(co_moving[0], mvert_moving[vt->tri[0]].co);
+                       copy_v3_v3(co_moving[1], mvert_moving[vt->tri[1]].co);
+                       copy_v3_v3(co_moving[2], mvert_moving[vt->tri[2]].co);
+
+                       ret = BLI_bvhtree_update_node(bvhtree, i, &co[0][0], &co_moving[0][0], 3);
+               }
+               else {
+                       ret = BLI_bvhtree_update_node(bvhtree, i, &co[0][0], NULL, 3);
                }
 
-               BLI_bvhtree_update_tree ( bvhtree );
+               /* check if tree is already full */
+               if (ret == false) {
+                       break;
+               }
        }
+
+       BLI_bvhtree_update_tree(bvhtree);
 }
 
 /***********************************
@@ -380,80 +390,29 @@ static CollPair* cloth_collision(ModifierData *md1, ModifierData *md2,
        ClothModifierData *clmd = (ClothModifierData *)md1;
        CollisionModifierData *collmd = (CollisionModifierData *) md2;
        /* Cloth *cloth = clmd->clothObject; */ /* UNUSED */
-       MFace *face1=NULL, *face2 = NULL;
+       const MVertTri *tri_a, *tri_b;
 #ifdef WITH_BULLET
        ClothVertex *verts1 = clmd->clothObject->verts;
 #endif
        double distance = 0;
        float epsilon1 = clmd->coll_parms->epsilon;
        float epsilon2 = BLI_bvhtree_getepsilon ( collmd->bvhtree );
-       int i;
 
-       face1 = & ( clmd->clothObject->mfaces[overlap->indexA] );
-       face2 = & ( collmd->mfaces[overlap->indexB] );
-
-       // check all 4 possible collisions
-       for ( i = 0; i < 4; i++ ) {
-               if ( i == 0 ) {
-                       // fill faceA
-                       collpair->ap1 = face1->v1;
-                       collpair->ap2 = face1->v2;
-                       collpair->ap3 = face1->v3;
-
-                       // fill faceB
-                       collpair->bp1 = face2->v1;
-                       collpair->bp2 = face2->v2;
-                       collpair->bp3 = face2->v3;
-               }
-               else if ( i == 1 ) {
-                       if ( face1->v4 ) {
-                               // fill faceA
-                               collpair->ap1 = face1->v1;
-                               collpair->ap2 = face1->v3;
-                               collpair->ap3 = face1->v4;
-
-                               // fill faceB
-                               collpair->bp1 = face2->v1;
-                               collpair->bp2 = face2->v2;
-                               collpair->bp3 = face2->v3;
-                       }
-                       else {
-                               i++;
-                       }
-               }
-               if ( i == 2 ) {
-                       if ( face2->v4 ) {
-                               // fill faceA
-                               collpair->ap1 = face1->v1;
-                               collpair->ap2 = face1->v2;
-                               collpair->ap3 = face1->v3;
-
-                               // fill faceB
-                               collpair->bp1 = face2->v1;
-                               collpair->bp2 = face2->v4;
-                               collpair->bp3 = face2->v3;
-                       }
-                       else {
-                               break;
-                       }
-               }
-               else if ( i == 3 ) {
-                       if ( face1->v4 && face2->v4 ) {
-                               // fill faceA
-                               collpair->ap1 = face1->v1;
-                               collpair->ap2 = face1->v3;
-                               collpair->ap3 = face1->v4;
-
-                               // fill faceB
-                               collpair->bp1 = face2->v1;
-                               collpair->bp2 = face2->v3;
-                               collpair->bp3 = face2->v4;
-                       }
-                       else {
-                               break;
-                       }
-               }
-               
+       tri_a = &clmd->clothObject->tri[overlap->indexA];
+       tri_b = &collmd->tri[overlap->indexB];
+
+       /* fill face_a */
+       collpair->ap1 = tri_a->tri[0];
+       collpair->ap2 = tri_a->tri[1];
+       collpair->ap3 = tri_a->tri[2];
+
+       /* fill face_b */
+       collpair->bp1 = tri_b->tri[0];
+       collpair->bp2 = tri_b->tri[1];
+       collpair->bp3 = tri_b->tri[2];
+
+       {
+
 #ifdef WITH_BULLET
                // calc distance + normal
                distance = plNearestPoints (
@@ -662,12 +621,12 @@ static void cloth_bvh_objcollisions_nearcheck ( ClothModifierData * clmd, Collis
 static int cloth_bvh_objcollisions_resolve ( ClothModifierData * clmd, CollisionModifierData *collmd, CollPair *collisions, CollPair *collisions_index)
 {
        Cloth *cloth = clmd->clothObject;
-       int i=0, j = 0, /*numfaces = 0, */ numverts = 0;
+       int i=0, j = 0, /*numfaces = 0, */ mvert_num = 0;
        ClothVertex *verts = NULL;
        int ret = 0;
        int result = 0;
        
-       numverts = clmd->clothObject->numverts;
+       mvert_num = clmd->clothObject->mvert_num;
        verts = cloth->verts;
        
        // process all collisions (calculate impulses, TODO: also repulses if distance too short)
@@ -680,7 +639,7 @@ static int cloth_bvh_objcollisions_resolve ( ClothModifierData * clmd, Collision
 
                        // apply impulses in parallel
                        if (result) {
-                               for (i = 0; i < numverts; i++) {
+                               for (i = 0; i < mvert_num; i++) {
                                        // calculate "velocities" (just xnew = xold + v; no dt in v)
                                        if (verts[i].impulse_count) {
                                                // VECADDMUL ( verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count );
@@ -706,7 +665,7 @@ int cloth_bvh_objcollision(Object *ob, ClothModifierData *clmd, float step, floa
 {
        Cloth *cloth= clmd->clothObject;
        BVHTree *cloth_bvh= cloth->bvhtree;
-       unsigned int i=0, /* numfaces = 0, */ /* UNUSED */ numverts = 0, k, l, j;
+       unsigned int i=0, /* numfaces = 0, */ /* UNUSED */ mvert_num = 0, k, l, j;
        int rounds = 0; // result counts applied collisions; ic is for debug output;
        ClothVertex *verts = NULL;
        int ret = 0, ret2 = 0;
@@ -718,7 +677,7 @@ int cloth_bvh_objcollision(Object *ob, ClothModifierData *clmd, float step, floa
        
        verts = cloth->verts;
        /* numfaces = cloth->numfaces; */ /* UNUSED */
-       numverts = cloth->numverts;
+       mvert_num = cloth->mvert_num;
 
        ////////////////////////////////////////////////////////////
        // static collisions
@@ -794,8 +753,8 @@ int cloth_bvh_objcollision(Object *ob, ClothModifierData *clmd, float step, floa
                // this is needed for bvh_calc_DOP_hull_moving() [kdop.c]
                ////////////////////////////////////////////////////////////
 
-               // verts come from clmd
-               for ( i = 0; i < numverts; i++ ) {
+               /* verts come from clmd */
+               for (i = 0; i < mvert_num; i++) {
                        if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) {
                                if ( verts [i].flags & CLOTH_VERT_FLAG_PINNED ) {
                                        continue;
@@ -820,7 +779,7 @@ int cloth_bvh_objcollision(Object *ob, ClothModifierData *clmd, float step, floa
                                verts = cloth->verts; // needed for openMP
        
                                /* numfaces = cloth->numfaces; */ /* UNUSED */
-                               numverts = cloth->numverts;
+                               mvert_num = cloth->mvert_num;
        
                                verts = cloth->verts;
        
@@ -898,8 +857,8 @@ int cloth_bvh_objcollision(Object *ob, ClothModifierData *clmd, float step, floa
                        ////////////////////////////////////////////////////////////
                        // SELFCOLLISIONS: update velocities
                        ////////////////////////////////////////////////////////////
-                       if ( ret2 ) {
-                               for ( i = 0; i < cloth->numverts; i++ ) {
+                       if (ret2) {
+                               for (i = 0; i < cloth->mvert_num; i++) {
                                        if ( ! ( verts [i].flags & CLOTH_VERT_FLAG_PINNED ) ) {
                                                sub_v3_v3v3(verts[i].tv, verts[i].tx, verts[i].txold);
                                        }
@@ -1104,10 +1063,11 @@ BLI_INLINE bool cloth_point_face_collision_params(const float p1[3], const float
 #endif
 }
 
-static CollPair *cloth_point_collpair(float p1[3], float p2[3], MVert *mverts, int bp1, int bp2, int bp3,
-                                      int index_cloth, int index_coll, float epsilon, CollPair *collpair)
+static CollPair *cloth_point_collpair(
+        float p1[3], float p2[3], const MVert *mverts, int bp1, int bp2, int bp3,
+        int index_cloth, int index_coll, float epsilon, CollPair *collpair)
 {
-       float *co1 = mverts[bp1].co, *co2 = mverts[bp2].co, *co3 = mverts[bp3].co;
+       const float *co1 = mverts[bp1].co, *co2 = mverts[bp2].co, *co3 = mverts[bp3].co;
        float lambda /*, distance1 */, distance2;
        float facenor[3], v1p1[3], v1p2[3];
        float w[4];
@@ -1149,22 +1109,25 @@ static CollPair *cloth_point_collpair(float p1[3], float p2[3], MVert *mverts, i
 }
 
 //Determines collisions on overlap, collisions are written to collpair[i] and collision+number_collision_found is returned
-static CollPair* cloth_point_collision(ModifierData *md1, ModifierData *md2,
-                                       BVHTreeOverlap *overlap, float epsilon, CollPair *collpair, float UNUSED(dt))
+static CollPair *cloth_point_collision(
+        ModifierData *md1, ModifierData *md2,
+        BVHTreeOverlap *overlap, float epsilon, CollPair *collpair, float UNUSED(dt))
 {
        ClothModifierData *clmd = (ClothModifierData *)md1;
        CollisionModifierData *collmd = (CollisionModifierData *) md2;
        /* Cloth *cloth = clmd->clothObject; */ /* UNUSED */
        ClothVertex *vert = NULL;
-       MFace *face = NULL;
-       MVert *mverts = collmd->current_x;
+       const MVertTri *vt;
+       const MVert *mverts = collmd->current_x;
 
        vert = &clmd->clothObject->verts[overlap->indexA];
-       face = &collmd->mfaces[overlap->indexB];
+       vt = &collmd->tri[overlap->indexB];
 
-       collpair = cloth_point_collpair(vert->tx, vert->x, mverts, face->v1, face->v2, face->v3, overlap->indexA, overlap->indexB, epsilon, collpair);
-       if (face->v4)
-               collpair = cloth_point_collpair(vert->tx, vert->x, mverts, face->v3, face->v4, face->v1, overlap->indexA, overlap->indexB, epsilon, collpair);
+       collpair = cloth_point_collpair(
+               vert->tx, vert->x, mverts,
+               vt->tri[0], vt->tri[1], vt->tri[2],
+               overlap->indexA, overlap->indexB,
+               epsilon, collpair);
 
        return collpair;
 }
@@ -1189,7 +1152,7 @@ static int cloth_points_objcollisions_resolve(ClothModifierData * clmd, Collisio
                                               CollPair *collisions, CollPair *collisions_index, float dt)
 {
        Cloth *cloth = clmd->clothObject;
-       int i=0, numverts = clmd->clothObject->numverts;
+       int i = 0, mvert_num = clmd->clothObject->mvert_num;
        ClothVertex *verts = cloth->verts;
        int ret = 0;
        
@@ -1199,7 +1162,7 @@ static int cloth_points_objcollisions_resolve(ClothModifierData * clmd, Collisio
                
                // apply impulses in parallel
                if (result) {
-                       for (i = 0; i < numverts; i++) {
+                       for (i = 0; i < mvert_num; i++) {
                                // calculate "velocities" (just xnew = xold + v; no dt in v)
                                if (verts[i].impulse_count) {
                                        // VECADDMUL ( verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count );
@@ -1223,29 +1186,29 @@ int cloth_points_objcollision(Object *ob, ClothModifierData *clmd, float step, f
        BVHTree *cloth_bvh;
        int rounds = 0; // result counts applied collisions; ic is for debug output;
        float round_dt = dt / (float)clmd->coll_parms->loop_count;
-       unsigned int i=0, numverts = 0;
+       unsigned int i = 0, mvert_num = 0;
        ClothVertex *verts = NULL;
        int ret = 0, ret2 = 0;
        Object **collobjs = NULL;
        unsigned int numcollobj = 0;
        
        verts = cloth->verts;
-       numverts = cloth->numverts;
+       mvert_num = cloth->mvert_num;
        
        ////////////////////////////////////////////////////////////
        // static collisions
        ////////////////////////////////////////////////////////////
        
        // create temporary cloth points bvh
-       cloth_bvh = BLI_bvhtree_new(numverts, MAX2(clmd->coll_parms->epsilon, clmd->coll_parms->distance_repel), 4, 6);
+       cloth_bvh = BLI_bvhtree_new(mvert_num, max_ff(clmd->coll_parms->epsilon, clmd->coll_parms->distance_repel), 4, 6);
        /* fill tree */
-       for (i = 0; i < numverts; i++) {
-               float co[6];
+       for (i = 0; i < mvert_num; i++) {
+               float co[2][3];
                
-               copy_v3_v3(&co[0*3], verts[i].x);
-               copy_v3_v3(&co[1*3], verts[i].tx);
+               copy_v3_v3(co[0], verts[i].x);
+               copy_v3_v3(co[1], verts[i].tx);
                
-               BLI_bvhtree_insert(cloth_bvh, i, co, 2);
+               BLI_bvhtree_insert(cloth_bvh, i, co[0], 2);
        }
        /* balance tree */
        BLI_bvhtree_balance(cloth_bvh);
@@ -1318,7 +1281,7 @@ int cloth_points_objcollision(Object *ob, ClothModifierData *clmd, float step, f
                ////////////////////////////////////////////////////////////
 
                // verts come from clmd
-               for ( i = 0; i < numverts; i++ ) {
+               for (i = 0; i < mvert_num; i++) {
                        if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) {
                                if ( verts [i].flags & CLOTH_VERT_FLAG_PINNED ) {
                                        continue;
@@ -1344,7 +1307,7 @@ void cloth_find_point_contacts(Object *ob, ClothModifierData *clmd, float step,
 {
        Cloth *cloth= clmd->clothObject;
        BVHTree *cloth_bvh;
-       unsigned int i=0, numverts = 0;
+       unsigned int i = 0, mvert_num = 0;
        ClothVertex *verts = NULL;
        
        ColliderContacts *collider_contacts;
@@ -1353,16 +1316,16 @@ void cloth_find_point_contacts(Object *ob, ClothModifierData *clmd, float step,
        unsigned int numcollobj = 0;
        
        verts = cloth->verts;
-       numverts = cloth->numverts;
+       mvert_num = cloth->mvert_num;
        
        ////////////////////////////////////////////////////////////
        // static collisions
        ////////////////////////////////////////////////////////////
        
        // create temporary cloth points bvh
-       cloth_bvh = BLI_bvhtree_new(numverts, MAX2(clmd->coll_parms->epsilon, clmd->coll_parms->distance_repel), 4, 6);
+       cloth_bvh = BLI_bvhtree_new(mvert_num, max_ff(clmd->coll_parms->epsilon, clmd->coll_parms->distance_repel), 4, 6);
        /* fill tree */
-       for (i = 0; i < numverts; i++) {
+       for (i = 0; i < mvert_num; i++) {
                float co[6];
                
                copy_v3_v3(&co[0*3], verts[i].x);
@@ -1442,7 +1405,7 @@ void cloth_find_point_contacts(Object *ob, ClothModifierData *clmd, float step,
        ////////////////////////////////////////////////////////////
        
        // verts come from clmd
-       for (i = 0; i < numverts; i++) {
+       for (i = 0; i < mvert_num; i++) {
                if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) {
                        if (verts [i].flags & CLOTH_VERT_FLAG_PINNED) {
                                continue;
index 89db2dd45a975a94f0ce7a90043dc481fcc18ee8..e340a0ade9435e7fb3c9b3ffb9755230c5aac301 100644 (file)
@@ -2477,10 +2477,6 @@ static int collision_sphere_to_edges(ParticleCollision *col, float radius, Parti
        int i;
 
        for (i=0; i<3; i++) {
-               /* in case of a quad, no need to check "edge" that goes through face twice */
-               if ((pce->x[3] && i==2))
-                       continue;
-
                cur = edge+i;
                cur->x[0] = pce->x[i]; cur->x[1] = pce->x[(i+1)%3];
                cur->v[0] = pce->v[i]; cur->v[1] = pce->v[(i+1)%3];
@@ -2524,10 +2520,6 @@ static int collision_sphere_to_verts(ParticleCollision *col, float radius, Parti
        int i;
 
        for (i=0; i<3; i++) {
-               /* in case of quad, only check one vert the first time */
-               if (pce->x[3] && i != 1)
-                       continue;
-
                cur = vert+i;
                cur->x[0] = pce->x[i];
                cur->v[0] = pce->v[i];
@@ -2555,21 +2547,19 @@ void BKE_psys_collision_neartest_cb(void *userdata, int index, const BVHTreeRay
 {
        ParticleCollision *col = (ParticleCollision *) userdata;
        ParticleCollisionElement pce;
-       MFace *face = col->md->mfaces + index;
+       const MVertTri *vt = &col->md->tri[index];
        MVert *x = col->md->x;
        MVert *v = col->md->current_v;
        float t = hit->dist/col->original_ray_length;
        int collision = 0;
 
-       pce.x[0] = x[face->v1].co;
-       pce.x[1] = x[face->v2].co;
-       pce.x[2] = x[face->v3].co;
-       pce.x[3] = face->v4 ? x[face->v4].co : NULL;
+       pce.x[0] = x[vt->tri[0]].co;
+       pce.x[1] = x[vt->tri[1]].co;
+       pce.x[2] = x[vt->tri[2]].co;
 
-       pce.v[0] = v[face->v1].co;
-       pce.v[1] = v[face->v2].co;
-       pce.v[2] = v[face->v3].co;
-       pce.v[3] = face->v4 ? v[face->v4].co : NULL;
+       pce.v[0] = v[vt->tri[0]].co;
+       pce.v[1] = v[vt->tri[1]].co;
+       pce.v[2] = v[vt->tri[2]].co;
 
        pce.tot = 3;
        pce.inside = 0;
@@ -2579,31 +2569,20 @@ void BKE_psys_collision_neartest_cb(void *userdata, int index, const BVHTreeRay
        if (col->hit == col->current && col->pce.index == index && col->pce.tot == 3)
                return;
 
-       do {
-               collision = collision_sphere_to_tri(col, ray->radius, &pce, &t);
-               if (col->pce.inside == 0) {
-                       collision += collision_sphere_to_edges(col, ray->radius, &pce, &t);
-                       collision += collision_sphere_to_verts(col, ray->radius, &pce, &t);
-               }
-
-               if (collision) {
-                       hit->dist = col->original_ray_length * t;
-                       hit->index = index;
-                               
-                       collision_point_velocity(&col->pce);
-
-                       col->hit = col->current;
-               }
+       collision = collision_sphere_to_tri(col, ray->radius, &pce, &t);
+       if (col->pce.inside == 0) {
+               collision += collision_sphere_to_edges(col, ray->radius, &pce, &t);
+               collision += collision_sphere_to_verts(col, ray->radius, &pce, &t);
+       }
 
-               pce.x[1] = pce.x[2];
-               pce.x[2] = pce.x[3];
-               pce.x[3] = NULL;
+       if (collision) {
+               hit->dist = col->original_ray_length * t;
+               hit->index = index;
 
-               pce.v[1] = pce.v[2];
-               pce.v[2] = pce.v[3];
-               pce.v[3] = NULL;
+               collision_point_velocity(&col->pce);
 
-       } while (pce.x[2]);
+               col->hit = col->current;
+       }
 }
 static int collision_detect(ParticleData *pa, ParticleCollision *col, BVHTreeRayHit *hit, ListBase *colliders)
 {
index 2f4a45828eaef02005aee0b69a964401116763c1..c6ea9e0f4f8523fb09aafa0660879e77987cd9cc 100644 (file)
@@ -543,7 +543,7 @@ static void ptcache_cloth_interpolate(int index, void *cloth_v, void **data, flo
 static int  ptcache_cloth_totpoint(void *cloth_v, int UNUSED(cfra))
 {
        ClothModifierData *clmd= cloth_v;
-       return clmd->clothObject ? clmd->clothObject->numverts : 0;
+       return clmd->clothObject ? clmd->clothObject->mvert_num : 0;
 }
 
 static void ptcache_cloth_error(void *cloth_v, const char *message)
index 055c3a86d0e2a5944a902fb021181fd5948624ba..0044c8df29802c541a70214b32c8ffac20310c90 100644 (file)
@@ -171,8 +171,6 @@ static float SoftHeunTol = 1.0f; /* humm .. this should be calculated from sb pa
 
 /* local prototypes */
 static void free_softbody_intern(SoftBody *sb);
-/* aye this belongs to arith.c */
-static void Vec3PlusStVec(float *v, float s, float *v1);
 
 /*+++ frame based timing +++*/
 
@@ -276,10 +274,10 @@ typedef struct ccdf_minmax {
 
 
 typedef struct ccd_Mesh {
-       int totvert, totface;
-       MVert *mvert;
-       MVert *mprevvert;
-       MFace *mface;
+       int mvert_num, tri_num;
+       const MVert *mvert;
+       const MVert *mprevvert;
+       const MVertTri *tri;
        int savety;
        ccdf_minmax *mima;
        /* Axis Aligned Bounding Box AABB */
@@ -294,26 +292,25 @@ static ccd_Mesh *ccd_mesh_make(Object *ob)
 {
        CollisionModifierData *cmd;
        ccd_Mesh *pccd_M = NULL;
-       ccdf_minmax *mima = NULL;
-       MFace *mface=NULL;
-       float v[3], hull;
+       ccdf_minmax *mima;
+       const MVertTri *vt;
+       float hull;
        int i;
 
        cmd =(CollisionModifierData *)modifiers_findByType(ob, eModifierType_Collision);
 
        /* first some paranoia checks */
        if (!cmd) return NULL;
-       if (!cmd->numverts || !cmd->numfaces) return NULL;
+       if (!cmd->mvert_num || !cmd->tri_num) return NULL;
 
        pccd_M = MEM_mallocN(sizeof(ccd_Mesh), "ccd_Mesh");
-       pccd_M->totvert = cmd->numverts;
-       pccd_M->totface = cmd->numfaces;
+       pccd_M->mvert_num = cmd->mvert_num;
+       pccd_M->tri_num = cmd->tri_num;
        pccd_M->savety  = CCD_SAVETY;
        pccd_M->bbmin[0]=pccd_M->bbmin[1]=pccd_M->bbmin[2]=1e30f;
        pccd_M->bbmax[0]=pccd_M->bbmax[1]=pccd_M->bbmax[2]=-1e30f;
        pccd_M->mprevvert=NULL;
 
-
        /* blow it up with forcefield ranges */
        hull = max_ff(ob->pd->pdef_sbift, ob->pd->pdef_sboft);
 
@@ -321,9 +318,11 @@ static ccd_Mesh *ccd_mesh_make(Object *ob)
        pccd_M->mvert = MEM_dupallocN(cmd->xnew);
        /* note that xnew coords are already in global space, */
        /* determine the ortho BB */
-       for (i=0; i < pccd_M->totvert; i++) {
+       for (i = 0; i < pccd_M->mvert_num; i++) {
+               const float *v;
+
                /* evaluate limits */
-               copy_v3_v3(v, pccd_M->mvert[i].co);
+               v = pccd_M->mvert[i].co;
                pccd_M->bbmin[0] = min_ff(pccd_M->bbmin[0], v[0] - hull);
                pccd_M->bbmin[1] = min_ff(pccd_M->bbmin[1], v[1] - hull);
                pccd_M->bbmin[2] = min_ff(pccd_M->bbmin[2], v[2] - hull);
@@ -334,20 +333,20 @@ static ccd_Mesh *ccd_mesh_make(Object *ob)
 
        }
        /* alloc and copy faces*/
-       pccd_M->mface = MEM_dupallocN(cmd->mfaces);
+       pccd_M->tri = MEM_dupallocN(cmd->tri);
 
        /* OBBs for idea1 */
-       pccd_M->mima = MEM_mallocN(sizeof(ccdf_minmax)*pccd_M->totface, "ccd_Mesh_Faces_mima");
-       mima  = pccd_M->mima;
-       mface = pccd_M->mface;
+       pccd_M->mima = MEM_mallocN(sizeof(ccdf_minmax) * pccd_M->tri_num, "ccd_Mesh_Faces_mima");
 
 
        /* anyhoo we need to walk the list of faces and find OBB they live in */
-       for (i=0; i < pccd_M->totface; i++) {
+       for (i = 0, mima  = pccd_M->mima, vt = pccd_M->tri; i < pccd_M->tri_num; i++, mima++, vt++) {
+               const float *v;
+
                mima->minx=mima->miny=mima->minz=1e30f;
                mima->maxx=mima->maxy=mima->maxz=-1e30f;
 
-               copy_v3_v3(v, pccd_M->mvert[mface->v1].co);
+               v = pccd_M->mvert[vt->tri[0]].co;
                mima->minx = min_ff(mima->minx, v[0] - hull);
                mima->miny = min_ff(mima->miny, v[1] - hull);
                mima->minz = min_ff(mima->minz, v[2] - hull);
@@ -355,7 +354,7 @@ static ccd_Mesh *ccd_mesh_make(Object *ob)
                mima->maxy = max_ff(mima->maxy, v[1] + hull);
                mima->maxz = max_ff(mima->maxz, v[2] + hull);
 
-               copy_v3_v3(v, pccd_M->mvert[mface->v2].co);
+               v = pccd_M->mvert[vt->tri[1]].co;
                mima->minx = min_ff(mima->minx, v[0] - hull);
                mima->miny = min_ff(mima->miny, v[1] - hull);
                mima->minz = min_ff(mima->minz, v[2] - hull);
@@ -363,26 +362,13 @@ static ccd_Mesh *ccd_mesh_make(Object *ob)
                mima->maxy = max_ff(mima->maxy, v[1] + hull);
                mima->maxz = max_ff(mima->maxz, v[2] + hull);
 
-               copy_v3_v3(v, pccd_M->mvert[mface->v3].co);
+               v = pccd_M->mvert[vt->tri[2]].co;
                mima->minx = min_ff(mima->minx, v[0] - hull);
                mima->miny = min_ff(mima->miny, v[1] - hull);
                mima->minz = min_ff(mima->minz, v[2] - hull);
                mima->maxx = max_ff(mima->maxx, v[0] + hull);
                mima->maxy = max_ff(mima->maxy, v[1] + hull);
                mima->maxz = max_ff(mima->maxz, v[2] + hull);
-
-               if (mface->v4) {
-                       copy_v3_v3(v, pccd_M->mvert[mface->v4].co);
-                       mima->minx = min_ff(mima->minx, v[0] - hull);
-                       mima->miny = min_ff(mima->miny, v[1] - hull);
-                       mima->minz = min_ff(mima->minz, v[2] - hull);
-                       mima->maxx = max_ff(mima->maxx, v[0] + hull);
-                       mima->maxy = max_ff(mima->maxy, v[1] + hull);
-                       mima->maxz = max_ff(mima->maxz, v[2] + hull);
-               }
-
-               mima++;
-               mface++;
        }
 
        return pccd_M;
@@ -390,19 +376,19 @@ static ccd_Mesh *ccd_mesh_make(Object *ob)
 static void ccd_mesh_update(Object *ob, ccd_Mesh *pccd_M)
 {
        CollisionModifierData *cmd;
-       ccdf_minmax *mima = NULL;
-       MFace *mface=NULL;
-       float v[3], hull;
+       ccdf_minmax *mima;
+       const MVertTri *vt;
+       float hull;
        int i;
 
        cmd =(CollisionModifierData *)modifiers_findByType(ob, eModifierType_Collision);
 
        /* first some paranoia checks */
        if (!cmd) return;
-       if (!cmd->numverts || !cmd->numfaces) return;
+       if (!cmd->mvert_num || !cmd->tri_num) return;
 
-       if ((pccd_M->totvert != cmd->numverts) ||
-           (pccd_M->totface != cmd->numfaces))
+       if ((pccd_M->mvert_num != cmd->mvert_num) ||
+           (pccd_M->tri_num != cmd->tri_num))
        {
                return;
        }
@@ -415,15 +401,17 @@ static void ccd_mesh_update(Object *ob, ccd_Mesh *pccd_M)
        hull = max_ff(ob->pd->pdef_sbift, ob->pd->pdef_sboft);
 
        /* rotate current to previous */
-       if (pccd_M->mprevvert) MEM_freeN(pccd_M->mprevvert);
+       if (pccd_M->mprevvert) MEM_freeN((void *)pccd_M->mprevvert);
        pccd_M->mprevvert = pccd_M->mvert;
        /* alloc and copy verts*/
        pccd_M->mvert = MEM_dupallocN(cmd->xnew);
        /* note that xnew coords are already in global space, */
        /* determine the ortho BB */
-       for (i=0; i < pccd_M->totvert; i++) {
+       for (i=0; i < pccd_M->mvert_num; i++) {
+               const float *v;
+
                /* evaluate limits */
-               copy_v3_v3(v, pccd_M->mvert[i].co);
+               v = pccd_M->mvert[i].co;
                pccd_M->bbmin[0] = min_ff(pccd_M->bbmin[0], v[0] - hull);
                pccd_M->bbmin[1] = min_ff(pccd_M->bbmin[1], v[1] - hull);
                pccd_M->bbmin[2] = min_ff(pccd_M->bbmin[2], v[2] - hull);
@@ -433,7 +421,7 @@ static void ccd_mesh_update(Object *ob, ccd_Mesh *pccd_M)
                pccd_M->bbmax[2] = max_ff(pccd_M->bbmax[2], v[2] + hull);
 
                /* evaluate limits */
-               copy_v3_v3(v, pccd_M->mprevvert[i].co);
+               v = pccd_M->mprevvert[i].co;
                pccd_M->bbmin[0] = min_ff(pccd_M->bbmin[0], v[0] - hull);
                pccd_M->bbmin[1] = min_ff(pccd_M->bbmin[1], v[1] - hull);
                pccd_M->bbmin[2] = min_ff(pccd_M->bbmin[2], v[2] - hull);
@@ -444,16 +432,15 @@ static void ccd_mesh_update(Object *ob, ccd_Mesh *pccd_M)
 
        }
 
-       mima  = pccd_M->mima;
-       mface = pccd_M->mface;
-
-
        /* anyhoo we need to walk the list of faces and find OBB they live in */
-       for (i=0; i < pccd_M->totface; i++) {
+       for (i = 0, mima  = pccd_M->mima, vt = pccd_M->tri; i < pccd_M->tri_num; i++, mima++, vt++) {
+               const float *v;
+
                mima->minx=mima->miny=mima->minz=1e30f;
                mima->maxx=mima->maxy=mima->maxz=-1e30f;
 
-               copy_v3_v3(v, pccd_M->mvert[mface->v1].co);
+               /* mvert */
+               v = pccd_M->mvert[vt->tri[0]].co;
                mima->minx = min_ff(mima->minx, v[0] - hull);
                mima->miny = min_ff(mima->miny, v[1] - hull);
                mima->minz = min_ff(mima->minz, v[2] - hull);
@@ -461,7 +448,7 @@ static void ccd_mesh_update(Object *ob, ccd_Mesh *pccd_M)
                mima->maxy = max_ff(mima->maxy, v[1] + hull);
                mima->maxz = max_ff(mima->maxz, v[2] + hull);
 
-               copy_v3_v3(v, pccd_M->mvert[mface->v2].co);
+               v = pccd_M->mvert[vt->tri[1]].co;
                mima->minx = min_ff(mima->minx, v[0] - hull);
                mima->miny = min_ff(mima->miny, v[1] - hull);
                mima->minz = min_ff(mima->minz, v[2] - hull);
@@ -469,7 +456,7 @@ static void ccd_mesh_update(Object *ob, ccd_Mesh *pccd_M)
                mima->maxy = max_ff(mima->maxy, v[1] + hull);
                mima->maxz = max_ff(mima->maxz, v[2] + hull);
 
-               copy_v3_v3(v, pccd_M->mvert[mface->v3].co);
+               v = pccd_M->mvert[vt->tri[2]].co;
                mima->minx = min_ff(mima->minx, v[0] - hull);
                mima->miny = min_ff(mima->miny, v[1] - hull);
                mima->minz = min_ff(mima->minz, v[2] - hull);
@@ -477,18 +464,9 @@ static void ccd_mesh_update(Object *ob, ccd_Mesh *pccd_M)
                mima->maxy = max_ff(mima->maxy, v[1] + hull);
                mima->maxz = max_ff(mima->maxz, v[2] + hull);
 
-               if (mface->v4) {
-                       copy_v3_v3(v, pccd_M->mvert[mface->v4].co);
-                       mima->minx = min_ff(mima->minx, v[0] - hull);
-                       mima->miny = min_ff(mima->miny, v[1] - hull);
-                       mima->minz = min_ff(mima->minz, v[2] - hull);
-                       mima->maxx = max_ff(mima->maxx, v[0] + hull);
-                       mima->maxy = max_ff(mima->maxy, v[1] + hull);
-                       mima->maxz = max_ff(mima->maxz, v[2] + hull);
-               }
-
 
-               copy_v3_v3(v, pccd_M->mprevvert[mface->v1].co);
+               /* mprevvert */
+               v = pccd_M->mprevvert[vt->tri[0]].co;
                mima->minx = min_ff(mima->minx, v[0] - hull);
                mima->miny = min_ff(mima->miny, v[1] - hull);
                mima->minz = min_ff(mima->minz, v[2] - hull);
@@ -496,7 +474,7 @@ static void ccd_mesh_update(Object *ob, ccd_Mesh *pccd_M)
                mima->maxy = max_ff(mima->maxy, v[1] + hull);
                mima->maxz = max_ff(mima->maxz, v[2] + hull);
 
-               copy_v3_v3(v, pccd_M->mprevvert[mface->v2].co);
+               v = pccd_M->mprevvert[vt->tri[1]].co;
                mima->minx = min_ff(mima->minx, v[0] - hull);
                mima->miny = min_ff(mima->miny, v[1] - hull);
                mima->minz = min_ff(mima->minz, v[2] - hull);
@@ -504,26 +482,13 @@ static void ccd_mesh_update(Object *ob, ccd_Mesh *pccd_M)
                mima->maxy = max_ff(mima->maxy, v[1] + hull);
                mima->maxz = max_ff(mima->maxz, v[2] + hull);
 
-               copy_v3_v3(v, pccd_M->mprevvert[mface->v3].co);
+               v = pccd_M->mprevvert[vt->tri[2]].co;
                mima->minx = min_ff(mima->minx, v[0] - hull);
                mima->miny = min_ff(mima->miny, v[1] - hull);
                mima->minz = min_ff(mima->minz, v[2] - hull);
                mima->maxx = max_ff(mima->maxx, v[0] + hull);
                mima->maxy = max_ff(mima->maxy, v[1] + hull);
                mima->maxz = max_ff(mima->maxz, v[2] + hull);
-
-               if (mface->v4) {
-                       copy_v3_v3(v, pccd_M->mprevvert[mface->v4].co);
-                       mima->minx = min_ff(mima->minx, v[0] - hull);
-                       mima->miny = min_ff(mima->miny, v[1] - hull);
-                       mima->minz = min_ff(mima->minz, v[2] - hull);
-                       mima->maxx = max_ff(mima->maxx, v[0] + hull);
-                       mima->maxy = max_ff(mima->maxy, v[1] + hull);
-                       mima->maxz = max_ff(mima->maxz, v[2] + hull);
-               }
-
-               mima++;
-               mface++;
        }
        return;
 }
@@ -531,9 +496,9 @@ static void ccd_mesh_update(Object *ob, ccd_Mesh *pccd_M)
 static void ccd_mesh_free(ccd_Mesh *ccdm)
 {
        if (ccdm && (ccdm->savety == CCD_SAVETY )) { /*make sure we're not nuking objects we don't know*/
-               MEM_freeN(ccdm->mface);
-               MEM_freeN(ccdm->mvert);
-               if (ccdm->mprevvert) MEM_freeN(ccdm->mprevvert);
+               MEM_freeN((void *)ccdm->mvert);
+               MEM_freeN((void *)ccdm->tri);
+               if (ccdm->mprevvert) MEM_freeN((void *)ccdm->mprevvert);
                MEM_freeN(ccdm->mima);
                MEM_freeN(ccdm);
                ccdm = NULL;
@@ -982,14 +947,6 @@ static void free_softbody_intern(SoftBody *sb)
 ** since that would only valid for 'slow' moving collision targets and dito particles
 */
 
-/* aye this belongs to arith.c */
-static void Vec3PlusStVec(float *v, float s, float *v1)
-{
-       v[0] += s*v1[0];
-       v[1] += s*v1[1];
-       v[2] += s*v1[2];
-}
-
 /* +++ dependency information functions*/
 
 static int are_there_deflectors(Scene *scene, unsigned int layer)
@@ -1119,11 +1076,11 @@ static int sb_detect_face_pointCached(float face_v1[3], float face_v2[3], float
                {
                        /* only with deflecting set */
                        if (ob->pd && ob->pd->deflect) {
-                               MVert *mvert= NULL;
-                               MVert *mprevvert= NULL;
+                               const MVert *mvert= NULL;
+                               const MVert *mprevvert= NULL;
                                if (ccdm) {
-                                       mvert= ccdm->mvert;
-                                       a    = ccdm->totvert;
+                                       mvert = ccdm->mvert;
+                                       a     = ccdm->mvert_num;
                                        mprevvert= ccdm->mprevvert;
                                        outerfacethickness = ob->pd->pdef_sboft;
                                        if ((aabbmax[0] < ccdm->bbmin[0]) ||
@@ -1153,7 +1110,7 @@ static int sb_detect_face_pointCached(float face_v1[3], float face_v2[3], float
                                                copy_v3_v3(nv1, mvert[a-1].co);
                                                if (mprevvert) {
                                                        mul_v3_fl(nv1, time);
-                                                       Vec3PlusStVec(nv1, (1.0f-time), mprevvert[a-1].co);
+                                                       madd_v3_v3fl(nv1, mprevvert[a - 1].co, 1.0f - time);
                                                }
                                                /* origin to face_v2*/
                                                sub_v3_v3(nv1, face_v2);
@@ -1171,7 +1128,7 @@ static int sb_detect_face_pointCached(float face_v1[3], float face_v2[3], float
                                                                *damp=df*tune*ob->pd->pdef_sbdamp;
 
                                                                df = 0.01f * expf(-100.0f * df);
-                                                               Vec3PlusStVec(force, -df, d_nvect);
+                                                               madd_v3_v3fl(force, d_nvect, -df);
                                                                deflected = 3;
                                                        }
                                                }
@@ -1193,7 +1150,7 @@ static int sb_detect_face_collisionCached(float face_v1[3], float face_v2[3], fl
        Object *ob;
        GHash *hash;
        GHashIterator *ihash;
-       float nv1[3], nv2[3], nv3[3], nv4[3], edge1[3], edge2[3], d_nvect[3], aabbmin[3], aabbmax[3];
+       float nv1[3], nv2[3], nv3[3], edge1[3], edge2[3], d_nvect[3], aabbmin[3], aabbmax[3];
        float t, tune = 10.0f;
        int a, deflected=0;
 
@@ -1213,16 +1170,17 @@ static int sb_detect_face_collisionCached(float face_v1[3], float face_v2[3], fl
                {
                        /* only with deflecting set */
                        if (ob->pd && ob->pd->deflect) {
-                               MFace *mface= NULL;
-                               MVert *mvert= NULL;
-                               MVert *mprevvert= NULL;
-                               ccdf_minmax *mima= NULL;
+                               const MVert *mvert = NULL;
+                               const MVert *mprevvert = NULL;
+                               const MVertTri *vt = NULL;
+                               const ccdf_minmax *mima = NULL;
+
                                if (ccdm) {
-                                       mface= ccdm->mface;
-                                       mvert= ccdm->mvert;
-                                       mprevvert= ccdm->mprevvert;
-                                       mima= ccdm->mima;
-                                       a = ccdm->totface;
+                                       mvert = ccdm->mvert;
+                                       vt = ccdm->tri;
+                                       mprevvert = ccdm->mprevvert;
+                                       mima = ccdm->mima;
+                                       a = ccdm->tri_num;
 
                                        if ((aabbmax[0] < ccdm->bbmin[0]) ||
                                            (aabbmax[1] < ccdm->bbmin[1]) ||
@@ -1247,42 +1205,34 @@ static int sb_detect_face_collisionCached(float face_v1[3], float face_v2[3], fl
 
                                /* use mesh*/
                                while (a--) {
-                                       if (
-                                               (aabbmax[0] < mima->minx) ||
-                                               (aabbmin[0] > mima->maxx) ||
-                                               (aabbmax[1] < mima->miny) ||
-                                               (aabbmin[1] > mima->maxy) ||
-                                               (aabbmax[2] < mima->minz) ||
-                                               (aabbmin[2] > mima->maxz)
-                                               ) {
-                                               mface++;
+                                       if ((aabbmax[0] < mima->minx) ||
+                                           (aabbmin[0] > mima->maxx) ||
+                                           (aabbmax[1] < mima->miny) ||
+                                           (aabbmin[1] > mima->maxy) ||
+                                           (aabbmax[2] < mima->minz) ||
+                                           (aabbmin[2] > mima->maxz))
+                                       {
                                                mima++;
+                                               vt++;
                                                continue;
                                        }
 
 
                                        if (mvert) {
 
-                                               copy_v3_v3(nv1, mvert[mface->v1].co);
-                                               copy_v3_v3(nv2, mvert[mface->v2].co);
-                                               copy_v3_v3(nv3, mvert[mface->v3].co);
-                                               if (mface->v4) {
-                                                       copy_v3_v3(nv4, mvert[mface->v4].co);
-                                               }
+                                               copy_v3_v3(nv1, mvert[vt->tri[0]].co);
+                                               copy_v3_v3(nv2, mvert[vt->tri[1]].co);
+                                               copy_v3_v3(nv3, mvert[vt->tri[2]].co);
+
                                                if (mprevvert) {
                                                        mul_v3_fl(nv1, time);
-                                                       Vec3PlusStVec(nv1, (1.0f-time), mprevvert[mface->v1].co);
+                                                       madd_v3_v3fl(nv1, mprevvert[vt->tri[0]].co, 1.0f - time);
 
                                                        mul_v3_fl(nv2, time);
-                                                       Vec3PlusStVec(nv2, (1.0f-time), mprevvert[mface->v2].co);
+                                                       madd_v3_v3fl(nv2, mprevvert[vt->tri[1]].co, 1.0f - time);
 
                                                        mul_v3_fl(nv3, time);
-                                                       Vec3PlusStVec(nv3, (1.0f-time), mprevvert[mface->v3].co);
-
-                                                       if (mface->v4) {
-                                                               mul_v3_fl(nv4, time);
-                                                               Vec3PlusStVec(nv4, (1.0f-time), mprevvert[mface->v4].co);
-                                                       }
+                                                       madd_v3_v3fl(nv3, mprevvert[vt->tri[2]].co, 1.0f - time);
                                                }
                                        }
 
@@ -1291,32 +1241,16 @@ static int sb_detect_face_collisionCached(float face_v1[3], float face_v2[3], fl
                                        sub_v3_v3v3(edge2, nv3, nv2);
                                        cross_v3_v3v3(d_nvect, edge2, edge1);
                                        normalize_v3(d_nvect);
-                                       if (
-                                               isect_line_tri_v3(nv1, nv2, face_v1, face_v2, face_v3, &t, NULL) ||
-                                               isect_line_tri_v3(nv2, nv3, face_v1, face_v2, face_v3, &t, NULL) ||
-                                               isect_line_tri_v3(nv3, nv1, face_v1, face_v2, face_v3, &t, NULL) ) {
-                                               Vec3PlusStVec(force, -0.5f, d_nvect);
+                                       if (isect_line_tri_v3(nv1, nv2, face_v1, face_v2, face_v3, &t, NULL) ||
+                                           isect_line_tri_v3(nv2, nv3, face_v1, face_v2, face_v3, &t, NULL) ||
+                                           isect_line_tri_v3(nv3, nv1, face_v1, face_v2, face_v3, &t, NULL) )
+                                       {
+                                               madd_v3_v3fl(force, d_nvect, -0.5f);
                                                *damp=tune*ob->pd->pdef_sbdamp;
                                                deflected = 2;
                                        }
-                                       if (mface->v4) { /* quad */
-                                               /* switch origin to be nv4 */
-                                               sub_v3_v3v3(edge1, nv3, nv4);
-                                               sub_v3_v3v3(edge2, nv1, nv4);
-                                               cross_v3_v3v3(d_nvect, edge2, edge1);
-                                               normalize_v3(d_nvect);
-                                               if (
-                                                       /* isect_line_tri_v3(nv1, nv3, face_v1, face_v2, face_v3, &t, NULL) ||
-                                                        * we did that edge already */
-                                                       isect_line_tri_v3(nv3, nv4, face_v1, face_v2, face_v3, &t, NULL) ||
-                                                       isect_line_tri_v3(nv4, nv1, face_v1, face_v2, face_v3, &t, NULL) ) {
-                                                       Vec3PlusStVec(force, -0.5f, d_nvect);
-                                                       *damp=tune*ob->pd->pdef_sbdamp;
-                                                       deflected = 2;
-                                               }
-                                       }
-                                       mface++;
                                        mima++;
+                                       vt++;
                                }/* while a */
                        } /* if (ob->pd && ob->pd->deflect) */
                        BLI_ghashIterator_step(ihash);
@@ -1345,26 +1279,15 @@ static void scan_for_ext_face_forces(Object *ob, float timenow)
                        bf->ext_force[0]=bf->ext_force[1]=bf->ext_force[2]=0.0f;
 /*+++edges intruding*/
                        bf->flag &= ~BFF_INTERSECT;
-                       feedback[0]=feedback[1]=feedback[2]=0.0f;
-                       if (sb_detect_face_collisionCached(sb->bpoint[bf->v1].pos, sb->bpoint[bf->v2].pos, sb->bpoint[bf->v3].pos,
-                                                          &damp, feedback, ob->lay, ob, timenow))
+                       zero_v3(feedback);
+                       if (sb_detect_face_collisionCached(
+                               sb->bpoint[bf->v1].pos, sb->bpoint[bf->v2].pos, sb->bpoint[bf->v3].pos,
+                               &damp, feedback, ob->lay, ob, timenow))
                        {
-                               Vec3PlusStVec(sb->bpoint[bf->v1].force, tune, feedback);
-                               Vec3PlusStVec(sb->bpoint[bf->v2].force, tune, feedback);
-                               Vec3PlusStVec(sb->bpoint[bf->v3].force, tune, feedback);
-//                             Vec3PlusStVec(bf->ext_force, tune, feedback);
-                               bf->flag |= BFF_INTERSECT;
-                               choke = min_ff(max_ff(damp, choke), 1.0f);
-                       }
-
-                       feedback[0]=feedback[1]=feedback[2]=0.0f;
-                       if ((bf->v4) && (sb_detect_face_collisionCached(sb->bpoint[bf->v1].pos, sb->bpoint[bf->v3].pos, sb->bpoint[bf->v4].pos,
-                                                                       &damp, feedback, ob->lay, ob, timenow)))
-                       {
-                               Vec3PlusStVec(sb->bpoint[bf->v1].force, tune, feedback);
-                               Vec3PlusStVec(sb->bpoint[bf->v3].force, tune, feedback);
-                               Vec3PlusStVec(sb->bpoint[bf->v4].force, tune, feedback);
-//                             Vec3PlusStVec(bf->ext_force, tune, feedback);
+                               madd_v3_v3fl(sb->bpoint[bf->v1].force, feedback, tune);
+                               madd_v3_v3fl(sb->bpoint[bf->v2].force, feedback, tune);
+                               madd_v3_v3fl(sb->bpoint[bf->v3].force, feedback, tune);
+//                             madd_v3_v3fl(bf->ext_force, feedback, tune);
                                bf->flag |= BFF_INTERSECT;
                                choke = min_ff(max_ff(damp, choke), 1.0f);
                        }
@@ -1374,26 +1297,15 @@ static void scan_for_ext_face_forces(Object *ob, float timenow)
                        if (( bf->flag & BFF_INTERSECT)==0) {
                                bf->flag &= ~BFF_CLOSEVERT;
                                tune = -1.0f;
-                               feedback[0]=feedback[1]=feedback[2]=0.0f;
-                               if (sb_detect_face_pointCached(sb->bpoint[bf->v1].pos, sb->bpoint[bf->v2].pos, sb->bpoint[bf->v3].pos,
-                                       &damp,  feedback, ob->lay, ob, timenow))
-                               {
-                                       Vec3PlusStVec(sb->bpoint[bf->v1].force, tune, feedback);
-                                       Vec3PlusStVec(sb->bpoint[bf->v2].force, tune, feedback);
-                                       Vec3PlusStVec(sb->bpoint[bf->v3].force, tune, feedback);
-//                                     Vec3PlusStVec(bf->ext_force, tune, feedback);
-                                       bf->flag |= BFF_CLOSEVERT;
-                                       choke = min_ff(max_ff(damp, choke), 1.0f);
-                               }
-
-                               feedback[0]=feedback[1]=feedback[2]=0.0f;
-                               if ((bf->v4) && (sb_detect_face_pointCached(sb->bpoint[bf->v1].pos, sb->bpoint[bf->v3].pos, sb->bpoint[bf->v4].pos,
-                                                                           &damp, feedback, ob->lay, ob, timenow)))
+                               zero_v3(feedback);
+                               if (sb_detect_face_pointCached(
+                                       sb->bpoint[bf->v1].pos, sb->bpoint[bf->v2].pos, sb->bpoint[bf->v3].pos,
+                                       &damp,  feedback, ob->lay, ob, timenow))
                                {
-                                       Vec3PlusStVec(sb->bpoint[bf->v1].force, tune, feedback);
-                                       Vec3PlusStVec(sb->bpoint[bf->v3].force, tune, feedback);
-                                       Vec3PlusStVec(sb->bpoint[bf->v4].force, tune, feedback);
-//                                     Vec3PlusStVec(bf->ext_force, tune, feedback);
+                                       madd_v3_v3fl(sb->bpoint[bf->v1].force, feedback, tune);
+                                       madd_v3_v3fl(sb->bpoint[bf->v2].force, feedback, tune);
+                                       madd_v3_v3fl(sb->bpoint[bf->v3].force, feedback, tune);
+//                                     madd_v3_v3fl(bf->ext_force, feedback, tune);
                                        bf->flag |= BFF_CLOSEVERT;
                                        choke = min_ff(max_ff(damp, choke), 1.0f);
                                }
@@ -1406,9 +1318,6 @@ static void scan_for_ext_face_forces(Object *ob, float timenow)
                                sb->bpoint[bf->v1].choke2 = max_ff(sb->bpoint[bf->v1].choke2, choke);
                                sb->bpoint[bf->v2].choke2 = max_ff(sb->bpoint[bf->v2].choke2, choke);
                                sb->bpoint[bf->v3].choke2 = max_ff(sb->bpoint[bf->v3].choke2, choke);
-                               if (bf->v4) {
-                                       sb->bpoint[bf->v2].choke2 = max_ff(sb->bpoint[bf->v2].choke2, choke);
-                               }
                        }
                }
        }
@@ -1425,7 +1334,7 @@ static int sb_detect_edge_collisionCached(float edge_v1[3], float edge_v2[3], fl
        Object *ob;
        GHash *hash;
        GHashIterator *ihash;
-       float nv1[3], nv2[3], nv3[3], nv4[3], edge1[3], edge2[3], d_nvect[3], aabbmin[3], aabbmax[3];
+       float nv1[3], nv2[3], nv3[3], edge1[3], edge2[3], d_nvect[3], aabbmin[3], aabbmax[3];
        float t, el;
        int a, deflected=0;
 
@@ -1443,16 +1352,17 @@ static int sb_detect_edge_collisionCached(float edge_v1[3], float edge_v2[3], fl
                {
                        /* only with deflecting set */
                        if (ob->pd && ob->pd->deflect) {
-                               MFace *mface= NULL;
-                               MVert *mvert= NULL;
-                               MVert *mprevvert= NULL;
-                               ccdf_minmax *mima= NULL;
+                               const MVert *mvert = NULL;
+                               const MVert *mprevvert = NULL;
+                               const MVertTri *vt = NULL;
+                               const ccdf_minmax *mima = NULL;
+
                                if (ccdm) {
-                                       mface= ccdm->mface;
-                                       mvert= ccdm->mvert;
-                                       mprevvert= ccdm->mprevvert;
-                                       mima= ccdm->mima;
-                                       a = ccdm->totface;
+                                       mvert = ccdm->mvert;
+                                       mprevvert = ccdm->mprevvert;
+                                       vt = ccdm->tri;
+                                       mima = ccdm->mima;
+                                       a = ccdm->tri_num;
 
                                        if ((aabbmax[0] < ccdm->bbmin[0]) ||
                                            (aabbmax[1] < ccdm->bbmin[1]) ||
@@ -1477,43 +1387,34 @@ static int sb_detect_edge_collisionCached(float edge_v1[3], float edge_v2[3], fl
 
                                /* use mesh*/
                                while (a--) {
-                                       if (
-                                               (aabbmax[0] < mima->minx) ||
-                                               (aabbmin[0] > mima->maxx) ||
-                                               (aabbmax[1] < mima->miny) ||
-                                               (aabbmin[1] > mima->maxy) ||
-                                               (aabbmax[2] < mima->minz) ||
-                                               (aabbmin[2] > mima->maxz)
-                                               )
+                                       if ((aabbmax[0] < mima->minx) ||
+                                           (aabbmin[0] > mima->maxx) ||
+                                           (aabbmax[1] < mima->miny) ||
+                                           (aabbmin[1] > mima->maxy) ||
+                                           (aabbmax[2] < mima->minz) ||
+                                           (aabbmin[2] > mima->maxz))
                                        {
-                                               mface++;
                                                mima++;
+                                               vt++;
                                                continue;
                                        }
 
 
                                        if (mvert) {
 
-                                               copy_v3_v3(nv1, mvert[mface->v1].co);
-                                               copy_v3_v3(nv2, mvert[mface->v2].co);
-                                               copy_v3_v3(nv3, mvert[mface->v3].co);
-                                               if (mface->v4) {
-                                                       copy_v3_v3(nv4, mvert[mface->v4].co);
-                                               }
+                                               copy_v3_v3(nv1, mvert[vt->tri[0]].co);
+                                               copy_v3_v3(nv2, mvert[vt->tri[1]].co);
+                                               copy_v3_v3(nv3, mvert[vt->tri[2]].co);
+
                                                if (mprevvert) {
                                                        mul_v3_fl(nv1, time);
-                                                       Vec3PlusStVec(nv1, (1.0f-time), mprevvert[mface->v1].co);
+                                                       madd_v3_v3fl(nv1, mprevvert[vt->tri[0]].co, 1.0f - time);
 
                                                        mul_v3_fl(nv2, time);
-                                                       Vec3PlusStVec(nv2, (1.0f-time), mprevvert[mface->v2].co);
+                                                       madd_v3_v3fl(nv2, mprevvert[vt->tri[1]].co, 1.0f - time);
 
                                                        mul_v3_fl(nv3, time);
-                                                       Vec3PlusStVec(nv3, (1.0f-time), mprevvert[mface->v3].co);
-
-                                                       if (mface->v4) {
-                                                               mul_v3_fl(nv4, time);
-                                                               Vec3PlusStVec(nv4, (1.0f-time), mprevvert[mface->v4].co);
-                                                       }
+                                                       madd_v3_v3fl(nv3, mprevvert[vt->tri[2]].co, 1.0f - time);
                                                }
                                        }
 
@@ -1531,34 +1432,13 @@ static int sb_detect_edge_collisionCached(float edge_v1[3], float edge_v2[3], fl
                                                i1 = dot_v3v3(v1, d_nvect);
                                                i2 = dot_v3v3(v2, d_nvect);
                                                intrusiondepth = -min_ff(i1, i2) / el;
-                                               Vec3PlusStVec(force, intrusiondepth, d_nvect);
+                                               madd_v3_v3fl(force, d_nvect, intrusiondepth);
                                                *damp=ob->pd->pdef_sbdamp;
                                                deflected = 2;
                                        }
-                                       if (mface->v4) { /* quad */
-                                               /* switch origin to be nv4 */
-                                               sub_v3_v3v3(edge1, nv3, nv4);
-                                               sub_v3_v3v3(edge2, nv1, nv4);
-
-                                               cross_v3_v3v3(d_nvect, edge2, edge1);
-                                               normalize_v3(d_nvect);
-                                               if (isect_line_tri_v3( edge_v1, edge_v2, nv1, nv3, nv4, &t, NULL)) {
-                                                       float v1[3], v2[3];
-                                                       float intrusiondepth, i1, i2;
-                                                       sub_v3_v3v3(v1, edge_v1, nv4);
-                                                       sub_v3_v3v3(v2, edge_v2, nv4);
-                                                       i1 = dot_v3v3(v1, d_nvect);
-                                                       i2 = dot_v3v3(v2, d_nvect);
-                                                       intrusiondepth = -min_ff(i1, i2) / el;
-
-
-                                                       Vec3PlusStVec(force, intrusiondepth, d_nvect);
-                                                       *damp=ob->pd->pdef_sbdamp;
-                                                       deflected = 2;
-                                               }
-                                       }
-                                       mface++;
+
                                        mima++;
+                                       vt++;
                                }/* while a */
                        } /* if (ob->pd && ob->pd->deflect) */
                        BLI_ghashIterator_step(ihash);
@@ -1629,10 +1509,10 @@ static void _scan_for_ext_spring_forces(Scene *scene, Object *ob, float timenow,
                                        normalize_v3(vel);
                                        if (ob->softflag & OB_SB_AERO_ANGLE) {
                                                normalize_v3(sp);
-                                               Vec3PlusStVec(bs->ext_force, f * (1.0f - fabsf(dot_v3v3(vel, sp))), vel);
+                                               madd_v3_v3fl(bs->ext_force, vel, f * (1.0f - fabsf(dot_v3v3(vel, sp))));
                                        }
                                        else {
-                                               Vec3PlusStVec(bs->ext_force, f, vel); // to keep compatible with 2.45 release files
+                                               madd_v3_v3fl(bs->ext_force, vel, f); // to keep compatible with 2.45 release files
                                        }
                                }
                                /* --- springs seeing wind */
@@ -1745,15 +1625,16 @@ static int choose_winner(float*w, float* pos, float*a, float*b, float*c, float*c
 
 
 
-static int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3], float *damp,
-                                                                        float force[3], unsigned int UNUSED(par_layer), struct Object *vertexowner,
-                                                                        float time, float vel[3], float *intrusion)
+static int sb_detect_vertex_collisionCached(
+        float opco[3], float facenormal[3], float *damp,
+        float force[3], unsigned int UNUSED(par_layer), struct Object *vertexowner,
+        float time, float vel[3], float *intrusion)
 {
        Object *ob= NULL;
        GHash *hash;
        GHashIterator *ihash;
-       float nv1[3], nv2[3], nv3[3], nv4[3], edge1[3], edge2[3], d_nvect[3], dv1[3], ve[3], avel[3] = {0.0, 0.0, 0.0},
-             vv1[3], vv2[3], vv3[3], vv4[3], coledge[3] = {0.0f, 0.0f, 0.0f}, mindistedge = 1000.0f,
+       float nv1[3], nv2[3], nv3[3], edge1[3], edge2[3], d_nvect[3], dv1[3], ve[3], avel[3] = {0.0, 0.0, 0.0},
+             vv1[3], vv2[3], vv3[3], coledge[3] = {0.0f, 0.0f, 0.0f}, mindistedge = 1000.0f,
              outerforceaccu[3], innerforceaccu[3],
              facedist, /* n_mag, */ /* UNUSED */ force_mag_norm, minx, miny, minz, maxx, maxy, maxz,
              innerfacethickness = -0.5f, outerfacethickness = 0.2f,
@@ -1773,17 +1654,17 @@ static int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3],
                {
                        /* only with deflecting set */
                        if (ob->pd && ob->pd->deflect) {
-                               MFace *mface= NULL;
-                               MVert *mvert= NULL;
-                               MVert *mprevvert= NULL;
-                               ccdf_minmax *mima= NULL;
+                               const MVert *mvert = NULL;
+                               const MVert *mprevvert = NULL;
+                               const MVertTri *vt = NULL;
+                               const ccdf_minmax *mima = NULL;
 
                                if (ccdm) {
-                                       mface= ccdm->mface;
-                                       mvert= ccdm->mvert;
-                                       mprevvert= ccdm->mprevvert;
-                                       mima= ccdm->mima;
-                                       a = ccdm->totface;
+                                       mvert = ccdm->mvert;
+                                       mprevvert = ccdm->mprevvert;
+                                       vt = ccdm->tri;
+                                       mima = ccdm->mima;
+                                       a = ccdm->tri_num;
 
                                        minx = ccdm->bbmin[0];
                                        miny = ccdm->bbmin[1];
@@ -1822,27 +1703,23 @@ static int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3],
                                avel[0]=avel[1]=avel[2]=0.0f;
                                /* use mesh*/
                                while (a--) {
-                                       if (
-                                               (opco[0] < mima->minx) ||
-                                               (opco[0] > mima->maxx) ||
-                                               (opco[1] < mima->miny) ||
-                                               (opco[1] > mima->maxy) ||
-                                               (opco[2] < mima->minz) ||
-                                               (opco[2] > mima->maxz)
-                                               ) {
-                                                       mface++;
-                                                       mima++;
-                                                       continue;
+                                       if ((opco[0] < mima->minx) ||
+                                           (opco[0] > mima->maxx) ||
+                                           (opco[1] < mima->miny) ||
+                                           (opco[1] > mima->maxy) ||
+                                           (opco[2] < mima->minz) ||
+                                           (opco[2] > mima->maxz))
+                                       {
+                                               mima++;
+                                               vt++;
+                                               continue;
                                        }
 
                                        if (mvert) {
 
-                                               copy_v3_v3(nv1, mvert[mface->v1].co);
-                                               copy_v3_v3(nv2, mvert[mface->v2].co);
-                                               copy_v3_v3(nv3, mvert[mface->v3].co);
-                                               if (mface->v4) {
-                                                       copy_v3_v3(nv4, mvert[mface->v4].co);
-                                               }
+                                               copy_v3_v3(nv1, mvert[vt->tri[0]].co);
+                                               copy_v3_v3(nv2, mvert[vt->tri[1]].co);
+                                               copy_v3_v3(nv3, mvert[vt->tri[2]].co);
 
                                                if (mprevvert) {
                                                        /* grab the average speed of the collider vertices
@@ -1851,26 +1728,18 @@ static int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3],
                                                        since the AABB reduced propabitlty to get here drasticallly
                                                        it might be a nice tradeof CPU <--> memory
                                                        */
-                                                       sub_v3_v3v3(vv1, nv1, mprevvert[mface->v1].co);
-                                                       sub_v3_v3v3(vv2, nv2, mprevvert[mface->v2].co);
-                                                       sub_v3_v3v3(vv3, nv3, mprevvert[mface->v3].co);
-                                                       if (mface->v4) {
-                                                               sub_v3_v3v3(vv4, nv4, mprevvert[mface->v4].co);
-                                                       }
+                                                       sub_v3_v3v3(vv1, nv1, mprevvert[vt->tri[0]].co);
+                                                       sub_v3_v3v3(vv2, nv2, mprevvert[vt->tri[1]].co);
+                                                       sub_v3_v3v3(vv3, nv3, mprevvert[vt->tri[2]].co);
 
                                                        mul_v3_fl(nv1, time);
-                                                       Vec3PlusStVec(nv1, (1.0f-time), mprevvert[mface->v1].co);
+                                                       madd_v3_v3fl(nv1, mprevvert[vt->tri[0]].co, 1.0f - time);
 
                                                        mul_v3_fl(nv2, time);
-                                                       Vec3PlusStVec(nv2, (1.0f-time), mprevvert[mface->v2].co);
+                                                       madd_v3_v3fl(nv2, mprevvert[vt->tri[1]].co, 1.0f - time);
 
                                                        mul_v3_fl(nv3, time);
-                                                       Vec3PlusStVec(nv3, (1.0f-time), mprevvert[mface->v3].co);
-
-                                                       if (mface->v4) {
-                                                               mul_v3_fl(nv4, time);
-                                                               Vec3PlusStVec(nv4, (1.0f-time), mprevvert[mface->v4].co);
-                                                       }
+                                                       madd_v3_v3fl(nv3, mprevvert[vt->tri[2]].co, 1.0f - time);
                                                }
                                        }
 
@@ -1893,12 +1762,12 @@ static int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3],
                                                        *damp=ob->pd->pdef_sbdamp;
                                                        if (facedist > 0.0f) {
                                                                *damp *= (1.0f - facedist/outerfacethickness);
-                                                               Vec3PlusStVec(outerforceaccu, force_mag_norm, d_nvect);
+                                                               madd_v3_v3fl(outerforceaccu, d_nvect, force_mag_norm);
                                                                deflected = 3;
 
                                                        }
                                                        else {
-                                                               Vec3PlusStVec(innerforceaccu, force_mag_norm, d_nvect);
+                                                               madd_v3_v3fl(innerforceaccu, d_nvect, force_mag_norm);
                                                                if (deflected < 2) deflected = 2;
                                                        }
                                                        if ((mprevvert) && (*damp > 0.0f)) {
@@ -1910,99 +1779,9 @@ static int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3],
                                                        ci++;
                                                }
                                        }
-                                       if (mface->v4) { /* quad */
-                                               /* switch origin to be nv4 */
-                                               sub_v3_v3v3(edge1, nv3, nv4);
-                                               sub_v3_v3v3(edge2, nv1, nv4);
-                                               sub_v3_v3v3(dv1, opco, nv4); /* abuse dv1 to have vertex in question at *origin* of triangle */
-
-                                               cross_v3_v3v3(d_nvect, edge2, edge1);
-                                               /* n_mag = */ /* UNUSED */ normalize_v3(d_nvect);
-                                               facedist = dot_v3v3(dv1, d_nvect);
-
-                                               if ((facedist > innerfacethickness) && (facedist < outerfacethickness)) {
-                                                       if (isect_point_tri_prism_v3(opco, nv1, nv3, nv4) ) {
-                                                               force_mag_norm =(float)exp(-ee*facedist);
-                                                               if (facedist > outerfacethickness*ff)
-                                                                       force_mag_norm =(float)force_mag_norm*fa*(facedist - outerfacethickness)*(facedist - outerfacethickness);
-                                                               *damp=ob->pd->pdef_sbdamp;
-                                                               if (facedist > 0.0f) {
-                                                                       *damp *= (1.0f - facedist/outerfacethickness);
-                                                                       Vec3PlusStVec(outerforceaccu, force_mag_norm, d_nvect);
-                                                                       deflected = 3;
-
-                                                               }
-                                                               else {
-                                                                       Vec3PlusStVec(innerforceaccu, force_mag_norm, d_nvect);
-                                                                       if (deflected < 2) deflected = 2;
-                                                               }
-
-                                                               if ((mprevvert) && (*damp > 0.0f)) {
-                                                                       choose_winner(ve, opco, nv1, nv3, nv4, vv1, vv3, vv4);
-                                                                       add_v3_v3(avel, ve);
-                                                                       cavel ++;
-                                                               }
-                                                               *intrusion += facedist;
-                                                               ci++;
-                                                       }
-
-                                               }
-                                               if ((deflected < 2)&& (G.debug_value != 444)) { /* we did not hit a face until now */
-                                                       /* see if 'outer' hits an edge */
-                                                       float dist;
-
-                                                       closest_to_line_segment_v3(ve, opco, nv1, nv2);
-                                                       sub_v3_v3v3(ve, opco, ve);
-                                                       dist = normalize_v3(ve);
-                                                       if ((dist < outerfacethickness)&&(dist < mindistedge )) {
-                                                               copy_v3_v3(coledge, ve);
-                                                               mindistedge = dist,
-                                                               deflected=1;
-                                                       }
 
-                                                       closest_to_line_segment_v3(ve, opco, nv2, nv3);
-                                                       sub_v3_v3v3(ve, opco, ve);
-                                                       dist = normalize_v3(ve);
-                                                       if ((dist < outerfacethickness)&&(dist < mindistedge )) {
-                                                               copy_v3_v3(coledge, ve);
-                                                               mindistedge = dist,
-                                                               deflected=1;
-                                                       }
-
-                                                       closest_to_line_segment_v3(ve, opco, nv3, nv1);
-                                                       sub_v3_v3v3(ve, opco, ve);
-                                                       dist = normalize_v3(ve);
-                                                       if ((dist < outerfacethickness)&&(dist < mindistedge )) {
-                                                               copy_v3_v3(coledge, ve);
-                                                               mindistedge = dist,
-                                                               deflected=1;
-                                                       }
-                                                       if (mface->v4) { /* quad */
-                                                               closest_to_line_segment_v3(ve, opco, nv3, nv4);
-                                                               sub_v3_v3v3(ve, opco, ve);
-                                                               dist = normalize_v3(ve);
-                                                               if ((dist < outerfacethickness)&&(dist < mindistedge )) {
-                                                                       copy_v3_v3(coledge, ve);
-                                                                       mindistedge = dist,
-                                                                               deflected=1;
-                                                               }
-
-                                                               closest_to_line_segment_v3(ve, opco, nv1, nv4);
-                                                               sub_v3_v3v3(ve, opco, ve);
-                                                               dist = normalize_v3(ve);
-                                                               if ((dist < outerfacethickness)&&(dist < mindistedge )) {
-                                                                       copy_v3_v3(coledge, ve);
-                                                                       mindistedge = dist,
-                                                                               deflected=1;
-                                                               }
-
-                                                       }
-
-
-                                               }
-                                       }
-                                       mface++;
                                        mima++;
+                                       vt++;
                                }/* while a */
                        } /* if (ob->pd && ob->pd->deflect) */
                        BLI_ghashIterator_step(ihash);
@@ -2013,7 +1792,7 @@ static int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3],
                force_mag_norm =(float)exp(-ee*mindistedge);
                if (mindistedge > outerfacethickness*ff)
                        force_mag_norm =(float)force_mag_norm*fa*(mindistedge - outerfacethickness)*(mindistedge - outerfacethickness);
-               Vec3PlusStVec(force, force_mag_norm, coledge);
+               madd_v3_v3fl(force, coledge, force_mag_norm);
                *damp=ob->pd->pdef_sbdamp;
                if (mindistedge > 0.0f) {
                        *damp *= (1.0f - mindistedge/outerfacethickness);
@@ -2149,7 +1928,7 @@ static void sb_spring_force(Object *ob, int bpi, BodySpring *bs, float iks, floa
        }
 
 
-       Vec3PlusStVec(bp1->force, (bs->len - distance)*forcefactor, dir);
+       madd_v3_v3fl(bp1->force, dir, (bs->len - distance) * forcefactor);
 
        /* do bp1 <--> bp2 viscous */
        sub_v3_v3v3(dvel, bp1->vec, bp2->vec);
@@ -2157,7 +1936,7 @@ static void sb_spring_force(Object *ob, int bpi, BodySpring *bs, float iks, floa
        absvel  = normalize_v3(dvel);
        projvel = dot_v3v3(dir, dvel);
        kd     *= absvel * projvel;
-       Vec3PlusStVec(bp1->force, -kd, dir);
+       madd_v3_v3fl(bp1->force, dir, -kd);
 
        /* do jacobian stuff if needed */
        if (nl_flags & NLF_BUILD) {
@@ -2250,15 +2029,15 @@ static int _softbody_calc_forces_slice_in_a_thread(Scene *scene, Object *ob, flo
                                                sub_v3_v3v3(dvel, velcenter, bp->vec);
                                                mul_v3_fl(dvel, _final_mass(ob, bp));
 
-                                               Vec3PlusStVec(bp->force, f*(1.0f-sb->balldamp), def);
-                                               Vec3PlusStVec(bp->force, sb->balldamp, dvel);
+                                               madd_v3_v3fl(bp->force, def, f * (1.0f - sb->balldamp));
+                                               madd_v3_v3fl(bp->force, dvel, sb->balldamp);
 
                                                /* exploit force(a, b) == -force(b, a) part2/2 */
                                                sub_v3_v3v3(dvel, velcenter, obp->vec);
                                                mul_v3_fl(dvel, _final_mass(ob, bp));
 
-                                               Vec3PlusStVec(obp->force, sb->balldamp, dvel);
-                                               Vec3PlusStVec(obp->force, -f*(1.0f-sb->balldamp), def);
+                                               madd_v3_v3fl(obp->force, dvel, sb->balldamp);
+                                               madd_v3_v3fl(obp->force, def, -f * (1.0f - sb->balldamp));
                                        }
                                }
                        }
@@ -2352,9 +2131,9 @@ static int _softbody_calc_forces_slice_in_a_thread(Scene *scene, Object *ob, flo
                                        }
 
                                        sub_v3_v3v3(cfforce, bp->vec, vel);
-                                       Vec3PlusStVec(bp->force, -cf*50.0f, cfforce);
+                                       madd_v3_v3fl(bp->force, cfforce, -cf * 50.0f);
 
-                                       Vec3PlusStVec(bp->force, kd, defforce);
+                                       madd_v3_v3fl(bp->force, defforce, kd);
                                }
 
                        }
@@ -2619,8 +2398,8 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
                                                        sub_v3_v3v3(dvel, velcenter, bp->vec);
                                                        mul_v3_fl(dvel, _final_mass(ob, bp));
 
-                                                       Vec3PlusStVec(bp->force, f*(1.0f-sb->balldamp), def);
-                                                       Vec3PlusStVec(bp->force, sb->balldamp, dvel);
+                                                       madd_v3_v3fl(bp->force, def, f * (1.0f - sb->balldamp));
+                                                       madd_v3_v3fl(bp->force, dvel, sb->balldamp);
 
                                                        if (nl_flags & NLF_BUILD) {
                                                                //int ia =3*(sb->totpoint-a);
@@ -2650,10 +2429,8 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
                                                        sub_v3_v3v3(dvel, velcenter, obp->vec);
                                                        mul_v3_fl(dvel, (_final_mass(ob, bp)+_final_mass(ob, obp))/2.0f);
 
-                                                       Vec3PlusStVec(obp->force, sb->balldamp, dvel);
-                                                       Vec3PlusStVec(obp->force, -f*(1.0f-sb->balldamp), def);
-
-
+                                                       madd_v3_v3fl(obp->force, dvel, sb->balldamp);
+                                                       madd_v3_v3fl(obp->force, def, -f * (1.0f - sb->balldamp));
                                                }
                                        }
                                }
@@ -2771,12 +2548,12 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
                                                                in heun step No1 and leave the heun step No2 adapt to it
                                                                so we kind of introduced a implicit solver for this case
                                                                */
-                                                               Vec3PlusStVec(bp->pos, -intrusion, facenormal);
+                                                               madd_v3_v3fl(bp->pos, facenormal, -intrusion);
                                                        }
                                                        else {
 
                                                                sub_v3_v3v3(cfforce, bp->vec, vel);
-                                                               Vec3PlusStVec(bp->force, -cf*50.0f, cfforce);
+                                                               madd_v3_v3fl(bp->force, cfforce, -cf * 50.0f);
                                                        }
 
 
@@ -2786,9 +2563,9 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
                                                }
                                                else {
                                                        sub_v3_v3v3(cfforce, bp->vec, vel);
-                                                       Vec3PlusStVec(bp->force, -cf*50.0f, cfforce);
+                                                       madd_v3_v3fl(bp->force, cfforce, -cf * 50.0f);
                                                }
-                                               Vec3PlusStVec(bp->force, kd, defforce);
+                                               madd_v3_v3fl(bp->force, defforce, kd);
                                                if (nl_flags & NLF_BUILD) {
                                                        // int ia =3*(sb->totpoint-a);
                                                        // int op =3*sb->totpoint;
index 541b4015a1b922969492bcb23255997f17c3a853..f497c5db4f02c61d3a89c2ac1b11cbf528e90d8c 100644 (file)
@@ -4894,9 +4894,10 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
                        collmd->current_xnew = NULL;
                        collmd->current_v = NULL;
                        collmd->time_x = collmd->time_xnew = -1000;
-                       collmd->numverts = 0;
+                       collmd->mvert_num = 0;
+                       collmd->tri_num = 0;
                        collmd->bvhtree = NULL;
-                       collmd->mfaces = NULL;
+                       collmd->tri = NULL;
                        
                }
                else if (md->type == eModifierType_Surface) {
index 12c6e0ec0a5a35abd78612bc66f5ae8f048e156a..39f1c0d705f1d6130daac6ef9cc740f41dcbe740 100644 (file)
@@ -96,6 +96,12 @@ typedef struct MLoopTri {
        unsigned int tri[3];
        unsigned int poly;
 } MLoopTri;
+#
+#
+typedef struct MVertTri {
+       unsigned int tri[3];
+} MVertTri;
+
 
 typedef struct MTexPoly {
        struct Image *tpage;
index 4db21b24a5a7837e94228a059dff208b8261bdcd..634159e4e60de27e13a33a4464a425752bac25bd 100644 (file)
@@ -612,10 +612,10 @@ typedef struct CollisionModifierData {
        struct MVert *current_x;    /* position at the actual inter-frame step */
        struct MVert *current_v;    /* (xnew - x) at the actual inter-frame step */
 
-       struct MFace *mfaces;       /* object face data */
+       struct MVertTri *tri;
 
-       unsigned int numverts;
-       unsigned int numfaces;
+       unsigned int mvert_num;
+       unsigned int tri_num;
        float time_x, time_xnew;    /* cfra time of modifier */
        struct BVHTree *bvhtree;    /* bounding volume hierarchy for this cloth object */
 } CollisionModifierData;
index 85901771a96ce0d1fd20e4503cd62ee68294a7fa..bebfbbe9a800c8c845ff2bb59765d82abed179c2 100644 (file)
@@ -58,7 +58,8 @@ static void initData(ModifierData *md)
        collmd->current_xnew = NULL;
        collmd->current_v = NULL;
        collmd->time_x = collmd->time_xnew = -1000;
-       collmd->numverts = 0;
+       collmd->mvert_num = 0;
+       collmd->tri_num = 0;
        collmd->bvhtree = NULL;
 }
 
@@ -77,10 +78,15 @@ static void freeData(ModifierData *md)
                MEM_SAFE_FREE(collmd->current_x);
                MEM_SAFE_FREE(collmd->current_xnew);
                MEM_SAFE_FREE(collmd->current_v);
-               MEM_SAFE_FREE(collmd->mfaces);
+
+               if (collmd->tri) {
+                       MEM_freeN((void *)collmd->tri);
+                       collmd->tri = NULL;
+               }
 
                collmd->time_x = collmd->time_xnew = -1000;
-               collmd->numverts = 0;
+               collmd->mvert_num = 0;
+               collmd->tri_num = 0;
        }
 }
 
@@ -110,7 +116,7 @@ static void deformVerts(ModifierData *md, Object *ob,
        
        if (dm) {
                float current_time = 0;
-               unsigned int numverts = 0;
+               unsigned int mvert_num = 0;
 
                CDDM_apply_vert_coords(dm, vertexCos);
                CDDM_calc_normals(dm);
@@ -120,19 +126,20 @@ static void deformVerts(ModifierData *md, Object *ob,
                if (G.debug_value > 0)
                        printf("current_time %f, collmd->time_xnew %f\n", current_time, collmd->time_xnew);
                
-               numverts = dm->getNumVerts(dm);
+               mvert_num = dm->getNumVerts(dm);
                
                if (current_time > collmd->time_xnew) {
                        unsigned int i;
 
                        /* check if mesh has changed */
-                       if (collmd->x && (numverts != collmd->numverts))
+                       if (collmd->x && (mvert_num != collmd->mvert_num))
                                freeData((ModifierData *)collmd);
 
                        if (collmd->time_xnew == -1000) { /* first time */
+
                                collmd->x = dm->dupVertArray(dm); /* frame start position */
 
-                               for (i = 0; i < numverts; i++) {
+                               for (i = 0; i < mvert_num; i++) {
                                        /* we save global positions */
                                        mul_m4_v3(ob->obmat, collmd->x[i].co);
                                }
@@ -142,56 +149,75 @@ static void deformVerts(ModifierData *md, Object *ob,
                                collmd->current_xnew = MEM_dupallocN(collmd->x); // inter-frame
                                collmd->current_v = MEM_dupallocN(collmd->x); // inter-frame
 
-                               collmd->numverts = numverts;
+                               collmd->mvert_num = mvert_num;
                                
-                               DM_ensure_tessface(dm); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */
+                               DM_ensure_looptri(dm);
+
+                               collmd->tri_num = dm->getNumLoopTri(dm);
+                               {
+                                       const MLoop *mloop = dm->getLoopArray(dm);
+                                       const MLoopTri *looptri = dm->getLoopTriArray(dm);
+                                       MVertTri *tri = MEM_mallocN(sizeof(*tri) * collmd->tri_num, __func__);
+                                       DM_verttri_from_looptri(tri, mloop, looptri, collmd->tri_num);
+                                       collmd->tri = tri;
+                               }
 
-                               collmd->mfaces = dm->dupTessFaceArray(dm);
-                               collmd->numfaces = dm->getNumTessFaces(dm);
-                               
                                /* create bounding box hierarchy */
-                               collmd->bvhtree = bvhtree_build_from_mvert(collmd->mfaces, collmd->numfaces, collmd->x, numverts, ob->pd->pdef_sboft);
+                               collmd->bvhtree = bvhtree_build_from_mvert(
+                                       collmd->x,
+                                       collmd->tri, collmd->tri_num,
+                                       ob->pd->pdef_sboft);
 
                                collmd->time_x = collmd->time_xnew = current_time;
                        }
-                       else if (numverts == collmd->numverts) {
+                       else if (mvert_num == collmd->mvert_num) {
                                /* put positions to old positions */
                                tempVert = collmd->x;
                                collmd->x = collmd->xnew;
                                collmd->xnew = tempVert;
                                collmd->time_x = collmd->time_xnew;
 
-                               memcpy(collmd->xnew, dm->getVertArray(dm), numverts * sizeof(MVert));
+                               memcpy(collmd->xnew, dm->getVertArray(dm), mvert_num * sizeof(MVert));
 
-                               for (i = 0; i < numverts; i++) {
+                               for (i = 0; i < mvert_num; i++) {
                                        /* we save global positions */
                                        mul_m4_v3(ob->obmat, collmd->xnew[i].co);
                                }
                                
-                               memcpy(collmd->current_xnew, collmd->x, numverts * sizeof(MVert));
-                               memcpy(collmd->current_x, collmd->x, numverts * sizeof(MVert));
+                               memcpy(collmd->current_xnew, collmd->x, mvert_num * sizeof(MVert));
+                               memcpy(collmd->current_x, collmd->x, mvert_num * sizeof(MVert));
                                
                                /* check if GUI setting has changed for bvh */
                                if (collmd->bvhtree) {
                                        if (ob->pd->pdef_sboft != BLI_bvhtree_getepsilon(collmd->bvhtree)) {
                                                BLI_bvhtree_free(collmd->bvhtree);
-                                               collmd->bvhtree = bvhtree_build_from_mvert(collmd->mfaces, collmd->numfaces, collmd->current_x, numverts, ob->pd->pdef_sboft);
+                                               collmd->bvhtree = bvhtree_build_from_mvert(
+                                                       collmd->current_x,
+                                                       collmd->tri, collmd->tri_num,
+                                                       ob->pd->pdef_sboft);
                                        }
                        
                                }
                                
                                /* happens on file load (ONLY when i decomment changes in readfile.c) */
                                if (!collmd->bvhtree) {
-                                       collmd->bvhtree = bvhtree_build_from_mvert(collmd->mfaces, collmd->numfaces, collmd->current_x, numverts, ob->pd->pdef_sboft);
+                                       collmd->bvhtree = bvhtree_build_from_mvert(
+                                               collmd->current_x,
+                                               collmd->tri, collmd->tri_num,
+                                               ob->pd->pdef_sboft);
                                }
                                else {
                                        /* recalc static bounding boxes */
-                                       bvhtree_update_from_mvert(collmd->bvhtree, collmd->mfaces, collmd->numfaces, collmd->current_x, collmd->current_xnew, collmd->numverts, 1);
+                                       bvhtree_update_from_mvert(
+                                               collmd->bvhtree,
+                                               collmd->current_x, collmd->current_xnew,
+                                               collmd->tri, collmd->tri_num,
+                                               true);
                                }
                                
                                collmd->time_xnew = current_time;
                        }
-                       else if (numverts != collmd->numverts) {
+                       else if (mvert_num != collmd->mvert_num) {
                                freeData((ModifierData *)collmd);
                        }
                        
@@ -200,7 +226,7 @@ static void deformVerts(ModifierData *md, Object *ob,
                        freeData((ModifierData *)collmd);
                }
                else {
-                       if (numverts != collmd->numverts) {
+                       if (mvert_num != collmd->mvert_num) {
                                freeData((ModifierData *)collmd);
                        }
                }
index de5fdd2b81d9af228c9e3d4fb56b1aa62e9a5a7a..c650d83c9274f34c5dcab9a83b802428a92830b4 100644 (file)
@@ -51,6 +51,7 @@ typedef enum eMassSpringSolverStatus {
 
 struct Implicit_Data *BPH_mass_spring_solver_create(int numverts, int numsprings);
 void BPH_mass_spring_solver_free(struct Implicit_Data *id);
+int BPH_mass_spring_solver_numvert(struct Implicit_Data *id);
 
 int BPH_cloth_solver_init(struct Object *ob, struct ClothModifierData *clmd);
 void BPH_cloth_solver_free(struct ClothModifierData *clmd);
index 68cc53eb534c41ccd649a53c778995cfb63fb875..19c3f3793f8d06cafc23b66a92599c71d2685258 100644 (file)
@@ -88,13 +88,13 @@ int BPH_cloth_solver_init(Object *UNUSED(ob), ClothModifierData *clmd)
        unsigned int i, nondiag;\r
        \r
        nondiag = cloth_count_nondiag_blocks(cloth);\r
-       cloth->implicit = id = BPH_mass_spring_solver_create(cloth->numverts, nondiag);\r
+       cloth->implicit = id = BPH_mass_spring_solver_create(cloth->mvert_num, nondiag);\r
        \r
-       for (i = 0; i < cloth->numverts; i++) {\r
+       for (i = 0; i < cloth->mvert_num; i++) {\r
                BPH_mass_spring_set_vertex_mass(id, i, verts[i].mass);\r
        }\r
        \r
-       for (i = 0; i < cloth->numverts; i++) {\r
+       for (i = 0; i < cloth->mvert_num; i++) {\r
                BPH_mass_spring_set_motion_state(id, i, verts[i].x, ZERO);\r
        }\r
        \r
@@ -115,11 +115,11 @@ void BKE_cloth_solver_set_positions(ClothModifierData *clmd)
 {\r
        Cloth *cloth = clmd->clothObject;\r
        ClothVertex *verts = cloth->verts;\r
-       unsigned int numverts = cloth->numverts, i;\r
+       unsigned int mvert_num = cloth->mvert_num, i;\r
        ClothHairData *cloth_hairdata = clmd->hairdata;\r
        Implicit_Data *id = cloth->implicit;\r
        \r
-       for (i = 0; i < numverts; i++) {\r
+       for (i = 0; i < mvert_num; i++) {\r
                if (cloth_hairdata) {\r
                        ClothHairData *root = &cloth_hairdata[i];\r
                        BPH_mass_spring_set_rest_transform(id, i, root->rot);\r
@@ -209,14 +209,14 @@ static void cloth_setup_constraints(ClothModifierData *clmd, ColliderContacts *c
        Cloth *cloth = clmd->clothObject;\r
        Implicit_Data *data = cloth->implicit;\r
        ClothVertex *verts = cloth->verts;\r
-       int numverts = cloth->numverts;\r
+       int mvert_num = cloth->mvert_num;\r
        int i, j, v;\r
        \r
        const float ZERO[3] = {0.0f, 0.0f, 0.0f};\r
        \r
        BPH_mass_spring_clear_constraints(data);\r
        \r
-       for (v = 0; v < numverts; v++) {\r
+       for (v = 0; v < mvert_num; v++) {\r
                if (verts[v].flags & CLOTH_VERT_FLAG_PINNED) {\r
                        /* pinned vertex constraints */\r
                        BPH_mass_spring_add_constraint_ndof0(data, v, ZERO); /* velocity is defined externally */\r
@@ -261,15 +261,15 @@ static void cloth_setup_constraints(ClothModifierData *clmd, ColliderContacts *c
 static int UNUSED_FUNCTION(cloth_calc_helper_forces)(Object *UNUSED(ob), ClothModifierData *clmd, float (*initial_cos)[3], float UNUSED(step), float dt)\r
 {\r
        Cloth *cloth= clmd->clothObject;\r
-       float (*cos)[3] = (float (*)[3])MEM_callocN(sizeof(float)*3*cloth->numverts, "cos cloth_calc_helper_forces");\r
-       float *masses = (float *)MEM_callocN(sizeof(float)*cloth->numverts, "cos cloth_calc_helper_forces");\r
+       float (*cos)[3] = (float (*)[3])MEM_callocN(sizeof(float[3]) * cloth->mvert_num, "cos cloth_calc_helper_forces");\r
+       float *masses = (float *)MEM_callocN(sizeof(float) * cloth->mvert_num, "cos cloth_calc_helper_forces");\r
        LinkNode *node;\r
        ClothSpring *spring;\r
        ClothVertex *cv;\r
        int i, steps;\r
        \r
        cv = cloth->verts;\r
-       for (i=0; i<cloth->numverts; i++, cv++) {\r
+       for (i = 0; i < cloth->mvert_num; i++, cv++) {\r
                copy_v3_v3(cos[i], cv->tx);\r
                \r
                if (cv->goal == 1.0f || len_squared_v3v3(initial_cos[i], cv->tx) != 0.0f) {\r
@@ -317,7 +317,7 @@ static int UNUSED_FUNCTION(cloth_calc_helper_forces)(Object *UNUSED(ob), ClothMo
        }\r
        \r
        cv = cloth->verts;\r
-       for (i=0; i<cloth->numverts; i++, cv++) {\r
+       for (i = 0; i < cloth->mvert_num; i++, cv++) {\r
                float vec[3];\r
                \r
                /*compute forces*/\r
@@ -444,11 +444,11 @@ static void hair_get_boundbox(ClothModifierData *clmd, float gmin[3], float gmax
 {\r
        Cloth *cloth = clmd->clothObject;\r
        Implicit_Data *data = cloth->implicit;\r
-       unsigned int numverts = cloth->numverts;\r
+       unsigned int looptri_num = cloth->tri_num;\r
        int i;\r
        \r
        INIT_MINMAX(gmin, gmax);\r
-       for (i = 0; i < numverts; i++) {\r
+       for (i = 0; i < looptri_num; i++) {\r
                float x[3];\r
                BPH_mass_spring_get_motion_state(data, i, x, NULL);\r
                DO_MINMAX(x, gmin, gmax);\r
@@ -463,8 +463,8 @@ static void cloth_calc_force(ClothModifierData *clmd, float UNUSED(frame), ListB
        unsigned int i  = 0;\r
        float           drag    = clmd->sim_parms->Cvi * 0.01f; /* viscosity of air scaled in percent */\r
        float           gravity[3] = {0.0f, 0.0f, 0.0f};\r
-       MFace           *mfaces         = cloth->mfaces;\r
-       unsigned int numverts = cloth->numverts;\r
+       const MVertTri *tri     = cloth->tri;\r
+       unsigned int mvert_num = cloth->mvert_num;\r
        ClothVertex *vert;\r
        \r
 #ifdef CLOTH_FORCE_GRAVITY\r
@@ -474,7 +474,7 @@ static void cloth_calc_force(ClothModifierData *clmd, float UNUSED(frame), ListB
                mul_v3_v3fl(gravity, clmd->scene->physics_settings.gravity, 0.001f * clmd->sim_parms->effector_weights->global_gravity);\r
        }\r
        vert = cloth->verts;\r
-       for (i = 0; i < cloth->numverts; i++, vert++) {\r
+       for (i = 0; i < cloth->mvert_num; i++, vert++) {\r
                BPH_mass_spring_force_gravity(data, i, vert->mass, gravity);\r
        }\r
 #endif\r
@@ -488,8 +488,8 @@ static void cloth_calc_force(ClothModifierData *clmd, float UNUSED(frame), ListB
        /* handle external forces like wind */\r
        if (effectors) {\r
                /* cache per-vertex forces to avoid redundant calculation */\r
-               float (*winvec)[3] = (float (*)[3])MEM_callocN(sizeof(float) * 3 * numverts, "effector forces");\r
-               for (i = 0; i < cloth->numverts; i++) {\r
+               float (*winvec)[3] = (float (*)[3])MEM_callocN(sizeof(float[3]) * mvert_num, "effector forces");\r
+               for (i = 0; i < cloth->mvert_num; i++) {\r
                        float x[3], v[3];\r
                        EffectedPoint epoint;\r
                        \r
@@ -498,13 +498,13 @@ static void cloth_calc_force(ClothModifierData *clmd, float UNUSED(frame), ListB
                        pdDoEffectors(effectors, NULL, clmd->sim_parms->effector_weights, &epoint, winvec[i], NULL);\r
                }\r
                \r
-               for (i = 0; i < cloth->numfaces; i++) {\r
-                       MFace *mf = &mfaces[i];\r
-                       BPH_mass_spring_force_face_wind(data, mf->v1, mf->v2, mf->v3, mf->v4, winvec);\r
+               for (i = 0; i < cloth->tri_num; i++) {\r
+                       const MVertTri *vt = &tri[i];\r
+                       BPH_mass_spring_force_face_wind(data, vt->tri[0], vt->tri[1], vt->tri[2], winvec);\r
                }\r
 \r
                /* Hair has only edges */\r
-               if (cloth->numfaces == 0) {\r
+               if (cloth->tri_num == 0) {\r
 #if 0\r
                        ClothHairData *hairdata = clmd->hairdata;\r
                        ClothHairData *hair_ij, *hair_kl;\r
@@ -525,7 +525,7 @@ static void cloth_calc_force(ClothModifierData *clmd, float UNUSED(frame), ListB
                        ClothHairData *hairdata = clmd->hairdata;\r
                        \r
                        vert = cloth->verts;\r
-                       for (i = 0; i < cloth->numverts; i++, vert++) {\r
+                       for (i = 0; i < cloth->mvert_num; i++, vert++) {\r
                                if (hairdata) {\r
                                        ClothHairData *hair = &hairdata[i];\r
                                        BPH_mass_spring_force_vertex_wind(data, i, hair->radius, winvec);\r
@@ -650,11 +650,11 @@ static void cloth_continuum_fill_grid(HairGrid *grid, Cloth *cloth)
 {\r
 #if 0\r
        Implicit_Data *data = cloth->implicit;\r
-       int numverts = cloth->numverts;\r
+       int mvert_num = cloth->mvert_num;\r
        ClothVertex *vert;\r
        int i;\r
        \r
-       for (i = 0, vert = cloth->verts; i < numverts; i++, vert++) {\r
+       for (i = 0, vert = cloth->verts; i < mvert_num; i++, vert++) {\r
                float x[3], v[3];\r
                \r
                cloth_get_vertex_motion_state(data, vert, x, v);\r
@@ -689,7 +689,7 @@ static void cloth_continuum_step(ClothModifierData *clmd, float dt)
        ClothSimSettings *parms = clmd->sim_parms;\r
        Cloth *cloth = clmd->clothObject;\r
        Implicit_Data *data = cloth->implicit;\r
-       int numverts = cloth->numverts;\r
+       int mvert_num = cloth->mvert_num;\r
        ClothVertex *vert;\r
        \r
        const float fluid_factor = 0.95f; /* blend between PIC and FLIP methods */\r
@@ -719,7 +719,7 @@ static void cloth_continuum_step(ClothModifierData *clmd, float dt)
                /* main hair continuum solver */\r
                BPH_hair_volume_solve_divergence(grid, dt, density_target, density_strength);\r
                \r
-               for (i = 0, vert = cloth->verts; i < numverts; i++, vert++) {\r
+               for (i = 0, vert = cloth->verts; i < mvert_num; i++, vert++) {\r
                        float x[3], v[3], nv[3];\r
                        \r
                        /* calculate volumetric velocity influence */\r
@@ -799,7 +799,7 @@ static void cloth_calc_volume_force(ClothModifierData *clmd)
        ClothSimSettings *parms = clmd->sim_parms;\r
        Cloth *cloth = clmd->clothObject;\r
        Implicit_Data *data = cloth->implicit;\r
-       int numverts = cloth->numverts;\r
+       int mvert_num = cloth->mvert_num;\r
        ClothVertex *vert;\r
        \r
        /* 2.0f is an experimental value that seems to give good results */\r
@@ -817,7 +817,7 @@ static void cloth_calc_volume_force(ClothModifierData *clmd)
                HairVertexGrid *vertex_grid = BPH_hair_volume_create_vertex_grid(clmd->sim_parms->voxel_res, gmin, gmax);\r
                \r
                vert = cloth->verts;\r
-               for (i = 0; i < numverts; i++, vert++) {\r
+               for (i = 0; i < mvert_num; i++, vert++) {\r
                        float x[3], v[3];\r
                        \r
                        if (vert->solver_index < 0) {\r
@@ -832,7 +832,7 @@ static void cloth_calc_volume_force(ClothModifierData *clmd)
                BPH_hair_volume_normalize_vertex_grid(vertex_grid);\r
                \r
                vert = cloth->verts;\r
-               for (i = 0; i < numverts; i++, vert++) {\r
+               for (i = 0; i < mvert_num; i++, vert++) {\r
                        float x[3], v[3], f[3], dfdx[3][3], dfdv[3][3];\r
                        \r
                        if (vert->solver_index < 0)\r
@@ -858,7 +858,7 @@ static void cloth_collision_solve_extra(Object *ob, ClothModifierData *clmd, Lis
        Cloth *cloth = clmd->clothObject;\r
        Implicit_Data *id = cloth->implicit;\r
        ClothVertex *verts = cloth->verts;\r
-       int numverts = cloth->numverts;\r
+       int mvert_num = cloth->mvert_num;\r
        const float spf = (float)clmd->sim_parms->stepsPerFrame / clmd->sim_parms->timescale;\r
        \r
        bool do_extra_solve;\r
@@ -870,7 +870,7 @@ static void cloth_collision_solve_extra(Object *ob, ClothModifierData *clmd, Lis
                return;\r
        \r
        // update verts to current positions\r
-       for (i = 0; i < numverts; i++) {\r
+       for (i = 0; i < mvert_num; i++) {\r
                BPH_mass_spring_get_new_position(id, i, verts[i].tx);\r
                \r
                sub_v3_v3v3(verts[i].tv, verts[i].tx, verts[i].txold);\r
@@ -878,7 +878,7 @@ static void cloth_collision_solve_extra(Object *ob, ClothModifierData *clmd, Lis
        }\r
        \r
 #if 0 /* unused */\r
-       for (i=0, cv=cloth->verts; i<cloth->numverts; i++, cv++) {\r
+       for (i=0, cv=cloth->verts; i<cloth->mvert_num; i++, cv++) {\r
                copy_v3_v3(initial_cos[i], cv->tx);\r
        }\r
 #endif\r
@@ -888,7 +888,7 @@ static void cloth_collision_solve_extra(Object *ob, ClothModifierData *clmd, Lis
        do_extra_solve = cloth_bvh_objcollision(ob, clmd, step / clmd->sim_parms->timescale, dt / clmd->sim_parms->timescale);\r
        \r
        // copy corrected positions back to simulation\r
-       for (i = 0; i < numverts; i++) {\r
+       for (i = 0; i < mvert_num; i++) {\r
                float curx[3];\r
                BPH_mass_spring_get_position(id, i, curx);\r
                // correct velocity again, just to be sure we had to change it due to adaptive collisions\r
@@ -898,7 +898,7 @@ static void cloth_collision_solve_extra(Object *ob, ClothModifierData *clmd, Lis
        if (do_extra_solve) {\r
 //             cloth_calc_helper_forces(ob, clmd, initial_cos, step/clmd->sim_parms->timescale, dt/clmd->sim_parms->timescale);\r
                \r
-               for (i = 0; i < numverts; i++) {\r
+               for (i = 0; i < mvert_num; i++) {\r
                \r
                        float newv[3];\r
                        \r
@@ -985,7 +985,7 @@ int BPH_cloth_solve(Object *ob, float frame, ClothModifierData *clmd, ListBase *
        float step=0.0f, tf=clmd->sim_parms->timescale;\r
        Cloth *cloth = clmd->clothObject;\r
        ClothVertex *verts = cloth->verts/*, *cv*/;\r
-       unsigned int numverts = cloth->numverts;\r
+       unsigned int mvert_num = cloth->mvert_num;\r
        float dt = clmd->sim_parms->timescale / clmd->sim_parms->stepsPerFrame;\r
        Implicit_Data *id = cloth->implicit;\r
        ColliderContacts *contacts = NULL;\r
@@ -998,7 +998,7 @@ int BPH_cloth_solve(Object *ob, float frame, ClothModifierData *clmd, ListBase *
        cloth_clear_result(clmd);\r
        \r
        if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) { /* do goal stuff */\r
-               for (i = 0; i < numverts; i++) {\r
+               for (i = 0; i < mvert_num; i++) {\r
                        // update velocities with constrained velocities from pinned verts\r
                        if (verts[i].flags & CLOTH_VERT_FLAG_PINNED) {\r
                                float v[3];\r
@@ -1013,7 +1013,7 @@ int BPH_cloth_solve(Object *ob, float frame, ClothModifierData *clmd, ListBase *
                ImplicitSolverResult result;\r
                \r
                /* copy velocities for collision */\r
-               for (i = 0; i < numverts; i++) {\r
+               for (i = 0; i < mvert_num; i++) {\r
                        BPH_mass_spring_get_motion_state(id, i, NULL, verts[i].tv);\r
                        copy_v3_v3(verts[i].v, verts[i].tv);\r
                }\r
@@ -1038,7 +1038,7 @@ int BPH_cloth_solve(Object *ob, float frame, ClothModifierData *clmd, ListBase *
                // damping velocity for artistic reasons\r
                // this is a bad way to do it, should be removed imo - lukas_t\r
                if (clmd->sim_parms->vel_damping != 1.0f) {\r
-                       for (i = 0; i < numverts; i++) {\r
+                       for (i = 0; i < mvert_num; i++) {\r
                                float v[3];\r
                                BPH_mass_spring_get_motion_state(id, i, NULL, v);\r
                                mul_v3_fl(v, clmd->sim_parms->vel_damping);\r
@@ -1066,7 +1066,7 @@ int BPH_cloth_solve(Object *ob, float frame, ClothModifierData *clmd, ListBase *
                BPH_mass_spring_apply_result(id);\r
                \r
                /* move pinned verts to correct position */\r
-               for (i = 0; i < numverts; i++) {\r
+               for (i = 0; i < mvert_num; i++) {\r
                        if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) {\r
                                if (verts[i].flags & CLOTH_VERT_FLAG_PINNED) {\r
                                        float x[3];\r
@@ -1087,7 +1087,7 @@ int BPH_cloth_solve(Object *ob, float frame, ClothModifierData *clmd, ListBase *
        }\r
        \r
        /* copy results back to cloth data */\r
-       for (i = 0; i < numverts; i++) {\r
+       for (i = 0; i < mvert_num; i++) {\r
                BPH_mass_spring_get_motion_state(id, i, verts[i].x, verts[i].v);\r
                copy_v3_v3(verts[i].txold, verts[i].x);\r
        }\r
index dba1cd11ae05bb83de88bac7a2a4b75ace5d284f..d1a75ca529787cb6e21e5837fb165051f014caa0 100644 (file)
@@ -107,7 +107,7 @@ void BPH_mass_spring_force_drag(struct Implicit_Data *data, float drag);
 /* Custom external force */
 void BPH_mass_spring_force_extern(struct Implicit_Data *data, int i, const float f[3], float dfdx[3][3], float dfdv[3][3]);
 /* Wind force, acting on a face */
-void BPH_mass_spring_force_face_wind(struct Implicit_Data *data, int v1, int v2, int v3, int v4, const float (*winvec)[3]);
+void BPH_mass_spring_force_face_wind(struct Implicit_Data *data, int v1, int v2, int v3, const float (*winvec)[3]);
 /* Wind force, acting on an edge */
 void BPH_mass_spring_force_edge_wind(struct Implicit_Data *data, int v1, int v2, float radius1, float radius2, const float (*winvec)[3]);
 /* Wind force, acting on a vertex */
index 5b1d83a3eef1bf8ef59621cbe26d26f559f819cb..0fd2a1f35cca96dd5433d1dc651c3eb3e4badee5 100644 (file)
@@ -1424,33 +1424,16 @@ static float calc_nor_area_tri(float nor[3], const float v1[3], const float v2[3
        return normalize_v3(nor);
 }
 
-static float calc_nor_area_quad(float nor[3], const float v1[3], const float v2[3], const float v3[3], const float v4[3])
-{
-       float n1[3], n2[3];
-       
-       sub_v3_v3v3(n1, v1, v3);
-       sub_v3_v3v3(n2, v2, v4);
-       
-       cross_v3_v3v3(nor, n1, n2);
-       return normalize_v3(nor);
-}
-
 /* XXX does not support force jacobians yet, since the effector system does not provide them either */
-void BPH_mass_spring_force_face_wind(Implicit_Data *data, int v1, int v2, int v3, int v4, const float (*winvec)[3])
+void BPH_mass_spring_force_face_wind(Implicit_Data *data, int v1, int v2, int v3, const float (*winvec)[3])
 {
        const float effector_scale = 0.02f;
        float win[3], nor[3], area;
        float factor;
        
-       // calculate face normal and area
-       if (v4) {
-               area = calc_nor_area_quad(nor, data->X[v1], data->X[v2], data->X[v3], data->X[v4]);
-               factor = effector_scale * area * 0.25f;
-       }
-       else {
-               area = calc_nor_area_tri(nor, data->X[v1], data->X[v2], data->X[v3]);
-               factor = effector_scale * area / 3.0f;
-       }
+       /* calculate face normal and area */
+       area = calc_nor_area_tri(nor, data->X[v1], data->X[v2], data->X[v3]);
+       factor = effector_scale * area / 3.0f;
        
        world_to_root_v3(data, v1, win, winvec[v1]);
        madd_v3_v3fl(data->F[v1], nor, factor * dot_v3v3(win, nor));
@@ -1460,11 +1443,6 @@ void BPH_mass_spring_force_face_wind(Implicit_Data *data, int v1, int v2, int v3
        
        world_to_root_v3(data, v3, win, winvec[v3]);
        madd_v3_v3fl(data->F[v3], nor, factor * dot_v3v3(win, nor));
-       
-       if (v4) {
-               world_to_root_v3(data, v4, win, winvec[v4]);
-               madd_v3_v3fl(data->F[v4], nor, factor * dot_v3v3(win, nor));
-       }
 }
 
 static void edge_wind_vertex(const float dir[3], float length, float radius, const float wind[3], float f[3], float UNUSED(dfdx[3][3]), float UNUSED(dfdv[3][3]))
index 0ea8ccb0a4953c7ef1d3155b431ef8e2c3e83ef8..64a75083f72c4ed1ef30d64a7266b393e389c404 100644 (file)
@@ -92,7 +92,6 @@ extern "C" {
 typedef float Scalar;
 
 static float I[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
-static float ZERO[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
 
 /* slightly extended Eigen vector class
  * with conversion to/from plain C float array
@@ -786,33 +785,16 @@ static float calc_nor_area_tri(float nor[3], const float v1[3], const float v2[3
        return normalize_v3(nor);
 }
 
-static float calc_nor_area_quad(float nor[3], const float v1[3], const float v2[3], const float v3[3], const float v4[3])
-{
-       float n1[3], n2[3];
-       
-       sub_v3_v3v3(n1, v1, v3);
-       sub_v3_v3v3(n2, v2, v4);
-       
-       cross_v3_v3v3(nor, n1, n2);
-       return normalize_v3(nor);
-}
-
 /* XXX does not support force jacobians yet, since the effector system does not provide them either */
-void BPH_mass_spring_force_face_wind(Implicit_Data *data, int v1, int v2, int v3, int v4, const float (*winvec)[3])
+void BPH_mass_spring_force_face_wind(Implicit_Data *data, int v1, int v2, int v3, const float (*winvec)[3])
 {
        const float effector_scale = 0.02f;
        float win[3], nor[3], area;
        float factor;
        
        // calculate face normal and area
-       if (v4) {
-               area = calc_nor_area_quad(nor, data->X.v3(v1), data->X.v3(v2), data->X.v3(v3), data->X.v3(v4));
-               factor = effector_scale * area * 0.25f;
-       }
-       else {
-               area = calc_nor_area_tri(nor, data->X.v3(v1), data->X.v3(v2), data->X.v3(v3));
-               factor = effector_scale * area / 3.0f;
-       }
+       area = calc_nor_area_tri(nor, data->X.v3(v1), data->X.v3(v2), data->X.v3(v3));
+       factor = effector_scale * area / 3.0f;
        
        world_to_root_v3(data, v1, win, winvec[v1]);
        madd_v3_v3fl(data->F.v3(v1), nor, factor * dot_v3v3(win, nor));
@@ -822,11 +804,6 @@ void BPH_mass_spring_force_face_wind(Implicit_Data *data, int v1, int v2, int v3
        
        world_to_root_v3(data, v3, win, winvec[v3]);
        madd_v3_v3fl(data->F.v3(v3), nor, factor * dot_v3v3(win, nor));
-       
-       if (v4) {
-               world_to_root_v3(data, v4, win, winvec[v4]);
-               madd_v3_v3fl(data->F.v3(v4), nor, factor * dot_v3v3(win, nor));
-       }
 }
 
 void BPH_mass_spring_force_edge_wind(Implicit_Data *data, int v1, int v2, const float (*winvec)[3])