Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Genrich <daniel.genrich@gmx.net>2008-02-12 14:04:58 +0300
committerDaniel Genrich <daniel.genrich@gmx.net>2008-02-12 14:04:58 +0300
commite82484b0bb628a533fc1cd43be804c365d54f3f1 (patch)
tree419a5a24f87b24da2d610c4d29aacd931488ef22
parent695ea7230ad3c2ef16f742f4cdc4247fa58056e9 (diff)
Cloth: New: *simple* (OpenMP enabled) Selfcollisions available
-rw-r--r--source/blender/blenkernel/BKE_cloth.h5
-rw-r--r--source/blender/blenkernel/BKE_collision.h8
-rw-r--r--source/blender/blenkernel/intern/cloth.c158
-rw-r--r--source/blender/blenkernel/intern/collision.c130
-rw-r--r--source/blender/blenkernel/intern/implicit.c8
-rw-r--r--source/blender/blenkernel/intern/kdop.c80
-rw-r--r--source/blender/blenkernel/intern/modifier.c2
-rw-r--r--source/blender/makesdna/DNA_cloth_types.h9
-rw-r--r--source/blender/src/buttons_object.c12
9 files changed, 248 insertions, 164 deletions
diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h
index 19fd0ef4105..8dc84f5945e 100644
--- a/source/blender/blenkernel/BKE_cloth.h
+++ b/source/blender/blenkernel/BKE_cloth.h
@@ -94,10 +94,11 @@ typedef struct ClothVertex
float goal; /* goal, from SB */
float impulse[3]; /* used in collision.c */
unsigned int impulse_count; /* same as above */
- float avg_spring_len; /* average length of connected springs, UNUSED ATM */
+ float avg_spring_len; /* average length of connected springs */
float struct_stiff;
float bend_stiff;
float shear_stiff;
+ int spring_count; /* how many springs attached? */
}
ClothVertex;
@@ -153,7 +154,7 @@ typedef enum
typedef enum
{
CLOTH_COLLSETTINGS_FLAG_ENABLED = ( 1 << 1 ), /* enables cloth - object collisions */
- CLOTH_COLLSETTINGS_FLAG_SELF = ( 1 << 2 ), /* unused */
+ CLOTH_COLLSETTINGS_FLAG_SELF = ( 1 << 2 ), /* enables selfcollisions */
} CLOTH_COLLISIONSETTINGS_FLAGS;
/* Spring types as defined in the paper.*/
diff --git a/source/blender/blenkernel/BKE_collision.h b/source/blender/blenkernel/BKE_collision.h
index 05c8d390ea6..463254b8e4f 100644
--- a/source/blender/blenkernel/BKE_collision.h
+++ b/source/blender/blenkernel/BKE_collision.h
@@ -73,6 +73,8 @@ typedef struct CollisionTree
int count_nodes; // how many nodes are used
int traversed; // how many nodes already traversed until this level?
int isleaf;
+ float alpha; /* for selfcollision */
+ float normal[3]; /* for selfcollision */
}
CollisionTree;
@@ -103,11 +105,11 @@ BVH;
typedef void ( *CM_COLLISION_RESPONSE ) ( ModifierData *md1, ModifierData *md2, CollisionTree *tree1, CollisionTree *tree2 );
// needed for collision.c
-int bvh_traverse ( ModifierData * md1, ModifierData * md2, CollisionTree * tree1, CollisionTree * tree2, float step, CM_COLLISION_RESPONSE collision_response);
-int bvh_traverse_mt ( ModifierData * md1, ModifierData * md2, CollisionTree * tree1, CollisionTree * tree2, float step, CM_COLLISION_RESPONSE collision_response);
-////////////////////////////////////////////////
+int bvh_traverse ( ModifierData * md1, ModifierData * md2, CollisionTree * tree1, CollisionTree * tree2, float step, CM_COLLISION_RESPONSE collision_response, int selfcollision);
+
////////////////////////////////////////
+
////////////////////////////////////////
// used for collisions in kdop.c and also collision.c
////////////////////////////////////////
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index e1e80a62d4c..ecd478be8fd 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -165,6 +165,7 @@ void cloth_init ( ClothModifierData *clmd )
clmd->sim_parms->editedframe = 0;
clmd->sim_parms->autoprotect = 25;
clmd->sim_parms->firstcachedframe = -1.0;
+ clmd->sim_parms->avg_spring_len = 0.0;
clmd->coll_parms->self_friction = 5.0;
clmd->coll_parms->friction = 5.0;
@@ -172,6 +173,8 @@ void cloth_init ( ClothModifierData *clmd )
clmd->coll_parms->epsilon = 0.015f;
clmd->coll_parms->flags = CLOTH_COLLSETTINGS_FLAG_ENABLED;
clmd->coll_parms->collision_list = NULL;
+ clmd->coll_parms->self_loop_count = 1.0;
+ clmd->coll_parms->selfepsilon = 0.75;
/* These defaults are copied from softbody.c's
* softbody_calc_forces() function.
@@ -269,130 +272,6 @@ void bvh_update_from_cloth(ClothModifierData *clmd, int moving)
bvh_update(bvh, moving);
}
-// unused in the moment, cloth needs quads from mesh
-DerivedMesh *CDDM_convert_to_triangle ( DerivedMesh *dm )
-{
- DerivedMesh *result = NULL;
- int i;
- int numverts = dm->getNumVerts ( dm );
- int numedges = dm->getNumEdges ( dm );
- int numfaces = dm->getNumFaces ( dm );
-
- MVert *mvert = CDDM_get_verts ( dm );
- MEdge *medge = CDDM_get_edges ( dm );
- MFace *mface = CDDM_get_faces ( dm );
-
- MVert *mvert2;
- MFace *mface2;
- unsigned int numtris=0;
- unsigned int numquads=0;
- int a = 0;
- int random = 0;
- int firsttime = 0;
- float vec1[3], vec2[3], vec3[3], vec4[3], vec5[3];
- float mag1=0, mag2=0;
-
- for ( i = 0; i < numfaces; i++ )
- {
- if ( mface[i].v4 )
- numquads++;
- else
- numtris++;
- }
-
- result = CDDM_from_template ( dm, numverts, 0, numtris + 2*numquads );
-
- if ( !result )
- return NULL;
-
- // do verts
- mvert2 = CDDM_get_verts ( result );
- for ( a=0; a<numverts; a++ )
- {
- MVert *inMV;
- MVert *mv = &mvert2[a];
-
- inMV = &mvert[a];
-
- DM_copy_vert_data ( dm, result, a, a, 1 );
- *mv = *inMV;
- }
-
-
- // do faces
- mface2 = CDDM_get_faces ( result );
- for ( a=0, i=0; a<numfaces; a++ )
- {
- MFace *mf = &mface2[i];
- MFace *inMF;
- inMF = &mface[a];
-
- /*
- DM_copy_face_data(dm, result, a, i, 1);
-
- *mf = *inMF;
- */
-
- if ( mface[a].v4 && random==1 )
- {
- mf->v1 = mface[a].v2;
- mf->v2 = mface[a].v3;
- mf->v3 = mface[a].v4;
- }
- else
- {
- mf->v1 = mface[a].v1;
- mf->v2 = mface[a].v2;
- mf->v3 = mface[a].v3;
- }
-
- mf->v4 = 0;
- mf->flag |= ME_SMOOTH;
-
- test_index_face ( mf, NULL, 0, 3 );
-
- if ( mface[a].v4 )
- {
- MFace *mf2;
-
- i++;
-
- mf2 = &mface2[i];
- /*
- DM_copy_face_data(dm, result, a, i, 1);
-
- *mf2 = *inMF;
- */
-
- if ( random==1 )
- {
- mf2->v1 = mface[a].v1;
- mf2->v2 = mface[a].v2;
- mf2->v3 = mface[a].v4;
- }
- else
- {
- mf2->v1 = mface[a].v4;
- mf2->v2 = mface[a].v1;
- mf2->v3 = mface[a].v3;
- }
- mf2->v4 = 0;
- mf2->flag |= ME_SMOOTH;
-
- test_index_face ( mf2, NULL, 0, 3 );
- }
-
- i++;
- }
-
- CDDM_calc_edges ( result );
- CDDM_calc_normals ( result );
-
- return result;
-
-}
-
-
DerivedMesh *CDDM_create_tearing ( ClothModifierData *clmd, DerivedMesh *dm )
{
DerivedMesh *result = NULL;
@@ -922,6 +801,11 @@ void cloth_free_modifier ( Object *ob, ClothModifierData *clmd )
// we save our faces for collision objects
if ( cloth->mfaces )
MEM_freeN ( cloth->mfaces );
+
+ if(cloth->edgehash)
+ BLI_edgehash_free ( cloth->edgehash, NULL );
+
+
/*
if(clmd->clothObject->facemarks)
MEM_freeN(clmd->clothObject->facemarks);
@@ -988,6 +872,11 @@ void cloth_free_modifier_extern ( ClothModifierData *clmd )
// we save our faces for collision objects
if ( cloth->mfaces )
MEM_freeN ( cloth->mfaces );
+
+ if(cloth->edgehash)
+ BLI_edgehash_free ( cloth->edgehash, NULL );
+
+
/*
if(clmd->clothObject->facemarks)
MEM_freeN(clmd->clothObject->facemarks);
@@ -1136,6 +1025,7 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d
clmd->clothObject->old_solver_type = 255;
// clmd->clothObject->old_collision_type = 255;
cloth = clmd->clothObject;
+ clmd->clothObject->edgehash = NULL;
}
else if ( !clmd->clothObject )
{
@@ -1236,8 +1126,7 @@ static void cloth_from_mesh ( Object *ob, ClothModifierData *clmd, DerivedMesh *
MFace *mface = CDDM_get_faces(dm);
unsigned int i = 0;
- /* Allocate our vertices.
- */
+ /* Allocate our vertices. */
clmd->clothObject->numverts = numverts;
clmd->clothObject->verts = MEM_callocN ( sizeof ( ClothVertex ) * clmd->clothObject->numverts, "clothVertex" );
if ( clmd->clothObject->verts == NULL )
@@ -1349,7 +1238,11 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
spring->kl = medge[i].v2;
VECSUB ( temp, cloth->verts[spring->kl].x, cloth->verts[spring->ij].x );
spring->restlen = sqrt ( INPR ( temp, temp ) );
- clmd->coll_parms->avg_spring_len += spring->restlen;
+ clmd->sim_parms->avg_spring_len += spring->restlen;
+ cloth->verts[spring->ij].avg_spring_len += spring->restlen;
+ cloth->verts[spring->kl].avg_spring_len += spring->restlen;
+ cloth->verts[spring->ij].spring_count++;
+ cloth->verts[spring->kl].spring_count++;
spring->type = CLOTH_SPRING_TYPE_STRUCTURAL;
spring->flags = 0;
spring->stiffness = (cloth->verts[spring->kl].struct_stiff + cloth->verts[spring->ij].struct_stiff) / 2.0;
@@ -1363,7 +1256,12 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
}
}
- clmd->coll_parms->avg_spring_len /= struct_springs;
+ clmd->sim_parms->avg_spring_len /= struct_springs;
+
+ for(i = 0; i < numverts; i++)
+ {
+ cloth->verts[i].avg_spring_len = cloth->verts[i].avg_spring_len * 0.49 / ((float)cloth->verts[i].spring_count);
+ }
// shear springs
for ( i = 0; i < numfaces; i++ )
@@ -1452,10 +1350,10 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
if ( edgelist )
MEM_freeN ( edgelist );
- BLI_edgehash_free ( edgehash, NULL );
+ cloth->edgehash = edgehash;
if(G.rt>0)
- printf("avg_len: %f\n",clmd->coll_parms->avg_spring_len);
+ printf("avg_len: %f\n",clmd->sim_parms->avg_spring_len);
return 1;
diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c
index da9312b01ab..9ec99548bb1 100644
--- a/source/blender/blenkernel/intern/collision.c
+++ b/source/blender/blenkernel/intern/collision.c
@@ -948,6 +948,29 @@ void cloth_collision_moving(ClothModifierData *clmd, ClothModifierData *coll_clm
cloth_collision_moving_tris(coll_clmd, clmd, tree2, tree1);
}
+void cloth_collision_self_static(ModifierData *md1, ModifierData *md2, CollisionTree *tree1, CollisionTree *tree2)
+{
+ ClothModifierData *clmd = (ClothModifierData *)md1;
+ CollisionModifierData *collmd = (CollisionModifierData *)md2;
+ CollPair *collpair = NULL;
+ Cloth *cloth1=NULL;
+ MFace *face1=NULL, *face2=NULL;
+ ClothVertex *verts1=NULL;
+ double distance = 0;
+ float epsilon = clmd->coll_parms->epsilon;
+ unsigned int i = 0;
+
+
+}
+
+/* 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];
+}
+
// cloth - object collisions
int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt)
{
@@ -956,12 +979,13 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt)
Cloth *cloth=NULL;
Object *coll_ob=NULL;
BVH *cloth_bvh=NULL;
- unsigned int i=0, j = 0, numfaces = 0, numverts = 0;
+ long i=0, j = 0, numfaces = 0, numverts = 0;
unsigned int result = 0, ic = 0, rounds = 0; // result counts applied collisions; ic is for debug output;
ClothVertex *verts = NULL;
float tnull[3] = {0,0,0};
int ret = 0;
ClothModifierData *tclmd;
+ int collisions = 0, count = 0;
if ((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) || !(((Cloth *)clmd->clothObject)->tree))
{
@@ -1006,7 +1030,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt)
collision_move_object(collmd, step + dt, step);
- bvh_traverse((ModifierData *)clmd, (ModifierData *)collmd, cloth_bvh->root, coll_bvh->root, step, cloth_collision_static);
+ bvh_traverse((ModifierData *)clmd, (ModifierData *)collmd, cloth_bvh->root, coll_bvh->root, step, cloth_collision_static, 0);
}
else
printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n");
@@ -1068,7 +1092,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt)
{
if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL)
{
- if(verts [i].goal >= SOFTGOALSNAP)
+ if(verts [i].flags & CLOTH_VERT_FLAG_PINNED)
{
continue;
}
@@ -1077,7 +1101,103 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt)
VECADD(verts[i].tx, verts[i].txold, verts[i].tv);
}
////////////////////////////////////////////////////////////
-
+
+
+ ////////////////////////////////////////////////////////////
+ // Test on *simple* selfcollisions
+ ////////////////////////////////////////////////////////////
+ if (clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_SELF)
+ {
+ collisions = 1;
+ verts = cloth->verts; // needed for openMP
+
+ for(count = 0; count < clmd->coll_parms->self_loop_count; count++)
+ {
+ if(collisions)
+ {
+ collisions = 0;
+ #pragma omp parallel for private(i,j, collisions) shared(verts, ret)
+ for(i = 0; i < cloth->numverts; i++)
+ {
+ for(j = i + 1; j < cloth->numverts; j++)
+ {
+ float temp[3];
+ float length = 0;
+ float mindistance = clmd->coll_parms->selfepsilon*(cloth->verts[i].avg_spring_len + cloth->verts[j].avg_spring_len);
+
+ if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL)
+ {
+ if((cloth->verts [i].flags & CLOTH_VERT_FLAG_PINNED)
+ && (cloth->verts [j].flags & CLOTH_VERT_FLAG_PINNED))
+ {
+ continue;
+ }
+ }
+
+ VECSUB(temp, verts[i].tx, verts[j].tx);
+
+ if ((ABS(temp[0]) > mindistance) || (ABS(temp[1]) > mindistance) || (ABS(temp[2]) > mindistance)) continue;
+
+ // check for adjacent points
+ if(BLI_edgehash_haskey (cloth->edgehash, i, j ))
+ {
+ continue;
+ }
+
+ length = Normalize(temp);
+
+ if(length < mindistance)
+ {
+ float correction = mindistance - length;
+
+ if(cloth->verts [i].flags & CLOTH_VERT_FLAG_PINNED)
+ {
+ VecMulf(temp, -correction);
+ VECADD(verts[j].tx, verts[j].tx, temp);
+ }
+ else if(cloth->verts [j].flags & CLOTH_VERT_FLAG_PINNED)
+ {
+ VecMulf(temp, correction);
+ VECADD(verts[i].tx, verts[i].tx, temp);
+ }
+ else
+ {
+ VecMulf(temp, -correction*0.5);
+ VECADD(verts[j].tx, verts[j].tx, temp);
+
+ VECSUB(verts[i].tx, verts[i].tx, temp);
+ }
+
+ collisions = 1;
+
+ if(!ret)
+ {
+ #pragma omp critical
+ {
+ ret = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ////////////////////////////////////////////////////////////
+
+ ////////////////////////////////////////////////////////////
+ // SELFCOLLISIONS: update velocities
+ ////////////////////////////////////////////////////////////
+ if(ret)
+ {
+ for(i = 0; i < cloth->numverts; i++)
+ {
+ if(!(cloth->verts [i].flags & CLOTH_VERT_FLAG_PINNED))
+ VECSUB(verts[i].tv, verts[i].tx, verts[i].txold);
+ }
+ }
+ ////////////////////////////////////////////////////////////
+ }
+
////////////////////////////////////////////////////////////
// moving collisions
//
@@ -1132,7 +1252,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt)
{
BVH *coll_bvh = coll_clmd->clothObject->tree;
- bvh_traverse(clmd, coll_clmd, cloth_bvh->root, coll_bvh->root, step, cloth_collision_moving);
+ bvh_traverse(clmd, coll_clmd, cloth_bvh->root, coll_bvh->root, step, cloth_collision_moving, 0);
}
else
printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n");
diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c
index 7c2721d9feb..bde56bb5fe1 100644
--- a/source/blender/blenkernel/intern/implicit.c
+++ b/source/blender/blenkernel/intern/implicit.c
@@ -1289,9 +1289,7 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s,
scaling = k + s->stiffness * ABS(clmd->sim_parms->max_struct-k);
- k = scaling / (clmd->coll_parms->avg_spring_len + FLT_EPSILON);
- if(G.rt>3)
- printf("struct scaling: %f\n", k);
+ k = scaling / (clmd->sim_parms->avg_spring_len + FLT_EPSILON);
// TODO: verify, half verified (couldn't see error)
mul_fvector_S(stretch_force, dir, k*(length-L));
@@ -1333,7 +1331,7 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s,
mul_fvector_S(dir, extent, 0.0f);
k = clmd->sim_parms->goalspring;
- k /= (clmd->coll_parms->avg_spring_len + FLT_EPSILON);
+ k /= (clmd->sim_parms->avg_spring_len + FLT_EPSILON);
k *= verts [s->ij].goal;
VECADDS(s->f, s->f, extent, k);
@@ -1353,7 +1351,7 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s,
k = clmd->sim_parms->bending;
scaling = k + s->stiffness * ABS(clmd->sim_parms->max_bend-k);
- cb = k = scaling / (20.0*(clmd->coll_parms->avg_spring_len + FLT_EPSILON));
+ cb = k = scaling / (20.0*(clmd->sim_parms->avg_spring_len + FLT_EPSILON));
if(G.rt>3)
printf("bend scaling: %f\n", k);
diff --git a/source/blender/blenkernel/intern/kdop.c b/source/blender/blenkernel/intern/kdop.c
index 817844dce6f..06525449bf4 100644
--- a/source/blender/blenkernel/intern/kdop.c
+++ b/source/blender/blenkernel/intern/kdop.c
@@ -71,6 +71,8 @@
#include "BIF_space.h"
#include "mydevice.h"
+#include "BKE_utildefines.h"
+
#ifdef _OPENMP
#include <omp.h>
@@ -387,12 +389,13 @@ DO_INLINE void bvh_calc_DOP_hull_from_faces(BVH * bvh, CollisionTree **tri, int
}
}
-DO_INLINE void bvh_calc_DOP_hull_static(BVH * bvh, CollisionTree **tri, int numfaces, float *bv)
+DO_INLINE void bvh_calc_DOP_hull_static(BVH * bvh, CollisionTree **tri, int numfaces, float *bv, CollisionTree *tree)
{
MFace *tempMFace = bvh->mfaces;
float *tempBV = bv;
float newminmax;
int i, j, k;
+
for (j = 0; j < numfaces; j++)
{
tempMFace = bvh->mfaces + (tri [j])->tri_index;
@@ -422,15 +425,31 @@ DO_INLINE void bvh_calc_DOP_hull_static(BVH * bvh, CollisionTree **tri, int numf
tempBV[(2 * i) + 1] = newminmax;
}
}
+
+ /* calculate normal of this face */
+ /* (code copied from cdderivedmesh.c) */
+ if(tempMFace->v4)
+ CalcNormFloat4(bvh->current_xold[tempMFace->v1].co, bvh->current_xold[tempMFace->v2].co,
+ bvh->current_xold[tempMFace->v3].co, bvh->current_xold[tempMFace->v4].co, tree->normal);
+ else
+ CalcNormFloat(bvh->current_xold[tempMFace->v1].co, bvh->current_xold[tempMFace->v2].co,
+ bvh->current_xold[tempMFace->v3].co, tree->normal);
+
+ tree->alpha = 0;
+
+
}
}
-DO_INLINE void bvh_calc_DOP_hull_moving(BVH * bvh, CollisionTree **tri, int numfaces, float *bv)
+DO_INLINE void bvh_calc_DOP_hull_moving(BVH * bvh, CollisionTree **tri, int numfaces, float *bv, CollisionTree *tree)
{
MFace *tempMFace = bvh->mfaces;
float *tempBV = bv;
float newminmax;
int i, j, k;
+
+ /* TODO: calculate normals */
+
for (j = 0; j < numfaces; j++)
{
tempMFace = bvh->mfaces + (tri [j])->tri_index;
@@ -614,7 +633,7 @@ void bvh_build (BVH *bvh)
tree->nodes[0] = tree->nodes[1] = tree->nodes[2] = tree->nodes[3] = NULL;
- bvh_calc_DOP_hull_static(bvh, &face_list[i], 1, tree->bv);
+ bvh_calc_DOP_hull_static(bvh, &face_list[i], 1, tree->bv, tree);
// inflate the bv with some epsilon
for (j = KDOP_START; j < KDOP_END; j++)
@@ -659,6 +678,19 @@ DO_INLINE int bvh_overlap(float *bv1, float *bv2)
return 1;
}
+// bvh_overlap_self - is it possbile for 2 bv's to selfcollide ?
+DO_INLINE int bvh_overlap_self(CollisionTree * tree1, CollisionTree * tree2)
+{
+ // printf("overlap: %f, q: %f\n", (saacos(INPR(tree1->normal, tree2->normal)) / 2.0)+MAX2(tree1->alpha, tree2->alpha), saacos(INPR(tree1->normal, tree2->normal)));
+
+ if((saacos(INPR(tree1->normal, tree2->normal)) / 2.0)+MAX2(tree1->alpha, tree2->alpha) > M_PI)
+ {
+ return 1;
+ }
+ else
+ return 0;
+}
+
/**
* bvh_traverse - traverse two bvh trees looking for potential collisions.
*
@@ -666,9 +698,9 @@ DO_INLINE int bvh_overlap(float *bv1, float *bv2)
* every other triangle that doesn't require any realloc, but uses
* much memory
*/
-int bvh_traverse ( ModifierData * md1, ModifierData * md2, CollisionTree * tree1, CollisionTree * tree2, float step, CM_COLLISION_RESPONSE collision_response)
+int bvh_traverse ( ModifierData * md1, ModifierData * md2, CollisionTree * tree1, CollisionTree * tree2, float step, CM_COLLISION_RESPONSE collision_response, int selfcollision)
{
- int i = 0, ret=0;
+ int i = 0, ret=0, overlap = 0;
/*
// Shouldn't be possible
@@ -678,7 +710,13 @@ int bvh_traverse ( ModifierData * md1, ModifierData * md2, CollisionTree * tree1
return 0;
}
*/
- if (bvh_overlap(tree1->bv, tree2->bv))
+
+ if(selfcollision)
+ overlap = bvh_overlap_self(tree1, tree2);
+ else
+ overlap = bvh_overlap(tree1->bv, tree2->bv);
+
+ if (overlap)
{
// Check if this node in the first tree is a leaf
if (tree1->isleaf)
@@ -698,7 +736,7 @@ int bvh_traverse ( ModifierData * md1, ModifierData * md2, CollisionTree * tree1
for (i = 0; i < 4; i++)
{
// Only traverse nodes that exist.
- if (tree2->nodes[i] && bvh_traverse (md1, md2, tree1, tree2->nodes[i], step, collision_response))
+ if (tree2->nodes[i] && bvh_traverse (md1, md2, tree1, tree2->nodes[i], step, collision_response, selfcollision))
ret = 1;
}
}
@@ -709,7 +747,7 @@ int bvh_traverse ( ModifierData * md1, ModifierData * md2, CollisionTree * tree1
for (i = 0; i < 4; i++)
{
// Only traverse nodes that exist.
- if (tree1->nodes [i] && bvh_traverse (md1, md2, tree1->nodes[i], tree2, step, collision_response))
+ if (tree1->nodes [i] && bvh_traverse (md1, md2, tree1->nodes[i], tree2, step, collision_response, selfcollision))
ret = 1;
}
}
@@ -717,12 +755,13 @@ int bvh_traverse ( ModifierData * md1, ModifierData * md2, CollisionTree * tree1
return ret;
}
-
// bottom up update of bvh tree:
// join the 4 children here
-void bvh_join(CollisionTree * tree)
+void bvh_join(CollisionTree *tree)
{
int i = 0, j = 0;
+ float max = 0;
+
if (!tree)
return;
@@ -743,10 +782,27 @@ void bvh_join(CollisionTree * tree)
tree->bv[(2 * j) + 1] = tree->nodes[i]->bv[(2 * j) + 1];
}
}
+
+ /* for selfcollisions */
+ if(!i)
+ {
+ tree->alpha = tree->nodes[i]->alpha;
+ VECCOPY(tree->normal, tree->nodes[i]->normal);
+ }
+ else
+ {
+ tree->alpha += saacos(INPR(tree->normal, tree->nodes[i]->normal)) / 2.0;
+ VECADD(tree->normal, tree->normal, tree->nodes[i]->normal);
+ VecMulf(tree->normal, 0.5);
+ max = MAX2(max, tree->nodes[i]->alpha);
+ }
+
}
else
break;
}
+
+ tree->alpha += max;
}
// update static bvh
@@ -765,9 +821,9 @@ void bvh_update(BVH * bvh, int moving)
leaf->parent->traversed = 0;
}
if(!moving)
- bvh_calc_DOP_hull_static(bvh, &leaf, 1, leaf->bv);
+ bvh_calc_DOP_hull_static(bvh, &leaf, 1, leaf->bv, leaf);
else
- bvh_calc_DOP_hull_moving(bvh, &leaf, 1, leaf->bv);
+ bvh_calc_DOP_hull_moving(bvh, &leaf, 1, leaf->bv, leaf);
// inflate the bv with some epsilon
for (j = KDOP_START; j < KDOP_END; j++)
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index 049146fb05f..ead7f4f2c9e 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -4960,8 +4960,6 @@ static void clothModifier_initData(ModifierData *md)
return;
cloth_init (clmd);
- if(G.rt >0)
- printf("clothModifier_initData\n");
}
static DerivedMesh *clothModifier_applyModifier(ModifierData *md, Object *ob,
diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h
index 2b18142258c..40abe012a5a 100644
--- a/source/blender/makesdna/DNA_cloth_types.h
+++ b/source/blender/makesdna/DNA_cloth_types.h
@@ -82,21 +82,21 @@ typedef struct SimulationSettings
float max_struct; /* max structural scaling value, min is "structural" */
float max_shear; /* max shear scaling value, UNUSED */
int firstcachedframe;
- int pad;
+ float avg_spring_len; /* used for normalized springs */
}
SimulationSettings;
typedef struct CollisionSettings
{
- float epsilon; /* The radius of a particle in the cloth. */
+ float epsilon; /* min distance for collisions. */
float self_friction; /* Fiction/damping with self contact. */
float friction; /* Friction/damping applied on contact with other object.*/
- short collision_type; /* which collision system is used. */
+ short self_loop_count; /* How many iterations for the selfcollision loop */
short loop_count; /* How many iterations for the collision loop. */
struct LinkNode *collision_list; /* e.g. pointer to temp memory for collisions */
int flags; /* collision flags defined in BKE_cloth.h */
- float avg_spring_len; /* for selfcollision */
+ float selfepsilon; /* for selfcollision */
}
CollisionSettings;
@@ -125,6 +125,7 @@ typedef struct Cloth
struct MFace *mfaces;
struct Implicit_Data *implicit; /* our implicit solver connects to this pointer */
struct Implicit_Data *implicitEM; /* our implicit solver connects to this pointer */
+ struct EdgeHash *edgehash; /* used for selfcollisions */
}
Cloth;
diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c
index 8ac960e92cd..62f7300fc98 100644
--- a/source/blender/src/buttons_object.c
+++ b/source/blender/src/buttons_object.c
@@ -5322,8 +5322,18 @@ static void object_panel_cloth_II(Object *ob)
if (clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_ENABLED)
{
uiDefButF(block, NUM, REDRAWBUTSOBJECT, "Min Distance:", 160,60,150,20, &clmd->coll_parms->epsilon, 0.001f, 1.0, 0.01f, 0, "Minimum distance between collision objects before collision response takes in, can be changed for each frame");
- uiDefButS(block, NUM, REDRAWBUTSOBJECT, "Collision Quality:", 10,40,150,20, &clmd->coll_parms->loop_count, 1.0, 100.0, 1.0, 0, "How many collision iterations should be done. (higher = better = slower), can be changed for each frame");
+ uiDefButS(block, NUM, REDRAWBUTSOBJECT, "Collision Quality:", 10,40,150,20, &clmd->coll_parms->loop_count, 1.0, 20.0, 1.0, 0, "How many collision iterations should be done. (higher = better = slower), can be changed for each frame");
uiDefButF(block, NUM, REDRAWBUTSOBJECT, "Friction:", 160,40,150,20, &clmd->coll_parms->friction, 0.0, 10.0, 1.0, 0, "Friction force if a collision happened (high=slower movement when collided)");
+
+ uiDefButBitI(block, TOG, CLOTH_COLLSETTINGS_FLAG_SELF, B_CLOTH_RENEW, "Enable selfcollisions", 10,20,150,20, &clmd->coll_parms->flags, 0, 0, 0, 0, "Enable selfcollisions with this object");
+ if (clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_SELF)
+ {
+ uiDefButF(block, NUM, REDRAWBUTSOBJECT, "Min Distance:", 160,20,150,20, &clmd->coll_parms->selfepsilon, 0.5f, 1.0, 0.01f, 0, "0.5 means no distance at all, 1.0 is maximum distance");
+ // self_loop_count
+ uiDefButS(block, NUM, REDRAWBUTSOBJECT, "Selfcoll Quality:", 10,0,150,20, &clmd->coll_parms->self_loop_count, 1.0, 10.0, 1.0, 0, "How many selfcollision iterations should be done. (higher = better = slower), can be changed for each frame");
+ }
+ else
+ uiDefBut(block, LABEL, 0, "",160,20,150,20, NULL, 0.0, 0, 0, 0, "");
}
else
uiDefBut(block, LABEL, 0, "",160,60,150,20, NULL, 0.0, 0, 0, 0, "");