Fixed typo which resulted in jumping cloth when collisions where enabled, fixed collision list memory leak. Ready to put real collision detection/response in.

This commit is contained in:
Daniel Genrich
2007-10-28 19:07:51 +00:00
parent 4f72523654
commit 67f8ca0b66
4 changed files with 61 additions and 36 deletions

View File

@@ -46,9 +46,10 @@ struct MFace;
struct DerivedMesh;
// this is needed for inlining behaviour
#ifndef _WIN32
#define LINUX
#define DO_INLINE inline
#define DO_INLINE
#else
#define DO_INLINE
#endif

View File

@@ -96,7 +96,7 @@ BVH *bvh_build_from_float3 (MFace *mfaces, unsigned int numfaces, float (*x)[3],
void bvh_free ( BVH *bvh );
// checks two bounding volume hierarchies for potential collisions and returns some list with those
int bvh_traverse(CollisionTree *tree1, CollisionTree *tree2, LinkNode *collision_list);
int bvh_traverse(CollisionTree *tree1, CollisionTree *tree2, LinkNode **collision_list);
// update bounding volumes, needs updated positions in bvh->x
void bvh_update_from_mvert(BVH * bvh, MVert *x, unsigned int numverts, MVert *xnew, int moving);

View File

@@ -581,21 +581,32 @@ DO_INLINE void mul_bfmatrix_lfvector( float (*to)[3], fmatrix3x3 *from, float (*
/* process off-diagonal entries (every off-diagonal entry needs to be symmetric) */
// TODO: pragma below is wrong, correct it!
// #pragma omp parallel for shared(to,from, fLongVector) private(i)
#pragma omp parallel for shared(to,from, fLongVector) private(i)
for(i = from[0].vcount; i < from[0].vcount+from[0].scount; i++)
{
unsigned int row = from[i].r;
unsigned int column = from[i].c;
// muladd_fmatrix_fvector(to[from[i].c], from[i].m, fLongVector[from[i].r]);
to[from[i].c][0] += INPR(from[i].m[0],fLongVector[from[i].r]);
to[from[i].c][1] += INPR(from[i].m[1],fLongVector[from[i].r]);
to[from[i].c][2] += INPR(from[i].m[2],fLongVector[from[i].r]);
to[column][0] += INPR(from[i].m[0],fLongVector[row]);
to[column][1] += INPR(from[i].m[1],fLongVector[row]);
to[column][2] += INPR(from[i].m[2],fLongVector[row]);
}
#pragma omp parallel for shared(to,from, fLongVector) private(i)
for(i = from[0].vcount; i < from[0].vcount+from[0].scount; i++)
{
unsigned int row = from[i].r;
unsigned int column = from[i].c;
// muladd_fmatrix_fvector(to[from[i].r], from[i].m, fLongVector[from[i].c]);
to[from[i].r][0] += INPR(from[i].m[0],fLongVector[from[i].c]);
to[from[i].r][1] += INPR(from[i].m[1],fLongVector[from[i].c]);
to[from[i].r][2] += INPR(from[i].m[2],fLongVector[from[i].c]);
to[row][0] += INPR(from[i].m[0],fLongVector[column]);
to[row][1] += INPR(from[i].m[1],fLongVector[column]);
to[row][2] += INPR(from[i].m[2],fLongVector[column]);
}
}
/* SPARSE SYMMETRIC add big matrix with big matrix: A = B + C*/
DO_INLINE void add_bfmatrix_bfmatrix( fmatrix3x3 *to, fmatrix3x3 *from, fmatrix3x3 *matrix)
@@ -1313,7 +1324,6 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec
float kd, ks;
LinkNode *search = cloth->springs;
VECCOPY(gravity, clmd->sim_parms.gravity);
mul_fvector_S(gravity, gravity, 0.001f); /* scale gravity force */
@@ -1406,7 +1416,7 @@ void simulate_implicit_euler(lfVector *Vnew, lfVector *lX, lfVector *lV, lfVecto
initdiag_bfmatrix(A, I);
zero_lfvector(dV, numverts);
subadd_bfmatrixS_bfmatrixS(A, dFdV, dt, dFdX, (dt*dt));
subadd_bfmatrixS_bfmatrixS(A, dFdV, dt, dFdX, (dt*dt));
mul_bfmatrix_lfvector(dFdXmV, dFdX, lV);
@@ -1492,12 +1502,12 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase
// call collision function
result = cloth_bvh_objcollision(clmd, step + dt, step, dt);
// copy corrected positions back to simulation
memcpy(cloth->current_xold, cloth->current_x, sizeof(lfVector) * numverts);
memcpy(id->Xnew, cloth->current_x, sizeof(lfVector) * numverts);
// copy corrected positions back to simulation
if(result)
{
memcpy(cloth->current_xold, cloth->current_x, sizeof(lfVector) * numverts);
memcpy(id->Xnew, cloth->current_x, sizeof(lfVector) * numverts);
for(i = 0; i < numverts; i++)
{
VECCOPY(id->Vnew[i], cloth->current_v[i]);
@@ -2161,6 +2171,8 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep,
Object *ob2 = NULL;
BVH *bvh1 = NULL, *bvh2 = NULL;
LinkNode *collision_list = NULL;
unsigned int i = 0;
int collisions = 0;
if (!(((Cloth *)clmd->clothObject)->tree))
{
@@ -2189,9 +2201,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep,
// check if there is a bounding volume hierarchy
if (collmd->tree)
{
int collisions = 0;
{
bvh2 = collmd->tree;
// update position + bvh of collision object
@@ -2199,14 +2209,13 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep,
bvh_update_from_mvert(collmd->tree, collmd->current_x, collmd->numverts, NULL, 0);
// fill collision list
collisions = bvh_traverse(bvh1->root, bvh2->root, collision_list);
printf("Found %d collisions.\n", collisions);
collisions += bvh_traverse(bvh1->root, bvh2->root, &collision_list);
// free collision list
if(collision_list)
{
LinkNode *search = collision_list;
while(search)
{
CollisionPair *coll_pair = search->link;
@@ -2220,7 +2229,15 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep,
}
}
}
return 0;
//////////////////////////////////////////////
// update velocities + positions
//////////////////////////////////////////////
for(i = 0; i < cloth->numverts; i++)
{
VECADD(cloth->current_x[i], cloth->current_xold[i], cloth->current_v[i]);
}
//////////////////////////////////////////////
return collisions;
}

View File

@@ -414,7 +414,7 @@ void bvh_calc_DOP_hull_static(BVH * bvh, CollisionTree **tri, int numfaces, floa
tempBV[(2 * i)] = newminmax;
if ((newminmax > tempBV[(2 * i) + 1])|| (k == 0 && j == 0))
tempBV[(2 * i) + 1] = newminmax;
}
}
}
}
}
@@ -593,20 +593,20 @@ BVH *bvh_build (BVH *bvh, MFace *mfaces, unsigned int numfaces)
if(bvh->mfaces)
{
bvh->root->point_index[0] = mfaces[i].v1;
bvh->root->point_index[1] = mfaces[i].v2;
bvh->root->point_index[2] = mfaces[i].v3;
tree->point_index[0] = mfaces[i].v1;
tree->point_index[1] = mfaces[i].v2;
tree->point_index[2] = mfaces[i].v3;
if(mfaces[i].v4)
bvh->root->point_index[3] = mfaces[i].v4;
tree->point_index[3] = mfaces[i].v4;
else
bvh->root->point_index[3] = -1;
tree->point_index[3] = -1;
}
else
{
bvh->root->point_index[0] = i;
bvh->root->point_index[1] = -1;
bvh->root->point_index[2] = -1;
bvh->root->point_index[3] = -1;
tree->point_index[0] = i;
tree->point_index[1] = -1;
tree->point_index[2] = -1;
tree->point_index[3] = -1;
}
tree->isleaf = 1;
@@ -641,7 +641,7 @@ BVH *bvh_build (BVH *bvh, MFace *mfaces, unsigned int numfaces)
// build root bvh
bvh_calc_DOP_hull_from_faces(bvh, face_list, bvh->numfaces, bvh->root->bv);
// This is the traversal function.
bvh_div_env_node(bvh, bvh->root, face_list, 0, bvh->numfaces-1, 0, nlink);
if (face_list)
@@ -673,6 +673,7 @@ BVH *bvh_build_from_mvert (MFace *mfaces, unsigned int numfaces, MVert *x, unsig
bvh->epsilon = epsilon;
bvh->numfaces = numfaces;
bvh->mfaces = mfaces;
// we have no faces, we save seperate points
if(!mfaces)
@@ -718,6 +719,7 @@ BVH *bvh_build_from_float3 (MFace *mfaces, unsigned int numfaces, float (*x)[3],
bvh->epsilon = epsilon;
bvh->numfaces = numfaces;
bvh->mfaces = mfaces;
// we have no faces, we save seperate points
if(!mfaces)
@@ -729,9 +731,12 @@ BVH *bvh_build_from_float3 (MFace *mfaces, unsigned int numfaces, float (*x)[3],
bvh->xnew = (MVert *)MEM_callocN(sizeof(MVert)*numverts, "BVH MVert");
for(i = 0; i < numverts; i++)
{
VECCOPY(bvh->xnew[i].co, x[i]);
}
bvh->x = MEM_dupallocN(bvh->xnew);
tree = (CollisionTree *)MEM_callocN(sizeof(CollisionTree), "CollisionTree");
if (tree == NULL)
@@ -773,7 +778,7 @@ int bvh_overlap(float *bv1, float *bv2)
* every other triangle that doesn't require any realloc, but uses
* much memory
*/
int bvh_traverse(CollisionTree *tree1, CollisionTree *tree2, LinkNode *collision_list)
int bvh_traverse(CollisionTree *tree1, CollisionTree *tree2, LinkNode **collision_list)
{
int i = 0, ret = 0, tempret = 0;
@@ -786,6 +791,7 @@ int bvh_traverse(CollisionTree *tree1, CollisionTree *tree2, LinkNode *collision
if (tree2->isleaf)
{
// save potential colliding triangles
CollisionPair *collpair = (CollisionPair *)MEM_callocN(sizeof(CollisionPair), "CollisionPair");
VECCOPY(collpair->point_indexA, tree1->point_index);
@@ -794,7 +800,7 @@ int bvh_traverse(CollisionTree *tree1, CollisionTree *tree2, LinkNode *collision
VECCOPY(collpair->point_indexB, tree2->point_index);
collpair->point_indexB[3] = tree2->point_index[3];
BLI_linklist_append(&collision_list, collpair);
BLI_linklist_append(&collision_list[0], collpair);
return 1;
}
@@ -870,6 +876,7 @@ void bvh_update(BVH * bvh, int moving)
{
leaf->parent->traversed = 0;
}
if(!moving)
bvh_calc_DOP_hull_static(bvh, &leaf, 1, leaf->bv);
else